Merge "Add a module for Material 3 apdative" into androidx-main
diff --git a/activity/activity-compose/api/current.ignore b/activity/activity-compose/api/current.ignore
new file mode 100644
index 0000000..771cee8
--- /dev/null
+++ b/activity/activity-compose/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.activity.compose.ManagedActivityResultLauncher#launch(I, androidx.core.app.ActivityOptionsCompat) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.compose.ManagedActivityResultLauncher.launch(I input, androidx.core.app.ActivityOptionsCompat options)
diff --git a/activity/activity-compose/api/current.txt b/activity/activity-compose/api/current.txt
index ff9df4f..48d220b 100644
--- a/activity/activity-compose/api/current.txt
+++ b/activity/activity-compose/api/current.txt
@@ -36,7 +36,7 @@
 
   public final class ManagedActivityResultLauncher<I, O> extends androidx.activity.result.ActivityResultLauncher<I> {
     method public androidx.activity.result.contract.ActivityResultContract<I,?> getContract();
-    method public void launch(I? input, androidx.core.app.ActivityOptionsCompat? options);
+    method public void launch(I input, androidx.core.app.ActivityOptionsCompat? options);
     method @Deprecated public void unregister();
   }
 
diff --git a/activity/activity-compose/api/public_plus_experimental_current.txt b/activity/activity-compose/api/public_plus_experimental_current.txt
index ff9df4f..48d220b 100644
--- a/activity/activity-compose/api/public_plus_experimental_current.txt
+++ b/activity/activity-compose/api/public_plus_experimental_current.txt
@@ -36,7 +36,7 @@
 
   public final class ManagedActivityResultLauncher<I, O> extends androidx.activity.result.ActivityResultLauncher<I> {
     method public androidx.activity.result.contract.ActivityResultContract<I,?> getContract();
-    method public void launch(I? input, androidx.core.app.ActivityOptionsCompat? options);
+    method public void launch(I input, androidx.core.app.ActivityOptionsCompat? options);
     method @Deprecated public void unregister();
   }
 
diff --git a/activity/activity-compose/api/restricted_current.ignore b/activity/activity-compose/api/restricted_current.ignore
new file mode 100644
index 0000000..771cee8
--- /dev/null
+++ b/activity/activity-compose/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.activity.compose.ManagedActivityResultLauncher#launch(I, androidx.core.app.ActivityOptionsCompat) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.compose.ManagedActivityResultLauncher.launch(I input, androidx.core.app.ActivityOptionsCompat options)
diff --git a/activity/activity-compose/api/restricted_current.txt b/activity/activity-compose/api/restricted_current.txt
index ff9df4f..48d220b 100644
--- a/activity/activity-compose/api/restricted_current.txt
+++ b/activity/activity-compose/api/restricted_current.txt
@@ -36,7 +36,7 @@
 
   public final class ManagedActivityResultLauncher<I, O> extends androidx.activity.result.ActivityResultLauncher<I> {
     method public androidx.activity.result.contract.ActivityResultContract<I,?> getContract();
-    method public void launch(I? input, androidx.core.app.ActivityOptionsCompat? options);
+    method public void launch(I input, androidx.core.app.ActivityOptionsCompat? options);
     method @Deprecated public void unregister();
   }
 
diff --git a/activity/activity-ktx/api/current.ignore b/activity/activity-ktx/api/current.ignore
new file mode 100644
index 0000000..eabc0b7
--- /dev/null
+++ b/activity/activity-ktx/api/current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.activity.result.ActivityResultCallerKt#registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O>, I, androidx.activity.result.ActivityResultRegistry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit>) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.ActivityResultCallerKt.registerForActivityResult(androidx.activity.result.ActivityResultCaller arg1, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback)
+InvalidNullConversion: androidx.activity.result.ActivityResultCallerKt#registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O>, I, kotlin.jvm.functions.Function1<? super O,kotlin.Unit>) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.ActivityResultCallerKt.registerForActivityResult(androidx.activity.result.ActivityResultCaller arg1, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback)
diff --git a/activity/activity-ktx/api/current.txt b/activity/activity-ktx/api/current.txt
index d9a358f..4f387c3 100644
--- a/activity/activity-ktx/api/current.txt
+++ b/activity/activity-ktx/api/current.txt
@@ -15,8 +15,8 @@
 package androidx.activity.result {
 
   public final class ActivityResultCallerKt {
-    method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
-    method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+    method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+    method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
   }
 
   public final class ActivityResultKt {
diff --git a/activity/activity-ktx/api/public_plus_experimental_current.txt b/activity/activity-ktx/api/public_plus_experimental_current.txt
index d9a358f..4f387c3 100644
--- a/activity/activity-ktx/api/public_plus_experimental_current.txt
+++ b/activity/activity-ktx/api/public_plus_experimental_current.txt
@@ -15,8 +15,8 @@
 package androidx.activity.result {
 
   public final class ActivityResultCallerKt {
-    method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
-    method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+    method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+    method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
   }
 
   public final class ActivityResultKt {
diff --git a/activity/activity-ktx/api/restricted_current.ignore b/activity/activity-ktx/api/restricted_current.ignore
new file mode 100644
index 0000000..eabc0b7
--- /dev/null
+++ b/activity/activity-ktx/api/restricted_current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.activity.result.ActivityResultCallerKt#registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O>, I, androidx.activity.result.ActivityResultRegistry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit>) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.ActivityResultCallerKt.registerForActivityResult(androidx.activity.result.ActivityResultCaller arg1, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback)
+InvalidNullConversion: androidx.activity.result.ActivityResultCallerKt#registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O>, I, kotlin.jvm.functions.Function1<? super O,kotlin.Unit>) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.ActivityResultCallerKt.registerForActivityResult(androidx.activity.result.ActivityResultCaller arg1, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback)
diff --git a/activity/activity-ktx/api/restricted_current.txt b/activity/activity-ktx/api/restricted_current.txt
index d9a358f..4f387c3 100644
--- a/activity/activity-ktx/api/restricted_current.txt
+++ b/activity/activity-ktx/api/restricted_current.txt
@@ -15,8 +15,8 @@
 package androidx.activity.result {
 
   public final class ActivityResultCallerKt {
-    method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
-    method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+    method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+    method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
   }
 
   public final class ActivityResultKt {
diff --git a/activity/activity/api/current.ignore b/activity/activity/api/current.ignore
index cd68216..3da4564 100644
--- a/activity/activity/api/current.ignore
+++ b/activity/activity/api/current.ignore
@@ -1,3 +1,13 @@
 // Baseline format: 1.0
+InvalidNullConversion: androidx.activity.result.ActivityResultCallback#onActivityResult(O) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter result in androidx.activity.result.ActivityResultCallback.onActivityResult(O result)
+InvalidNullConversion: androidx.activity.result.contract.ActivityResultContract#createIntent(android.content.Context, I) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.contract.ActivityResultContract.createIntent(android.content.Context context, I input)
+InvalidNullConversion: androidx.activity.result.contract.ActivityResultContract#getSynchronousResult(android.content.Context, I) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.contract.ActivityResultContract.getSynchronousResult(android.content.Context context, I input)
+InvalidNullConversion: androidx.activity.result.contract.ActivityResultContract.SynchronousResult#SynchronousResult(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.activity.result.contract.ActivityResultContract.SynchronousResult(T value)
+
+
 RemovedMethod: androidx.activity.ComponentActivity#onBackPressed():
     Removed method androidx.activity.ComponentActivity.onBackPressed()
diff --git a/activity/activity/api/current.txt b/activity/activity/api/current.txt
index 7d61b26..c7520eb 100644
--- a/activity/activity/api/current.txt
+++ b/activity/activity/api/current.txt
@@ -176,7 +176,7 @@
   }
 
   public fun interface ActivityResultCallback<O> {
-    method public void onActivityResult(O? result);
+    method public void onActivityResult(O result);
   }
 
   public interface ActivityResultCaller {
@@ -255,15 +255,15 @@
 
   public abstract class ActivityResultContract<I, O> {
     ctor public ActivityResultContract();
-    method public abstract android.content.Intent createIntent(android.content.Context context, I? input);
-    method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<O>? getSynchronousResult(android.content.Context context, I? input);
-    method public abstract O! parseResult(int resultCode, android.content.Intent? intent);
+    method public abstract android.content.Intent createIntent(android.content.Context context, I input);
+    method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<O>? getSynchronousResult(android.content.Context context, I input);
+    method public abstract O parseResult(int resultCode, android.content.Intent? intent);
   }
 
   public static final class ActivityResultContract.SynchronousResult<T> {
-    ctor public ActivityResultContract.SynchronousResult(T? value);
-    method public T! getValue();
-    property public final T! value;
+    ctor public ActivityResultContract.SynchronousResult(T value);
+    method public T getValue();
+    property public final T value;
   }
 
   public final class ActivityResultContracts {
diff --git a/activity/activity/api/public_plus_experimental_current.txt b/activity/activity/api/public_plus_experimental_current.txt
index 7d61b26..c7520eb 100644
--- a/activity/activity/api/public_plus_experimental_current.txt
+++ b/activity/activity/api/public_plus_experimental_current.txt
@@ -176,7 +176,7 @@
   }
 
   public fun interface ActivityResultCallback<O> {
-    method public void onActivityResult(O? result);
+    method public void onActivityResult(O result);
   }
 
   public interface ActivityResultCaller {
@@ -255,15 +255,15 @@
 
   public abstract class ActivityResultContract<I, O> {
     ctor public ActivityResultContract();
-    method public abstract android.content.Intent createIntent(android.content.Context context, I? input);
-    method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<O>? getSynchronousResult(android.content.Context context, I? input);
-    method public abstract O! parseResult(int resultCode, android.content.Intent? intent);
+    method public abstract android.content.Intent createIntent(android.content.Context context, I input);
+    method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<O>? getSynchronousResult(android.content.Context context, I input);
+    method public abstract O parseResult(int resultCode, android.content.Intent? intent);
   }
 
   public static final class ActivityResultContract.SynchronousResult<T> {
-    ctor public ActivityResultContract.SynchronousResult(T? value);
-    method public T! getValue();
-    property public final T! value;
+    ctor public ActivityResultContract.SynchronousResult(T value);
+    method public T getValue();
+    property public final T value;
   }
 
   public final class ActivityResultContracts {
diff --git a/activity/activity/api/restricted_current.ignore b/activity/activity/api/restricted_current.ignore
index cd68216..3da4564 100644
--- a/activity/activity/api/restricted_current.ignore
+++ b/activity/activity/api/restricted_current.ignore
@@ -1,3 +1,13 @@
 // Baseline format: 1.0
+InvalidNullConversion: androidx.activity.result.ActivityResultCallback#onActivityResult(O) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter result in androidx.activity.result.ActivityResultCallback.onActivityResult(O result)
+InvalidNullConversion: androidx.activity.result.contract.ActivityResultContract#createIntent(android.content.Context, I) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.contract.ActivityResultContract.createIntent(android.content.Context context, I input)
+InvalidNullConversion: androidx.activity.result.contract.ActivityResultContract#getSynchronousResult(android.content.Context, I) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.contract.ActivityResultContract.getSynchronousResult(android.content.Context context, I input)
+InvalidNullConversion: androidx.activity.result.contract.ActivityResultContract.SynchronousResult#SynchronousResult(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.activity.result.contract.ActivityResultContract.SynchronousResult(T value)
+
+
 RemovedMethod: androidx.activity.ComponentActivity#onBackPressed():
     Removed method androidx.activity.ComponentActivity.onBackPressed()
diff --git a/activity/activity/api/restricted_current.txt b/activity/activity/api/restricted_current.txt
index dc7e159..9244450 100644
--- a/activity/activity/api/restricted_current.txt
+++ b/activity/activity/api/restricted_current.txt
@@ -175,7 +175,7 @@
   }
 
   public fun interface ActivityResultCallback<O> {
-    method public void onActivityResult(O? result);
+    method public void onActivityResult(O result);
   }
 
   public interface ActivityResultCaller {
@@ -254,15 +254,15 @@
 
   public abstract class ActivityResultContract<I, O> {
     ctor public ActivityResultContract();
-    method public abstract android.content.Intent createIntent(android.content.Context context, I? input);
-    method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<O>? getSynchronousResult(android.content.Context context, I? input);
-    method public abstract O! parseResult(int resultCode, android.content.Intent? intent);
+    method public abstract android.content.Intent createIntent(android.content.Context context, I input);
+    method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<O>? getSynchronousResult(android.content.Context context, I input);
+    method public abstract O parseResult(int resultCode, android.content.Intent? intent);
   }
 
   public static final class ActivityResultContract.SynchronousResult<T> {
-    ctor public ActivityResultContract.SynchronousResult(T? value);
-    method public T! getValue();
-    property public final T! value;
+    ctor public ActivityResultContract.SynchronousResult(T value);
+    method public T getValue();
+    property public final T value;
   }
 
   public final class ActivityResultContracts {
diff --git a/annotation/annotation/src/commonMain/kotlin/androidx/annotation/RestrictTo.kt b/annotation/annotation/src/commonMain/kotlin/androidx/annotation/RestrictTo.kt
index 1b5036e..6a52ecb 100644
--- a/annotation/annotation/src/commonMain/kotlin/androidx/annotation/RestrictTo.kt
+++ b/annotation/annotation/src/commonMain/kotlin/androidx/annotation/RestrictTo.kt
@@ -19,20 +19,21 @@
 import androidx.annotation.RestrictTo.Scope
 
 /**
- * Denotes that the annotated element should only be accessed from within a
- * specific scope (as defined by [Scope]).
+ * Denotes that the annotated element should only be accessed from within a specific scope (as
+ * defined by [Scope]).
  *
- *
- * Example of restricting usage within a library (based on gradle group ID):
+ * Example of restricting usage within a library (based on Gradle group ID):
  * ```
  * @RestrictTo(GROUP_ID)
  * public void resetPaddingToInitialValues() { ...
  * ```
+ *
  * Example of restricting usage to tests:
  * ```
  * @RestrictTo(Scope.TESTS)
  * public abstract int getUserId();
  * ```
+ *
  * Example of restricting usage to subclasses:
  * ```
  * @RestrictTo(Scope.SUBCLASSES)
@@ -53,56 +54,62 @@
 )
 public expect annotation class RestrictTo(
     /**
-     * The scope to which usage should be restricted.
+     * The scope(s) to which usage should be restricted.
      */
     vararg val value: Scope
 ) {
     public enum class Scope {
         /**
-         * Restrict usage to code within the same library (e.g. the same
-         * gradle group ID and artifact ID).
+         * Restrict usage to code within the same library (e.g. the same Gradle group ID and
+         * artifact ID).
          */
         LIBRARY,
 
         /**
          * Restrict usage to code within the same group of libraries.
-         * This corresponds to the gradle group ID.
+         *
+         * This corresponds to the Gradle group ID.
          */
         LIBRARY_GROUP,
 
         /**
-         * Restrict usage to code within packages whose groups share
-         * the same library group prefix up to the last ".", so for
-         * example libraries foo.bar:lib1 and foo.baz:lib2 share
-         * the prefix "foo." and so they can use each other's
-         * apis that are restricted to this scope. Similarly for
-         * com.foo.bar:lib1 and com.foo.baz:lib2 where they share
-         * "com.foo.". Library com.bar.qux:lib3 however will not
-         * be able to use the restricted api because it only
-         * shares the prefix "com." and not all the way until the
-         * last ".".
+         * Restrict usage to code within packages whose Gradle group IDs share the same prefix up to
+         * the last `.` separator.
+         *
+         * For example, libraries `foo.bar:lib1` and `foo.baz:lib2` share the `foo.` prefix and can
+         * therefore use each other's APIs that are restricted to this scope. Similar applies to
+         * libraries `com.foo.bar:lib1` and `com.foo.baz:lib2`, which share the `com.foo.` prefix.
+         *
+         * Library `com.bar.qux:lib3`, however, will not be able to use the restricted API because
+         * it only shares the prefix `com.` and not all the way until the last `.` separator.
          */
         LIBRARY_GROUP_PREFIX,
 
         /**
-         * Restrict usage to code within the same group ID (based on gradle
-         * group ID). This is an alias for [LIBRARY_GROUP_PREFIX].
+         * Restrict usage to code within the same group ID (based on Gradle group ID).
          *
-         * @deprecated Use [LIBRARY_GROUP_PREFIX] instead
+         * This is an alias for [LIBRARY_GROUP_PREFIX].
          */
-        @Deprecated("Use LIBRARY_GROUP_PREFIX instead.")
+        @Deprecated(
+            message = "Use @RestrictTo(LIBRARY_GROUP_PREFIX) instead",
+            replaceWith = ReplaceWith(
+                "LIBRARY_GROUP_PREFIX",
+                "androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX"
+            )
+        )
         GROUP_ID,
 
         /**
-         * Restrict usage to tests.
+         * Restrict usage to test source sets or code annotated with the [TESTS] restriction scope.
+         *
+         * This is equivalent to `@VisibleForTesting(NONE)`.
          */
         TESTS,
 
         /**
          * Restrict usage to subclasses of the enclosing class.
          *
-         * **Note:** This scope should not be used to annotate
-         * packages.
+         * **Note:** This scope should not be used to annotate packages.
          */
         SUBCLASSES,
     }
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 af8360c..5b1fdc6 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
@@ -16,6 +16,10 @@
 
 package androidx.appactions.interaction.capabilities.communication
 
+import androidx.appactions.builtintypes.experimental.properties.Participant
+import androidx.appactions.builtintypes.experimental.types.Call
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
 import androidx.appactions.interaction.capabilities.core.Capability
 import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
 import androidx.appactions.interaction.capabilities.core.CapabilityFactory
@@ -27,11 +31,6 @@
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters.PARTICIPANT_TYPE_SPEC
 import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
 import androidx.appactions.interaction.capabilities.core.properties.Property
-import androidx.appactions.interaction.capabilities.core.values.Call
-import androidx.appactions.interaction.capabilities.core.values.Call.CallFormat
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.properties.Participant
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
 import androidx.appactions.interaction.proto.ParamValue
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
@@ -87,7 +86,7 @@
     // TODO(b/268369632): Remove Property from public capability APIs.
     class Properties
     internal constructor(
-        val callFormat: Property<CallFormat>?,
+        val callFormat: Property<Call.CanonicalValue.CallFormat>?,
         val participant: Property<Participant>?
     ) {
         override fun toString(): String {
@@ -113,13 +112,14 @@
         }
 
         class Builder {
-            private var callFormat: Property<CallFormat>? = null
+            private var callFormat: Property<Call.CanonicalValue.CallFormat>? = null
 
             private var participant: Property<Participant>? = null
 
-            fun setCallFormat(callFormat: Property<CallFormat>): Builder = apply {
-                this.callFormat = callFormat
-            }
+            fun setCallFormat(callFormat: Property<Call.CanonicalValue.CallFormat>): Builder =
+                apply {
+                    this.callFormat = callFormat
+                }
 
             fun build(): Properties = Properties(callFormat, participant)
         }
@@ -127,7 +127,7 @@
 
     class Arguments
     internal constructor(
-        val callFormat: CallFormat?,
+        val callFormat: Call.CanonicalValue.CallFormat?,
         val participantList: List<ParticipantValue>,
     ) {
         override fun toString(): String {
@@ -153,10 +153,10 @@
         }
 
         class Builder : BuilderOf<Arguments> {
-            private var callFormat: CallFormat? = null
+            private var callFormat: Call.CanonicalValue.CallFormat? = null
             private var participantList: List<ParticipantValue> = mutableListOf()
 
-            fun setCallFormat(callFormat: CallFormat): Builder = apply {
+            fun setCallFormat(callFormat: Call.CanonicalValue.CallFormat): Builder = apply {
                 this.callFormat = callFormat
             }
 
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 6f428e1..d2b8b20 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
@@ -16,6 +16,11 @@
 
 package androidx.appactions.interaction.capabilities.communication
 
+import androidx.appactions.builtintypes.experimental.properties.Recipient
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
+import androidx.appactions.builtintypes.experimental.types.Message
+
 import androidx.appactions.interaction.capabilities.core.Capability
 import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
 import androidx.appactions.interaction.capabilities.core.CapabilityFactory
@@ -28,10 +33,6 @@
 import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
 import androidx.appactions.interaction.capabilities.core.properties.StringValue
 import androidx.appactions.interaction.capabilities.core.properties.Property
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.Message
-import androidx.appactions.interaction.capabilities.core.values.properties.Recipient
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
 import androidx.appactions.interaction.proto.ParamValue
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
diff --git a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/ParticipantValue.kt b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/ParticipantValue.kt
index c8e6e41..a367315 100644
--- a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/ParticipantValue.kt
+++ b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/ParticipantValue.kt
@@ -15,11 +15,11 @@
  */
 package androidx.appactions.interaction.capabilities.communication
 
+import androidx.appactions.builtintypes.experimental.properties.Participant
 import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
 import androidx.appactions.interaction.capabilities.core.impl.converters.UnionTypeSpec
 import androidx.appactions.interaction.capabilities.core.values.SearchAction
-import androidx.appactions.interaction.capabilities.core.values.properties.Participant
 
 class ParticipantValue private constructor(
     val asParticipant: Participant?,
diff --git a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/RecipientValue.kt b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/RecipientValue.kt
index a91015c..ee21e47 100644
--- a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/RecipientValue.kt
+++ b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/RecipientValue.kt
@@ -16,11 +16,11 @@
 
 package androidx.appactions.interaction.capabilities.communication
 
+import androidx.appactions.builtintypes.experimental.properties.Recipient
 import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
 import androidx.appactions.interaction.capabilities.core.impl.converters.UnionTypeSpec
 import androidx.appactions.interaction.capabilities.core.values.SearchAction
-import androidx.appactions.interaction.capabilities.core.values.properties.Recipient
 
 class RecipientValue private constructor(
     val asRecipient: Recipient?,
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Attendee.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Attendee.kt
index d4234c3..5ebbc27 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Attendee.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Attendee.kt
@@ -25,4 +25,11 @@
 class Attendee(person: Person) {
     @get:JvmName("asPerson")
     val asPerson: Person? = person
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is Attendee) return false
+        if (asPerson != other.asPerson) return false
+        return true
+    }
 }
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/EndDate.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/EndDate.kt
index ea9c33a..5c36634 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/EndDate.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/EndDate.kt
@@ -17,7 +17,21 @@
 package androidx.appactions.builtintypes.experimental.properties
 
 import java.time.LocalDate
+import java.time.ZonedDateTime
 
-class EndDate(localDate: LocalDate) {
-    val localDate: LocalDate? = localDate
+class EndDate internal constructor(
+    @get:JvmName("asDate")
+    val asDate: LocalDate? = null,
+    @get:JvmName("asZonedDateTime")
+    val asZonedDateTime: ZonedDateTime? = null
+) {
+    constructor(date: LocalDate) : this(asDate = date, asZonedDateTime = null)
+    constructor(zonedDateTime: ZonedDateTime) : this(asDate = null, asZonedDateTime = zonedDateTime)
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is EndDate) return false
+        if (asDate != other.asDate) return false
+        if (asZonedDateTime != other.asZonedDateTime) return false
+        return true
+    }
 }
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/ItemListElement.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/ItemListElement.kt
index 395c1bf..8f7803c 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/ItemListElement.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/ItemListElement.kt
@@ -21,4 +21,11 @@
 class ItemListElement(asListItem: ListItem) {
     @get:JvmName("asListItem")
     val asListItem: ListItem = asListItem
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is ItemListElement) return false
+        if (asListItem != other.asListItem) return false
+        return true
+    }
 }
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Name.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Name.kt
index 7327971..b779c3d 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Name.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Name.kt
@@ -19,4 +19,11 @@
 class Name(asText: String) {
     @get:JvmName("asText")
     val asText: String = asText
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is Name) return false
+        if (asText != other.asText) return false
+        return true
+    }
 }
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Participant.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Participant.kt
index b84d253..abb312b 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Participant.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Participant.kt
@@ -25,4 +25,10 @@
 class Participant(person: Person) {
     @get:JvmName("asPerson")
     val asPerson: Person? = person
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is Participant) return false
+        if (asPerson != other.asPerson) return false
+        return true
+    }
 }
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Recipient.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Recipient.kt
index d5a9a01..7663eb4 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Recipient.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Recipient.kt
@@ -25,4 +25,11 @@
 class Recipient(person: Person) {
     @get:JvmName("asPerson")
     val asPerson: Person? = person
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is Recipient) return false
+        if (asPerson != other.asPerson) return false
+        return true
+    }
 }
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/StartDate.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/StartDate.kt
index 96d54eae..4328dd8 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/StartDate.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/StartDate.kt
@@ -17,7 +17,22 @@
 package androidx.appactions.builtintypes.experimental.properties
 
 import java.time.LocalDate
+import java.time.ZonedDateTime
 
-class StartDate(localDate: LocalDate) {
-    val localDate: LocalDate? = localDate
+class StartDate internal constructor(
+    @get:JvmName("asDate")
+    val asDate: LocalDate? = null,
+    @get:JvmName("asZonedDateTime")
+    val asZonedDateTime: ZonedDateTime? = null
+) {
+    constructor(date: LocalDate) : this(asDate = date, asZonedDateTime = null)
+    constructor(zonedDateTime: ZonedDateTime) : this(asDate = null, asZonedDateTime = zonedDateTime)
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is StartDate) return false
+        if (asDate != other.asDate) return false
+        if (asZonedDateTime != other.asZonedDateTime) return false
+        return true
+    }
 }
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/CalendarEvent.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/CalendarEvent.kt
index 8545b7f..fa8d0d8 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/CalendarEvent.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/CalendarEvent.kt
@@ -22,6 +22,7 @@
 import androidx.appactions.builtintypes.experimental.properties.StartDate
 import androidx.appactions.builtintypes.experimental.properties.Attendee
 import java.time.LocalDate
+import java.time.ZonedDateTime
 
 interface CalendarEvent : Thing {
     val startDate: StartDate?
@@ -37,8 +38,10 @@
     interface Builder<Self : Builder<Self>> : Thing.Builder<Self> {
         fun setStartDate(startDate: StartDate?): Self
         fun setStartDate(value: LocalDate): Self
+        fun setStartDate(value: ZonedDateTime): Self
         fun setEndDate(endDate: EndDate?): Self
         fun setEndDate(value: LocalDate): Self
+        fun setEndDate(value: ZonedDateTime): Self
         fun addAttendee(attendee: Attendee): Self
         fun addAttendees(value: List<Attendee>): Self
 
@@ -65,6 +68,10 @@
         startDate = StartDate(value)
     }
 
+    override fun setStartDate(value: ZonedDateTime): CalendarEventBuilderImpl = apply {
+        startDate = StartDate(value)
+    }
+
     override fun setEndDate(endDate: EndDate?): CalendarEventBuilderImpl = apply {
         this.endDate = endDate
     }
@@ -73,6 +80,10 @@
         endDate = EndDate(value)
     }
 
+    override fun setEndDate(value: ZonedDateTime): CalendarEventBuilderImpl = apply {
+        endDate = EndDate(value)
+    }
+
     override fun addAttendee(attendee: Attendee): CalendarEventBuilderImpl = apply {
         attendeeList.add(attendee)
     }
@@ -106,4 +117,16 @@
             .setStartDate(startDate)
             .setEndDate(endDate)
             .addAttendees(attendeeList)
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is CalendarEventImpl) return false
+        if (attendeeList != other.attendeeList) return false
+        if (endDate != other.endDate) return false
+        if (startDate != other.startDate) return false
+        if (identifier != other.identifier) return false
+        if (name != other.name) return false
+
+        return true
+    }
 }
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ItemList.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ItemList.kt
index 4d5eecd..e2308b6 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ItemList.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ItemList.kt
@@ -81,4 +81,13 @@
             .setIdentifier(identifier)
             .setName(name)
             .addItemListElements(itemListElements)
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is ItemListImpl) return false
+        if (this.name != other.name) return false
+        if (this.identifier != other.identifier) return false
+        if (this.itemListElements != other.itemListElements) return false
+        return true
+    }
 }
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ListItem.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ListItem.kt
index 4c199e0..65b4845 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ListItem.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ListItem.kt
@@ -57,4 +57,12 @@
 ) : ListItem {
     override fun toBuilder(): ListItem.Builder<*> =
         ListItemBuilderImpl().setIdentifier(identifier).setName(name)
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is ListItemImpl) return false
+        if (this.name != other.name) return false
+        if (this.identifier != other.identifier) return false
+        return true
+    }
 }
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Person.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Person.kt
index 6e92203..62a5892 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Person.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Person.kt
@@ -72,4 +72,14 @@
             .setName(name)
             .setEmail(email)
             .setTelephone(telephone)
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is PersonImpl) return false
+        if (email != other.email) return false
+        if (telephone != other.telephone) return false
+        if (identifier != other.identifier) return false
+        if (name != other.name) return false
+        return true
+    }
 }
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Thing.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Thing.kt
index ecdd7e8..1051242 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Thing.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Thing.kt
@@ -53,9 +53,25 @@
     override fun setName(text: String): ThingBuilderImpl = apply { name = Name(text) }
     override fun setName(name: Name?): ThingBuilderImpl = apply { this.name = name }
     override fun clearName(): ThingBuilderImpl = apply { name = null }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+
+        other as ThingBuilderImpl
+        if (this.name != other.name) return false
+        if (this.identifier != other.identifier) return false
+        return true
+    }
 }
 
 private class ThingImpl(override val identifier: String?, override val name: Name?) : Thing {
     override fun toBuilder(): Thing.Builder<*> =
         ThingBuilderImpl().setIdentifier(identifier).setName(name)
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is ThingImpl) return false
+        if (this.name != other.name) return false
+        if (this.identifier != other.identifier) return false
+        return true
+    }
 }
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Timer.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Timer.kt
index afe2dba..b90d44b 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Timer.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Timer.kt
@@ -50,4 +50,12 @@
 private class TimerImpl(override val identifier: String?, override val name: Name?) : Timer {
     override fun toBuilder(): Timer.Builder<*> =
         TimerBuilderImpl().setIdentifier(identifier).setName(name)
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is TimerImpl) return false
+        if (identifier != other.identifier) return false
+        if (name != other.name) return false
+        return true
+    }
 }
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/entity/EntityProvider.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/entity/EntityProvider.kt
index c3fcad0..5433788 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/entity/EntityProvider.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/entity/EntityProvider.kt
@@ -24,7 +24,7 @@
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeSpec
 import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException
 import androidx.appactions.interaction.capabilities.core.values.SearchAction
-import androidx.appactions.interaction.capabilities.core.values.Thing
+import androidx.appactions.builtintypes.experimental.types.Thing
 import androidx.appactions.interaction.proto.GroundingRequest
 import androidx.appactions.interaction.proto.GroundingResponse
 import androidx.concurrent.futures.await
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/ParamValueConverter.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/ParamValueConverter.kt
index 3c50190..df74750 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/ParamValueConverter.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/ParamValueConverter.kt
@@ -38,6 +38,7 @@
          * @param typeSpec the TypeSpec of the structured type, which can
          * read/write objects to/from Struct.
          */
+        @JvmStatic
         fun <T> of(typeSpec: TypeSpec<T>) = object : ParamValueConverter<T> {
             override fun fromParamValue(paramValue: ParamValue): T {
                 return typeSpec.fromValue(paramValueToValue(paramValue))
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/SlotTypeConverter.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/SlotTypeConverter.java
index d1af888..20ef55b 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/SlotTypeConverter.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/SlotTypeConverter.java
@@ -17,6 +17,7 @@
 package androidx.appactions.interaction.capabilities.core.impl.converters;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
 import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
 import androidx.appactions.interaction.proto.ParamValue;
 
@@ -30,6 +31,7 @@
  * @param <T>
  */
 @FunctionalInterface
+@RestrictTo(RestrictTo.Scope.LIBRARY)
 public interface SlotTypeConverter<T> {
     @NonNull
     static <T> SlotTypeConverter<List<T>> ofRepeated(
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConverters.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConverters.java
index 60082a6..34f1ddc 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConverters.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConverters.java
@@ -17,22 +17,23 @@
 package androidx.appactions.interaction.capabilities.core.impl.converters;
 
 import androidx.annotation.NonNull;
+import androidx.appactions.builtintypes.experimental.properties.Attendee;
+import androidx.appactions.builtintypes.experimental.properties.ItemListElement;
+import androidx.appactions.builtintypes.experimental.properties.Participant;
+import androidx.appactions.builtintypes.experimental.properties.Recipient;
+import androidx.appactions.builtintypes.experimental.types.Alarm;
+import androidx.appactions.builtintypes.experimental.types.CalendarEvent;
+import androidx.appactions.builtintypes.experimental.types.Call;
+import androidx.appactions.builtintypes.experimental.types.ItemList;
+import androidx.appactions.builtintypes.experimental.types.ListItem;
+import androidx.appactions.builtintypes.experimental.types.Message;
+import androidx.appactions.builtintypes.experimental.types.Person;
+import androidx.appactions.builtintypes.experimental.types.SafetyCheck;
+import androidx.appactions.builtintypes.experimental.types.Timer;
 import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
 import androidx.appactions.interaction.capabilities.core.properties.StringValue;
-import androidx.appactions.interaction.capabilities.core.values.Alarm;
-import androidx.appactions.interaction.capabilities.core.values.CalendarEvent;
-import androidx.appactions.interaction.capabilities.core.values.Call;
 import androidx.appactions.interaction.capabilities.core.values.EntityValue;
-import androidx.appactions.interaction.capabilities.core.values.ItemList;
-import androidx.appactions.interaction.capabilities.core.values.ListItem;
-import androidx.appactions.interaction.capabilities.core.values.Message;
-import androidx.appactions.interaction.capabilities.core.values.Person;
-import androidx.appactions.interaction.capabilities.core.values.SafetyCheck;
 import androidx.appactions.interaction.capabilities.core.values.SearchAction;
-import androidx.appactions.interaction.capabilities.core.values.Timer;
-import androidx.appactions.interaction.capabilities.core.values.properties.Attendee;
-import androidx.appactions.interaction.capabilities.core.values.properties.Participant;
-import androidx.appactions.interaction.capabilities.core.values.properties.Recipient;
 import androidx.appactions.interaction.proto.Entity;
 import androidx.appactions.interaction.proto.ParamValue;
 
@@ -42,94 +43,136 @@
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeParseException;
+import java.util.Optional;
 
 /** Converters for capability argument values. Convert from internal proto types to public types. */
 public final class TypeConverters {
     public static final String FIELD_NAME_TYPE = "@type";
     public static final TypeSpec<ListItem> LIST_ITEM_TYPE_SPEC =
-            TypeSpecBuilder.newBuilderForThing("ListItem", ListItem::newBuilder).build();
-    public static final TypeSpec<ItemList> ITEM_LIST_TYPE_SPEC =
-            TypeSpecBuilder.newBuilderForThing("ItemList", ItemList::newBuilder)
-                    .bindRepeatedSpecField(
-                            "itemListElement",
-                            ItemList::getListItems,
-                            ItemList.Builder::addAllListItems,
+            TypeSpecBuilder.newBuilderForThing(
+                    "ListItem",
+                    ListItem::Builder,
+                    ListItem.Builder::build).build();
+    public static final TypeSpec<ItemListElement> ITEM_LIST_ELEMENT_TYPE_SPEC =
+            new UnionTypeSpec.Builder<ItemListElement>()
+                    .bindMemberType(
+                            ItemListElement::asListItem,
+                            ItemListElement::new,
                             LIST_ITEM_TYPE_SPEC)
                     .build();
+    public static final TypeSpec<ItemList> ITEM_LIST_TYPE_SPEC =
+            TypeSpecBuilder.newBuilderForThing(
+                            "ItemList",
+                            ItemList::Builder,
+                            ItemList.Builder::build)
+                    .bindRepeatedSpecField(
+                            "itemListElement",
+                            ItemList::getItemListElements,
+                            ItemList.Builder::addItemListElements,
+                            ITEM_LIST_ELEMENT_TYPE_SPEC)
+                    .build();
+
     public static final TypeSpec<Person> PERSON_TYPE_SPEC =
-            TypeSpecBuilder.newBuilderForThing("Person", Person::newBuilder)
-                    .bindStringField("email", Person::getEmail, Person.Builder::setEmail)
+            TypeSpecBuilder.newBuilderForThing(
+                            "Person",
+                            Person::Builder,
+                            Person.Builder::build)
+                    .bindStringField("email",
+                            person -> Optional.ofNullable(person.getEmail()),
+                            Person.Builder::setEmail)
                     .bindStringField(
-                            "telephone", Person::getTelephone, Person.Builder::setTelephone)
-                    .bindStringField("name", Person::getName, Person.Builder::setName)
+                            "telephone",
+                            person -> Optional.ofNullable(person.getTelephone()),
+                            Person.Builder::setTelephone)
+                    .bindStringField("name",
+                            person -> Optional.ofNullable(person.getName())
+                                    .flatMap(name -> Optional.ofNullable(name.asText())),
+                            Person.Builder::setName)
                     .build();
     public static final TypeSpec<Alarm> ALARM_TYPE_SPEC =
-            TypeSpecBuilder.newBuilderForThing("Alarm", Alarm::newBuilder).build();
+            TypeSpecBuilder.newBuilderForThing(
+                    "Alarm", Alarm::Builder, Alarm.Builder::build).build();
     public static final TypeSpec<Timer> TIMER_TYPE_SPEC =
-            TypeSpecBuilder.newBuilderForThing("Timer", Timer::newBuilder).build();
+            TypeSpecBuilder.newBuilderForThing(
+                    "Timer", Timer::Builder, Timer.Builder::build).build();
     public static final TypeSpec<Attendee> ATTENDEE_TYPE_SPEC =
             new UnionTypeSpec.Builder<Attendee>()
                     .bindMemberType(
-                            (attendee) -> attendee.asPerson().orElse(null),
+                            Attendee::asPerson,
                             Attendee::new,
                             PERSON_TYPE_SPEC)
                     .build();
     public static final TypeSpec<CalendarEvent> CALENDAR_EVENT_TYPE_SPEC =
-            TypeSpecBuilder.newBuilderForThing("CalendarEvent", CalendarEvent::newBuilder)
+            TypeSpecBuilder.newBuilderForThing(
+                            "CalendarEvent",
+                            CalendarEvent::Builder,
+                            CalendarEvent.Builder::build)
                     .bindZonedDateTimeField(
                             "startDate",
-                            CalendarEvent::getStartDate,
+                            calendarEvent -> Optional.ofNullable(
+                                    calendarEvent.getStartDate().asZonedDateTime()),
                             CalendarEvent.Builder::setStartDate)
                     .bindZonedDateTimeField(
-                            "endDate", CalendarEvent::getEndDate, CalendarEvent.Builder::setEndDate)
+                            "endDate",
+                            calendarEvent -> Optional.ofNullable(
+                                    calendarEvent.getEndDate().asZonedDateTime()),
+                            CalendarEvent.Builder::setEndDate)
                     .bindRepeatedSpecField(
                             "attendee",
                             CalendarEvent::getAttendeeList,
-                            CalendarEvent.Builder::addAllAttendee,
+                            CalendarEvent.Builder::addAttendees,
                             ATTENDEE_TYPE_SPEC)
                     .build();
     public static final TypeSpec<SafetyCheck> SAFETY_CHECK_TYPE_SPEC =
-            TypeSpecBuilder.newBuilderForThing("SafetyCheck", SafetyCheck::newBuilder)
+            TypeSpecBuilder.newBuilderForThing(
+                            "SafetyCheck",
+                            SafetyCheck::Builder,
+                            SafetyCheck.Builder::build)
                     .bindDurationField(
-                            "duration", SafetyCheck::getDuration, SafetyCheck.Builder::setDuration)
+                            "duration",
+                            safetyCheck -> Optional.ofNullable(safetyCheck.getDuration()),
+                            SafetyCheck.Builder::setDuration)
                     .bindZonedDateTimeField(
-                            "checkinTime",
-                            SafetyCheck::getCheckinTime,
-                            SafetyCheck.Builder::setCheckinTime)
+                            "checkInTime",
+                            safetyCheck -> Optional.ofNullable(safetyCheck.getCheckInTime()),
+                            SafetyCheck.Builder::setCheckInTime)
                     .build();
     public static final TypeSpec<Recipient> RECIPIENT_TYPE_SPEC =
             new UnionTypeSpec.Builder<Recipient>()
                     .bindMemberType(
-                            (recipient) -> recipient.asPerson().orElse(null),
+                            Recipient::asPerson,
                             Recipient::new,
                             PERSON_TYPE_SPEC)
                     .build();
     public static final TypeSpec<Participant> PARTICIPANT_TYPE_SPEC =
             new UnionTypeSpec.Builder<Participant>()
                     .bindMemberType(
-                            (participant) -> participant.asPerson().orElse(null),
+                            Participant::asPerson,
                             Participant::new,
                             PERSON_TYPE_SPEC)
                     .build();
     public static final TypeSpec<Message> MESSAGE_TYPE_SPEC =
-            TypeSpecBuilder.newBuilderForThing("Message", Message::newBuilder)
-                    .bindIdentifier(Message::getId)
+            TypeSpecBuilder.newBuilderForThing(
+                            "Message",
+                            Message::Builder,
+                            Message.Builder::build)
+                    .bindIdentifier(message -> Optional.ofNullable(message.getIdentifier()))
                     .bindRepeatedSpecField(
                             "recipient",
                             Message::getRecipientList,
-                            Message.Builder::addAllRecipient,
+                            Message.Builder::addRecipients,
                             RECIPIENT_TYPE_SPEC)
                     .bindStringField(
-                            "text", Message::getMessageText, Message.Builder::setMessageText)
+                            "text",
+                            message -> Optional.of(message.getText().asText()),
+                            Message.Builder::setText)
                     .build();
     public static final TypeSpec<Call> CALL_TYPE_SPEC =
-            TypeSpecBuilder.newBuilderForThing("Call", Call::newBuilder)
-                    .bindIdentifier(Call::getId)
-                    .bindEnumField(
-                            "callFormat",
-                            Call::getCallFormat,
-                            Call.Builder::setCallFormat,
-                            Call.CallFormat.class)
+            TypeSpecBuilder.newBuilderForThing(
+                            "Call",
+                            Call::Builder,
+                            Call.Builder::build)
+                    .bindIdentifier(call -> Optional.ofNullable(call.getIdentifier()))
                     .bindRepeatedSpecField(
                             "participant",
                             Call::getParticipantList,
@@ -138,42 +181,11 @@
                     .build();
 
     public static final ParamValueConverter<Integer> INTEGER_PARAM_VALUE_CONVERTER =
-            new ParamValueConverter<Integer>() {
-                @NonNull
-                @Override
-                public ParamValue toParamValue(Integer value) {
-                    return ParamValue.newBuilder().setNumberValue(value * 1.0).build();
-                }
+            ParamValueConverter.of(TypeSpec.INTEGER_TYPE_SPEC);
 
-                @Override
-                public Integer fromParamValue(@NonNull ParamValue paramValue)
-                        throws StructConversionException {
-                    if (paramValue.hasNumberValue()) {
-                        return (int) paramValue.getNumberValue();
-                    }
-                    throw new StructConversionException(
-                            "Cannot parse integer because number_value"
-                                    + " is missing from ParamValue.");
-                }
-            };
     public static final ParamValueConverter<Boolean> BOOLEAN_PARAM_VALUE_CONVERTER =
-            new ParamValueConverter<Boolean>() {
-                @NonNull
-                @Override
-                public ParamValue toParamValue(Boolean value) {
-                    return ParamValue.newBuilder().setBoolValue(value).build();
-                }
+            ParamValueConverter.of(TypeSpec.BOOL_TYPE_SPEC);
 
-                @Override
-                public Boolean fromParamValue(@NonNull ParamValue paramValue)
-                        throws StructConversionException {
-                    if (paramValue.hasBoolValue()) {
-                        return paramValue.getBoolValue();
-                    }
-                    throw new StructConversionException(
-                            "Cannot parse boolean because bool_value is missing from ParamValue.");
-                }
-            };
     public static final ParamValueConverter<EntityValue> ENTITY_PARAM_VALUE_CONVERTER =
             new ParamValueConverter<EntityValue>() {
                 @NonNull
@@ -194,21 +206,8 @@
                 }
             };
     public static final ParamValueConverter<String> STRING_PARAM_VALUE_CONVERTER =
-            new ParamValueConverter<String>() {
-                @NonNull
-                @Override
-                public ParamValue toParamValue(String value) {
-                    return ParamValue.newBuilder().setStringValue(value).build();
-                }
+            ParamValueConverter.of(TypeSpec.STRING_TYPE_SPEC);
 
-                @Override
-                public String fromParamValue(@NonNull ParamValue paramValue) {
-                    if (paramValue.hasIdentifier()) {
-                        return paramValue.getIdentifier();
-                    }
-                    return paramValue.getStringValue();
-                }
-            };
     public static final ParamValueConverter<LocalDate> LOCAL_DATE_PARAM_VALUE_CONVERTER =
             new ParamValueConverter<LocalDate>() {
                 @NonNull
@@ -331,30 +330,33 @@
                     }
                 }
             };
-    public static final ParamValueConverter<Call.CallFormat> CALL_FORMAT_PARAM_VALUE_CONVERTER =
-            new ParamValueConverter<Call.CallFormat>() {
+    public static final ParamValueConverter<Call.CanonicalValue.CallFormat>
+            CALL_FORMAT_PARAM_VALUE_CONVERTER =
+            new ParamValueConverter<Call.CanonicalValue.CallFormat>() {
+
                 @NonNull
                 @Override
-                public ParamValue toParamValue(Call.CallFormat value) {
+                public ParamValue toParamValue(Call.CanonicalValue.CallFormat value) {
                     // TODO(b/275456249)): Implement backwards conversion.
                     return ParamValue.getDefaultInstance();
                 }
 
                 @Override
-                public Call.CallFormat fromParamValue(@NonNull ParamValue paramValue)
+                public Call.CanonicalValue.CallFormat fromParamValue(@NonNull ParamValue paramValue)
                         throws StructConversionException {
                     String identifier = paramValue.getIdentifier();
-                    if (identifier.equals(Call.CallFormat.AUDIO.toString())) {
-                        return Call.CallFormat.AUDIO;
-                    } else if (identifier.equals(Call.CallFormat.VIDEO.toString())) {
-                        return Call.CallFormat.VIDEO;
+                    if (identifier.equals(Call.CanonicalValue.CallFormat.Audio.getTextValue())) {
+                        return Call.CanonicalValue.CallFormat.Audio;
+                    } else if (identifier.equals(
+                            Call.CanonicalValue.CallFormat.Video.getTextValue())) {
+                        return Call.CanonicalValue.CallFormat.Video;
                     }
                     throw new StructConversionException(
                             String.format("Unknown enum format '%s'.", identifier));
                 }
             };
     public static final EntityConverter<
-                    androidx.appactions.interaction.capabilities.core.properties.Entity>
+            androidx.appactions.interaction.capabilities.core.properties.Entity>
             ENTITY_ENTITY_CONVERTER =
                     (entity) -> {
                         Entity.Builder builder =
@@ -382,15 +384,16 @@
             (localTime) -> Entity.newBuilder().setStringValue(localTime.toString()).build();
     public static final EntityConverter<Duration> DURATION_ENTITY_CONVERTER =
             (duration) -> Entity.newBuilder().setStringValue(duration.toString()).build();
-    public static final EntityConverter<Call.CallFormat> CALL_FORMAT_ENTITY_CONVERTER =
-            (callFormat) -> Entity.newBuilder().setIdentifier(callFormat.toString()).build();
+    public static final EntityConverter<Call.CanonicalValue.CallFormat>
+            CALL_FORMAT_ENTITY_CONVERTER =
+                    (callFormat) ->
+                            Entity.newBuilder().setIdentifier(callFormat.getTextValue()).build();
 
-    private TypeConverters() {}
+    private TypeConverters() {
+    }
 
     /**
-     * @param nestedTypeSpec
-     * @param <T>
-     * @return
+     *
      */
     @NonNull
     public static <T> TypeSpec<SearchAction<T>> createSearchActionTypeSpec(
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpec.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpec.kt
index ff9b0e3..fbb5d4a 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpec.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpec.kt
@@ -38,6 +38,7 @@
     fun fromValue(value: Value): T
 
     companion object {
+        @JvmField
         val STRING_TYPE_SPEC = object : TypeSpec<String> {
             override fun getIdentifier(obj: String): String? = null
 
@@ -51,6 +52,7 @@
             }
         }
 
+        @JvmField
         val BOOL_TYPE_SPEC = object : TypeSpec<Boolean> {
             override fun getIdentifier(obj: Boolean): String? = null
 
@@ -64,6 +66,7 @@
             }
         }
 
+        @JvmField
         val NUMBER_TYPE_SPEC = object : TypeSpec<Double> {
             override fun getIdentifier(obj: Double): String? = null
 
@@ -77,6 +80,7 @@
             }
         }
 
+        @JvmField
         val INTEGER_TYPE_SPEC = object : TypeSpec<Int> {
             override fun getIdentifier(obj: Int): String? = null
 
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecBuilder.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecBuilder.java
index 7b03d72..f8ea421 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecBuilder.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecBuilder.java
@@ -18,9 +18,9 @@
 
 import static androidx.appactions.interaction.capabilities.core.impl.utils.ImmutableCollectors.toImmutableList;
 
+import androidx.appactions.builtintypes.experimental.types.Thing;
 import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
 import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
-import androidx.appactions.interaction.capabilities.core.values.Thing;
 import androidx.appactions.interaction.protobuf.ListValue;
 import androidx.appactions.interaction.protobuf.Struct;
 import androidx.appactions.interaction.protobuf.Value;
@@ -80,7 +80,7 @@
      * StructConversionException.
      *
      * @param struct the Struct to get values from.
-     * @param key the String key of the field to retrieve.
+     * @param key    the String key of the field to retrieve.
      */
     private static Value getFieldFromStruct(Struct struct, String key)
             throws StructConversionException {
@@ -98,26 +98,11 @@
     }
 
     /**
-     * Creates a new TypeSpecBuilder for a child class of Thing.
-     *
-     * <p>Comes with bindings for Thing fields.
-     */
-    static <T extends Thing, BuilderT extends Thing.Builder<BuilderT> & BuilderOf<T>>
-            TypeSpecBuilder<T, BuilderT> newBuilderForThing(
-                    String typeName, Supplier<BuilderT> builderSupplier) {
-        return newBuilder(typeName, builderSupplier)
-                .bindIdentifier(T::getId)
-                .bindStringField("identifier", T::getId, BuilderT::setId)
-                .bindStringField("name", T::getName, BuilderT::setName);
-    }
-
-    /**
      * Creates a new TypeSpecBuilder for a child class of Thing (temporary BuiltInTypes).
      *
      * <p>Comes with bindings for Thing fields.
      */
-    static <T extends androidx.appactions.builtintypes.experimental.types.Thing,
-            BuilderT extends androidx.appactions.builtintypes.experimental.types.Thing.Builder<?>>
+    static <T extends Thing, BuilderT extends Thing.Builder<?>>
             TypeSpecBuilder<T, BuilderT> newBuilderForThing(
                     String typeName,
                     Supplier<BuilderT> builderSupplier,
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Alarm.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Alarm.java
deleted file mode 100644
index ca545f1..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Alarm.java
+++ /dev/null
@@ -1,39 +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.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-/** Represents a single item in an item list. */
-@AutoValue
-public abstract class Alarm extends Thing {
-
-    /** Create a new Alarm instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_Alarm.Builder();
-    }
-
-    /** Builder class for Alarm entities. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder> implements
-            BuilderOf<Alarm> {
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/CalendarEvent.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/CalendarEvent.java
deleted file mode 100644
index d35dcf1..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/CalendarEvent.java
+++ /dev/null
@@ -1,114 +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.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.properties.Attendee;
-
-import com.google.auto.value.AutoValue;
-
-import java.time.ZonedDateTime;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-/** Represents a CalendarEvent. */
-@SuppressWarnings("AutoValueImmutableFields")
-@AutoValue
-public abstract class CalendarEvent extends Thing {
-    /** Create a new CalendarEvent.Builder instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_CalendarEvent.Builder();
-    }
-
-    /** Returns the start date. */
-    @NonNull
-    public abstract Optional<ZonedDateTime> getStartDate();
-
-    /** Returns the end date. */
-    @NonNull
-    public abstract Optional<ZonedDateTime> getEndDate();
-
-    /** Returns the {@link Attendee}s in the CalendarEvent. */
-    @NonNull
-    public abstract List<Attendee> getAttendeeList();
-
-    /** Builder class for building a CalendarEvent. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder>
-            implements BuilderOf<CalendarEvent> {
-
-        private final List<Attendee> mAttendeeList = new ArrayList<>();
-
-        /** Sets start date. */
-        @NonNull
-        public abstract Builder setStartDate(@NonNull ZonedDateTime startDate);
-
-        /** Sets end date. */
-        @NonNull
-        public abstract Builder setEndDate(@NonNull ZonedDateTime endDate);
-
-        /** Adds a person. */
-        @NonNull
-        public final Builder addAttendee(@NonNull Person person) {
-            mAttendeeList.add(new Attendee(person));
-            return this;
-        }
-
-        /** Adds a Attendee. */
-        @NonNull
-        public final Builder addAttendee(@NonNull Attendee attendee) {
-            mAttendeeList.add(attendee);
-            return this;
-        }
-
-        /** Add a list of attendees. */
-        @NonNull
-        public final Builder addAllAttendee(@NonNull Iterable<Attendee> attendees) {
-            for (Attendee attendee : attendees) {
-                mAttendeeList.add(attendee);
-            }
-            return this;
-        }
-
-        /** Add a list of persons. */
-        @NonNull
-        public final Builder addAllPerson(@NonNull Iterable<Person> persons) {
-            for (Person person : persons) {
-                mAttendeeList.add(new Attendee(person));
-            }
-            return this;
-        }
-
-        /** Builds and returns the CalendarEvent instance. */
-        @Override
-        @NonNull
-        public final CalendarEvent build() {
-            setAttendeeList(mAttendeeList);
-            return autoBuild();
-        }
-
-        /** Sets the attendees of the CalendarEvent. */
-        @NonNull
-        abstract Builder setAttendeeList(@NonNull List<Attendee> attendeeList);
-
-        @NonNull
-        abstract CalendarEvent autoBuild();
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Call.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Call.java
deleted file mode 100644
index 5698873..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Call.java
+++ /dev/null
@@ -1,121 +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.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.properties.Participant;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-/** Represents a Call. */
-@AutoValue
-public abstract class Call extends Thing {
-    /** Create a new Call.Builder instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_Call.Builder();
-    }
-
-    /** Returns the call format, e.g. video or audio. */
-    @NonNull
-    public abstract Optional<CallFormat> getCallFormat();
-
-    /** Returns the {@link Participant}s in the call. */
-    @NonNull
-    @SuppressWarnings("AutoValueImmutableFields")
-    public abstract List<Participant> getParticipantList();
-
-    /** Format of the call. */
-    public enum CallFormat {
-        AUDIO("Audio"),
-        VIDEO("Video");
-
-        private final String mCallFormat;
-
-        CallFormat(String callFormat) {
-            this.mCallFormat = callFormat;
-        }
-
-        @Override
-        public String toString() {
-            return mCallFormat;
-        }
-    }
-
-    /** Builder class for building a Call. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder> implements BuilderOf<Call> {
-
-        private final List<Participant> mParticipantList = new ArrayList<>();
-
-        /** Sets call format. */
-        @NonNull
-        public abstract Builder setCallFormat(@NonNull CallFormat callFormat);
-
-        /** Adds a person. */
-        @NonNull
-        public final Builder addParticipant(@NonNull Person person) {
-            mParticipantList.add(new Participant(person));
-            return this;
-        }
-
-        /** Adds a Participant. */
-        @NonNull
-        public final Builder addParticipant(@NonNull Participant participant) {
-            mParticipantList.add(participant);
-            return this;
-        }
-
-        /** Add a list of participants. */
-        @NonNull
-        public final Builder addAllParticipant(@NonNull Iterable<Participant> participants) {
-            for (Participant participant : participants) {
-                mParticipantList.add(participant);
-            }
-            return this;
-        }
-
-        /** Add a list of persons. */
-        @NonNull
-        public final Builder addAllPerson(@NonNull Iterable<Person> persons) {
-            for (Person person : persons) {
-                mParticipantList.add(new Participant(person));
-            }
-            return this;
-        }
-
-        /** Builds and returns the Call instance. */
-        @Override
-        @NonNull
-        public final Call build() {
-            setParticipantList(mParticipantList);
-            return autoBuild();
-        }
-
-        /** Sets the participants of the call. */
-        @NonNull
-        abstract Builder setParticipantList(@NonNull List<Participant> participantList);
-
-        @NonNull
-        abstract Call autoBuild();
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/GenericErrorStatus.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/GenericErrorStatus.java
deleted file mode 100644
index a7c0713..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/GenericErrorStatus.java
+++ /dev/null
@@ -1,50 +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.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-/** GenericErrorStatus for ExecutionStatus. */
-@AutoValue
-public abstract class GenericErrorStatus extends Thing {
-
-    /** Create a new GenericErrorStatus instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_GenericErrorStatus.Builder();
-    }
-
-    /** Create a new default instance. */
-    @NonNull
-    public static GenericErrorStatus getDefaultInstance() {
-        return new AutoValue_GenericErrorStatus.Builder().build();
-    }
-
-    @Override
-    public final String toString() {
-        return "GenericErrorStatus";
-    }
-
-    /** Builder class for GenericErrorStatus status. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder>
-            implements BuilderOf<GenericErrorStatus> {
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/ItemList.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/ItemList.java
deleted file mode 100644
index bf0a69f..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/ItemList.java
+++ /dev/null
@@ -1,76 +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.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/** Represents an ItemList object. */
-@SuppressWarnings("AutoValueImmutableFields")
-@AutoValue
-public abstract class ItemList extends Thing {
-
-    /** Create a new ItemList.Builder instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_ItemList.Builder();
-    }
-
-    /** Returns the optional list items in this ItemList. */
-    @NonNull
-    public abstract List<ListItem> getListItems();
-
-    /** Builder class for building item lists with items. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder>
-            implements BuilderOf<ItemList> {
-
-        private final List<ListItem> mListItemsToBuild = new ArrayList<>();
-
-        /** Add one or more ListItem to the ItemList to be built. */
-        @NonNull
-        public final Builder addListItem(@NonNull ListItem... listItems) {
-            Collections.addAll(mListItemsToBuild, listItems);
-            return this;
-        }
-
-        /** Add a list of ListItem to the ItemList to be built. */
-        @NonNull
-        public final Builder addAllListItems(@NonNull List<ListItem> listItems) {
-            return addListItem(listItems.toArray(new ListItem[0]));
-        }
-
-        abstract Builder setListItems(List<ListItem> listItems);
-
-        /** Builds and returns the ItemList. */
-        @Override
-        @NonNull
-        public final ItemList build() {
-            setListItems(Collections.unmodifiableList(mListItemsToBuild));
-            return autoBuild();
-        }
-
-        @NonNull
-        abstract ItemList autoBuild();
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/ListItem.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/ListItem.java
deleted file mode 100644
index e79e99f..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/ListItem.java
+++ /dev/null
@@ -1,45 +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.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-/** Represents a single item in an item list. */
-@AutoValue
-public abstract class ListItem extends Thing {
-
-    /** Creates a ListItem given its name. */
-    @NonNull
-    public static ListItem create(@NonNull String id, @NonNull String name) {
-        return newBuilder().setId(id).setName(name).build();
-    }
-
-    /** Create a new ListItem.Builder instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_ListItem.Builder();
-    }
-
-    /** Builder class for building item lists with items. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder>
-            implements BuilderOf<ListItem> {
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Message.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Message.java
deleted file mode 100644
index 7e5d875..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Message.java
+++ /dev/null
@@ -1,97 +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.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.properties.Recipient;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-/** Represents an message object. */
-@SuppressWarnings("AutoValueImmutableFields")
-@AutoValue
-public abstract class Message extends Thing {
-
-    /** Create a new Message.Builder instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_Message.Builder();
-    }
-
-    /** Returns the recipients of the message. */
-    @NonNull
-    public abstract List<Recipient> getRecipientList();
-
-    /** Returns the message text. */
-    @NonNull
-    public abstract Optional<String> getMessageText();
-
-    /** Builder class for building an Message. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder>
-            implements BuilderOf<Message> {
-
-        private final List<Recipient> mRecipientList = new ArrayList<>();
-
-        /** Adds a {@link Person}. */
-        @NonNull
-        public final Builder addRecipient(@NonNull Person person) {
-            mRecipientList.add(new Recipient(person));
-            return this;
-        }
-
-        /** Adds a {@link Recipient}. */
-        @NonNull
-        public final Builder addRecipient(@NonNull Recipient recipient) {
-            mRecipientList.add(recipient);
-            return this;
-        }
-
-        /** Adds a list of {@link Recipient}s. */
-        @NonNull
-        public final Builder addAllRecipient(@NonNull Iterable<Recipient> recipients) {
-            for (Recipient recipient : recipients) {
-                mRecipientList.add(recipient);
-            }
-            return this;
-        }
-
-        /** Sets the message text. */
-        @NonNull
-        public abstract Builder setMessageText(@NonNull String messageText);
-
-        /** Builds and returns the Message instance. */
-        @Override
-        @NonNull
-        public final Message build() {
-            setRecipientList(mRecipientList);
-            return autoBuild();
-        }
-
-        /** Sets the recipients of the message. */
-        @NonNull
-        abstract Builder setRecipientList(@NonNull List<Recipient> recipientList);
-
-        @NonNull
-        abstract Message autoBuild();
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Person.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Person.java
deleted file mode 100644
index a54bb59..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Person.java
+++ /dev/null
@@ -1,55 +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.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.Optional;
-
-/** Represents a person. */
-@AutoValue
-public abstract class Person extends Thing {
-    /** Create a new Person.Builder instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_Person.Builder();
-    }
-
-    /** Returns the email. */
-    @NonNull
-    public abstract Optional<String> getEmail();
-
-    /** Returns the telephone. */
-    @NonNull
-    public abstract Optional<String> getTelephone();
-
-    /** Builder class for building a Person. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder> implements
-            BuilderOf<Person> {
-        /** Sets the email. */
-        @NonNull
-        public abstract Builder setEmail(@NonNull String email);
-
-        /** Sets the telephone. */
-        @NonNull
-        public abstract Builder setTelephone(@NonNull String telephone);
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/SafetyCheck.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/SafetyCheck.java
deleted file mode 100644
index afe240c..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/SafetyCheck.java
+++ /dev/null
@@ -1,65 +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.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-import java.time.Duration;
-import java.time.ZonedDateTime;
-import java.util.Optional;
-
-/** Represents a SafetyCheck. */
-@AutoValue
-public abstract class SafetyCheck extends Thing {
-    /** Create a new SafetyCheck instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_SafetyCheck.Builder();
-    }
-
-    /** Returns the duration. */
-    @NonNull
-    public abstract Optional<Duration> getDuration();
-
-    /** Returns the check-in time. */
-    @NonNull
-    public abstract Optional<ZonedDateTime> getCheckinTime();
-
-    /** Builder class for building a SafetyCheck. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder>
-            implements BuilderOf<SafetyCheck> {
-        @NonNull
-        public abstract Builder setDuration(@NonNull Duration duration);
-
-        @NonNull
-        public abstract Builder setCheckinTime(@NonNull ZonedDateTime checkinTime);
-
-        /** Builds and returns the SafetyCheck instance. */
-        @Override
-        @NonNull
-        public final SafetyCheck build() {
-            return autoBuild();
-        }
-
-        @NonNull
-        abstract SafetyCheck autoBuild();
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/SuccessStatus.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/SuccessStatus.java
deleted file mode 100644
index af4469a..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/SuccessStatus.java
+++ /dev/null
@@ -1,50 +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.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-/** SuccessStatus for ExecutionStatus. */
-@AutoValue
-public abstract class SuccessStatus extends Thing {
-
-    /** Create a new SuccessStatus instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_SuccessStatus.Builder();
-    }
-
-    /** Create a new default instance. */
-    @NonNull
-    public static SuccessStatus getDefaultInstance() {
-        return new AutoValue_SuccessStatus.Builder().build();
-    }
-
-    @Override
-    public final String toString() {
-        return "SuccessStatus";
-    }
-
-    /** Builder class for SuccessStatus status. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder>
-            implements BuilderOf<SuccessStatus> {
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Thing.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Thing.java
deleted file mode 100644
index 7d897f0..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Thing.java
+++ /dev/null
@@ -1,47 +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.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-
-import java.util.Optional;
-
-/** Common interface for structured entity. */
-public abstract class Thing {
-    /** Returns the id of this thing. */
-    @NonNull
-    public abstract Optional<String> getId();
-
-    /** Returns the name of this thing. */
-    @NonNull
-    public abstract Optional<String> getName();
-
-    /**
-     * Base builder class that can be extended to build objects that extend Thing.
-     *
-     * @param <T>
-     */
-    public abstract static class Builder<T extends Builder<T>> {
-        /** Sets the id of the Thing to be built. */
-        @NonNull
-        public abstract T setId(@NonNull String id);
-
-        /** Sets the name of the Thing to be built. */
-        @NonNull
-        public abstract T setName(@NonNull String name);
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Timer.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Timer.java
deleted file mode 100644
index 80627b4..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Timer.java
+++ /dev/null
@@ -1,39 +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.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-/** Represents a Timer. */
-@AutoValue
-public abstract class Timer extends Thing {
-
-    /** Create a new Timer instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_Timer.Builder();
-    }
-
-    /** Builder class for Timer. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder> implements
-            BuilderOf<Timer> {
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/ActionAlreadyInProgress.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/ActionAlreadyInProgress.java
deleted file mode 100644
index 57fe650..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/ActionAlreadyInProgress.java
+++ /dev/null
@@ -1,51 +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.appactions.interaction.capabilities.core.values.executionstatus;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.Thing;
-
-import com.google.auto.value.AutoValue;
-
-/** Error status for execution failure due to the action being in progress. */
-@AutoValue
-public abstract class ActionAlreadyInProgress extends Thing {
-
-    /** Create a new ActionAlreadyInProgress instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_ActionAlreadyInProgress.Builder();
-    }
-
-    /** Create a new default instance. */
-    @NonNull
-    public static ActionAlreadyInProgress getDefaultInstance() {
-        return new AutoValue_ActionAlreadyInProgress.Builder().build();
-    }
-
-    @Override
-    public final String toString() {
-        return "ActionAlreadyInProgress";
-    }
-
-    /** Builder class for ActionAlreadyInProgress status. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder>
-            implements BuilderOf<ActionAlreadyInProgress> {
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/ActionNotInProgress.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/ActionNotInProgress.java
deleted file mode 100644
index 4b342a6..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/ActionNotInProgress.java
+++ /dev/null
@@ -1,51 +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.appactions.interaction.capabilities.core.values.executionstatus;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.Thing;
-
-import com.google.auto.value.AutoValue;
-
-/** Error status for execution failure due to the action not being in progress. */
-@AutoValue
-public abstract class ActionNotInProgress extends Thing {
-
-    /** Create a new ActionNotInProgress instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_ActionNotInProgress.Builder();
-    }
-
-    /** Create a new default instance. */
-    @NonNull
-    public static ActionNotInProgress getDefaultInstance() {
-        return new AutoValue_ActionNotInProgress.Builder().build();
-    }
-
-    @Override
-    public final String toString() {
-        return "ActionNotInProgress";
-    }
-
-    /** Builder class for ActionNotInProgress status. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder>
-            implements BuilderOf<ActionNotInProgress> {
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/NoInternetConnection.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/NoInternetConnection.java
deleted file mode 100644
index 3a3bb5b..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/NoInternetConnection.java
+++ /dev/null
@@ -1,51 +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.appactions.interaction.capabilities.core.values.executionstatus;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.Thing;
-
-import com.google.auto.value.AutoValue;
-
-/** Error status for execution failure due to no internet connection. */
-@AutoValue
-public abstract class NoInternetConnection extends Thing {
-
-    /** Create a new NoInternetConnection instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_NoInternetConnection.Builder();
-    }
-
-    /** Create a new default instance. */
-    @NonNull
-    public static NoInternetConnection getDefaultInstance() {
-        return new AutoValue_NoInternetConnection.Builder().build();
-    }
-
-    @Override
-    public final String toString() {
-        return "NoInternetConnection";
-    }
-
-    /** Builder class for NoInternetConnection status. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder>
-            implements BuilderOf<NoInternetConnection> {
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Attendee.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Attendee.java
deleted file mode 100644
index 1c5ef74..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Attendee.java
+++ /dev/null
@@ -1,62 +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.appactions.interaction.capabilities.core.values.properties;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appactions.interaction.capabilities.core.values.Person;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.Optional;
-
-/**
- * Represents the value of the union property: http://schema.org/attendee, currently it only can
- * contain {@link Person}.
- */
-public class Attendee {
-    private final Value mValue;
-
-    public Attendee(@NonNull Person person) {
-        mValue = new AutoValue_Attendee_Value(Optional.of(person));
-    }
-
-    @NonNull
-    public Optional<Person> asPerson() {
-        return mValue.person();
-    }
-
-    @Override
-    public int hashCode() {
-        return mValue.hashCode();
-    }
-
-    @Override
-    public boolean equals(@Nullable Object object) {
-        if (object instanceof Attendee) {
-            Attendee that = (Attendee) object;
-            return this.mValue.equals(that.mValue);
-        }
-        return false;
-    }
-
-    /** Represents the value in the this wrapper class. */
-    @AutoValue
-    abstract static class Value {
-        abstract Optional<Person> person();
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Participant.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Participant.java
deleted file mode 100644
index 02cbc7b..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Participant.java
+++ /dev/null
@@ -1,62 +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.appactions.interaction.capabilities.core.values.properties;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appactions.interaction.capabilities.core.values.Person;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.Optional;
-
-/**
- * Represents the value of the union property: http://schema.org/participant, currently it only can
- * contain {@link Person}.
- */
-public class Participant {
-    private final Value mValue;
-
-    public Participant(@NonNull Person person) {
-        mValue = new AutoValue_Participant_Value(Optional.of(person));
-    }
-
-    @NonNull
-    public Optional<Person> asPerson() {
-        return mValue.person();
-    }
-
-    @Override
-    public int hashCode() {
-        return mValue.hashCode();
-    }
-
-    @Override
-    public boolean equals(@Nullable Object object) {
-        if (object instanceof Participant) {
-            Participant that = (Participant) object;
-            return this.mValue.equals(that.mValue);
-        }
-        return false;
-    }
-
-    /** Represents the value in the this wrapper class. */
-    @AutoValue
-    abstract static class Value {
-        abstract Optional<Person> person();
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Recipient.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Recipient.java
deleted file mode 100644
index 56d2021..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Recipient.java
+++ /dev/null
@@ -1,62 +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.appactions.interaction.capabilities.core.values.properties;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appactions.interaction.capabilities.core.values.Person;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.Optional;
-
-/**
- * Represents the value of the union property: http://schema.org/recipient, currently it only can
- * contain {@link Person}.
- */
-public class Recipient {
-    private final Value mValue;
-
-    public Recipient(@NonNull Person person) {
-        mValue = new AutoValue_Recipient_Value(Optional.of(person));
-    }
-
-    @NonNull
-    public Optional<Person> asPerson() {
-        return mValue.person();
-    }
-
-    @Override
-    public int hashCode() {
-        return mValue.hashCode();
-    }
-
-    @Override
-    public boolean equals(@Nullable Object object) {
-        if (object instanceof Recipient) {
-            Recipient that = (Recipient) object;
-            return this.mValue.equals(that.mValue);
-        }
-        return false;
-    }
-
-    /** Represents the value in the this wrapper class. */
-    @AutoValue
-    abstract static class Value {
-        abstract Optional<Person> person();
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/entity/AlarmProvider.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/entity/AlarmProvider.kt
index b412f34..8e2af97 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/entity/AlarmProvider.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/entity/AlarmProvider.kt
@@ -16,8 +16,8 @@
 
 package androidx.appactions.interaction.capabilities.core.entity
 
+import androidx.appactions.builtintypes.experimental.types.Alarm
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
-import androidx.appactions.interaction.capabilities.core.values.Alarm
 
 /**  Internal testing object for entity provider */
 class AlarmProvider internal constructor(
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/entity/EntityProviderTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/entity/EntityProviderTest.kt
index b7a58e7..72eeb27 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/entity/EntityProviderTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/entity/EntityProviderTest.kt
@@ -16,7 +16,7 @@
 
 package androidx.appactions.interaction.capabilities.core.entity
 
-import androidx.appactions.interaction.capabilities.core.values.Alarm
+import androidx.appactions.builtintypes.experimental.types.Alarm
 import androidx.appactions.interaction.proto.Entity
 import androidx.appactions.interaction.proto.GroundingRequest
 import androidx.appactions.interaction.proto.GroundingResponse
@@ -86,7 +86,7 @@
     private fun createExternalCandidate(id: String, name: String): EntityLookupCandidate<Alarm> {
         val candidateBuilder: EntityLookupCandidate.Builder<Alarm> =
             EntityLookupCandidate.Builder()
-        candidateBuilder.setCandidate(Alarm.newBuilder().setName(name).setId(id).build())
+        candidateBuilder.setCandidate(Alarm.Builder().setName(name).setIdentifier(id).build())
         return candidateBuilder.build()
     }
 
@@ -148,7 +148,7 @@
     fun success() = runBlocking<Unit> {
         val candidateBuilder: EntityLookupCandidate.Builder<Alarm> =
             EntityLookupCandidate.Builder()
-        candidateBuilder.setCandidate(Alarm.newBuilder().setName("testing-alarm").build())
+        candidateBuilder.setCandidate(Alarm.Builder().setName("testing-alarm").build())
         val entityProvider = AlarmProvider(
             "id",
             createExternalResponse(
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt
index e94ab42..6b386e5 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt
@@ -85,7 +85,7 @@
             ArgumentUtils.buildArgs(
                 mapOf(
                     "optionalString" to
-                        ParamValue.newBuilder().setIdentifier("string argument value").build()
+                        ParamValue.newBuilder().setStringValue("string argument value").build()
                 )
             ),
             callbackInternal
@@ -138,7 +138,7 @@
             ArgumentUtils.buildArgs(
                 mapOf(
                     "optionalString" to
-                        ParamValue.newBuilder().setIdentifier("string argument value").build()
+                        ParamValue.newBuilder().setStringValue("string argument value").build()
                 )
             ),
             callbackInternal
@@ -218,7 +218,7 @@
             ArgumentUtils.buildArgs(
                 mapOf(
                     "optionalString" to
-                        ParamValue.newBuilder().setIdentifier("string value 1").build()
+                        ParamValue.newBuilder().setStringValue("string value 1").build()
                 )
             ),
             callbackInternal1
@@ -227,7 +227,7 @@
             ArgumentUtils.buildArgs(
                 mapOf(
                     "optionalString" to
-                        ParamValue.newBuilder().setIdentifier("string value 2").build()
+                        ParamValue.newBuilder().setStringValue("string value 2").build()
                 )
             ),
             callbackInternal2
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConvertersTest.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConvertersTest.java
index dd78f17..074820d 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConvertersTest.java
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConvertersTest.java
@@ -31,19 +31,20 @@
 
 import static org.junit.Assert.assertThrows;
 
+import androidx.appactions.builtintypes.experimental.properties.Attendee;
+import androidx.appactions.builtintypes.experimental.properties.Participant;
+import androidx.appactions.builtintypes.experimental.properties.Recipient;
+import androidx.appactions.builtintypes.experimental.types.CalendarEvent;
+import androidx.appactions.builtintypes.experimental.types.Call;
+import androidx.appactions.builtintypes.experimental.types.ItemList;
+import androidx.appactions.builtintypes.experimental.types.ListItem;
+import androidx.appactions.builtintypes.experimental.types.Message;
+import androidx.appactions.builtintypes.experimental.types.Person;
+import androidx.appactions.builtintypes.experimental.types.SafetyCheck;
+import androidx.appactions.builtintypes.experimental.types.Timer;
 import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
-import androidx.appactions.interaction.capabilities.core.values.CalendarEvent;
-import androidx.appactions.interaction.capabilities.core.values.Call;
 import androidx.appactions.interaction.capabilities.core.values.EntityValue;
-import androidx.appactions.interaction.capabilities.core.values.ItemList;
-import androidx.appactions.interaction.capabilities.core.values.ListItem;
-import androidx.appactions.interaction.capabilities.core.values.Message;
-import androidx.appactions.interaction.capabilities.core.values.Person;
-import androidx.appactions.interaction.capabilities.core.values.SafetyCheck;
 import androidx.appactions.interaction.capabilities.core.values.SearchAction;
-import androidx.appactions.interaction.capabilities.core.values.Timer;
-import androidx.appactions.interaction.capabilities.core.values.properties.Participant;
-import androidx.appactions.interaction.capabilities.core.values.properties.Recipient;
 import androidx.appactions.interaction.proto.Entity;
 import androidx.appactions.interaction.proto.ParamValue;
 import androidx.appactions.interaction.protobuf.ListValue;
@@ -71,44 +72,44 @@
     }
 
     private static final Person PERSON_JAVA_THING =
-            Person.newBuilder()
+            Person.Builder()
                     .setName("name")
                     .setEmail("email")
                     .setTelephone("telephone")
-                    .setId("id")
+                    .setIdentifier("id")
                     .build();
-    private static final Person PERSON_JAVA_THING_2 = Person.newBuilder().setId("id2").build();
+    private static final Person PERSON_JAVA_THING_2 = Person.Builder().setIdentifier("id2").build();
     private static final CalendarEvent CALENDAR_EVENT_JAVA_THING =
-            CalendarEvent.newBuilder()
+            CalendarEvent.Builder()
                     .setStartDate(ZonedDateTime.of(2022, 1, 1, 8, 0, 0, 0, ZoneOffset.UTC))
                     .setEndDate(ZonedDateTime.of(2023, 1, 1, 8, 0, 0, 0, ZoneOffset.UTC))
-                    .addAttendee(PERSON_JAVA_THING)
-                    .addAttendee(PERSON_JAVA_THING_2)
+                    .addAttendee(new Attendee(PERSON_JAVA_THING))
+                    .addAttendee(new Attendee(PERSON_JAVA_THING_2))
                     .build();
     private static final Call CALL_JAVA_THING =
-            Call.newBuilder()
-                    .setId("id")
-                    .setCallFormat(Call.CallFormat.AUDIO)
+            Call.Builder()
+                    .setIdentifier("id")
                     .addParticipant(PERSON_JAVA_THING)
                     .build();
     private static final Message MESSAGE_JAVA_THING =
-            Message.newBuilder()
-                    .setId("id")
+            Message.Builder()
+                    .setIdentifier("id")
                     .addRecipient(PERSON_JAVA_THING)
-                    .setMessageText("hello")
+                    .setText("hello")
                     .build();
     private static final SafetyCheck SAFETY_CHECK_JAVA_THING =
-            SafetyCheck.newBuilder()
-                    .setId("id")
+            SafetyCheck.Builder()
+                    .setIdentifier("id")
                     .setDuration(Duration.ofMinutes(5))
-                    .setCheckinTime(ZonedDateTime.of(2023, 01, 10, 10, 0, 0, 0, ZoneOffset.UTC))
+                    .setCheckInTime(ZonedDateTime.of(2023, 01, 10, 10, 0, 0, 0, ZoneOffset.UTC))
                     .build();
 
     private static final Struct PERSON_STRUCT =
             Struct.newBuilder()
                     .putFields("@type", Value.newBuilder().setStringValue("Person").build())
                     .putFields("identifier", Value.newBuilder().setStringValue("id").build())
-                    .putFields("name", Value.newBuilder().setStringValue("name").build())
+                    .putFields("name",
+                            Value.newBuilder().setStringValue("name").build())
                     .putFields("email", Value.newBuilder().setStringValue("email").build())
                     .putFields("telephone", Value.newBuilder().setStringValue("telephone").build())
                     .build();
@@ -150,7 +151,6 @@
             Struct.newBuilder()
                     .putFields("@type", Value.newBuilder().setStringValue("Call").build())
                     .putFields("identifier", Value.newBuilder().setStringValue("id").build())
-                    .putFields("callFormat", Value.newBuilder().setStringValue("Audio").build())
                     .putFields(
                             "participant",
                             Value.newBuilder()
@@ -183,7 +183,7 @@
                     .putFields("identifier", Value.newBuilder().setStringValue("id").build())
                     .putFields("duration", Value.newBuilder().setStringValue("PT5M").build())
                     .putFields(
-                            "checkinTime",
+                            "checkInTime",
                             Value.newBuilder().setStringValue("2023-01-10T10:00Z").build())
                     .build();
 
@@ -201,8 +201,8 @@
                                 .build());
 
         assertThat(
-                        SlotTypeConverter.ofSingular(TypeConverters.ENTITY_PARAM_VALUE_CONVERTER)
-                                .convert(input))
+                SlotTypeConverter.ofSingular(TypeConverters.ENTITY_PARAM_VALUE_CONVERTER)
+                        .convert(input))
                 .isEqualTo(
                         EntityValue.newBuilder().setId("entity-id").setValue("string-val").build());
     }
@@ -226,27 +226,12 @@
                         ParamValue.newBuilder().setStringValue("hello world").build());
 
         assertThat(
-                        SlotTypeConverter.ofSingular(TypeConverters.STRING_PARAM_VALUE_CONVERTER)
-                                .convert(input))
+                SlotTypeConverter.ofSingular(TypeConverters.STRING_PARAM_VALUE_CONVERTER)
+                        .convert(input))
                 .isEqualTo("hello world");
     }
 
     @Test
-    public void toStringValue_withIdentifier() throws Exception {
-        List<ParamValue> input =
-                Collections.singletonList(
-                        ParamValue.newBuilder()
-                                .setIdentifier("id1")
-                                .setStringValue("hello world")
-                                .build());
-
-        assertThat(
-                        SlotTypeConverter.ofSingular(TypeConverters.STRING_PARAM_VALUE_CONVERTER)
-                                .convert(input))
-                .isEqualTo("id1");
-    }
-
-    @Test
     public void toStringValue_fromSingleParam() throws Exception {
         ParamValue input = ParamValue.newBuilder().setStringValue("hello world").build();
 
@@ -256,7 +241,7 @@
 
     @Test
     public void listItem_conversions_matchesExpected() throws Exception {
-        ListItem listItem = ListItem.create("itemId", "Test Item");
+        ListItem listItem = ListItem.Builder().setIdentifier("itemId").setName("Test Item").build();
         Struct listItemStruct =
                 Struct.newBuilder()
                         .putFields("@type", Value.newBuilder().setStringValue("ListItem").build())
@@ -270,20 +255,21 @@
         assertThat(EntityConverter.Companion.of(LIST_ITEM_TYPE_SPEC).convert(listItem))
                 .isEqualTo(listItemProto);
         assertThat(
-                        ParamValueConverter.Companion.of(LIST_ITEM_TYPE_SPEC)
-                                .fromParamValue(toParamValue(listItemStruct, "itemId")))
+                ParamValueConverter.Companion.of(LIST_ITEM_TYPE_SPEC)
+                        .fromParamValue(toParamValue(listItemStruct, "itemId")))
                 .isEqualTo(listItem);
     }
 
     @Test
     public void itemList_conversions_matchesExpected() throws Exception {
         ItemList itemList =
-                ItemList.newBuilder()
-                        .setId("testList")
+                ItemList.Builder()
+                        .setIdentifier("testList")
                         .setName("Test List")
-                        .addListItem(
-                                ListItem.create("item1", "apple"),
-                                ListItem.create("item2", "banana"))
+                        .addItemListElement(
+                                ListItem.Builder().setIdentifier("item1").setName("apple").build())
+                        .addItemListElement(
+                                ListItem.Builder().setIdentifier("item2").setName("banana").build())
                         .build();
         Struct itemListStruct =
                 Struct.newBuilder()
@@ -361,10 +347,8 @@
 
         assertThat(EntityConverter.Companion.of(ITEM_LIST_TYPE_SPEC).convert(itemList))
                 .isEqualTo(itemListProto);
-        assertThat(
-                        ParamValueConverter.Companion.of(ITEM_LIST_TYPE_SPEC)
-                                .fromParamValue(toParamValue(itemListStruct, "testList")))
-                .isEqualTo(itemList);
+        assertThat(ParamValueConverter.Companion.of(ITEM_LIST_TYPE_SPEC)
+                .fromParamValue(toParamValue(itemListStruct, "testList"))).isEqualTo(itemList);
     }
 
     @Test
@@ -373,7 +357,7 @@
                 ParamValueConverter.Companion.of(PARTICIPANT_TYPE_SPEC);
         ParamValue paramValue =
                 ParamValue.newBuilder()
-                        .setIdentifier(PERSON_JAVA_THING.getId().orElse("id"))
+                        .setIdentifier(PERSON_JAVA_THING.getIdentifier())
                         .setStructValue(PERSON_STRUCT)
                         .build();
         Participant participant = new Participant(PERSON_JAVA_THING);
@@ -396,7 +380,8 @@
                 ParamValueConverter.Companion.of(RECIPIENT_TYPE_SPEC);
         ParamValue paramValue =
                 ParamValue.newBuilder()
-                        .setIdentifier(PERSON_JAVA_THING.getId().orElse("id"))
+                        .setIdentifier(PERSON_JAVA_THING.getIdentifier() == null ? "id" :
+                                PERSON_JAVA_THING.getIdentifier())
                         .setStructValue(PERSON_STRUCT)
                         .build();
         Recipient recipient = new Recipient(PERSON_JAVA_THING);
@@ -486,7 +471,7 @@
                                         .convert(input));
         assertThat(thrown)
                 .hasMessageThat()
-                .isEqualTo("Cannot parse boolean because bool_value is missing from ParamValue.");
+                .matches("cannot convert .+ into Value.");
     }
 
     @Test
@@ -501,7 +486,7 @@
                                         .convert(input));
         assertThat(thrown)
                 .hasMessageThat()
-                .isEqualTo("Cannot parse integer because number_value is missing from ParamValue.");
+                .matches("cannot convert .+ into Value.");
     }
 
     @Test
@@ -511,9 +496,9 @@
                         ParamValue.newBuilder().setStringValue("2018-06-17").build());
 
         assertThat(
-                        SlotTypeConverter.ofSingular(
-                                        TypeConverters.LOCAL_DATE_PARAM_VALUE_CONVERTER)
-                                .convert(input))
+                SlotTypeConverter.ofSingular(
+                                TypeConverters.LOCAL_DATE_PARAM_VALUE_CONVERTER)
+                        .convert(input))
                 .isEqualTo(LocalDate.of(2018, 6, 17));
     }
 
@@ -558,9 +543,9 @@
                         ParamValue.newBuilder().setStringValue("15:10:05").build());
 
         assertThat(
-                        SlotTypeConverter.ofSingular(
-                                        TypeConverters.LOCAL_TIME_PARAM_VALUE_CONVERTER)
-                                .convert(input))
+                SlotTypeConverter.ofSingular(
+                                TypeConverters.LOCAL_TIME_PARAM_VALUE_CONVERTER)
+                        .convert(input))
                 .isEqualTo(LocalTime.of(15, 10, 5));
     }
 
@@ -604,8 +589,8 @@
                         ParamValue.newBuilder().setStringValue("America/New_York").build());
 
         assertThat(
-                        SlotTypeConverter.ofSingular(TypeConverters.ZONE_ID_PARAM_VALUE_CONVERTER)
-                                .convert(input))
+                SlotTypeConverter.ofSingular(TypeConverters.ZONE_ID_PARAM_VALUE_CONVERTER)
+                        .convert(input))
                 .isEqualTo(ZoneId.of("America/New_York"));
     }
 
@@ -648,9 +633,9 @@
                         ParamValue.newBuilder().setStringValue("2018-06-17T15:10:05Z").build());
 
         assertThat(
-                        SlotTypeConverter.ofSingular(
-                                        TypeConverters.ZONED_DATETIME_PARAM_VALUE_CONVERTER)
-                                .convert(input))
+                SlotTypeConverter.ofSingular(
+                                TypeConverters.ZONED_DATETIME_PARAM_VALUE_CONVERTER)
+                        .convert(input))
                 .isEqualTo(ZonedDateTime.of(2018, 6, 17, 15, 10, 5, 0, ZoneOffset.UTC));
     }
 
@@ -751,8 +736,8 @@
     @Test
     public void searchActionConverter_withNestedObject() throws Exception {
         ItemList itemList =
-                ItemList.newBuilder()
-                        .addListItem(ListItem.newBuilder().setName("sugar").build())
+                ItemList.Builder()
+                        .addItemListElement(ListItem.Builder().setName("sugar").build())
                         .build();
         Struct nestedObject = TypeConverters.ITEM_LIST_TYPE_SPEC.toValue(itemList).getStructValue();
         ParamValue input =
@@ -790,24 +775,24 @@
     public void toTimer_success() throws Exception {
         ParamValueConverter<Timer> paramValueConverter =
                 ParamValueConverter.Companion.of(TIMER_TYPE_SPEC);
-        Timer timer = Timer.newBuilder().setId("abc").build();
+        Timer timer = Timer.Builder().setIdentifier("abc").build();
 
         assertThat(
-                        paramValueConverter.fromParamValue(
-                                ParamValue.newBuilder()
-                                        .setStructValue(
-                                                Struct.newBuilder()
-                                                        .putFields(
-                                                                "@type",
-                                                                Value.newBuilder()
-                                                                        .setStringValue("Timer")
-                                                                        .build())
-                                                        .putFields(
-                                                                "identifier",
-                                                                Value.newBuilder()
-                                                                        .setStringValue("abc")
-                                                                        .build()))
-                                        .build()))
+                paramValueConverter.fromParamValue(
+                        ParamValue.newBuilder()
+                                .setStructValue(
+                                        Struct.newBuilder()
+                                                .putFields(
+                                                        "@type",
+                                                        Value.newBuilder()
+                                                                .setStringValue("Timer")
+                                                                .build())
+                                                .putFields(
+                                                        "identifier",
+                                                        Value.newBuilder()
+                                                                .setStringValue("abc")
+                                                                .build()))
+                                .build()))
                 .isEqualTo(timer);
     }
 
@@ -836,8 +821,8 @@
     @Test
     public void toParamValues_safetyCheck_success() {
         assertThat(
-                        ParamValueConverter.Companion.of(SAFETY_CHECK_TYPE_SPEC)
-                                .toParamValue(SAFETY_CHECK_JAVA_THING))
+                ParamValueConverter.Companion.of(SAFETY_CHECK_TYPE_SPEC)
+                        .toParamValue(SAFETY_CHECK_JAVA_THING))
                 .isEqualTo(
                         ParamValue.newBuilder()
                                 .setStructValue(SAFETY_CHECK_STRUCT)
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/UnionTypeSpecTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/UnionTypeSpecTest.kt
index cad1967..74057e2 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/UnionTypeSpecTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/UnionTypeSpecTest.kt
@@ -16,8 +16,8 @@
 
 package androidx.appactions.interaction.capabilities.core.impl.converters
 
-import androidx.appactions.interaction.capabilities.core.values.Alarm
-import androidx.appactions.interaction.capabilities.core.values.Timer
+import androidx.appactions.builtintypes.experimental.types.Alarm
+import androidx.appactions.builtintypes.experimental.types.Timer
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -48,9 +48,9 @@
 class UnionTypeSpecTest {
   @Test
   fun unionType_identifier() {
-    val alarmUnion = AlarmOrTimer(Alarm.newBuilder().setId("alarmId").build())
-    val timerUnion = AlarmOrTimer(Timer.newBuilder().setId("timerId").build())
-    val timerUnionWithoutId = AlarmOrTimer(Timer.newBuilder().build())
+    val alarmUnion = AlarmOrTimer(Alarm.Builder().setIdentifier("alarmId").build())
+    val timerUnion = AlarmOrTimer(Timer.Builder().setIdentifier("timerId").build())
+    val timerUnionWithoutId = AlarmOrTimer(Timer.Builder().build())
     assertThat(ALARM_OR_TIMER_TYPE_SPEC.getIdentifier(alarmUnion)).isEqualTo("alarmId")
     assertThat(ALARM_OR_TIMER_TYPE_SPEC.getIdentifier(timerUnion)).isEqualTo("timerId")
     assertThat(ALARM_OR_TIMER_TYPE_SPEC.getIdentifier(timerUnionWithoutId)).isNull()
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImplTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImplTest.kt
index 932f146..4ab5a88 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImplTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImplTest.kt
@@ -16,6 +16,7 @@
 package androidx.appactions.interaction.capabilities.core.impl.task
 
 import android.util.SizeF
+import androidx.appactions.builtintypes.experimental.types.ListItem
 import androidx.appactions.interaction.capabilities.core.AppEntityListener
 import androidx.appactions.interaction.capabilities.core.Capability
 import androidx.appactions.interaction.capabilities.core.EntitySearchResult
@@ -46,7 +47,6 @@
 import androidx.appactions.interaction.capabilities.core.testing.spec.TestEnum
 import androidx.appactions.interaction.capabilities.core.testing.spec.Properties
 import androidx.appactions.interaction.capabilities.core.values.EntityValue
-import androidx.appactions.interaction.capabilities.core.values.ListItem
 import androidx.appactions.interaction.capabilities.core.values.SearchAction
 import androidx.appactions.interaction.capabilities.testing.internal.ArgumentUtils.buildRequestArgs
 import androidx.appactions.interaction.capabilities.testing.internal.ArgumentUtils.buildSearchActionParamValue
@@ -146,6 +146,7 @@
                         override fun onCreate(sessionContext: SessionContext) {
                             onCreateInvocationCount.incrementAndGet()
                         }
+
                         override fun onExecuteAsync(arguments: Arguments) =
                             Futures.immediateFuture(
                                 ExecutionResult.Builder<Output>().build(),
@@ -702,8 +703,9 @@
                 .setListItem(Property.Builder<ListItem>().setRequired(true).build())
                 .setAnyString(Property.Builder<StringValue>().setRequired(true).build())
                 .build()
-        val item1: ListItem = ListItem.newBuilder().setName("red apple").setId("item1").build()
-        val item2: ListItem = ListItem.newBuilder().setName("green apple").setId("item2").build()
+        val item1: ListItem = ListItem.Builder().setName("red apple").setIdentifier("item1").build()
+        val item2: ListItem =
+            ListItem.Builder().setName("green apple").setIdentifier("item2").build()
         val onReceivedDeferred = CompletableDeferred<ListItem>()
         val onExecuteListItemDeferred = CompletableDeferred<ListItem>()
         val onExecuteStringDeferred = CompletableDeferred<String>()
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskSlotProcessorTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskSlotProcessorTest.kt
index d8d9872..049344e 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskSlotProcessorTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskSlotProcessorTest.kt
@@ -29,8 +29,6 @@
 import androidx.appactions.interaction.proto.DisambiguationData
 import androidx.appactions.interaction.proto.Entity
 import androidx.appactions.interaction.proto.ParamValue
-import androidx.appactions.interaction.protobuf.Struct
-import androidx.appactions.interaction.protobuf.Value
 import com.google.common.truth.Truth.assertThat
 import com.google.common.util.concurrent.ListenableFuture
 import kotlinx.coroutines.CompletableDeferred
@@ -132,7 +130,7 @@
             )
         val taskParamMap: MutableMap<String, TaskParamBinding<*>> = HashMap()
         taskParamMap["singularValue"] = binding
-        val args = listOf(ParamValue.newBuilder().setIdentifier("testValue").build())
+        val args = listOf(ParamValue.newBuilder().setStringValue("testValue").build())
         val (isSuccessful, processedValues) =
             TaskSlotProcessor.processSlot(
                 "singularValue",
@@ -163,7 +161,7 @@
             )
         val taskParamMap: MutableMap<String, TaskParamBinding<*>> = HashMap()
         taskParamMap["singularValue"] = binding
-        val args = listOf(ParamValue.newBuilder().setIdentifier("testValue").build())
+        val args = listOf(ParamValue.newBuilder().setStringValue("testValue").build())
         val (isSuccessful, processedValues) =
             TaskSlotProcessor.processSlot(
                 "singularValue",
@@ -199,8 +197,8 @@
         taskParamMap["repeatedValue"] = binding
         val args =
             listOf(
-                ParamValue.newBuilder().setIdentifier("testValue1").build(),
-                ParamValue.newBuilder().setIdentifier("testValue2").build(),
+                ParamValue.newBuilder().setStringValue("testValue1").build(),
+                ParamValue.newBuilder().setStringValue("testValue2").build(),
             )
         val (isSuccessful, processedValues) =
             TaskSlotProcessor.processSlot(
@@ -247,8 +245,8 @@
         taskParamMap["repeatedValue"] = binding
         val args =
             listOf(
-                ParamValue.newBuilder().setIdentifier("testValue1").build(),
-                ParamValue.newBuilder().setIdentifier("testValue2").build(),
+                ParamValue.newBuilder().setStringValue("testValue1").build(),
+                ParamValue.newBuilder().setStringValue("testValue2").build(),
             )
         val (isSuccessful, processedValues) =
             TaskSlotProcessor.processSlot(
@@ -304,13 +302,7 @@
                     .setValue(
                         ParamValue.newBuilder()
                             .setIdentifier("id")
-                            .setStructValue(
-                                Struct.newBuilder()
-                                    .putFields(
-                                        "id",
-                                        Value.newBuilder().setStringValue("1234").build(),
-                                    ),
-                            ),
+                            .setStringValue("1234")
                     )
                     .build()
             val values =
@@ -328,7 +320,7 @@
             val (isSuccessful, processedValues) =
                 TaskSlotProcessor.processSlot("assistantDrivenSlot", values, taskParamMap)
             assertThat(isSuccessful).isFalse()
-            assertThat(onReceivedDeferred.awaitSync()).isEqualTo("id")
+            assertThat(onReceivedDeferred.awaitSync()).isEqualTo("1234")
             assertThat(renderDeferred.awaitSync()).isEqualTo(listOf("entity-1", "entity-2"))
             assertThat(processedValues)
                 .containsExactly(
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.java
index 1b8a88e..a2317c7 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.java
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.java
@@ -19,6 +19,7 @@
 import static androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters.LIST_ITEM_TYPE_SPEC;
 
 import androidx.annotation.NonNull;
+import androidx.appactions.builtintypes.experimental.types.ListItem;
 import androidx.appactions.interaction.capabilities.core.AppEntityListener;
 import androidx.appactions.interaction.capabilities.core.BaseExecutionSession;
 import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
@@ -29,7 +30,6 @@
 import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder;
 import androidx.appactions.interaction.capabilities.core.properties.Property;
 import androidx.appactions.interaction.capabilities.core.properties.StringValue;
-import androidx.appactions.interaction.capabilities.core.values.ListItem;
 
 import com.google.auto.value.AutoValue;
 
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 f4a5294..14c0fed 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
@@ -16,14 +16,14 @@
 
 package androidx.appactions.interaction.capabilities.productivity
 
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
 import androidx.appactions.interaction.capabilities.core.Capability
 import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
 import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
 import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
 import androidx.appactions.interaction.capabilities.core.properties.Property
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
 import androidx.appactions.interaction.proto.ParamValue
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
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 ec8fea6..d05acf9 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
@@ -16,14 +16,14 @@
 
 package androidx.appactions.interaction.capabilities.productivity
 
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
 import androidx.appactions.interaction.capabilities.core.Capability
 import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
 import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
 import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
 import androidx.appactions.interaction.capabilities.core.properties.Property
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
 import androidx.appactions.interaction.proto.ParamValue
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
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 d8b2fb0..accb730 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
@@ -16,14 +16,14 @@
 
 package androidx.appactions.interaction.capabilities.productivity
 
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
 import androidx.appactions.interaction.capabilities.core.Capability
 import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
 import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
 import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
 import androidx.appactions.interaction.capabilities.core.properties.Property
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
 import androidx.appactions.interaction.proto.ParamValue
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
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 360b356..8a96645 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
@@ -16,6 +16,8 @@
 
 package androidx.appactions.interaction.capabilities.productivity
 
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
 import androidx.appactions.interaction.capabilities.core.Capability
 import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
 import androidx.appactions.interaction.capabilities.core.ExecutionSessionFactory
@@ -27,8 +29,6 @@
 import androidx.appactions.interaction.capabilities.core.properties.Property
 import androidx.appactions.interaction.capabilities.core.impl.task.SessionBridge
 import androidx.appactions.interaction.capabilities.core.impl.task.TaskHandler
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
 import androidx.appactions.interaction.proto.ParamValue
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
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 c018c60..fa589e7 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
@@ -16,14 +16,14 @@
 
 package androidx.appactions.interaction.capabilities.productivity
 
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
 import androidx.appactions.interaction.capabilities.core.Capability
 import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
 import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
 import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
 import androidx.appactions.interaction.capabilities.core.properties.Property
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
 import androidx.appactions.interaction.proto.ParamValue
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/TimerValue.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/TimerValue.kt
index f642bb1..ff9ae5b 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/TimerValue.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/TimerValue.kt
@@ -16,12 +16,12 @@
 
 package androidx.appactions.interaction.capabilities.productivity
 
+import androidx.appactions.builtintypes.experimental.types.Timer
 import androidx.appactions.interaction.capabilities.core.impl.converters.EntityConverter
 import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
 import androidx.appactions.interaction.capabilities.core.impl.converters.UnionTypeSpec
 import androidx.appactions.interaction.capabilities.core.values.SearchAction
-import androidx.appactions.interaction.capabilities.core.values.Timer
 import java.util.Objects
 
 class TimerValue
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 79e0bd3..a0829de 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
@@ -16,14 +16,14 @@
 
 package androidx.appactions.interaction.capabilities.safety
 
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
+import androidx.appactions.builtintypes.experimental.types.NoInternetConnection
 import androidx.appactions.interaction.capabilities.core.Capability
 import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
 import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
 import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
-import androidx.appactions.interaction.capabilities.core.values.executionstatus.NoInternetConnection
 import androidx.appactions.interaction.capabilities.safety.executionstatus.EmergencySharingInProgress
 import androidx.appactions.interaction.capabilities.safety.executionstatus.SafetyAccountNotLoggedIn
 import androidx.appactions.interaction.capabilities.safety.executionstatus.SafetyFeatureNotOnboarded
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 0bf2a33..cd5b319 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
@@ -16,6 +16,11 @@
 
 package androidx.appactions.interaction.capabilities.safety
 
+import androidx.appactions.builtintypes.experimental.types.ActionNotInProgress
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.NoInternetConnection
+import androidx.appactions.builtintypes.experimental.types.SafetyCheck
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
 import androidx.appactions.interaction.capabilities.core.Capability
 import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
 import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
@@ -24,11 +29,6 @@
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters.SAFETY_CHECK_TYPE_SPEC
 import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
 import androidx.appactions.interaction.capabilities.core.properties.Property
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SafetyCheck
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
-import androidx.appactions.interaction.capabilities.core.values.executionstatus.ActionNotInProgress
-import androidx.appactions.interaction.capabilities.core.values.executionstatus.NoInternetConnection
 import androidx.appactions.interaction.capabilities.safety.executionstatus.EmergencySharingInProgress
 import androidx.appactions.interaction.capabilities.safety.executionstatus.SafetyAccountNotLoggedIn
 import androidx.appactions.interaction.capabilities.safety.executionstatus.SafetyFeatureNotOnboarded
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 1224831..afc9f18 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
@@ -16,15 +16,15 @@
 
 package androidx.appactions.interaction.capabilities.safety
 
+import androidx.appactions.builtintypes.experimental.types.ActionNotInProgress
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.NoInternetConnection
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
 import androidx.appactions.interaction.capabilities.core.Capability
 import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
 import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
 import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
-import androidx.appactions.interaction.capabilities.core.values.executionstatus.ActionNotInProgress
-import androidx.appactions.interaction.capabilities.core.values.executionstatus.NoInternetConnection
 import androidx.appactions.interaction.capabilities.safety.executionstatus.SafetyAccountNotLoggedIn
 import androidx.appactions.interaction.capabilities.safety.executionstatus.SafetyFeatureNotOnboarded
 import androidx.appactions.interaction.proto.ParamValue
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 01d3ff9..3e5156b 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
@@ -16,15 +16,15 @@
 
 package androidx.appactions.interaction.capabilities.safety
 
+import androidx.appactions.builtintypes.experimental.types.ActionNotInProgress
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.NoInternetConnection
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
 import androidx.appactions.interaction.capabilities.core.Capability
 import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
 import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
 import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
-import androidx.appactions.interaction.capabilities.core.values.executionstatus.ActionNotInProgress
-import androidx.appactions.interaction.capabilities.core.values.executionstatus.NoInternetConnection
 import androidx.appactions.interaction.capabilities.safety.executionstatus.SafetyAccountNotLoggedIn
 import androidx.appactions.interaction.capabilities.safety.executionstatus.SafetyFeatureNotOnboarded
 import androidx.appactions.interaction.proto.ParamValue
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/EmergencySharingInProgress.java b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/EmergencySharingInProgress.java
deleted file mode 100644
index 86c1e31..0000000
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/EmergencySharingInProgress.java
+++ /dev/null
@@ -1,51 +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.appactions.interaction.capabilities.safety.executionstatus;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.Thing;
-
-import com.google.auto.value.AutoValue;
-
-/** Error status for execution failure due to emergency sharing being in progress. */
-@AutoValue
-public abstract class EmergencySharingInProgress extends Thing {
-
-    /** Builder class for EmergencySharingInProgress status. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder>
-            implements BuilderOf<EmergencySharingInProgress> {
-    }
-
-    /** Create a new EmergencySharingInProgress instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_EmergencySharingInProgress.Builder();
-    }
-
-    /** Create a new default instance. */
-    @NonNull
-    public static EmergencySharingInProgress getDefaultInstance() {
-        return new AutoValue_EmergencySharingInProgress.Builder().build();
-    }
-
-    @Override
-    public final String toString() {
-        return "EmergencySharingInProgress";
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/EmergencySharingInProgress.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/EmergencySharingInProgress.kt
new file mode 100644
index 0000000..4fc874c
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/EmergencySharingInProgress.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.appactions.interaction.capabilities.safety.executionstatus
+
+import androidx.appactions.builtintypes.experimental.properties.Name
+import androidx.appactions.builtintypes.experimental.types.Thing
+
+interface EmergencySharingInProgress : Thing {
+    override fun toBuilder(): Builder<*>
+
+    companion object {
+        @JvmStatic
+        fun Builder(): Builder<*> = EmergencySharingInProgressBuilderImpl()
+    }
+
+    interface Builder<Self : Builder<Self>> : Thing.Builder<Self> {
+        override fun build(): EmergencySharingInProgress
+    }
+}
+
+private class EmergencySharingInProgressBuilderImpl :
+    EmergencySharingInProgress.Builder<EmergencySharingInProgressBuilderImpl> {
+
+    private var identifier: String? = null
+    private var name: Name? = null
+
+    override fun build() = EmergencySharingInProgressImpl(identifier, name)
+
+    override fun setIdentifier(text: String?): EmergencySharingInProgressBuilderImpl =
+        apply { identifier = text }
+
+    override fun setName(text: String): EmergencySharingInProgressBuilderImpl =
+        apply { name = Name(text) }
+
+    override fun setName(name: Name?): EmergencySharingInProgressBuilderImpl =
+        apply { this.name = name }
+
+    override fun clearName(): EmergencySharingInProgressBuilderImpl = apply { name = null }
+}
+
+private class EmergencySharingInProgressImpl(
+    override val identifier: String?,
+    override val name: Name?
+) :
+    EmergencySharingInProgress {
+    override fun toBuilder(): EmergencySharingInProgress.Builder<*> =
+        EmergencySharingInProgressBuilderImpl().setIdentifier(identifier).setName(name)
+
+    override fun toString(): String = "EmergencySharingInProgress"
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyAccountNotLoggedIn.java b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyAccountNotLoggedIn.java
deleted file mode 100644
index f4b9b4f..0000000
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyAccountNotLoggedIn.java
+++ /dev/null
@@ -1,51 +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.appactions.interaction.capabilities.safety.executionstatus;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.Thing;
-
-import com.google.auto.value.AutoValue;
-
-/** Error status for execution failure due to logged out account. */
-@AutoValue
-public abstract class SafetyAccountNotLoggedIn extends Thing {
-
-    /** Builder class for SafetyAccountNotLoggedIn status. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder>
-            implements BuilderOf<SafetyAccountNotLoggedIn> {
-    }
-
-    /** Create a new SafetyAccountNotLoggedIn instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_SafetyAccountNotLoggedIn.Builder();
-    }
-
-    /** Create a new default instance. */
-    @NonNull
-    public static SafetyAccountNotLoggedIn getDefaultInstance() {
-        return new AutoValue_SafetyAccountNotLoggedIn.Builder().build();
-    }
-
-    @Override
-    public final String toString() {
-        return "SafetyAccountNotLoggedIn";
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyAccountNotLoggedIn.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyAccountNotLoggedIn.kt
new file mode 100644
index 0000000..fed52ff
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyAccountNotLoggedIn.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.appactions.interaction.capabilities.safety.executionstatus
+
+import androidx.appactions.builtintypes.experimental.properties.Name
+import androidx.appactions.builtintypes.experimental.types.Thing
+
+interface SafetyAccountNotLoggedIn : Thing {
+    override fun toBuilder(): Builder<*>
+
+    companion object {
+        @JvmStatic
+        fun Builder(): Builder<*> = SafetyAccountNotLoggedInBuilderImpl()
+    }
+
+    interface Builder<Self : Builder<Self>> : Thing.Builder<Self> {
+        override fun build(): SafetyAccountNotLoggedIn
+    }
+}
+
+private class SafetyAccountNotLoggedInBuilderImpl :
+    SafetyAccountNotLoggedIn.Builder<SafetyAccountNotLoggedInBuilderImpl> {
+
+    private var identifier: String? = null
+    private var name: Name? = null
+
+    override fun build() = SafetyAccountNotLoggedInImpl(identifier, name)
+
+    override fun setIdentifier(text: String?): SafetyAccountNotLoggedInBuilderImpl =
+        apply { identifier = text }
+
+    override fun setName(text: String): SafetyAccountNotLoggedInBuilderImpl =
+        apply { name = Name(text) }
+
+    override fun setName(name: Name?): SafetyAccountNotLoggedInBuilderImpl =
+        apply { this.name = name }
+
+    override fun clearName(): SafetyAccountNotLoggedInBuilderImpl = apply { name = null }
+}
+
+private class SafetyAccountNotLoggedInImpl(
+    override val identifier: String?,
+    override val name: Name?
+) :
+    SafetyAccountNotLoggedIn {
+    override fun toBuilder(): SafetyAccountNotLoggedIn.Builder<*> =
+        SafetyAccountNotLoggedInBuilderImpl().setIdentifier(identifier).setName(name)
+
+    override fun toString(): String = "SafetyAccountNotLoggedIn"
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyFeatureNotOnboarded.java b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyFeatureNotOnboarded.java
deleted file mode 100644
index cfed520..0000000
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyFeatureNotOnboarded.java
+++ /dev/null
@@ -1,51 +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.appactions.interaction.capabilities.safety.executionstatus;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.Thing;
-
-import com.google.auto.value.AutoValue;
-
-/** Error status for execution failure due to user not being onboard. */
-@AutoValue
-public abstract class SafetyFeatureNotOnboarded extends Thing {
-
-    /** Builder class for SafetyFeatureNotOnboarded status. */
-    @AutoValue.Builder
-    public abstract static class Builder extends Thing.Builder<Builder>
-            implements BuilderOf<SafetyFeatureNotOnboarded> {
-    }
-
-    /** Create a new SafetyFeatureNotOnboarded instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_SafetyFeatureNotOnboarded.Builder();
-    }
-
-    /** Create a new default instance. */
-    @NonNull
-    public static SafetyFeatureNotOnboarded getDefaultInstance() {
-        return new AutoValue_SafetyFeatureNotOnboarded.Builder().build();
-    }
-
-    @Override
-    public final String toString() {
-        return "SafetyFeatureNotOnboarded";
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyFeatureNotOnboarded.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyFeatureNotOnboarded.kt
new file mode 100644
index 0000000..46d84ab
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyFeatureNotOnboarded.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.appactions.interaction.capabilities.safety.executionstatus
+
+import androidx.appactions.builtintypes.experimental.properties.Name
+import androidx.appactions.builtintypes.experimental.types.Thing
+
+interface SafetyFeatureNotOnboarded : Thing {
+    override fun toBuilder(): Builder<*>
+
+    companion object {
+        @JvmStatic
+        fun Builder(): Builder<*> = SafetyFeatureNotOnboardedBuilderImpl()
+    }
+
+    interface Builder<Self : Builder<Self>> : Thing.Builder<Self> {
+        override fun build(): SafetyFeatureNotOnboarded
+    }
+}
+
+private class SafetyFeatureNotOnboardedBuilderImpl :
+    SafetyFeatureNotOnboarded.Builder<SafetyFeatureNotOnboardedBuilderImpl> {
+
+    private var identifier: String? = null
+    private var name: Name? = null
+
+    override fun build() = SafetyFeatureNotOnboardedImpl(identifier, name)
+
+    override fun setIdentifier(text: String?): SafetyFeatureNotOnboardedBuilderImpl =
+        apply { identifier = text }
+
+    override fun setName(text: String): SafetyFeatureNotOnboardedBuilderImpl =
+        apply { name = Name(text) }
+
+    override fun setName(name: Name?): SafetyFeatureNotOnboardedBuilderImpl =
+        apply { this.name = name }
+
+    override fun clearName(): SafetyFeatureNotOnboardedBuilderImpl = apply { name = null }
+}
+
+private class SafetyFeatureNotOnboardedImpl(
+    override val identifier: String?,
+    override val name: Name?
+) :
+    SafetyFeatureNotOnboarded {
+    override fun toBuilder(): SafetyFeatureNotOnboarded.Builder<*> =
+        SafetyFeatureNotOnboardedBuilderImpl().setIdentifier(identifier).setName(name)
+
+    override fun toString(): String = "SafetyFeatureNotOnboarded"
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/AppInteractionServiceEntityProviderTest.kt b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/AppInteractionServiceEntityProviderTest.kt
index 6f339d4..b571b2f 100644
--- a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/AppInteractionServiceEntityProviderTest.kt
+++ b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/AppInteractionServiceEntityProviderTest.kt
@@ -16,9 +16,9 @@
 
 package androidx.appactions.interaction.service
 
+import androidx.appactions.builtintypes.experimental.types.Alarm
 import androidx.appactions.interaction.capabilities.core.impl.converters.EntityConverter
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
-import androidx.appactions.interaction.capabilities.core.values.Alarm
 import androidx.appactions.interaction.capabilities.testing.internal.ArgumentUtils.buildSearchActionParamValue
 import androidx.appactions.interaction.capabilities.testing.internal.TestingUtils.awaitSync
 import androidx.appactions.interaction.proto.GroundingRequest
@@ -66,7 +66,7 @@
 
     @Test
     fun alarmProvider_incorrectProviderId(): Unit = runBlocking {
-        val morningAlarm = Alarm.newBuilder().setId("alarm1").setName("Morning Alarm").build()
+        val morningAlarm = Alarm.Builder().setIdentifier("alarm1").setName("Morning Alarm").build()
         val alarmProvider = FakeAlarmEntityProvider(
             "alarmProvider",
             listOf(morningAlarm)
@@ -110,7 +110,7 @@
 
     @Test
     fun alarmProvider_success(): Unit = runBlocking {
-        val morningAlarm = Alarm.newBuilder().setId("alarm1").setName("Morning Alarm").build()
+        val morningAlarm = Alarm.Builder().setIdentifier("alarm1").setName("Morning Alarm").build()
         val alarmProvider = FakeAlarmEntityProvider(
             "alarmProvider",
             listOf(morningAlarm)
diff --git a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/UiSessionsTest.kt b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/UiSessionsTest.kt
index 84f10a2..e9e60c5 100644
--- a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/UiSessionsTest.kt
+++ b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/UiSessionsTest.kt
@@ -270,7 +270,7 @@
         session.execute(
             buildArgs(
                 mapOf(
-                    "fieldOne" to ParamValue.newBuilder().setIdentifier("hello").build(),
+                    "fieldOne" to ParamValue.newBuilder().setStringValue("hello").build(),
                 ),
             ),
             callback,
diff --git a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeAlarmEntityProvider.kt b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeAlarmEntityProvider.kt
index c2b23b1..fd99a27 100644
--- a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeAlarmEntityProvider.kt
+++ b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeAlarmEntityProvider.kt
@@ -16,12 +16,12 @@
 
 package androidx.appactions.interaction.service.testing.internal
 
+import androidx.appactions.builtintypes.experimental.types.Alarm
 import androidx.appactions.interaction.capabilities.core.entity.EntityProvider
 import androidx.appactions.interaction.capabilities.core.entity.EntityLookupRequest
 import androidx.appactions.interaction.capabilities.core.entity.EntityLookupResponse
 import androidx.appactions.interaction.capabilities.core.entity.EntityLookupCandidate
 import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
-import androidx.appactions.interaction.capabilities.core.values.Alarm
 
 class FakeAlarmEntityProvider(
     override val id: String,
diff --git a/benchmark/benchmark-junit4/api/api_lint.ignore b/benchmark/benchmark-junit4/api/api_lint.ignore
index fa24057..e28c732 100644
--- a/benchmark/benchmark-junit4/api/api_lint.ignore
+++ b/benchmark/benchmark-junit4/api/api_lint.ignore
@@ -1,4 +1,10 @@
 // Baseline format: 1.0
+GetterSetterNames: field PerfettoTraceRule.enableAppTagTracing:
+    Invalid name for boolean property `enableAppTagTracing`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PerfettoTraceRule.enableUserspaceTracing:
+    Invalid name for boolean property `enableUserspaceTracing`. Should start with one of `has`, `can`, `should`, `is`.
+
+
 InvalidNullabilityOverride: androidx.benchmark.junit4.BenchmarkRule#apply(org.junit.runners.model.Statement, org.junit.runner.Description) parameter #0:
     Invalid nullability on parameter `base` in method `apply`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.benchmark.junit4.BenchmarkRule#apply(org.junit.runners.model.Statement, org.junit.runner.Description) parameter #1:
diff --git a/benchmark/benchmark-junit4/api/current.txt b/benchmark/benchmark-junit4/api/current.txt
index 873f105..819dd90 100644
--- a/benchmark/benchmark-junit4/api/current.txt
+++ b/benchmark/benchmark-junit4/api/current.txt
@@ -12,7 +12,7 @@
   }
 
   public final class BenchmarkRule.Scope {
-    method public inline <T> T! runWithTimingDisabled(kotlin.jvm.functions.Function0<? extends T> block);
+    method public inline <T> T runWithTimingDisabled(kotlin.jvm.functions.Function0<? extends T> block);
   }
 
   public final class BenchmarkRuleKt {
diff --git a/benchmark/benchmark-junit4/api/public_plus_experimental_current.txt b/benchmark/benchmark-junit4/api/public_plus_experimental_current.txt
index b376c11..f68f2a0 100644
--- a/benchmark/benchmark-junit4/api/public_plus_experimental_current.txt
+++ b/benchmark/benchmark-junit4/api/public_plus_experimental_current.txt
@@ -12,7 +12,7 @@
   }
 
   public final class BenchmarkRule.Scope {
-    method public inline <T> T! runWithTimingDisabled(kotlin.jvm.functions.Function0<? extends T> block);
+    method public inline <T> T runWithTimingDisabled(kotlin.jvm.functions.Function0<? extends T> block);
   }
 
   public final class BenchmarkRuleKt {
diff --git a/benchmark/benchmark-junit4/api/restricted_current.txt b/benchmark/benchmark-junit4/api/restricted_current.txt
index c2d8056..1003a639 100644
--- a/benchmark/benchmark-junit4/api/restricted_current.txt
+++ b/benchmark/benchmark-junit4/api/restricted_current.txt
@@ -13,7 +13,7 @@
 
   public final class BenchmarkRule.Scope {
     method @kotlin.PublishedApi internal androidx.benchmark.BenchmarkState getOuterState();
-    method public inline <T> T! runWithTimingDisabled(kotlin.jvm.functions.Function0<? extends T> block);
+    method public inline <T> T runWithTimingDisabled(kotlin.jvm.functions.Function0<? extends T> block);
   }
 
   public final class BenchmarkRuleKt {
diff --git a/benchmark/benchmark-macro/api/api_lint.ignore b/benchmark/benchmark-macro/api/api_lint.ignore
new file mode 100644
index 0000000..33968af
--- /dev/null
+++ b/benchmark/benchmark-macro/api/api_lint.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+GetterSetterNames: field Metric.Measurement.requireSingleValue:
+    Invalid name for boolean property `requireSingleValue`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/benchmark/benchmark-macro/api/public_plus_experimental_current.txt b/benchmark/benchmark-macro/api/public_plus_experimental_current.txt
index 86e2432..1597078 100644
--- a/benchmark/benchmark-macro/api/public_plus_experimental_current.txt
+++ b/benchmark/benchmark-macro/api/public_plus_experimental_current.txt
@@ -208,13 +208,13 @@
 
   @androidx.benchmark.perfetto.ExperimentalPerfettoTraceProcessorApi public final class PerfettoTraceProcessor {
     ctor public PerfettoTraceProcessor();
-    method public <T> T! loadTrace(androidx.benchmark.perfetto.PerfettoTrace trace, kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor.Session,? extends T> block);
-    method public static <T> T! runServer(kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor,? extends T> block);
+    method public <T> T loadTrace(androidx.benchmark.perfetto.PerfettoTrace trace, kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor.Session,? extends T> block);
+    method public static <T> T runServer(kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor,? extends T> block);
     field public static final androidx.benchmark.perfetto.PerfettoTraceProcessor.Companion Companion;
   }
 
   public static final class PerfettoTraceProcessor.Companion {
-    method public <T> T! runServer(kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor,? extends T> block);
+    method public <T> T runServer(kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor,? extends T> block);
   }
 
   public static final class PerfettoTraceProcessor.Session {
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/ProfileInstallBroadcastTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/ProfileInstallBroadcastTest.kt
index 6398e36..055ccfd 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/ProfileInstallBroadcastTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/ProfileInstallBroadcastTest.kt
@@ -19,13 +19,10 @@
 import android.os.Build
 import androidx.benchmark.junit4.PerfettoTraceRule
 import androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi
-import androidx.core.os.BuildCompat
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import androidx.test.filters.SdkSuppress
 import kotlin.test.assertNull
-import org.junit.Assume
-import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -37,12 +34,6 @@
     @get:Rule
     val perfettoTraceRule = PerfettoTraceRule()
 
-    @Before
-    fun setUp() {
-        // TODO: to re-enable for api 34 (b/276970167)
-        Assume.assumeTrue(!BuildCompat.isAtLeastU())
-    }
-
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
     @Test
     fun installProfile() {
diff --git a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/AddressType.kt b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/AddressType.kt
new file mode 100644
index 0000000..02f2550
--- /dev/null
+++ b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/AddressType.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.bluetooth
+
+import android.bluetooth.BluetoothDevice
+import androidx.annotation.IntDef
+import androidx.annotation.RestrictTo
+
+/**
+ * Represents a Bluetooth device address type.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+@Retention(AnnotationRetention.SOURCE)
+@IntDef(
+    AddressType.ADDRESS_TYPE_PUBLIC,
+    AddressType.ADDRESS_TYPE_RANDOM,
+    AddressType.ADDRESS_TYPE_UNKNOWN
+)
+public annotation class AddressType {
+    companion object {
+        /* Address type is public and registered with the IEEE. */
+        public const val ADDRESS_TYPE_PUBLIC: Int = BluetoothDevice.ADDRESS_TYPE_PUBLIC
+
+        /* Address type is random. */
+        public const val ADDRESS_TYPE_RANDOM: Int = BluetoothDevice.ADDRESS_TYPE_RANDOM
+
+        /* Address type is unknown. */
+        public const val ADDRESS_TYPE_UNKNOWN: Int = BluetoothDevice.ADDRESS_TYPE_UNKNOWN
+    }
+}
\ No newline at end of file
diff --git a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanType.kt b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanType.kt
new file mode 100644
index 0000000..e26a338
--- /dev/null
+++ b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanType.kt
@@ -0,0 +1,50 @@
+/*
+ * 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.ScanSettings
+import androidx.annotation.IntDef
+import androidx.annotation.RestrictTo
+
+/**
+ * Bluetooth LE scan type that defines which scan results to send into the scan flow.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+@Retention(AnnotationRetention.SOURCE)
+@IntDef(
+    ScanType.ALL_MATCHES,
+    ScanType.FIRST_MATCH,
+    ScanType.MATCH_LOST
+)
+public annotation class ScanType {
+    companion object {
+        /* Send scan result for every Bluetooth advertisement that matches the filter criteria. */
+        public const val ALL_MATCHES: Int = ScanSettings.CALLBACK_TYPE_ALL_MATCHES
+
+        /**
+         * Send scan result for only the first advertisement packet received that matches the filter
+         * criteria.
+         */
+        public const val FIRST_MATCH: Int = ScanSettings.CALLBACK_TYPE_FIRST_MATCH
+
+        /**
+         * Send scan result when advertisements are no longer received from a device that has been
+         * previously reported by a first match scan type.
+         */
+        public const val MATCH_LOST: Int = ScanSettings.CALLBACK_TYPE_MATCH_LOST
+    }
+}
\ No newline at end of file
diff --git a/bluetooth/integration-tests/testapp/build.gradle b/bluetooth/integration-tests/testapp/build.gradle
index 18d2ce1..ba207e7 100644
--- a/bluetooth/integration-tests/testapp/build.gradle
+++ b/bluetooth/integration-tests/testapp/build.gradle
@@ -44,22 +44,20 @@
 
 dependencies {
     implementation(libs.kotlinStdlib)
-
     implementation(project(":bluetooth:bluetooth"))
 
-    implementation("androidx.core:core-ktx:1.9.0")
+    implementation("androidx.activity:activity-ktx:1.7.0")
     implementation("androidx.appcompat:appcompat:1.6.1")
+    implementation(libs.constraintLayout)
+    implementation("androidx.core:core-ktx:1.10.0")
+    implementation("androidx.fragment:fragment-ktx:1.5.6")
+    implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.1")
+    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.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.3.0")
 
     implementation(libs.material)
 
-    implementation("androidx.activity:activity-ktx:1.7.0")
-    implementation("androidx.fragment:fragment-ktx:1.5.6")
-
-    implementation(libs.constraintLayout)
-
-    implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.1")
-    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1")
-
-    implementation("androidx.navigation:navigation-fragment-ktx:2.5.3")
-    implementation("androidx.navigation:navigation-ui-ktx:2.5.3")
+    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
 }
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiseDataAdapter.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiseDataAdapter.kt
new file mode 100644
index 0000000..a48c218
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiseDataAdapter.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.bluetooth.integration.testapp.ui.advertiser
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageButton
+import android.widget.TextView
+import androidx.bluetooth.integration.testapp.R
+import androidx.recyclerview.widget.RecyclerView
+
+class AdvertiseDataAdapter(var advertiseData: List<String>, private val onClick: (Int) -> Unit) :
+    RecyclerView.Adapter<AdvertiseDataAdapter.ViewHolder>() {
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+        val view = LayoutInflater.from(parent.context)
+            .inflate(R.layout.item_advertiser_data, parent, false)
+        return ViewHolder(view, onClick)
+    }
+
+    override fun getItemCount(): Int {
+        return advertiseData.size
+    }
+
+    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+        val advertiseData = advertiseData[position]
+        holder.bind(advertiseData)
+    }
+
+    inner class ViewHolder(itemView: View, private val onClick: (Int) -> Unit) :
+        RecyclerView.ViewHolder(itemView) {
+
+        private val textViewData: TextView = itemView.findViewById(R.id.text_view_data)
+        private val imageButtonClear: ImageButton = itemView.findViewById(R.id.image_button_clear)
+
+        init {
+            imageButtonClear.setOnClickListener {
+                imageButtonClear.isClickable = false
+                onClick(absoluteAdapterPosition)
+            }
+        }
+
+        fun bind(advertiseData: String) {
+            textViewData.text = advertiseData
+            imageButtonClear.isClickable = true
+        }
+    }
+}
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserFragment.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserFragment.kt
index 3f12108..73c1935 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserFragment.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserFragment.kt
@@ -16,20 +16,61 @@
 
 package androidx.bluetooth.integration.testapp.ui.advertiser
 
+import android.annotation.SuppressLint
 import android.os.Bundle
 import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
+import android.widget.EditText
+
+import androidx.appcompat.app.AlertDialog
+import androidx.appcompat.widget.PopupMenu
+import androidx.bluetooth.AdvertiseResult
+import androidx.bluetooth.BluetoothLe
+import androidx.bluetooth.integration.testapp.R
 import androidx.bluetooth.integration.testapp.databinding.FragmentAdvertiserBinding
+import androidx.bluetooth.integration.testapp.ui.common.setViewEditText
+import androidx.bluetooth.integration.testapp.ui.common.toast
+import androidx.core.view.isVisible
 import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+
+import java.util.UUID
 
 class AdvertiserFragment : Fragment() {
 
-    companion object {
+    private companion object {
         private const val TAG = "AdvertiserFragment"
     }
 
+    private lateinit var advertiserViewModel: AdvertiserViewModel
+
+    private lateinit var bluetoothLe: BluetoothLe
+
+    private var advertiseDataAdapter: AdvertiseDataAdapter? = null
+
+    private val advertiseScope = CoroutineScope(Dispatchers.Main + Job())
+    private var advertiseJob: Job? = null
+
+    private var isAdvertising: Boolean = false
+        set(value) {
+            field = value
+            if (value) {
+                _binding?.buttonAdvertise?.text = getString(R.string.stop_advertising)
+            } else {
+                _binding?.buttonAdvertise?.text = getString(R.string.start_advertising)
+                advertiseJob?.cancel()
+                advertiseJob = null
+            }
+            _binding?.viewOverlay?.isVisible = value
+        }
+
     private var _binding: FragmentAdvertiserBinding? = null
 
     // This property is only valid between onCreateView and onDestroyView.
@@ -40,17 +81,188 @@
         container: ViewGroup?,
         savedInstanceState: Bundle?
     ): View {
-        Log.d(
-            TAG, "onCreateView() called with: inflater = $inflater, " +
-                "container = $container, savedInstanceState = $savedInstanceState"
-        )
+        advertiserViewModel = ViewModelProvider(this)[AdvertiserViewModel::class.java]
+
+        bluetoothLe = BluetoothLe(requireContext())
 
         _binding = FragmentAdvertiserBinding.inflate(inflater, container, false)
+
+        initData()
+
+        binding.checkBoxIncludeDeviceName.setOnCheckedChangeListener { _, isChecked ->
+            advertiserViewModel.includeDeviceName = isChecked
+        }
+
+        binding.checkBoxConnectable.setOnCheckedChangeListener { _, isChecked ->
+            advertiserViewModel.connectable = isChecked
+        }
+
+        binding.checkBoxDiscoverable.setOnCheckedChangeListener { _, isChecked ->
+            advertiserViewModel.discoverable = isChecked
+        }
+
+        binding.buttonAddData.setOnClickListener {
+            with(PopupMenu(requireContext(), binding.buttonAddData)) {
+                menu.add(getString(R.string.service_uuid))
+                menu.add(getString(R.string.service_data))
+                menu.add(getString(R.string.manufacturer_data))
+
+                setOnMenuItemClickListener { menuItem ->
+                    showDialogFor(menuItem.title.toString())
+                    true
+                }
+                show()
+            }
+        }
+
+        advertiseDataAdapter = AdvertiseDataAdapter(
+            advertiserViewModel.advertiseData,
+            ::onClickRemoveAdvertiseData
+        )
+        binding.recyclerViewAdvertiseData.adapter = advertiseDataAdapter
+
+        binding.buttonAdvertise.setOnClickListener {
+            if (advertiseJob?.isActive == true) {
+                isAdvertising = false
+            } else {
+                startAdvertise()
+            }
+        }
+
         return binding.root
     }
 
     override fun onDestroyView() {
         super.onDestroyView()
         _binding = null
+        isAdvertising = false
+    }
+
+    private fun initData() {
+        binding.checkBoxIncludeDeviceName.isChecked = advertiserViewModel.includeDeviceName
+        binding.checkBoxConnectable.isChecked = advertiserViewModel.connectable
+        binding.checkBoxDiscoverable.isChecked = advertiserViewModel.discoverable
+    }
+
+    private fun showDialogFor(title: String) {
+        when (title) {
+            getString(R.string.service_uuid) -> showDialogForServiceUuid()
+            getString(R.string.service_data) -> showDialogForServiceData()
+            getString(R.string.manufacturer_data) -> showDialogForManufacturerData()
+        }
+    }
+
+    private fun showDialogForServiceUuid() {
+        val editText = EditText(requireActivity())
+        editText.hint = getString(R.string.uuid_or_service_name)
+
+        AlertDialog.Builder(requireContext())
+            .setTitle(getString(R.string.service_uuid))
+            .setViewEditText(editText)
+            .setPositiveButton(getString(R.string.add)) { _, _ ->
+                val editTextInput = editText.text.toString()
+
+                advertiserViewModel.serviceUuids.add(UUID.fromString(editTextInput))
+                refreshAdvertiseData()
+            }
+            .setNegativeButton(getString(R.string.cancel), null)
+            .create()
+            .show()
+    }
+
+    private fun showDialogForServiceData() {
+        val view = layoutInflater.inflate(R.layout.dialog_service_data, null)
+        val editTextUuidOrServiceName =
+            view.findViewById<EditText>(R.id.edit_text_uuid_or_service_name)
+        val editTextDataHex = view.findViewById<EditText>(R.id.edit_text_data_hex)
+
+        AlertDialog.Builder(requireContext())
+            .setTitle(getString(R.string.service_data))
+            .setView(view)
+            .setPositiveButton(getString(R.string.add)) { _, _ ->
+                val editTextUuidOrServiceNameInput = editTextUuidOrServiceName.text.toString()
+                val editTextDataHexInput = editTextDataHex.text.toString()
+
+                val serviceData = Pair(
+                    UUID.fromString(editTextUuidOrServiceNameInput),
+                    editTextDataHexInput.toByteArray()
+                )
+                advertiserViewModel.serviceDatas.add(serviceData)
+            }
+            .setNegativeButton(getString(R.string.cancel), null)
+            .create()
+            .show()
+    }
+
+    private fun showDialogForManufacturerData() {
+        val view = layoutInflater.inflate(R.layout.dialog_manufacturer_data, null)
+        val editText16BitCompanyIdentifier =
+            view.findViewById<EditText>(R.id.edit_text_16_bit_company_identifier)
+        val editTextDataHex = view.findViewById<EditText>(R.id.edit_text_data_hex)
+
+        AlertDialog.Builder(requireContext())
+            .setTitle(getString(R.string.manufacturer_data))
+            .setView(view)
+            .setPositiveButton(getString(R.string.add)) { _, _ ->
+                val editText16BitCompanyIdentifierInput =
+                    editText16BitCompanyIdentifier.text.toString()
+                val editTextDataHexInput = editTextDataHex.text.toString()
+
+                val manufacturerData = Pair(
+                    editText16BitCompanyIdentifierInput.toInt(),
+                    editTextDataHexInput.toByteArray()
+                )
+                advertiserViewModel.manufacturerDatas.add(manufacturerData)
+            }
+            .setNegativeButton(getString(R.string.cancel), null)
+            .create()
+            .show()
+    }
+
+    @SuppressLint("NotifyDataSetChanged")
+    private fun refreshAdvertiseData() {
+        advertiseDataAdapter?.advertiseData = advertiserViewModel.advertiseData
+        advertiseDataAdapter?.notifyDataSetChanged()
+    }
+
+    private fun onClickRemoveAdvertiseData(index: Int) {
+        advertiserViewModel.removeAdvertiseDataAtIndex(index)
+        advertiseDataAdapter?.advertiseData = advertiserViewModel.advertiseData
+        advertiseDataAdapter?.notifyItemRemoved(index)
+    }
+
+    // Permissions are handled by MainActivity requestBluetoothPermissions
+    @SuppressLint("MissingPermission")
+    private fun startAdvertise() {
+        advertiseJob = advertiseScope.launch {
+            isAdvertising = true
+
+            bluetoothLe.advertise(advertiserViewModel.advertiseParams)
+                .collect {
+                    Log.d(TAG, "AdvertiseResult collected: $it")
+
+                    when (it) {
+                        AdvertiseResult.ADVERTISE_STARTED -> {
+                            toast("ADVERTISE_STARTED").show()
+                        }
+                        AdvertiseResult.ADVERTISE_FAILED_DATA_TOO_LARGE -> {
+                            isAdvertising = false
+                            toast("ADVERTISE_FAILED_DATA_TOO_LARGE").show()
+                        }
+                        AdvertiseResult.ADVERTISE_FAILED_FEATURE_UNSUPPORTED -> {
+                            isAdvertising = false
+                            toast("ADVERTISE_FAILED_FEATURE_UNSUPPORTED").show()
+                        }
+                        AdvertiseResult.ADVERTISE_FAILED_INTERNAL_ERROR -> {
+                            isAdvertising = false
+                            toast("ADVERTISE_FAILED_INTERNAL_ERROR").show()
+                        }
+                        AdvertiseResult.ADVERTISE_FAILED_TOO_MANY_ADVERTISERS -> {
+                            isAdvertising = false
+                            toast("ADVERTISE_FAILED_TOO_MANY_ADVERTISERS").show()
+                        }
+                    }
+                }
+        }
     }
 }
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserViewModel.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserViewModel.kt
new file mode 100644
index 0000000..f0e4cdd
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserViewModel.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.bluetooth.integration.testapp.ui.advertiser
+
+import androidx.bluetooth.AdvertiseParams
+import androidx.lifecycle.ViewModel
+import java.util.UUID
+
+class AdvertiserViewModel : ViewModel() {
+
+    private companion object {
+        private const val TAG = "AdvertiserViewModel"
+    }
+
+    var includeDeviceAddress = false
+    var includeDeviceName = false
+    var connectable = false
+    var discoverable = false
+    var timeoutMillis = 0
+    var manufacturerDatas = mutableListOf<Pair<Int, ByteArray>>()
+    var serviceDatas = mutableListOf<Pair<UUID, ByteArray>>()
+    var serviceUuids = mutableListOf<UUID>()
+
+    val advertiseData: List<String>
+        get() = listOf(
+            manufacturerDatas
+                .map { "Manufacturer Data:\n" +
+                    "Company ID: 0x${it.first} Data: 0x${it.second.toString(Charsets.UTF_8)}" },
+            serviceDatas
+                .map { "Service Data:\n" +
+                    "UUID: ${it.first} Data: 0x${it.second.toString(Charsets.UTF_8)}" },
+            serviceUuids
+                .map { "128-bit Service UUID:\n" +
+                    "$it" }
+        ).flatten()
+
+    val advertiseParams: AdvertiseParams
+        get() = AdvertiseParams(
+            includeDeviceAddress,
+            includeDeviceName,
+            connectable,
+            discoverable,
+            timeoutMillis,
+            manufacturerDatas.toMap(),
+            serviceDatas.toMap(),
+            serviceUuids
+        )
+
+    fun removeAdvertiseDataAtIndex(index: Int) {
+        val manufacturerDataSize = manufacturerDatas.size
+        val serviceDataSize = serviceDatas.size
+
+        if (index < manufacturerDataSize) {
+            manufacturerDatas.removeAt(index)
+        } else if (index < serviceDataSize + manufacturerDataSize) {
+            serviceDatas.removeAt(index - manufacturerDataSize)
+        } else {
+            serviceUuids.removeAt(index - manufacturerDataSize - serviceDataSize)
+        }
+    }
+}
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/AlertDialog.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/AlertDialog.kt
new file mode 100644
index 0000000..e5d876d
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/AlertDialog.kt
@@ -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.bluetooth.integration.testapp.ui.common
+
+import android.widget.EditText
+import android.widget.FrameLayout
+import androidx.appcompat.app.AlertDialog
+
+fun AlertDialog.Builder.setViewEditText(editText: EditText): AlertDialog.Builder {
+    val frameLayout = FrameLayout(editText.context)
+    frameLayout.addView(editText)
+    val frameLayoutParams = FrameLayout.LayoutParams(
+        FrameLayout.LayoutParams.MATCH_PARENT,
+        FrameLayout.LayoutParams.WRAP_CONTENT
+    )
+    frameLayoutParams.setMargins(16.dp, 8.dp, 16.dp, 8.dp)
+    frameLayout.layoutParams = frameLayoutParams
+
+    val container = FrameLayout(editText.context)
+    container.addView(frameLayout)
+
+    setView(container)
+
+    return this
+}
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/Fragment.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/Fragment.kt
new file mode 100644
index 0000000..395bd0d7
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/Fragment.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.bluetooth.integration.testapp.ui.common
+
+import android.widget.Toast
+import androidx.fragment.app.Fragment
+
+fun Fragment.toast(msg: String): Toast {
+    return Toast.makeText(requireContext(), msg, Toast.LENGTH_SHORT)
+}
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/Number.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/Number.kt
new file mode 100644
index 0000000..a86edb2
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/Number.kt
@@ -0,0 +1,27 @@
+/*
+ * 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.integration.testapp.ui.common
+
+import android.content.res.Resources
+import android.util.TypedValue
+
+val Number.dp
+    get() = TypedValue.applyDimension(
+        TypedValue.COMPLEX_UNIT_DIP,
+        toFloat(),
+        Resources.getSystem().displayMetrics
+    ).toInt()
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerFragment.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerFragment.kt
index 919b434..7411f0a 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerFragment.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerFragment.kt
@@ -41,7 +41,7 @@
 
 class ScannerFragment : Fragment() {
 
-    companion object {
+    private companion object {
         private const val TAG = "ScannerFragment"
     }
 
@@ -58,8 +58,12 @@
     private var isScanning: Boolean = false
         set(value) {
             field = value
-            if (value) _binding?.buttonScan?.text = getString(R.string.stop_scanning)
-            else _binding?.buttonScan?.text = getString(R.string.start_scanning)
+            if (value) {
+                _binding?.buttonScan?.text = getString(R.string.stop_scanning)
+            } else {
+                _binding?.buttonScan?.text = getString(R.string.start_scanning)
+                scanJob?.cancel()
+            }
         }
 
     private var _binding: FragmentScannerBinding? = null
@@ -84,29 +88,30 @@
             DividerItemDecoration(context, LinearLayoutManager.VERTICAL)
         )
 
-        return binding.root
-    }
-
-    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-        super.onViewCreated(view, savedInstanceState)
+        initData()
 
         binding.buttonScan.setOnClickListener {
             if (scanJob?.isActive == true) {
-                scanJob?.cancel()
                 isScanning = false
             } else {
                 startScan()
             }
         }
+
+        return binding.root
     }
 
     override fun onDestroyView() {
         super.onDestroyView()
         _binding = null
-        scanJob?.cancel()
         isScanning = false
     }
 
+    private fun initData() {
+        scannerAdapter?.submitList(scannerViewModel.results)
+        scannerAdapter?.notifyItemRangeChanged(0, scannerViewModel.results.size)
+    }
+
     private fun startScan() {
         // TODO(ofy) Migrate to androidx.bluetooth.BluetoothLe once scan API is in place
         val scanSettings = ScanSettings.Builder()
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerViewModel.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerViewModel.kt
index e9ab0e8..7d213fd 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerViewModel.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerViewModel.kt
@@ -21,7 +21,7 @@
 
 class ScannerViewModel : ViewModel() {
 
-    companion object {
+    private companion object {
         private const val TAG = "ScannerViewModel"
     }
 
diff --git a/bluetooth/integration-tests/testapp/src/main/res/drawable/baseline_clear_24.xml b/bluetooth/integration-tests/testapp/src/main/res/drawable/baseline_clear_24.xml
new file mode 100644
index 0000000..2750a06
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/res/drawable/baseline_clear_24.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.
+  -->
+
+<vector android:height="24dp" android:tint="#000000"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
+</vector>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/drawable/grey_rounded_background.xml b/bluetooth/integration-tests/testapp/src/main/res/drawable/grey_rounded_background.xml
new file mode 100644
index 0000000..9cafe24
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/res/drawable/grey_rounded_background.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.
+  -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="#32000000" />
+    <corners android:radius="16dp" />
+</shape>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/layout/dialog_manufacturer_data.xml b/bluetooth/integration-tests/testapp/src/main/res/layout/dialog_manufacturer_data.xml
new file mode 100644
index 0000000..e9d1138
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/res/layout/dialog_manufacturer_data.xml
@@ -0,0 +1,74 @@
+<?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="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:paddingStart="16dp"
+    android:paddingTop="8dp"
+    android:paddingEnd="16dp">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="0x"
+            android:textColor="@color/black"
+            android:textSize="21sp"
+            tools:ignore="HardcodedText" />
+
+        <EditText
+            android:id="@+id/edit_text_16_bit_company_identifier"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="4dp"
+            android:layout_marginEnd="4dp"
+            android:hint="@string/sixteen_bit_company_identifier"
+            android:inputType="text" />
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="0x"
+            android:textColor="@color/black"
+            android:textSize="21sp"
+            tools:ignore="HardcodedText" />
+
+        <EditText
+            android:id="@+id/edit_text_data_hex"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="4dp"
+            android:layout_marginEnd="4dp"
+            android:hint="@string/data_hex"
+            android:inputType="text" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/layout/dialog_service_data.xml b/bluetooth/integration-tests/testapp/src/main/res/layout/dialog_service_data.xml
new file mode 100644
index 0000000..0c91f3c
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/res/layout/dialog_service_data.xml
@@ -0,0 +1,57 @@
+<?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="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:paddingStart="16dp"
+    android:paddingTop="8dp"
+    android:paddingEnd="16dp">
+
+    <EditText
+        android:id="@+id/edit_text_uuid_or_service_name"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:hint="@string/uuid_or_service_name"
+        android:inputType="text" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="0x"
+            android:textColor="@color/black"
+            android:textSize="21sp"
+            tools:ignore="HardcodedText" />
+
+        <EditText
+            android:id="@+id/edit_text_data_hex"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="4dp"
+            android:layout_marginEnd="4dp"
+            android:hint="@string/data_hex"
+            android:inputType="text" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_advertiser.xml b/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_advertiser.xml
index 14e7b3e..c6e37d3 100644
--- a/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_advertiser.xml
+++ b/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_advertiser.xml
@@ -16,7 +16,112 @@
   -->
 <androidx.constraintlayout.widget.ConstraintLayout
     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">
 
+    <TextView
+        android:id="@+id/text_view_configure_advertising_packet"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="16dp"
+        android:text="@string/configure_advertising_packet"
+        android:textColor="@color/black"
+        android:textSize="21sp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <com.google.android.material.textfield.TextInputLayout
+        android:id="@+id/text_input_layout_display_name"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:hint="@string/display_name"
+        app:layout_constraintTop_toBottomOf="@+id/text_view_configure_advertising_packet">
+
+        <com.google.android.material.textfield.TextInputEditText
+            android:id="@+id/text_input_edit_text_display_name"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:inputType="text"
+            android:maxLines="1" />
+
+    </com.google.android.material.textfield.TextInputLayout>
+
+    <CheckBox
+        android:id="@+id/check_box_include_device_name"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="16dp"
+        android:layout_marginTop="8dp"
+        android:text="@string/include_device_name"
+        app:layout_constraintTop_toBottomOf="@+id/text_input_layout_display_name" />
+
+    <CheckBox
+        android:id="@+id/check_box_connectable"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="16dp"
+        android:text="@string/connectable"
+        app:layout_constraintTop_toBottomOf="@+id/check_box_include_device_name" />
+
+    <CheckBox
+        android:id="@+id/check_box_discoverable"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="16dp"
+        android:text="@string/discoverable"
+        app:layout_constraintTop_toBottomOf="@+id/check_box_connectable" />
+
+    <TextView
+        android:id="@+id/text_view_advertising_data"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="8dp"
+        android:layout_marginEnd="8dp"
+        android:padding="8dp"
+        android:text="@string/advertising_data"
+        android:textColor="@color/black"
+        android:textSize="21sp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/check_box_discoverable" />
+
+    <Button
+        android:id="@+id/button_add_data"
+        style="@style/Widget.AppCompat.Button.Borderless"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="8dp"
+        android:text="@string/add_data"
+        android:textColor="@color/purple_500"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/text_view_advertising_data" />
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/recycler_view_advertise_data"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        app:layoutManager="LinearLayoutManager"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/button_add_data"
+        tools:itemCount="3"
+        tools:listitem="@layout/item_advertiser_data" />
+
+    <View
+        android:id="@+id/view_overlay"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@color/black_alpha_50"
+        android:clickable="true"
+        android:visibility="gone" />
+
+    <Button
+        android:id="@+id/button_advertise"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_margin="16dp"
+        android:text="@string/start_advertising"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent" />
+
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/layout/item_advertiser_data.xml b/bluetooth/integration-tests/testapp/src/main/res/layout/item_advertiser_data.xml
new file mode 100644
index 0000000..031bd18
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/res/layout/item_advertiser_data.xml
@@ -0,0 +1,49 @@
+<?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:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_marginStart="16dp"
+    android:layout_marginTop="4dp"
+    android:layout_marginEnd="16dp"
+    android:layout_marginBottom="4dp"
+    android:background="@drawable/grey_rounded_background"
+    android:gravity="center_vertical"
+    android:orientation="horizontal"
+    android:padding="4dp">
+
+    <TextView
+        android:id="@+id/text_view_data"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:padding="8dp"
+        android:textColor="@color/black"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/button_add_data"
+        tools:text="16-Bit Service UUID: 0x1800" />
+
+    <ImageButton
+        android:id="@+id/image_button_clear"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="@drawable/baseline_clear_24"
+        android:contentDescription="@string/clear_data" />
+
+</LinearLayout>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/values/colors.xml b/bluetooth/integration-tests/testapp/src/main/res/values/colors.xml
index 6d70d3a..a7e6ba3 100644
--- a/bluetooth/integration-tests/testapp/src/main/res/values/colors.xml
+++ b/bluetooth/integration-tests/testapp/src/main/res/values/colors.xml
@@ -22,4 +22,5 @@
     <color name="teal_700">#FF018786</color>
     <color name="black">#FF000000</color>
     <color name="white">#FFFFFFFF</color>
+    <color name="black_alpha_50">#80000000</color>
 </resources>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml b/bluetooth/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml
index 0576493..5707c81 100644
--- a/bluetooth/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml
+++ b/bluetooth/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml
@@ -27,6 +27,26 @@
     <string name="scan_result_icon">Scan Result Icon</string>
     <string name="connect">Connect</string>
 
+    <!-- Advertiser -->
+    <string name="configure_advertising_packet">Configure Advertising Packet</string>
+    <string name="display_name">Display Name</string>
+    <string name="include_device_name">Include Device Name</string>
+    <string name="connectable">Connectable</string>
+    <string name="discoverable">Discoverable</string>
+    <string name="advertising_data">Advertising Data</string>
+    <string name="add_data">Add Data</string>
+    <string name="start_advertising">Start Advertising</string>
+    <string name="stop_advertising">Stop Advertising</string>
+    <string name="service_uuid">Service UUID</string>
+    <string name="uuid_or_service_name">UUID or service name</string>
+    <string name="service_data">Service Data</string>
+    <string name="data_hex">Data (HEX)</string>
+    <string name="manufacturer_data">Manufacturer Data</string>
+    <string name="sixteen_bit_company_identifier">16-bit Company Identifier</string>
+    <string name="add">Add</string>
+    <string name="cancel">Cancel</string>
+    <string name="clear_data">Clear Data</string>
+
     <string name="scan_using_androidx_bluetooth">Scan using AndroidX Bluetooth APIs</string>
     <string name="scan_start_message">Scan started. Results are in Logcat</string>
 
diff --git a/build.gradle b/build.gradle
index 3a6b8e5..fc4788f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -25,3 +25,9 @@
 apply from: "buildSrc/dependencies.gradle"
 
 apply plugin: AndroidXRootPlugin
+
+// workaround for https://github.com/gradle/gradle/issues/24822
+if (project.hasProperty("androidx.update.signatures")) {
+    apply plugin: "java-library"
+    apply from: "buildSrc/shared-dependencies.gradle"
+}
diff --git a/buildSrc-tests/project-subsets/build.gradle b/buildSrc-tests/project-subsets/build.gradle
deleted file mode 100644
index 3ee8f3d..0000000
--- a/buildSrc-tests/project-subsets/build.gradle
+++ /dev/null
@@ -1,33 +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.
- */
-
-plugins {
-    id("AndroidXPlugin")
-    id("kotlin")
-}
-
-dependencies {
-    implementation gradleTestKit()
-    testImplementation libs.junit
-}
-tasks["test"].configure { t ->
-    // The output of this task can potentially depend on the contents of settings.gradle
-    // and any files referenced by it, including every build.gradle and any scripts or plugins they
-    // apply too. We don't have a convenient way to identify the true inputs here, so we always
-    // run this task and leave details around incrementality up to the Gradle builds that we spawn
-    t.outputs.upToDateWhen { false }
-}
-
diff --git a/buildSrc-tests/project-subsets/src/test/kotlin/androidx/build/ProjectSubsetsTest.kt b/buildSrc-tests/project-subsets/src/test/kotlin/androidx/build/ProjectSubsetsTest.kt
deleted file mode 100644
index 5bfe120..0000000
--- a/buildSrc-tests/project-subsets/src/test/kotlin/androidx/build/ProjectSubsetsTest.kt
+++ /dev/null
@@ -1,109 +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.build
-
-import org.gradle.testkit.runner.GradleRunner
-import org.junit.Test
-import java.io.File
-
-/**
- * This class tests that each of the project subsets defined in settings.gradle can be built
- * successfully and does not involve a project that attempts to reference
- * another project defined only in a different subset, b/172277767 .
- *
- * This is implemented using the Gradle TestKit so it can be
- * run in parallel with other tasks, b/180012150 .
- */
-public class ProjectSubsetsTest {
-    @Test
-    fun testSubsetMain() {
-        validateSubset("main")
-    }
-
-    @Test
-    fun testSubsetCamera() {
-        validateSubset("camera")
-    }
-
-    @Test
-    fun testSubsetCompose() {
-        validateSubset("compose")
-    }
-
-    @Test
-    fun testSubsetFlan() {
-        validateSubset("flan")
-    }
-
-    @Test
-    fun testSubsetMedia() {
-        validateSubset("media")
-    }
-
-    @Test
-    fun testSubsetWear() {
-        validateSubset("wear")
-    }
-
-    @Test
-    fun testSubsetGlance() {
-        validateSubset("glance")
-    }
-
-    @Test
-    fun testSubsetTools() {
-        validateSubset("tools")
-    }
-
-    @Test
-    fun testSubsetKmp() {
-        validateSubset("kmp")
-    }
-
-    @Test
-    fun testSubsetNative() {
-        validateSubset("native")
-    }
-
-    @Test
-    fun testSubsetWindow() {
-        validateSubset("window")
-    }
-    /**
-     * Validates a specific project subset
-     */
-    fun validateSubset(name: String) {
-        val projectDir = File("../..").normalize()
-        var outDir = System.getenv("OUT_DIR")
-        if (outDir == null || outDir == "") {
-            outDir = File(projectDir, "../../out").normalize().toString()
-        }
-        // --dependency-verification=off is set because we don't have to do validation of
-        // dependencies during these tests, it is already handled by the main build.
-        // Having it validate here breaks in androidx-studio-integration case where we
-        // might get new dependencies from AGP that are missinng signatures.
-
-        // Run buildOnServer to validate project dependencies and constraints
-        GradleRunner.create()
-            .withProjectDir(projectDir)
-            .withArguments(
-                "-Pandroidx.projects=$name", "buildOnServer", "-m", "--dependency-verification=off"
-            )
-            .withTestKitDir(File(outDir, ".gradle-testkit"))
-            .build(); // fails the test if the build fails
-    }
-}
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt
index 1d529cd..32f63ba 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt
@@ -153,6 +153,7 @@
                     error.add("ComposableLambdaParameterPosition")
                     error.add("CompositionLocalNaming")
                     error.add("ComposableModifierFactory")
+                    error.add("AutoboxingStateValueProperty")
                     error.add("InvalidColorHexValue")
                     error.add("MissingColorAlphaChannel")
                     error.add("ModifierFactoryReturnType")
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXGradleProperties.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXGradleProperties.kt
index d373a4f..f6ed376 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXGradleProperties.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXGradleProperties.kt
@@ -152,6 +152,11 @@
  */
 const val ALLOW_CUSTOM_COMPILE_SDK = "androidx.allowCustomCompileSdk"
 
+/**
+ * Whether to update gradle signature verification metadata
+ */
+const val UPDATE_SIGNATURES = "androidx.update.signatures"
+
 val ALL_ANDROIDX_PROPERTIES = setOf(
     ADD_GROUP_CONSTRAINTS,
     ALTERNATIVE_PROJECT_URL,
@@ -179,7 +184,8 @@
     ENABLED_KMP_TARGET_PLATFORMS,
     ALLOW_MISSING_LINT_CHECKS_PROJECT,
     XCODEGEN_DOWNLOAD_URI,
-    ALLOW_CUSTOM_COMPILE_SDK
+    ALLOW_CUSTOM_COMPILE_SDK,
+    UPDATE_SIGNATURES
 )
 
 /**
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/uptodatedness/TaskUpToDateValidator.kt b/buildSrc/private/src/main/kotlin/androidx/build/uptodatedness/TaskUpToDateValidator.kt
index 66d49df..e43634f 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/uptodatedness/TaskUpToDateValidator.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/uptodatedness/TaskUpToDateValidator.kt
@@ -136,7 +136,6 @@
 // Additional tasks that are expected to be temporarily out-of-date after running once
 // Tasks in this set we don't even try to rerun, because they're known to be unnecessary
 val DONT_TRY_RERUNNING_TASKS = setOf(
-    ":buildSrc-tests:project-subsets:test",
     "listTaskOutputs",
     "tasks",
 
diff --git a/buildSrc/shared-dependencies.gradle b/buildSrc/shared-dependencies.gradle
new file mode 100644
index 0000000..1b67981
--- /dev/null
+++ b/buildSrc/shared-dependencies.gradle
@@ -0,0 +1,50 @@
+// This file applies dependencies common to projects in buildSrc
+
+apply from: "${buildscript.sourceFile.parent}/kotlin-dsl-dependency.gradle"
+dependencies {
+
+    // Gradle APIs
+    implementation(gradleApi())
+    compileOnly(findGradleKotlinDsl())
+
+    // Android Gradle Plugin APIs used by Stable AIDL
+    implementation(libs.androidGradlePluginApi)
+
+    // Plugins we use and configure
+    implementation(libs.androidGradlePluginz)
+    implementation(libs.androidToolsCommon) // for com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
+    implementation(libs.androidToolsRepository) // com.android.repository for Stable AIDL plugin
+    implementation(libs.androidToolsSdkCommon) // com.android.ide.common for Stable AIDL plugin
+    implementation(libs.kotlinGradlePluginz)
+
+    // variety of json parsers
+    implementation(libs.gson)
+    implementation(libs.jsonSimple)
+
+    // XML parsers used in MavenUploadHelper.kt
+    implementation(libs.dom4j) {
+        // Optional dependency where Ivy fails to parse the POM file.
+        exclude(group:"net.java.dev.msv", module:"xsdlib")
+    }
+    implementation(libs.xerces)
+
+    implementation(libs.shadow) // used by BundleInsideHelper.kt
+    implementation(libs.apacheAnt) // used in AarManifestTransformerTask.kt for unziping
+    implementation(libs.toml)
+    implementation(libs.apacheCommonIo) // used in CheckApiEquivalenceTask.kt
+    implementation(libs.dexMemberList) // used in ReportLibraryMetricsTask.kt
+
+    implementation(libs.protobufGradlePluginz) // needed to compile inspection plugin
+    implementation(libs.kotlinPoet) // needed to compile material-icon-generator
+    implementation(libs.xmlpull) // needed to compile material-icon-generator
+
+    implementation(libs.protobuf) // needed to compile baseline-profile gradle plugins
+    implementation(libs.agpTestingPlatformCoreProto) // needed to compile baseline-profile gradle plugins
+
+    // dependencies that aren't used by buildSrc directly but that we resolve here so that the
+    // root project doesn't need to re-resolve them and their dependencies on every build
+    runtimeOnly(libs.hiltAndroidGradlePluginz)
+    runtimeOnly(libs.javapoet) // for hiltAndroidGradlePluginz to workaround https://github.com/google/dagger/issues/3068
+    runtimeOnly(libs.kspGradlePluginz)
+    runtimeOnly(libs.wireGradlePluginz)
+}
diff --git a/buildSrc/shared.gradle b/buildSrc/shared.gradle
index 6cb909a..b342c0b 100644
--- a/buildSrc/shared.gradle
+++ b/buildSrc/shared.gradle
@@ -1,6 +1,5 @@
-
+// This file applies configuration common to projects in buildSrc
 apply plugin: "kotlin"
-apply from: "../kotlin-dsl-dependency.gradle"
 apply plugin: "java-gradle-plugin"
 
 buildscript {
@@ -14,53 +13,10 @@
 
 dependencies {
     implementation(project(":jetpad-integration"))
-
-    // Gradle APIs
-    implementation(gradleApi())
-    compileOnly(findGradleKotlinDsl())
-
-    // Android Gradle Plugin APIs used by Stable AIDL
-    implementation(libs.androidGradlePluginApi)
-
-    // Plugins we use and configure
-    implementation(libs.androidGradlePluginz)
-    implementation(libs.androidToolsCommon) // for com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
-    implementation(libs.androidToolsRepository) // com.android.repository for Stable AIDL plugin
-    implementation(libs.androidToolsSdkCommon) // com.android.ide.common for Stable AIDL plugin
-    implementation(libs.kotlinGradlePluginz)
-
-    // variety of json parsers
-    implementation(libs.gson)
-    implementation(libs.jsonSimple)
-
-    // XML parsers used in MavenUploadHelper.kt
-    implementation(libs.dom4j) {
-        // Optional dependency where Ivy fails to parse the POM file.
-        exclude(group:"net.java.dev.msv", module:"xsdlib")
-    }
-    implementation(libs.xerces)
-
-    implementation(libs.shadow) // used by BundleInsideHelper.kt
-    implementation(libs.apacheAnt) // used in AarManifestTransformerTask.kt for unziping
-    implementation(libs.toml)
-    implementation(libs.apacheCommonIo) // used in CheckApiEquivalenceTask.kt
-    implementation(libs.dexMemberList) // used in ReportLibraryMetricsTask.kt
-
-    implementation(libs.protobufGradlePluginz) // needed to compile inspection plugin
-    implementation(libs.kotlinPoet) // needed to compile material-icon-generator
-    implementation(libs.xmlpull) // needed to compile material-icon-generator
-
-    implementation(libs.protobuf) // needed to compile baseline-profile gradle plugins
-    implementation(libs.agpTestingPlatformCoreProto) // needed to compile baseline-profile gradle plugins
-
-    // dependencies that aren't used by buildSrc directly but that we resolve here so that the
-    // root project doesn't need to re-resolve them and their dependencies on every build
-    runtimeOnly(libs.hiltAndroidGradlePluginz)
-    runtimeOnly(libs.javapoet) // for hiltAndroidGradlePluginz to workaround https://github.com/google/dagger/issues/3068
-    runtimeOnly(libs.kspGradlePluginz)
-    runtimeOnly(libs.wireGradlePluginz)
 }
 
+apply from: "../shared-dependencies.gradle"
+
 java {
     sourceCompatibility = JavaVersion.VERSION_11
     targetCompatibility = JavaVersion.VERSION_11
diff --git a/busytown/androidx_host_tests.sh b/busytown/androidx_host_tests.sh
index 00ba171..bba9e74 100755
--- a/busytown/androidx_host_tests.sh
+++ b/busytown/androidx_host_tests.sh
@@ -5,10 +5,9 @@
 
 cd "$(dirname $0)"
 
-impl/build.sh test linuxX64Test \
+impl/build.sh test \
     -Pandroidx.ignoreTestFailures \
     -Pandroidx.displayTestOutput=false \
-    -Pandroidx.enabled.kmp.target.platforms=+native \
     "$@"
 
 echo "Completing $0 at $(date)"
diff --git a/busytown/androidx_host_tests_max_dep_versions.sh b/busytown/androidx_host_tests_max_dep_versions.sh
index a56dbc4..ef49669 100755
--- a/busytown/androidx_host_tests_max_dep_versions.sh
+++ b/busytown/androidx_host_tests_max_dep_versions.sh
@@ -5,9 +5,9 @@
 
 cd "$(dirname $0)"
 
-impl/build.sh test linuxX64Test -Pandroidx.useMaxDepVersions \
+impl/build.sh test \
+    -Pandroidx.useMaxDepVersions \
     -Pandroidx.displayTestOutput=false \
-    -Pandroidx.enabled.kmp.target.platforms=+native \
     -Pandroidx.ignoreTestFailures "$@"
 
 echo "Completing $0 at $(date)"
diff --git a/camera/camera-camera2-pipe-integration/api/public_plus_experimental_current.txt b/camera/camera-camera2-pipe-integration/api/public_plus_experimental_current.txt
index 6b10990..9d11137 100644
--- a/camera/camera-camera2-pipe-integration/api/public_plus_experimental_current.txt
+++ b/camera/camera-camera2-pipe-integration/api/public_plus_experimental_current.txt
@@ -28,7 +28,7 @@
 
   @RequiresApi(21) public static final class Camera2Interop.Extender<T> {
     ctor public Camera2Interop.Extender(androidx.camera.core.ExtendableBuilder<T> baseBuilder);
-    method public <ValueT> androidx.camera.camera2.pipe.integration.interop.Camera2Interop.Extender<T> setCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT> key, ValueT? value);
+    method public <ValueT> androidx.camera.camera2.pipe.integration.interop.Camera2Interop.Extender<T> setCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT> key, ValueT value);
     method public androidx.camera.camera2.pipe.integration.interop.Camera2Interop.Extender<T> setDeviceStateCallback(android.hardware.camera2.CameraDevice.StateCallback stateCallback);
     method @RequiresApi(28) public androidx.camera.camera2.pipe.integration.interop.Camera2Interop.Extender<T> setPhysicalCameraId(String cameraId);
     method public androidx.camera.camera2.pipe.integration.interop.Camera2Interop.Extender<T> setSessionCaptureCallback(android.hardware.camera2.CameraCaptureSession.CaptureCallback captureCallback);
@@ -44,7 +44,7 @@
     ctor public CaptureRequestOptions.Builder();
     method public androidx.camera.camera2.pipe.integration.interop.CaptureRequestOptions build();
     method public <ValueT> androidx.camera.camera2.pipe.integration.interop.CaptureRequestOptions.Builder clearCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT> key);
-    method public <ValueT> androidx.camera.camera2.pipe.integration.interop.CaptureRequestOptions.Builder setCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT> key, ValueT? value);
+    method public <ValueT> androidx.camera.camera2.pipe.integration.interop.CaptureRequestOptions.Builder setCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT> key, ValueT value);
   }
 
   @kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalCamera2Interop {
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapter.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapter.kt
index a741f20..17ecd63 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapter.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapter.kt
@@ -195,8 +195,10 @@
         // TODO: use DynamicRangesCompat instead after it is migrates from camera-camera2.
         if (Build.VERSION.SDK_INT >= 33) {
             val availableProfiles = cameraProperties.metadata[
-                CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES]!!
-            return profileSetToDynamicRangeSet(availableProfiles.supportedProfiles)
+                CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES]
+            if (availableProfiles != null) {
+                return profileSetToDynamicRangeSet(availableProfiles.supportedProfiles)
+            }
         }
         return setOf(DynamicRange.SDR)
     }
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/CameraQuirks.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/CameraQuirks.kt
index c46831d..d80d27a 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/CameraQuirks.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/CameraQuirks.kt
@@ -95,6 +95,9 @@
         if (CaptureSessionStuckQuirk.isEnabled()) {
             quirks.add(CaptureSessionStuckQuirk())
         }
+        if (FinalizeSessionOnCloseQuirk.isEnabled()) {
+            quirks.add(FinalizeSessionOnCloseQuirk())
+        }
 
         Quirks(quirks)
     }
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/FinalizeSessionOnCloseQuirk.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/FinalizeSessionOnCloseQuirk.kt
new file mode 100644
index 0000000..95a6727
--- /dev/null
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/FinalizeSessionOnCloseQuirk.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.camera.camera2.pipe.integration.compat.quirk
+
+import android.annotation.SuppressLint
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.CameraGraph.Flags.FinalizeSessionOnCloseBehavior
+import androidx.camera.core.impl.Quirk
+
+/**
+ * A quirk that finalizes [androidx.camera.camera2.pipe.compat.CaptureSessionState] when the
+ * CameraGraph is stopped or closed.
+ *
+ * QuirkSummary
+ * - Bug Id:      277310425
+ * - Description: When CameraX sets up its video recorder, it waits for the previous Surfaces to be
+ *                released before setting them in the new CameraGraph. However, CameraPipe would
+ *                also wait for the Surfaces to be set before it creates a new capture session and
+ *                finalize the previous session, and therefore not releasing the Surfaces. This
+ *                essentially creates a deadlock, and this quirk would enable a behavior in
+ *                CameraPipe such that the current session gets finalized either immediately or on a
+ *                timeout after the CameraGraph is stopped or closed.
+ * - Device(s):   All devices.
+ */
+@SuppressLint("CameraXQuirksClassDetector")
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+class FinalizeSessionOnCloseQuirk : Quirk {
+    companion object {
+        fun isEnabled() = true
+
+        fun getBehavior() =
+            if (Build.BRAND == "google") {
+                // Finalize immediately for devices that allow immediate Surface reuse.
+                FinalizeSessionOnCloseBehavior.IMMEDIATE
+            } else {
+                FinalizeSessionOnCloseBehavior.TIMEOUT
+            }
+    }
+}
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/config/CameraConfig.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/config/CameraConfig.kt
index b827dcd..0c5a985 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/config/CameraConfig.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/config/CameraConfig.kt
@@ -38,6 +38,7 @@
 import androidx.camera.camera2.pipe.integration.compat.ZoomCompat
 import androidx.camera.camera2.pipe.integration.compat.quirk.CameraQuirks
 import androidx.camera.camera2.pipe.integration.compat.quirk.CaptureSessionStuckQuirk
+import androidx.camera.camera2.pipe.integration.compat.quirk.FinalizeSessionOnCloseQuirk
 import androidx.camera.camera2.pipe.integration.impl.CameraPipeCameraProperties
 import androidx.camera.camera2.pipe.integration.impl.CameraProperties
 import androidx.camera.camera2.pipe.integration.impl.ComboRequestListener
@@ -156,7 +157,14 @@
                 Log.debug { "CameraPipe should be enabling CaptureSessionStuckQuirk" }
             }
             // TODO(b/276354253): Set quirkWaitForRepeatingRequestOnDisconnect flag for overrides.
-            return CameraGraph.Flags()
+
+            // TODO(b/277310425): When creating a CameraGraph, this flag should be turned OFF when
+            //  this behavior is not needed based on the use case interaction and the device on
+            //  which the test is running.
+            val quirkFinalizeSessionOnCloseBehavior = FinalizeSessionOnCloseQuirk.getBehavior()
+            return CameraGraph.Flags(
+                quirkFinalizeSessionOnCloseBehavior = quirkFinalizeSessionOnCloseBehavior,
+            )
         }
     }
 
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/config/UseCaseCameraConfig.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/config/UseCaseCameraConfig.kt
index a4635da..d8e75a8 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/config/UseCaseCameraConfig.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/config/UseCaseCameraConfig.kt
@@ -138,6 +138,9 @@
         }
 
         // Build up a config (using TEMPLATE_PREVIEW by default)
+        // TODO(b/277310425): Turn off CameraGraph.Flags.quirkFinalizeSessionOnCloseBehavior when
+        //  it's not needed. This should be needed only when all use cases are detached (with
+        //  VideoCapture) on devices where Surfaces cannot be released immediately.
         val graph = cameraPipe.create(
             CameraGraph.Config(
                 camera = cameraConfig.cameraId,
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/MeteringRepeating.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/MeteringRepeating.kt
index 00d5f2c4..ddba7d3 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/MeteringRepeating.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/MeteringRepeating.kt
@@ -78,7 +78,7 @@
     override fun onSuggestedStreamSpecUpdated(suggestedStreamSpec: StreamSpec): StreamSpec {
         updateSessionConfig(createPipeline(meteringSurfaceSize).build())
         notifyActive()
-        return StreamSpec.builder(meteringSurfaceSize).build()
+        return suggestedStreamSpec.toBuilder().setResolution(meteringSurfaceSize).build()
     }
 
     override fun onUnbind() {
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraError.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraError.kt
index 60e6949..6de5177 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraError.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraError.kt
@@ -172,4 +172,7 @@
 }
 
 // TODO(b/276918807): When we have CameraProperties, handle the exception on a more granular level.
-class DoNotDisturbException(message: String) : RuntimeException(message)
\ No newline at end of file
+class DoNotDisturbException(message: String) : RuntimeException(message)
+
+// An exception indicating that the CameraDevice.close() call has stalled.
+class CameraCloseStallException(message: String) : RuntimeException(message)
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraGraph.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraGraph.kt
index b1dda57..7e5ce4b 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraGraph.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraGraph.kt
@@ -26,6 +26,7 @@
 import androidx.annotation.RequiresApi
 import androidx.camera.camera2.pipe.CameraGraph.Constants3A.DEFAULT_FRAME_LIMIT
 import androidx.camera.camera2.pipe.CameraGraph.Constants3A.DEFAULT_TIME_LIMIT_NS
+import androidx.camera.camera2.pipe.CameraGraph.Flags.FinalizeSessionOnCloseBehavior.Companion.OFF
 import androidx.camera.camera2.pipe.GraphState.GraphStateStarting
 import androidx.camera.camera2.pipe.GraphState.GraphStateStopped
 import androidx.camera.camera2.pipe.GraphState.GraphStateStopping
@@ -151,7 +152,36 @@
          * - API levels: All
          */
         val quirkWaitForRepeatingRequestOnDisconnect: Boolean? = null,
-    )
+
+        val quirkFinalizeSessionOnCloseBehavior: FinalizeSessionOnCloseBehavior = OFF,
+    ) {
+
+        @JvmInline
+        value class FinalizeSessionOnCloseBehavior private constructor(val value: Int) {
+            companion object {
+                /**
+                 * OFF indicates that the CameraGraph only finalizes capture session under regular
+                 *  conditions, i.e., when the camera device is closed, or when a new capture
+                 *  session is created.
+                 */
+                val OFF = FinalizeSessionOnCloseBehavior(0)
+
+                /**
+                 * IMMEDIATE indicates that the CameraGraph will finalize the current session
+                 *  immediately when the CameraGraph is stopped or closed. This should be the
+                 *  default behavior for devices that allows for immediate Surface reuse.
+                 */
+                val IMMEDIATE = FinalizeSessionOnCloseBehavior(1)
+
+                /**
+                 * TIMEOUT indicates that the CameraGraph will finalize the current session on a 2s
+                 *  timeout when the CameraGraph is stopped or closed. This should only be enabled
+                 *  for devices that require waiting for Surfaces to be released.
+                 */
+                val TIMEOUT = FinalizeSessionOnCloseBehavior(2)
+            }
+        }
+    }
 
     enum class OperatingMode {
         NORMAL,
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CameraController.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CameraController.kt
index e1772d1..35995c4 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CameraController.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CameraController.kt
@@ -101,6 +101,7 @@
             captureSequenceProcessorFactory,
             cameraSurfaceManager,
             timeSource,
+            config.flags.quirkFinalizeSessionOnCloseBehavior,
             scope
         )
         currentSession = session
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2DeviceCloser.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2DeviceCloser.kt
index fb1663d..30f87b1 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2DeviceCloser.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2DeviceCloser.kt
@@ -21,6 +21,7 @@
 import android.hardware.camera2.CameraDevice
 import android.view.Surface
 import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.CameraCloseStallException
 import androidx.camera.camera2.pipe.CameraId
 import androidx.camera.camera2.pipe.core.Debug
 import androidx.camera.camera2.pipe.core.Log
@@ -29,6 +30,8 @@
 import javax.inject.Inject
 import javax.inject.Singleton
 import kotlinx.atomicfu.atomic
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withTimeoutOrNull
 
 internal interface Camera2DeviceCloser {
     fun closeCamera(
@@ -81,7 +84,13 @@
             }
         }
         Log.debug { "Closing $cameraDevice" }
-        cameraDevice.closeWithTrace()
+        runBlocking {
+            withTimeoutOrNull(2000L) {
+                cameraDevice.closeWithTrace()
+            } ?: {
+                throw CameraCloseStallException("The camera close call failed to return in 2000ms")
+            }
+        }
         if (camera2Quirks.shouldWaitForCameraDeviceOnClosed(cameraId)) {
             Log.debug { "Waiting for camera device to be completely closed" }
             if (androidCameraState.awaitCameraDeviceClosed(timeoutMillis = 2000)) {
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionState.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionState.kt
index 9580eef..0852ebf 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionState.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionState.kt
@@ -22,6 +22,7 @@
 import android.view.Surface
 import androidx.annotation.GuardedBy
 import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.CameraGraph.Flags.FinalizeSessionOnCloseBehavior
 import androidx.camera.camera2.pipe.CameraSurfaceManager
 import androidx.camera.camera2.pipe.StreamId
 import androidx.camera.camera2.pipe.core.Debug
@@ -35,6 +36,7 @@
 import java.util.Collections.synchronizedMap
 import kotlinx.atomicfu.atomic
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
 
 internal val captureSessionDebugIds = atomic(0)
@@ -63,6 +65,7 @@
     private val captureSequenceProcessorFactory: Camera2CaptureSequenceProcessorFactory,
     private val cameraSurfaceManager: CameraSurfaceManager,
     private val timeSource: TimeSource,
+    private val finalizeSessionOnCloseBehavior: FinalizeSessionOnCloseBehavior,
     private val scope: CoroutineScope
 ) : CameraCaptureSessionWrapper.StateCallback {
     private val debugId = captureSessionDebugIds.incrementAndGet()
@@ -182,7 +185,7 @@
             Log.debug { "$this Finalizing Session" }
             Debug.traceStart { "$this#onSessionFinalized" }
             disconnect()
-            finalizeSession()
+            finalizeSession(0L)
             Debug.traceStop()
         }
     }
@@ -294,30 +297,52 @@
             Debug.traceStop()
         }
 
-        var shouldFinalizeSession: Boolean
+        var shouldFinalizeSession = false
+        var finalizeSessionDelayMs = 0L
         synchronized(lock) {
             // If the CameraDevice is never opened, the session will never be created. For cleanup
             // reasons, make sure the session is finalized after shutdown if the cameraDevice was
             // never set.
-            shouldFinalizeSession = state != State.CLOSED &&
-                (_cameraDevice == null || !hasAttemptedCaptureSession)
+            if (state != State.CLOSED) {
+                if (_cameraDevice == null || !hasAttemptedCaptureSession) {
+                    shouldFinalizeSession = true
+                } else if (finalizeSessionOnCloseBehavior ==
+                    FinalizeSessionOnCloseBehavior.IMMEDIATE
+                ) {
+                    shouldFinalizeSession = true
+                } else if (finalizeSessionOnCloseBehavior ==
+                    FinalizeSessionOnCloseBehavior.TIMEOUT
+                ) {
+                    shouldFinalizeSession = true
+                    finalizeSessionDelayMs = 2000L
+                }
+            }
             _cameraDevice = null
             state = State.CLOSED
         }
 
         if (shouldFinalizeSession) {
-            finalizeSession()
+            finalizeSession(finalizeSessionDelayMs)
         }
     }
 
-    private fun finalizeSession() {
-        val tokenList =
-            synchronized(lock) {
-                val tokens = _surfaceTokenMap.values.toList()
-                _surfaceTokenMap.clear()
-                tokens
+    private fun finalizeSession(delayMs: Long = 0L) {
+        if (delayMs != 0L) {
+            scope.launch {
+                Log.debug { "Finalizing $this in $delayMs ms" }
+                delay(delayMs)
+                finalizeSession(0L)
             }
-        tokenList.forEach { it.close() }
+        } else {
+            Log.debug { "Finalizing $this" }
+            val tokenList =
+                synchronized(lock) {
+                    val tokens = _surfaceTokenMap.values.toList()
+                    _surfaceTokenMap.clear()
+                    tokens
+                }
+            tokenList.forEach { it.close() }
+        }
     }
 
     private fun finalizeOutputsIfAvailable(retryAllowed: Boolean = true) {
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 475d2fb..3635a7c 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
@@ -128,6 +128,7 @@
                     },
                     CameraSurfaceManager(),
                     SystemTimeSource(),
+                    CameraGraph.Flags.FinalizeSessionOnCloseBehavior.OFF,
                     this
                 )
             )
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/CaptureSessionStateTest.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/CaptureSessionStateTest.kt
index 5298f07..45f4731 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/CaptureSessionStateTest.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/CaptureSessionStateTest.kt
@@ -19,6 +19,7 @@
 import android.graphics.SurfaceTexture
 import android.os.Build
 import android.view.Surface
+import androidx.camera.camera2.pipe.CameraGraph.Flags.FinalizeSessionOnCloseBehavior
 import androidx.camera.camera2.pipe.CameraSurfaceManager
 import androidx.camera.camera2.pipe.CaptureSequenceProcessor
 import androidx.camera.camera2.pipe.Request
@@ -90,6 +91,7 @@
                 captureSequenceProcessorFactory,
                 cameraSurfaceManager,
                 timeSource,
+                FinalizeSessionOnCloseBehavior.OFF,
                 this
             )
         // When disconnect is called first
@@ -112,6 +114,7 @@
                 captureSequenceProcessorFactory,
                 cameraSurfaceManager,
                 timeSource,
+                FinalizeSessionOnCloseBehavior.OFF,
                 this
             )
 
@@ -139,6 +142,7 @@
                 captureSequenceProcessorFactory,
                 cameraSurfaceManager,
                 timeSource,
+                FinalizeSessionOnCloseBehavior.OFF,
                 this
             )
 
@@ -172,6 +176,7 @@
                 captureSequenceProcessorFactory,
                 cameraSurfaceManager,
                 timeSource,
+                FinalizeSessionOnCloseBehavior.OFF,
                 this
             )
         // When surfaces are configured
@@ -195,6 +200,7 @@
                 captureSequenceProcessorFactory,
                 cameraSurfaceManager,
                 timeSource,
+                FinalizeSessionOnCloseBehavior.OFF,
                 this
             )
         // When surfaces are configured
@@ -218,6 +224,7 @@
                 captureSequenceProcessorFactory,
                 cameraSurfaceManager,
                 timeSource,
+                FinalizeSessionOnCloseBehavior.OFF,
                 this
             )
         // When surfaces are configured
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompat.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompat.java
index 286b8a3..9503797 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompat.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompat.java
@@ -349,6 +349,53 @@
     }
 
     /**
+     * Return current dynamic range profile.
+     *
+     * <p>On API level 32 and lower, this value will return what is set by
+     * {@link #setDynamicRangeProfile(long)}, but when the output configuration is used in a
+     * {@link SessionConfigurationCompat} that is used to
+     * {@link androidx.camera.camera2.internal.compat.CameraDeviceCompat#createCaptureSession(
+     * SessionConfigurationCompat) create a capture session}, the value will be ignored and
+     * camera will run the output as {@code STANDARD} dynamic range.
+     */
+    public long getDynamicRangeProfile() {
+        return mImpl.getDynamicRangeProfile();
+    }
+
+    /**
+     * Set a specific device supported dynamic range profile.
+     *
+     * <p>Clients can choose from any profile advertised as supported in
+     * {@link
+     * android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES}
+     * queried using
+     * {@link android.hardware.camera2.params.DynamicRangeProfiles#getSupportedProfiles()}. If this
+     * is not explicitly set, then the default profile will be
+     * {@link android.hardware.camera2.params.DynamicRangeProfiles#STANDARD}.
+     *
+     * <p>Do note that invalid combinations between the registered output surface pixel format and
+     * the configured dynamic range profile will cause capture session initialization failure.
+     * Invalid combinations include any 10-bit dynamic range profile advertised in
+     * {@link android.hardware.camera2.params.DynamicRangeProfiles#getSupportedProfiles()}
+     * combined with an output Surface pixel format
+     * different from {@link android.graphics.ImageFormat#PRIVATE} (the default for Surfaces
+     * initialized by {@link android.view.SurfaceView}, {@link android.view.TextureView},
+     * {@link android.media.MediaRecorder}, {@link android.media.MediaCodec} etc.) or
+     * {@link android.graphics.ImageFormat#YCBCR_P010}.
+     *
+     * <p>On API level 32 and lower, the only supported dynamic range is
+     * {@link android.hardware.camera2.params.DynamicRangeProfiles#STANDARD}. On those API
+     * levels, any other values will be ignored when the output configuring is used in a
+     * {@link SessionConfigurationCompat} that is used to
+     * {@link androidx.camera.camera2.internal.compat.CameraDeviceCompat#createCaptureSession(
+     * SessionConfigurationCompat) create a capture session}, and the
+     * dynamic range used by the camera will remain {@code STANDARD} dynamic range.
+     */
+    public void setDynamicRangeProfile(long profile) {
+        mImpl.setDynamicRangeProfile(profile);
+    }
+
+    /**
      * Set the stream use case associated with this {@link OutputConfigurationCompat}.
      *
      * Stream use case is used to describe the purpose of the stream, whether it's for live
@@ -452,6 +499,10 @@
 
         int getMaxSharedSurfaceCount();
 
+        long getDynamicRangeProfile();
+
+        void setDynamicRangeProfile(long profile);
+
         void setStreamUseCase(long streamUseCase);
 
         long getStreamUseCase();
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi24Impl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi24Impl.java
index 4198f6c..61540cb 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi24Impl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi24Impl.java
@@ -16,6 +16,7 @@
 
 package androidx.camera.camera2.internal.compat.params;
 
+import android.hardware.camera2.params.DynamicRangeProfiles;
 import android.hardware.camera2.params.OutputConfiguration;
 import android.view.Surface;
 
@@ -82,6 +83,16 @@
     }
 
     @Override
+    public long getDynamicRangeProfile() {
+        return ((OutputConfigurationParamsApi24) mObject).mDynamicRangeProfile;
+    }
+
+    @Override
+    public void setDynamicRangeProfile(long profile) {
+        ((OutputConfigurationParamsApi24) mObject).mDynamicRangeProfile = profile;
+    }
+
+    @Override
     @Nullable
     public Surface getSurface() {
         return ((OutputConfiguration) getOutputConfiguration()).getSurface();
@@ -112,6 +123,7 @@
         @Nullable
         String mPhysicalCameraId;
         boolean mIsShared;
+        long mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
 
         OutputConfigurationParamsApi24(@NonNull OutputConfiguration configuration) {
             mOutputConfiguration = configuration;
@@ -127,6 +139,7 @@
 
             return Objects.equals(mOutputConfiguration, otherOutputConfig.mOutputConfiguration)
                     && mIsShared == otherOutputConfig.mIsShared
+                    && mDynamicRangeProfile == otherOutputConfig.mDynamicRangeProfile
                     && Objects.equals(mPhysicalCameraId, otherOutputConfig.mPhysicalCameraId);
 
         }
@@ -141,7 +154,8 @@
             // (h * 31) XOR mPhysicalCameraId.hashCode()
             h = ((h << 5) - h)
                     ^ (mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode());
-
+            // (h * 31) XOR mDynamicRangeProfile
+            h = ((h << 5) - h) ^ Long.hashCode(mDynamicRangeProfile);
             return h;
         }
     }
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi26Impl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi26Impl.java
index f4ccd74..abbdfcd 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi26Impl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi26Impl.java
@@ -17,6 +17,7 @@
 package androidx.camera.camera2.internal.compat.params;
 
 import android.annotation.SuppressLint;
+import android.hardware.camera2.params.DynamicRangeProfiles;
 import android.hardware.camera2.params.OutputConfiguration;
 import android.view.Surface;
 
@@ -118,6 +119,16 @@
         return ((OutputConfigurationParamsApi26) mObject).mPhysicalCameraId;
     }
 
+    @Override
+    public long getDynamicRangeProfile() {
+        return ((OutputConfigurationParamsApi26) mObject).mDynamicRangeProfile;
+    }
+
+    @Override
+    public void setDynamicRangeProfile(long profile) {
+        ((OutputConfigurationParamsApi26) mObject).mDynamicRangeProfile = profile;
+    }
+
     /**
      * Remove a surface from this OutputConfiguration.
      */
@@ -177,6 +188,8 @@
         @Nullable
         String mPhysicalCameraId;
 
+        long mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
+
         OutputConfigurationParamsApi26(@NonNull OutputConfiguration configuration) {
             mOutputConfiguration = configuration;
         }
@@ -190,6 +203,7 @@
             OutputConfigurationParamsApi26 otherOutputConfig = (OutputConfigurationParamsApi26) obj;
 
             return Objects.equals(mOutputConfiguration, otherOutputConfig.mOutputConfiguration)
+                    && mDynamicRangeProfile == otherOutputConfig.mDynamicRangeProfile
                     && Objects.equals(mPhysicalCameraId, otherOutputConfig.mPhysicalCameraId);
 
         }
@@ -203,7 +217,8 @@
             // (h * 31) XOR mPhysicalCameraId.hashCode()
             h = ((h << 5) - h)
                     ^ (mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode());
-
+            // (h * 31) XOR mDynamicRangeProfile
+            h = ((h << 5) - h) ^ Long.hashCode(mDynamicRangeProfile);
             return h;
         }
     }
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi28Impl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi28Impl.java
index 4d0d30b..6adb087 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi28Impl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi28Impl.java
@@ -16,6 +16,7 @@
 
 package androidx.camera.camera2.internal.compat.params;
 
+import android.hardware.camera2.params.DynamicRangeProfiles;
 import android.hardware.camera2.params.OutputConfiguration;
 import android.view.Surface;
 
@@ -24,6 +25,8 @@
 import androidx.annotation.RequiresApi;
 import androidx.core.util.Preconditions;
 
+import java.util.Objects;
+
 /**
  * Implementation of the OutputConfiguration compat methods for API 28 and above.
  */
@@ -31,11 +34,11 @@
 class OutputConfigurationCompatApi28Impl extends OutputConfigurationCompatApi26Impl {
 
     OutputConfigurationCompatApi28Impl(@NonNull Surface surface) {
-        super(new OutputConfiguration(surface));
+        this(new OutputConfigurationParamsApi28(new OutputConfiguration(surface)));
     }
 
     OutputConfigurationCompatApi28Impl(int surfaceGroupId, @NonNull Surface surface) {
-        this(new OutputConfiguration(surfaceGroupId, surface));
+        this(new OutputConfigurationParamsApi28(new OutputConfiguration(surfaceGroupId, surface)));
     }
 
     OutputConfigurationCompatApi28Impl(@NonNull Object outputConfiguration) {
@@ -45,7 +48,8 @@
     @RequiresApi(28)
     static OutputConfigurationCompatApi28Impl wrap(
             @NonNull OutputConfiguration outputConfiguration) {
-        return new OutputConfigurationCompatApi28Impl(outputConfiguration);
+        return new OutputConfigurationCompatApi28Impl(
+                new OutputConfigurationParamsApi28(outputConfiguration));
     }
 
     /**
@@ -79,11 +83,56 @@
         return null;
     }
 
+    @Override
+    public long getDynamicRangeProfile() {
+        return ((OutputConfigurationParamsApi28) mObject).mDynamicRangeProfile;
+    }
+
+    @Override
+    public void setDynamicRangeProfile(long profile) {
+        ((OutputConfigurationParamsApi28) mObject).mDynamicRangeProfile = profile;
+    }
+
     @NonNull
     @Override
     public Object getOutputConfiguration() {
-        Preconditions.checkArgument(mObject instanceof OutputConfiguration);
-        return mObject;
+        Preconditions.checkArgument(mObject instanceof OutputConfigurationParamsApi28);
+        return ((OutputConfigurationParamsApi28) mObject).mOutputConfiguration;
+    }
+
+    private static final class OutputConfigurationParamsApi28 {
+        @NonNull
+        final OutputConfiguration mOutputConfiguration;
+
+        long mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
+
+        OutputConfigurationParamsApi28(@NonNull OutputConfiguration configuration) {
+            mOutputConfiguration = configuration;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof OutputConfigurationParamsApi28)) {
+                return false;
+            }
+
+            OutputConfigurationParamsApi28 otherOutputConfig = (OutputConfigurationParamsApi28) obj;
+
+            return Objects.equals(mOutputConfiguration, otherOutputConfig.mOutputConfiguration)
+                    && mDynamicRangeProfile == otherOutputConfig.mDynamicRangeProfile;
+
+        }
+
+        @Override
+        public int hashCode() {
+            int h = 1;
+            // Strength reduction; in case the compiler has illusions about divisions being faster
+            // (h * 31) XOR mOutputConfiguration.hashCode()
+            h = ((h << 5) - h) ^ mOutputConfiguration.hashCode();
+            // (h * 31) XOR mDynamicRangeProfile
+            h = ((h << 5) - h) ^ Long.hashCode(mDynamicRangeProfile);
+            return h;
+        }
     }
 }
 
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi33Impl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi33Impl.java
index 78e9cab..a2d905b 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi33Impl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi33Impl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2022 The Android Open Source Project
+ * 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.
@@ -21,6 +21,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
+import androidx.core.util.Preconditions;
 
 /**
  * Implementation of the OutputConfiguration compat methods for API 33 and above.
@@ -47,6 +48,23 @@
     }
 
     @Override
+    public long getDynamicRangeProfile() {
+        return ((OutputConfiguration) getOutputConfiguration()).getDynamicRangeProfile();
+    }
+
+    @Override
+    public void setDynamicRangeProfile(long profile) {
+        ((OutputConfiguration) getOutputConfiguration()).setDynamicRangeProfile(profile);
+    }
+
+    @NonNull
+    @Override
+    public Object getOutputConfiguration() {
+        Preconditions.checkArgument(mObject instanceof OutputConfiguration);
+        return mObject;
+    }
+
+    @Override
     public void setStreamUseCase(long streamUseCase) {
         if (streamUseCase == OutputConfigurationCompat.STREAM_USE_CASE_NONE) {
             return;
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatBaseImpl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatBaseImpl.java
index a24552e..ef70b78 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatBaseImpl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatBaseImpl.java
@@ -18,6 +18,7 @@
 
 import android.annotation.SuppressLint;
 import android.graphics.ImageFormat;
+import android.hardware.camera2.params.DynamicRangeProfiles;
 import android.os.Build;
 import android.util.Size;
 import android.view.Surface;
@@ -144,6 +145,16 @@
         return OutputConfigurationParamsApi21.MAX_SURFACES_COUNT;
     }
 
+    @Override
+    public long getDynamicRangeProfile() {
+        return ((OutputConfigurationParamsApi21) mObject).mDynamicRangeProfile;
+    }
+
+    @Override
+    public void setDynamicRangeProfile(long profile) {
+        ((OutputConfigurationParamsApi21) mObject).mDynamicRangeProfile = profile;
+    }
+
     /**
      * Get the {@link Surface} associated with this {@link OutputConfigurationCompat}.
      */
@@ -230,6 +241,7 @@
         @Nullable
         String mPhysicalCameraId;
         boolean mIsShared = false;
+        long mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
 
         OutputConfigurationParamsApi21(@NonNull Surface surface) {
             Preconditions.checkNotNull(surface, "Surface must not be null");
@@ -310,6 +322,7 @@
                     || mConfiguredFormat != otherOutputConfig.mConfiguredFormat
                     || mConfiguredGenerationId != otherOutputConfig.mConfiguredGenerationId
                     || mIsShared != otherOutputConfig.mIsShared
+                    || mDynamicRangeProfile != otherOutputConfig.mDynamicRangeProfile
                     || !Objects.equals(mPhysicalCameraId, otherOutputConfig.mPhysicalCameraId)) {
                 return false;
             }
@@ -337,7 +350,8 @@
             // (h * 31) XOR mPhysicalCameraId.hashCode()
             h = ((h << 5) - h)
                     ^ (mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode());
-
+            // (h * 31) XOR mDynamicRangeProfile
+            h = ((h << 5) - h) ^ Long.hashCode(mDynamicRangeProfile);
             return h;
         }
     }
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatTest.java b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatTest.java
index 4c3dead..7b2ad2a 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatTest.java
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatTest.java
@@ -23,6 +23,7 @@
 import static org.mockito.Mockito.verify;
 
 import android.graphics.SurfaceTexture;
+import android.hardware.camera2.params.DynamicRangeProfiles;
 import android.hardware.camera2.params.OutputConfiguration;
 import android.os.Build;
 import android.util.Size;
@@ -46,6 +47,8 @@
     private static final int TEST_GROUP_ID = 100;
     private static final String PHYSICAL_CAMERA_ID = "1";
 
+    private static final long DYNAMIC_RANGE_PROFILE = DynamicRangeProfiles.HLG10;
+
     private static void assumeSurfaceSharingAvailable(
             OutputConfigurationCompat outputConfigCompat) {
         Assume.assumeTrue("API level does not support surface sharing.",
@@ -235,4 +238,14 @@
 
         verify(outputConfig, times(1)).setPhysicalCameraId(PHYSICAL_CAMERA_ID);
     }
+
+    @Test
+    public void canSetDynamicRangeProfile() {
+        OutputConfigurationCompat outputConfigCompat =
+                new OutputConfigurationCompat(mock(Surface.class));
+
+        outputConfigCompat.setDynamicRangeProfile(DYNAMIC_RANGE_PROFILE);
+
+        assertThat(outputConfigCompat.getDynamicRangeProfile()).isEqualTo(DYNAMIC_RANGE_PROFILE);
+    }
 }
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 1470829..60d5d804 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
@@ -71,6 +71,7 @@
 class DefaultSurfaceProcessorTest {
 
     companion object {
+        private const val JPEG_QUALITY = 100
         private const val WIDTH = 640
         private const val HEIGHT = 480
         private const val CUSTOM_SHADER_FORMAT = """
@@ -143,7 +144,7 @@
         createSurfaceProcessor()
 
         // Act: take a snapshot and then release the processor.
-        val snapshotFuture = surfaceProcessor.snapshot()
+        val snapshotFuture = surfaceProcessor.snapshot(JPEG_QUALITY)
         surfaceProcessor.release()
 
         // Assert: the snapshot future should receive an exception.
@@ -176,7 +177,7 @@
         surfaceProcessor.onOutputSurface(surfaceOutput)
 
         // Act: take a snapshot and draw a Bitmap to the input Surface
-        surfaceProcessor.snapshot()
+        surfaceProcessor.snapshot(JPEG_QUALITY)
         val inputImage = createBitmap(WIDTH, HEIGHT)
         val inputSurface = surfaceRequest.deferrableSurface.surface.get()
         val canvas = inputSurface.lockHardwareCanvas()
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
index dfc5a4f..27c35c0 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
@@ -390,6 +390,8 @@
             mMetadataMatchingCaptureCallback = new CameraCaptureCallback() {
             };
         } else if (isSessionProcessorEnabledInCurrentCamera()) {
+            // TODO: remove this section and the rest of the code where it needs the
+            //  isSessionProcessorEnabledInCurrentCamera check.
             ImageReaderProxy imageReader;
             // SessionProcessor only outputs JPEG format.
             if (getImageFormat() == ImageFormat.JPEG) {
@@ -1699,10 +1701,6 @@
             // Use old pipeline for custom ImageReader.
             return false;
         }
-        if (isSessionProcessorEnabledInCurrentCamera()) {
-            // Use old pipeline when extension is enabled.
-            return false;
-        }
 
         if (config.getBufferFormat(ImageFormat.JPEG) != ImageFormat.JPEG) {
             // Use old pipeline for non-JPEG output format.
@@ -1726,8 +1724,9 @@
         Size resolution = streamSpec.getResolution();
 
         checkState(mImagePipeline == null);
-        mImagePipeline = new ImagePipeline(config, resolution, getEffect(),
-                !requireNonNull(getCamera()).getHasTransform());
+        boolean isVirtualCamera = !requireNonNull(getCamera()).getHasTransform()
+                || isSessionProcessorEnabledInCurrentCamera();
+        mImagePipeline = new ImagePipeline(config, resolution, getEffect(), isVirtualCamera);
 
         if (mTakePictureManager == null) {
             // mTakePictureManager is reused when the Surface is reset.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/StreamSpec.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/StreamSpec.java
index 17c29ae..f381cfc 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/StreamSpec.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/StreamSpec.java
@@ -16,10 +16,12 @@
 
 package androidx.camera.core.impl;
 
+import android.hardware.camera2.CameraMetadata;
 import android.util.Range;
 import android.util.Size;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.camera.core.DynamicRange;
 
@@ -60,6 +62,14 @@
     @NonNull
     public abstract Range<Integer> getExpectedFrameRateRange();
 
+    /**
+     * Returns the implementation options associated with this stream
+     * specification.
+     * @return the implementation options for the stream.
+     */
+    @Nullable
+    public abstract Config getImplementationOptions();
+
     /** Returns a build for a stream configuration that takes a required resolution. */
     @NonNull
     public static Builder builder(@NonNull Size resolution) {
@@ -101,6 +111,15 @@
         @NonNull
         public abstract Builder setExpectedFrameRateRange(@NonNull Range<Integer> range);
 
+        /**
+         * Sets the implementation options.
+         *
+         * <p>If not set, the default expected frame rate range is
+         * {@link CameraMetadata#SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT}.
+         */
+        @NonNull
+        public abstract Builder setImplementationOptions(@NonNull Config config);
+
         /** Builds the stream specification */
         @NonNull
         public abstract StreamSpec build();
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/processing/DefaultSurfaceProcessor.java b/camera/camera-core/src/main/java/androidx/camera/core/processing/DefaultSurfaceProcessor.java
index 0a5b262..bfce459 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/processing/DefaultSurfaceProcessor.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/processing/DefaultSurfaceProcessor.java
@@ -20,15 +20,19 @@
 import static androidx.camera.core.impl.ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE;
 import static androidx.core.util.Preconditions.checkState;
 
+import static java.util.Objects.requireNonNull;
+
 import android.graphics.Bitmap;
 import android.graphics.ImageFormat;
 import android.graphics.SurfaceTexture;
 import android.opengl.Matrix;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.util.Pair;
 import android.util.Size;
 import android.view.Surface;
 
+import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
@@ -86,7 +90,7 @@
     // Only access this on GL thread.
     private boolean mIsReleased = false;
     // Only access this on GL thread.
-    private final List<CallbackToFutureAdapter.Completer<Void>> mPendingSnapshots =
+    private final List<Pair<CallbackToFutureAdapter.Completer<Void>, Integer>> mPendingSnapshots =
             new ArrayList<>();
 
     /** Constructs {@link DefaultSurfaceProcessor} with default shaders. */
@@ -178,13 +182,15 @@
 
     @NonNull
     @Override
-    public ListenableFuture<Void> snapshot() {
+    public ListenableFuture<Void> snapshot(@IntRange(from = 0, to = 100) int jpegQuality) {
         return Futures.nonCancellationPropagating(CallbackToFutureAdapter.getFuture(
                 completer -> {
-                    executeSafely(() -> mPendingSnapshots.add(completer),
-                            () -> completer.setException(
-                                    new Exception(
-                                            "Failed to snapshot: OpenGLRenderer not ready.")));
+                    Pair<CallbackToFutureAdapter.Completer<Void>, Integer> pendingSnapshot =
+                            new Pair<>(completer, jpegQuality);
+                    executeSafely(
+                            () -> mPendingSnapshots.add(pendingSnapshot),
+                            () -> completer.setException(new Exception(
+                                    "Failed to snapshot: OpenGLRenderer not ready.")));
                     return "DefaultSurfaceProcessor#snapshot";
                 }));
     }
@@ -221,7 +227,12 @@
         }
 
         // Execute all pending snapshots.
-        takeSnapshotAndDrawJpeg(jpegOutput);
+        try {
+            takeSnapshotAndDrawJpeg(jpegOutput);
+        } catch (RuntimeException e) {
+            // Propagates error back to the app if failed to take snapshot.
+            failAllPendingSnapshots(e);
+        }
     }
 
     /**
@@ -237,26 +248,42 @@
 
         // No JPEG Surface, fail all snapshot requests.
         if (jpegOutput == null) {
-            for (CallbackToFutureAdapter.Completer<Void> completer : mPendingSnapshots) {
-                completer.setException(
-                        new Exception("Failed to snapshot: no JPEG Surface."));
-            }
-            mPendingSnapshots.clear();
+            failAllPendingSnapshots(new Exception("Failed to snapshot: no JPEG Surface."));
             return;
         }
 
-        // Get JPEG bytes.
-        byte[] jpegBytes = getJpegByteArray(jpegOutput.getSecond(), jpegOutput.getThird());
+        // Get snapshot Bitmap.
+        Bitmap bitmap = getBitmap(jpegOutput.getSecond(), jpegOutput.getThird());
+
         // Write to JPEG surface, once for each snapshot request.
-        for (CallbackToFutureAdapter.Completer<Void> completer : mPendingSnapshots) {
-            writeJpegBytesToSurface(jpegOutput.getFirst(), jpegBytes);
-            completer.set(null);
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        byte[] jpegBytes = null;
+        int jpegQuality = -1;
+        for (Pair<CallbackToFutureAdapter.Completer<Void>, Integer> pendingSnapshot :
+                mPendingSnapshots) {
+            if (jpegQuality != pendingSnapshot.second) {
+                // If the quality is different, re-encode the bitmap.
+                outputStream.reset();
+                bitmap.compress(Bitmap.CompressFormat.JPEG, pendingSnapshot.second, outputStream);
+                jpegBytes = outputStream.toByteArray();
+                jpegQuality = pendingSnapshot.second;
+            }
+            writeJpegBytesToSurface(jpegOutput.getFirst(), requireNonNull(jpegBytes));
+            pendingSnapshot.first.set(null);
+        }
+        mPendingSnapshots.clear();
+    }
+
+    private void failAllPendingSnapshots(@NonNull Throwable throwable) {
+        for (Pair<CallbackToFutureAdapter.Completer<Void>, Integer> pendingSnapshot :
+                mPendingSnapshots) {
+            pendingSnapshot.first.setException(throwable);
         }
         mPendingSnapshots.clear();
     }
 
     @NonNull
-    private byte[] getJpegByteArray(@NonNull Size size, @NonNull float[] textureTransform) {
+    private Bitmap getBitmap(@NonNull Size size, @NonNull float[] textureTransform) {
         // Flip the snapshot. This is for reverting the GL transform added in SurfaceOutputImpl.
         float[] snapshotTransform = new float[16];
         // TODO(b/278109696): move GL flipping to MatrixExt.
@@ -265,11 +292,8 @@
         Matrix.scaleM(snapshotTransform, 0, 1f, -1f, 1f);
         Matrix.multiplyMM(snapshotTransform, 0, snapshotTransform, 0, textureTransform, 0);
         // Take a snapshot Bitmap and compress it to JPEG.
-        Bitmap bitmap = mGlRenderer.snapshot(size, snapshotTransform);
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        // TODO: Use the JPEG quality from SessionConfig.
-        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
-        return outputStream.toByteArray();
+        return mGlRenderer.snapshot(size, snapshotTransform);
+
     }
 
     @WorkerThread
@@ -279,8 +303,9 @@
             for (SurfaceOutput surfaceOutput : mOutputSurfaces.keySet()) {
                 surfaceOutput.close();
             }
-            for (CallbackToFutureAdapter.Completer<Void> completer : mPendingSnapshots) {
-                completer.setException(
+            for (Pair<CallbackToFutureAdapter.Completer<Void>, Integer> pendingSnapshot :
+                    mPendingSnapshots) {
+                pendingSnapshot.first.setException(
                         new Exception("Failed to snapshot: DefaultSurfaceProcessor is released."));
             }
             mOutputSurfaces.clear();
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceProcessorInternal.java b/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceProcessorInternal.java
index 6260709..0dd1f6da 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceProcessorInternal.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceProcessorInternal.java
@@ -18,6 +18,7 @@
 
 import android.os.Build;
 
+import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.camera.core.SurfaceProcessor;
@@ -51,7 +52,7 @@
      * Takes a snapshot of the next available frame and write it to JPEG outputs.
      */
     @NonNull
-    default ListenableFuture<Void> snapshot() {
+    default ListenableFuture<Void> snapshot(@IntRange(from = 0, to = 100) int jpegQuality) {
         return Futures.immediateFuture(null);
     }
 }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceProcessorWithExecutor.java b/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceProcessorWithExecutor.java
index 3873031..853f16c 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceProcessorWithExecutor.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceProcessorWithExecutor.java
@@ -16,6 +16,7 @@
 
 package androidx.camera.core.processing;
 
+import static androidx.camera.core.impl.utils.futures.Futures.immediateFailedFuture;
 import static androidx.core.util.Preconditions.checkState;
 
 import android.os.Build;
@@ -29,6 +30,8 @@
 import androidx.camera.core.SurfaceProcessor;
 import androidx.camera.core.SurfaceRequest;
 
+import com.google.common.util.concurrent.ListenableFuture;
+
 import java.util.concurrent.Executor;
 
 /**
@@ -91,6 +94,13 @@
         });
     }
 
+    @NonNull
+    @Override
+    public ListenableFuture<Void> snapshot(int jpegQuality) {
+        return immediateFailedFuture(
+                new Exception("Snapshot not supported by external SurfaceProcessor"));
+    }
+
     @Override
     public void release() {
         // No-op. External SurfaceProcessor should not be released by CameraX.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/StreamSharing.java b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/StreamSharing.java
index 67ab0e2..4ba6851 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/StreamSharing.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/StreamSharing.java
@@ -102,10 +102,10 @@
             @NonNull UseCaseConfigFactory useCaseConfigFactory) {
         super(DEFAULT_CONFIG);
         mVirtualCamera = new VirtualCamera(parentCamera, children, useCaseConfigFactory,
-                () -> {
+                jpegQuality -> {
                     SurfaceProcessorNode sharingNode = mSharingNode;
                     if (sharingNode != null) {
-                        return sharingNode.getSurfaceProcessor().snapshot();
+                        return sharingNode.getSurfaceProcessor().snapshot(jpegQuality);
                     } else {
                         return Futures.immediateFailedFuture(new Exception(
                                 "Failed to take picture: pipeline is not ready."));
@@ -312,7 +312,7 @@
          * Takes a snapshot of the current stream and write it to the children with JPEG Surface.
          */
         @NonNull
-        ListenableFuture<Void> jpegSnapshot();
+        ListenableFuture<Void> jpegSnapshot(int jpegQuality);
     }
 
     @VisibleForTesting
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCameraControl.java b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCameraControl.java
index 887e1e5..1ca8ace 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCameraControl.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCameraControl.java
@@ -18,6 +18,7 @@
 import static androidx.core.util.Preconditions.checkArgument;
 
 import static java.util.Collections.singletonList;
+import static java.util.Objects.requireNonNull;
 
 import android.graphics.Rect;
 import android.os.Build;
@@ -43,6 +44,8 @@
 @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
 public class VirtualCameraControl implements CameraControlInternal {
 
+    private static final int DEFAULT_JPEG_QUALITY = 100;
+
     private final CameraControlInternal mParent;
     private final StreamSharing.Control mStreamSharingControl;
 
@@ -121,7 +124,13 @@
             @ImageCapture.CaptureMode int captureMode,
             @ImageCapture.FlashType int flashType) {
         checkArgument(captureConfigs.size() == 1, "Only support one capture config.");
-        return Futures.allAsList(singletonList(mStreamSharingControl.jpegSnapshot()));
+        int jpegQuality = getJpegQuality(captureConfigs.get(0));
+        return Futures.allAsList(singletonList(mStreamSharingControl.jpegSnapshot(jpegQuality)));
+    }
+
+    private int getJpegQuality(@NonNull CaptureConfig captureConfig) {
+        return requireNonNull(captureConfig.getImplementationOptions().retrieveOption(
+                CaptureConfig.OPTION_JPEG_QUALITY, DEFAULT_JPEG_QUALITY));
     }
 
     @NonNull
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt
index a7143fb..5581da2 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt
@@ -328,14 +328,14 @@
 
     @Config(minSdk = 28)
     @Test
-    fun extensionIsOn_pipelineDisabled() {
-        assertThat(
-            bindImageCapture(
-                useProcessingPipeline = true,
-                bufferFormat = ImageFormat.JPEG,
-                sessionProcessor = FakeSessionProcessor(null, null)
-            ).isProcessingPipelineEnabled
-        ).isFalse()
+    fun extensionIsOn_pipelineEnabled() {
+        val imageCapture = bindImageCapture(
+            useProcessingPipeline = true,
+            bufferFormat = ImageFormat.JPEG,
+            sessionProcessor = FakeSessionProcessor(null, null)
+        )
+        assertThat(imageCapture.isProcessingPipelineEnabled).isTrue()
+        assertThat(imageCapture.imagePipeline!!.expectsMetadata()).isFalse()
     }
 
     @Test
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/impl/StreamSpecTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/impl/StreamSpecTest.kt
index fee7f3e..d8674dc 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/impl/StreamSpecTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/impl/StreamSpecTest.kt
@@ -20,6 +20,9 @@
 import android.util.Range
 import android.util.Size
 import androidx.camera.core.DynamicRange
+import androidx.camera.core.impl.ImageInputConfig.OPTION_INPUT_FORMAT
+import androidx.camera.core.impl.UseCaseConfigFactory.CaptureType
+import androidx.camera.testing.fakes.FakeUseCaseConfig
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -70,8 +73,30 @@
         assertThat(streamSpec.expectedFrameRateRange).isEqualTo(TEST_EXPECTED_FRAME_RATE_RANGE)
     }
 
+    @Test
+    fun defaultImplementationOptionsIsNull() {
+        val streamSpec = StreamSpec.builder(TEST_RESOLUTION).build()
+
+        assertThat(streamSpec.implementationOptions)
+            .isNull()
+    }
+
+    @Test
+    fun canRetrieveStreamUseCase() {
+        val streamSpec = StreamSpec.builder(TEST_RESOLUTION)
+            .setImplementationOptions(TEST_IMPLEMENTATION_OPTION)
+            .build()
+
+        assertThat(streamSpec.implementationOptions!!.containsOption(OPTION_INPUT_FORMAT)).isTrue()
+        assertThat(streamSpec.implementationOptions!!.retrieveOption(OPTION_INPUT_FORMAT))
+            .isEqualTo(TEST_INPUT_FORMAT)
+    }
+
     companion object {
         private val TEST_RESOLUTION = Size(640, 480)
         private val TEST_EXPECTED_FRAME_RATE_RANGE = Range(30, 30)
+        private const val TEST_INPUT_FORMAT = 1
+        private val TEST_IMPLEMENTATION_OPTION =
+            FakeUseCaseConfig.Builder(CaptureType.PREVIEW, TEST_INPUT_FORMAT).useCaseConfig.config
     }
 }
\ No newline at end of file
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/StreamSharingTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/StreamSharingTest.kt
index 9f8be2f..571a6b7 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/StreamSharingTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/StreamSharingTest.kt
@@ -24,6 +24,7 @@
 import androidx.camera.core.CameraEffect.PREVIEW
 import androidx.camera.core.CameraEffect.VIDEO_CAPTURE
 import androidx.camera.core.ImageCapture
+import androidx.camera.core.ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY
 import androidx.camera.core.ImageProxy
 import androidx.camera.core.impl.CameraCaptureCallback
 import androidx.camera.core.impl.CameraCaptureResult
@@ -99,9 +100,10 @@
     }
 
     @Test
-    fun childTakingPicture_triggersSnapshot() {
-        // Arrange: set up StreamSharing with ImageCapture as child
-        val imageCapture = ImageCapture.Builder().build()
+    fun childTakingPicture_getJpegQuality() {
+        // Arrange: set up StreamSharing with min latency ImageCapture as child
+        val imageCapture =
+            ImageCapture.Builder().setCaptureMode(CAPTURE_MODE_MINIMIZE_LATENCY).build()
         streamSharing = StreamSharing(camera, setOf(child1, imageCapture), useCaseConfigFactory)
         streamSharing.bindToCamera(camera, null, defaultConfig)
         streamSharing.onSuggestedStreamSpecUpdated(StreamSpec.builder(size).build())
@@ -112,8 +114,8 @@
         })
         shadowOf(getMainLooper()).idle()
 
-        // Assert: the snapshot is triggered.
-        assertThat(sharingProcessor.isSnapshotTriggered).isTrue()
+        // Assert: the jpeg quality of min latency capture is 95.
+        assertThat(sharingProcessor.jpegQuality).isEqualTo(95)
     }
 
     @Test
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessorTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessorTest.kt
index 46e04fa..78fa363 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessorTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessorTest.kt
@@ -265,7 +265,7 @@
             analysisSemaphore
         )
 
-        fakeLifecycleOwner.pauseAndStop()
+        withContext(Dispatchers.Main) { fakeLifecycleOwner.pauseAndStop() }
 
         delay(1000)
         previewSemaphore.drainPermits()
@@ -308,24 +308,28 @@
             })
         }
 
-        fakeLifecycleOwner.pauseAndStop()
+        withContext(Dispatchers.Main) { fakeLifecycleOwner.pauseAndStop() }
         assertThat(cameraClosedLatch.await(1, TimeUnit.SECONDS)).isTrue()
 
-        fakeCaptureExtenderImpl.assertInvokeOrder(listOf(
-            "onInit",
-            "onPresetSession",
-            "onEnableSession",
-            "onDisableSession",
-            "onDeInit",
-        ))
+        fakeCaptureExtenderImpl.assertInvokeOrder(
+            listOf(
+                "onInit",
+                "onPresetSession",
+                "onEnableSession",
+                "onDisableSession",
+                "onDeInit",
+            )
+        )
 
-        fakePreviewExtenderImpl.assertInvokeOrder(listOf(
-            "onInit",
-            "onPresetSession",
-            "onEnableSession",
-            "onDisableSession",
-            "onDeInit",
-        ))
+        fakePreviewExtenderImpl.assertInvokeOrder(
+            listOf(
+                "onInit",
+                "onPresetSession",
+                "onEnableSession",
+                "onDisableSession",
+                "onDeInit",
+            )
+        )
     }
 
     class ResultMonitor {
@@ -342,6 +346,7 @@
                 }
             }
         }
+
         fun assertCaptureKey(key: CaptureRequest.Key<*>, value: Any) {
             keyToCheck = key
             valueToCheck = value
@@ -370,9 +375,11 @@
         val previewSemaphore = Semaphore(0)
         val analysisSemaphore = Semaphore(0)
         fakePreviewExtenderImpl.captureStage = createCaptureStage(
-            parameters = listOf(Pair(
-                CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF
-            ))
+            parameters = listOf(
+                Pair(
+                    CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF
+                )
+            )
         )
 
         verifyUseCasesOutput(
@@ -420,8 +427,11 @@
         // Trigger RequestUpdateProcessor to update repeating request to have new parameters.
         fakePreviewExtenderImpl.fakeRequestUpdateProcessor?.captureStage =
             createCaptureStage(
-                parameters = listOf(Pair(CaptureRequest.CONTROL_AE_MODE,
-                    CaptureRequest.CONTROL_AE_MODE_OFF)
+                parameters = listOf(
+                    Pair(
+                        CaptureRequest.CONTROL_AE_MODE,
+                        CaptureRequest.CONTROL_AE_MODE_OFF
+                    )
                 )
             )
 
@@ -724,6 +734,7 @@
         fun assertInvokeOrder(expectList: List<String>) {
             assertThat(expectList).containsExactlyElementsIn(invokeList).inOrder()
         }
+
         override fun onInit(
             cameraId: String,
             cameraCharacteristics: CameraCharacteristics,
@@ -735,14 +746,17 @@
         override fun onDeInit() {
             recordInvoking("onDeInit")
         }
+
         override fun onPresetSession(): CaptureStageImpl? {
             recordInvoking("onPresetSession")
             return null
         }
+
         override fun onEnableSession(): CaptureStageImpl? {
             recordInvoking("onEnableSession")
             return onEnableSessionCaptureStage
         }
+
         override fun onDisableSession(): CaptureStageImpl? {
             recordInvoking("onDisableSession")
             return onDisableSessionCaptureStage
@@ -762,17 +776,21 @@
             when (processorType) {
                 PROCESSOR_TYPE_REQUEST_UPDATE_ONLY ->
                     fakeRequestUpdateProcessor = FakeRequestUpdateProcessor()
+
                 PROCESSOR_TYPE_IMAGE_PROCESSOR ->
                     fakePreviewImageProcessorImpl = FakePreviewImageProcessorImpl()
+
                 PROCESSOR_TYPE_NONE -> {}
             }
         }
+
         override fun isExtensionAvailable(
             cameraId: String,
             cameraCharacteristics: CameraCharacteristics
         ): Boolean {
             return true
         }
+
         override fun init(cameraId: String, cameraCharacteristics: CameraCharacteristics) {
             recordInvoking("init")
         }
@@ -795,6 +813,7 @@
         fun setCaptureStage(captureStage: CaptureStageImpl) {
             _captureStage = captureStage
         }
+
         override fun getProcessorType() = processorType
         override fun getProcessor() =
             when (processorType) {
@@ -832,6 +851,7 @@
         override fun init(cameraId: String, cameraCharacteristics: CameraCharacteristics) {
             recordInvoking("init")
         }
+
         override fun getCaptureProcessor() = fakeCaptureProcessorImpl
 
         override fun getCaptureStages() = _captureStages
@@ -959,6 +979,7 @@
                 deferredSubmit = CompletableDeferred<List<RequestProcessor.Request>>()
             }
         }
+
         override fun submit(
             request: RequestProcessor.Request,
             callback: RequestProcessor.Callback
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/IgnoreAudioProblematicDeviceRule.kt b/camera/camera-testing/src/main/java/androidx/camera/testing/IgnoreAudioProblematicDeviceRule.kt
new file mode 100644
index 0000000..1d1713e
--- /dev/null
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/IgnoreAudioProblematicDeviceRule.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.camera.testing
+
+import androidx.annotation.RequiresApi
+import androidx.camera.testing.IgnoreProblematicDeviceRule.Companion.isPixel2Api26Emulator
+import org.junit.AssumptionViolatedException
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+
+/**
+ * Test class to set the TestRule that should not be run on the audio problematically devices.
+ */
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+class IgnoreAudioProblematicDeviceRule : TestRule {
+    private val isProblematicDevices = isPixel2Api26Emulator
+
+    override fun apply(base: Statement, description: Description): Statement {
+        return object : Statement() {
+            override fun evaluate() {
+                if (isProblematicDevices) {
+                    throw AssumptionViolatedException(
+                        "AudioRecord of the emulator may not be well prepared for related" +
+                            " tests. Ignore the test: " + description.displayName +
+                            ". To test on emulator devices, please remove the" +
+                            " IgnoreAudioProblematicallyDeviceRule from the test class."
+                    )
+                } else {
+                    base.evaluate()
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/IgnoreProblematicDeviceRule.kt b/camera/camera-testing/src/main/java/androidx/camera/testing/IgnoreProblematicDeviceRule.kt
index 73fee52..99214e5 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/IgnoreProblematicDeviceRule.kt
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/IgnoreProblematicDeviceRule.kt
@@ -30,23 +30,9 @@
  */
 @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
 class IgnoreProblematicDeviceRule : TestRule {
-    private var avdName: String = try {
-        val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
-        device.executeShellCommand("getprop ro.kernel.qemu.avd_name").filterNot {
-            it == '_' || it == '-' || it == ' '
-        }
-    } catch (e: Exception) {
-        Log.d("ProblematicDeviceRule", "Cannot get avd name", e)
-        ""
-    }
-
-    private val pixel2Api26Emulator = isEmulator && avdName.contains(
-        "Pixel2", ignoreCase = true
-    ) && Build.VERSION.SDK_INT == Build.VERSION_CODES.O
-
     private val api21Emulator = isEmulator && Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP
 
-    private val isProblematicDevices = pixel2Api26Emulator || api21Emulator
+    private val isProblematicDevices = isPixel2Api26Emulator || api21Emulator
 
     override fun apply(base: Statement, description: Description): Statement {
         return object : Statement() {
@@ -75,7 +61,19 @@
             EMULATOR_HARDWARE_RANCHU,
             EMULATOR_HARDWARE_GCE
         )
+        private var avdName: String = try {
+            val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+            device.executeShellCommand("getprop ro.kernel.qemu.avd_name").filterNot {
+                it == '_' || it == '-' || it == ' '
+            }
+        } catch (e: Exception) {
+            Log.d("ProblematicDeviceRule", "Cannot get avd name", e)
+            ""
+        }
 
         val isEmulator = emulatorHardwareNames.contains(Build.HARDWARE.lowercase())
+        val isPixel2Api26Emulator = isEmulator && avdName.contains(
+            "Pixel2", ignoreCase = true
+        ) && Build.VERSION.SDK_INT == Build.VERSION_CODES.O
     }
 }
\ No newline at end of file
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeSurfaceProcessorInternal.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeSurfaceProcessorInternal.java
index 269b142a..94bd4cc 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeSurfaceProcessorInternal.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeSurfaceProcessorInternal.java
@@ -18,6 +18,7 @@
 
 import android.os.Build;
 
+import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.camera.core.impl.utils.futures.Futures;
@@ -35,7 +36,7 @@
         SurfaceProcessorInternal {
 
     private boolean mIsReleased;
-    private boolean mIsSnapshotTriggered = false;
+    private int mJpegQuality = 0;
 
     /**
      * {@inheritDoc}
@@ -64,12 +65,13 @@
 
     @Override
     @NonNull
-    public ListenableFuture<Void> snapshot() {
-        mIsSnapshotTriggered = true;
+    public ListenableFuture<Void> snapshot(int jpegQuality) {
+        mJpegQuality = jpegQuality;
         return Futures.immediateFuture(null);
     }
 
-    public boolean isSnapshotTriggered() {
-        return mIsSnapshotTriggered;
+    @IntRange(from = 0, to = 100)
+    public int getJpegQuality() {
+        return mJpegQuality;
     }
 }
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioSettingsAudioProfileResolverTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioSettingsAudioProfileResolverTest.kt
index 39cbed2..4424a86 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioSettingsAudioProfileResolverTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioSettingsAudioProfileResolverTest.kt
@@ -30,6 +30,7 @@
 import androidx.camera.testing.CameraPipeConfigTestRule
 import androidx.camera.testing.CameraUtil
 import androidx.camera.testing.CameraXUtil
+import androidx.camera.testing.IgnoreAudioProblematicDeviceRule
 import androidx.camera.video.AudioSpec
 import androidx.camera.video.Quality
 import androidx.camera.video.Recorder
@@ -64,6 +65,10 @@
     private val cameraConfig: CameraXConfig
 ) {
 
+    // Ignore problematic device for b/277176784
+    @get:Rule
+    val ignoreProblematicDeviceRule = IgnoreAudioProblematicDeviceRule()
+
     companion object {
         @JvmStatic
         @Parameterized.Parameters(name = "{0}")
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/encoder/AudioEncoderTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/encoder/AudioEncoderTest.kt
index bf7c596..9f85c6c 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/encoder/AudioEncoderTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/encoder/AudioEncoderTest.kt
@@ -16,6 +16,7 @@
 package androidx.camera.video.internal.encoder
 
 import android.media.MediaCodecInfo
+import android.os.Build
 import androidx.camera.core.impl.Observable.Observer
 import androidx.camera.core.impl.Timebase
 import androidx.camera.core.impl.utils.executor.CameraXExecutors
@@ -40,6 +41,7 @@
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
 import org.junit.After
+import org.junit.Assume.assumeFalse
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -128,6 +130,12 @@
 
     @Test
     fun canRestartEncoder() {
+        // Skip for b/269129619
+        assumeFalse(
+            "Skip test for Cuttlefish API 30 flaky native crash",
+            Build.MODEL.contains("Cuttlefish") && Build.VERSION.SDK_INT == 30
+        )
+
         // Arrange.
         fakeAudioLoop.start()
 
diff --git a/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageAnalysisBaseTest.kt b/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageAnalysisBaseTest.kt
index b4a58eb..0add8e7 100644
--- a/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageAnalysisBaseTest.kt
+++ b/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageAnalysisBaseTest.kt
@@ -33,6 +33,9 @@
 import androidx.testutils.withActivity
 import com.google.common.truth.Truth.assertWithMessage
 import java.util.concurrent.TimeUnit
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withContext
 import org.junit.Assume
 import org.junit.BeforeClass
 import org.junit.Rule
@@ -87,10 +90,12 @@
         CoreAppTestUtil.prepareDeviceUI(InstrumentationRegistry.getInstrumentation())
     }
 
-    protected fun tearDown() {
-        val context = ApplicationProvider.getApplicationContext<Context>()
-        val cameraProvider = ProcessCameraProvider.getInstance(context)[10, TimeUnit.SECONDS]
-        cameraProvider.shutdown()[10, TimeUnit.SECONDS]
+    protected fun tearDown(): Unit = runBlocking {
+        withContext(Dispatchers.Main) {
+            val context = ApplicationProvider.getApplicationContext<Context>()
+            val cameraProvider = ProcessCameraProvider.getInstance(context)[10, TimeUnit.SECONDS]
+            cameraProvider.shutdown()[10, TimeUnit.SECONDS]
+        }
         mDevice.unfreezeRotation()
     }
 
diff --git a/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureBaseTest.kt b/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureBaseTest.kt
index 29ae33f..741b76f 100644
--- a/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureBaseTest.kt
+++ b/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureBaseTest.kt
@@ -38,6 +38,9 @@
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
 import java.util.concurrent.TimeUnit
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withContext
 import org.junit.Assume.assumeFalse
 import org.junit.Assume.assumeTrue
 import org.junit.BeforeClass
@@ -109,10 +112,12 @@
         assumeTrue("Failed to create pictures directory", createPicturesFolder())
     }
 
-    protected fun tearDown() {
-        val context = ApplicationProvider.getApplicationContext<Context>()
-        val cameraProvider = ProcessCameraProvider.getInstance(context)[10, TimeUnit.SECONDS]
-        cameraProvider.shutdown()[10, TimeUnit.SECONDS]
+    protected fun tearDown(): Unit = runBlocking {
+        withContext(Dispatchers.Main) {
+            val context = ApplicationProvider.getApplicationContext<Context>()
+            val cameraProvider = ProcessCameraProvider.getInstance(context)[10, TimeUnit.SECONDS]
+            cameraProvider.shutdown()[10, TimeUnit.SECONDS]
+        }
         mDevice.unfreezeRotation()
     }
 
diff --git a/car/app/app-samples/navigation/mobile/src/main/AndroidManifestWithSdkVersion.xml b/car/app/app-samples/navigation/mobile/src/main/AndroidManifestWithSdkVersion.xml
index d88bd0d..e2ec81f 100644
--- a/car/app/app-samples/navigation/mobile/src/main/AndroidManifestWithSdkVersion.xml
+++ b/car/app/app-samples/navigation/mobile/src/main/AndroidManifestWithSdkVersion.xml
@@ -37,31 +37,18 @@
     <uses-permission android:name="androidx.car.app.ACCESS_SURFACE"/>
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
 
-    <!-- Various required feature settings for an automotive app. -->
-    <uses-feature
-        android:name="android.hardware.type.automotive"
-        android:required="true" />
-    <uses-feature
-        android:name="android.software.car.templates_host"
-        android:required="true" />
-    <uses-feature
-        android:name="android.hardware.wifi"
-        android:required="false" />
-    <uses-feature
-        android:name="android.hardware.screen.portrait"
-        android:required="false" />
-    <uses-feature
-        android:name="android.hardware.screen.landscape"
-        android:required="false" />
+    <!-- For Microphone Recording -->
+    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
+    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
 
     <application
         android:icon="@drawable/ic_launcher"
         android:label="@string/app_name">
 
-         <meta-data
-             android:name="com.android.automotive"
-             android:resource="@xml/automotive_app_desc"
-             tools:ignore="MetadataTagInsideApplicationTag" />
+        <meta-data
+            android:name="com.google.android.gms.car.application"
+            android:resource="@xml/automotive_app_desc"
+            tools:ignore="MetadataTagInsideApplicationTag" />
 
         <meta-data android:name="androidx.car.app.minCarApiLevel"
             android:value="1"
@@ -77,31 +64,16 @@
                 <category android:name="androidx.car.app.category.NAVIGATION"/>
                 <category android:name="androidx.car.app.category.FEATURE_CLUSTER"/>
             </intent-filter>
+            <intent-filter>
+                <action android:name="androidx.car.app.action.NAVIGATE" />
+                <category android:name="android.intent.category.DEFAULT"/>
+                <data android:scheme="geo" />
+            </intent-filter>
         </service>
         <service
             android:name="androidx.car.app.sample.navigation.common.nav.NavigationService"
             android:enabled="true"
             android:exported="true">
         </service>
-
-        <activity
-            android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
-            android:name="androidx.car.app.activity.CarAppActivity"
-            android:exported="true"
-            android:launchMode="singleTask"
-            android:label="Navigation">
-
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-            <intent-filter>
-                <action android:name="androidx.car.app.action.NAVIGATE" />
-                <category android:name="android.intent.category.DEFAULT"/>
-                <data android:scheme="geo" />
-            </intent-filter>
-            <meta-data android:name="distractionOptimized" android:value="true"/>
-        </activity>
-
     </application>
 </manifest>
diff --git a/car/app/app-samples/showcase/automotive/src/main/AndroidManifestWithSdkVersion.xml b/car/app/app-samples/showcase/automotive/src/main/AndroidManifestWithSdkVersion.xml
index e614136..3d44975 100644
--- a/car/app/app-samples/showcase/automotive/src/main/AndroidManifestWithSdkVersion.xml
+++ b/car/app/app-samples/showcase/automotive/src/main/AndroidManifestWithSdkVersion.xml
@@ -27,7 +27,7 @@
 
   <uses-sdk
       android:minSdkVersion="29"
-      android:targetSdkVersion="29" />
+      android:targetSdkVersion="31" />
 
   <uses-permission android:name="android.permission.INTERNET"/>
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
diff --git a/car/app/app-samples/showcase/mobile/src/main/AndroidManifestWithSdkVersion.xml b/car/app/app-samples/showcase/mobile/src/main/AndroidManifestWithSdkVersion.xml
index 25e08d7..1c9c267 100644
--- a/car/app/app-samples/showcase/mobile/src/main/AndroidManifestWithSdkVersion.xml
+++ b/car/app/app-samples/showcase/mobile/src/main/AndroidManifestWithSdkVersion.xml
@@ -27,7 +27,7 @@
 
   <uses-sdk
       android:minSdkVersion="23"
-      android:targetSdkVersion="29" />
+      android:targetSdkVersion="31" />
 
   <uses-permission android:name="android.permission.INTERNET"/>
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
diff --git a/car/app/app/api/current.txt b/car/app/app/api/current.txt
index 1f0f4cf..c8ce9a4 100644
--- a/car/app/app/api/current.txt
+++ b/car/app/app/api/current.txt
@@ -225,6 +225,7 @@
 
   @androidx.car.app.annotations.RequiresCarApi(2) public class ConstraintManager implements androidx.car.app.managers.Manager {
     method public int getContentLimit(int);
+    method @androidx.car.app.annotations.RequiresCarApi(6) public boolean isAppDrivenRefreshEnabled();
     field public static final int CONTENT_LIMIT_TYPE_GRID = 1; // 0x1
     field public static final int CONTENT_LIMIT_TYPE_LIST = 0; // 0x0
     field public static final int CONTENT_LIMIT_TYPE_PANE = 4; // 0x4
@@ -987,8 +988,10 @@
   }
 
   @androidx.car.app.annotations.CarProtocol public final class Row implements androidx.car.app.model.Item {
+    method @androidx.car.app.annotations.RequiresCarApi(6) public java.util.List<androidx.car.app.model.Action!> getActions();
     method public androidx.car.app.model.CarIcon? getImage();
     method public androidx.car.app.model.Metadata? getMetadata();
+    method @androidx.car.app.annotations.RequiresCarApi(6) public int getNumericDecoration();
     method public androidx.car.app.model.OnClickDelegate? getOnClickDelegate();
     method public int getRowImageType();
     method public java.util.List<androidx.car.app.model.CarText!> getTexts();
@@ -1006,6 +1009,7 @@
 
   public static final class Row.Builder {
     ctor public Row.Builder();
+    method @androidx.car.app.annotations.RequiresCarApi(6) public androidx.car.app.model.Row.Builder addAction(androidx.car.app.model.Action);
     method public androidx.car.app.model.Row.Builder addText(CharSequence);
     method public androidx.car.app.model.Row.Builder addText(androidx.car.app.model.CarText);
     method public androidx.car.app.model.Row build();
@@ -1014,6 +1018,7 @@
     method public androidx.car.app.model.Row.Builder setImage(androidx.car.app.model.CarIcon);
     method public androidx.car.app.model.Row.Builder setImage(androidx.car.app.model.CarIcon, int);
     method public androidx.car.app.model.Row.Builder setMetadata(androidx.car.app.model.Metadata);
+    method @IntRange(from=0) @androidx.car.app.annotations.RequiresCarApi(6) public androidx.car.app.model.Row.Builder setNumericDecoration(int);
     method public androidx.car.app.model.Row.Builder setOnClickListener(androidx.car.app.model.OnClickListener);
     method public androidx.car.app.model.Row.Builder setTitle(CharSequence);
     method public androidx.car.app.model.Row.Builder setTitle(androidx.car.app.model.CarText);
diff --git a/car/app/app/api/public_plus_experimental_current.txt b/car/app/app/api/public_plus_experimental_current.txt
index 33ffc83..02f26c1 100644
--- a/car/app/app/api/public_plus_experimental_current.txt
+++ b/car/app/app/api/public_plus_experimental_current.txt
@@ -233,7 +233,7 @@
 
   @androidx.car.app.annotations.RequiresCarApi(2) public class ConstraintManager implements androidx.car.app.managers.Manager {
     method public int getContentLimit(int);
-    method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(6) public boolean isAppDrivenRefreshEnabled();
+    method @androidx.car.app.annotations.RequiresCarApi(6) public boolean isAppDrivenRefreshEnabled();
     field public static final int CONTENT_LIMIT_TYPE_GRID = 1; // 0x1
     field public static final int CONTENT_LIMIT_TYPE_LIST = 0; // 0x0
     field public static final int CONTENT_LIMIT_TYPE_PANE = 4; // 0x4
@@ -1449,10 +1449,10 @@
   }
 
   @androidx.car.app.annotations.CarProtocol public final class Row implements androidx.car.app.model.Item {
-    method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(6) public java.util.List<androidx.car.app.model.Action!> getActions();
+    method @androidx.car.app.annotations.RequiresCarApi(6) public java.util.List<androidx.car.app.model.Action!> getActions();
     method public androidx.car.app.model.CarIcon? getImage();
     method public androidx.car.app.model.Metadata? getMetadata();
-    method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(6) public int getNumericDecoration();
+    method @androidx.car.app.annotations.RequiresCarApi(6) public int getNumericDecoration();
     method public androidx.car.app.model.OnClickDelegate? getOnClickDelegate();
     method public int getRowImageType();
     method public java.util.List<androidx.car.app.model.CarText!> getTexts();
@@ -1470,7 +1470,7 @@
 
   public static final class Row.Builder {
     ctor public Row.Builder();
-    method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(6) public androidx.car.app.model.Row.Builder addAction(androidx.car.app.model.Action);
+    method @androidx.car.app.annotations.RequiresCarApi(6) public androidx.car.app.model.Row.Builder addAction(androidx.car.app.model.Action);
     method public androidx.car.app.model.Row.Builder addText(CharSequence);
     method public androidx.car.app.model.Row.Builder addText(androidx.car.app.model.CarText);
     method public androidx.car.app.model.Row build();
@@ -1479,7 +1479,7 @@
     method public androidx.car.app.model.Row.Builder setImage(androidx.car.app.model.CarIcon);
     method public androidx.car.app.model.Row.Builder setImage(androidx.car.app.model.CarIcon, int);
     method public androidx.car.app.model.Row.Builder setMetadata(androidx.car.app.model.Metadata);
-    method @IntRange(from=0) @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(6) public androidx.car.app.model.Row.Builder setNumericDecoration(int);
+    method @IntRange(from=0) @androidx.car.app.annotations.RequiresCarApi(6) public androidx.car.app.model.Row.Builder setNumericDecoration(int);
     method public androidx.car.app.model.Row.Builder setOnClickListener(androidx.car.app.model.OnClickListener);
     method public androidx.car.app.model.Row.Builder setTitle(CharSequence);
     method public androidx.car.app.model.Row.Builder setTitle(androidx.car.app.model.CarText);
@@ -1529,14 +1529,12 @@
     method public String getContentId();
     method public androidx.car.app.model.CarIcon getIcon();
     method public androidx.car.app.model.CarText getTitle();
-    method @Deprecated public boolean isActive();
-    method public androidx.car.app.model.Tab.Builder toBuilder();
   }
 
   public static final class Tab.Builder {
     ctor public Tab.Builder();
+    ctor public Tab.Builder(androidx.car.app.model.Tab);
     method public androidx.car.app.model.Tab build();
-    method @Deprecated public androidx.car.app.model.Tab.Builder setActive(boolean);
     method public androidx.car.app.model.Tab.Builder setContentId(String);
     method public androidx.car.app.model.Tab.Builder setIcon(androidx.car.app.model.CarIcon);
     method public androidx.car.app.model.Tab.Builder setTitle(CharSequence);
diff --git a/car/app/app/api/restricted_current.txt b/car/app/app/api/restricted_current.txt
index 1f0f4cf..c8ce9a4 100644
--- a/car/app/app/api/restricted_current.txt
+++ b/car/app/app/api/restricted_current.txt
@@ -225,6 +225,7 @@
 
   @androidx.car.app.annotations.RequiresCarApi(2) public class ConstraintManager implements androidx.car.app.managers.Manager {
     method public int getContentLimit(int);
+    method @androidx.car.app.annotations.RequiresCarApi(6) public boolean isAppDrivenRefreshEnabled();
     field public static final int CONTENT_LIMIT_TYPE_GRID = 1; // 0x1
     field public static final int CONTENT_LIMIT_TYPE_LIST = 0; // 0x0
     field public static final int CONTENT_LIMIT_TYPE_PANE = 4; // 0x4
@@ -987,8 +988,10 @@
   }
 
   @androidx.car.app.annotations.CarProtocol public final class Row implements androidx.car.app.model.Item {
+    method @androidx.car.app.annotations.RequiresCarApi(6) public java.util.List<androidx.car.app.model.Action!> getActions();
     method public androidx.car.app.model.CarIcon? getImage();
     method public androidx.car.app.model.Metadata? getMetadata();
+    method @androidx.car.app.annotations.RequiresCarApi(6) public int getNumericDecoration();
     method public androidx.car.app.model.OnClickDelegate? getOnClickDelegate();
     method public int getRowImageType();
     method public java.util.List<androidx.car.app.model.CarText!> getTexts();
@@ -1006,6 +1009,7 @@
 
   public static final class Row.Builder {
     ctor public Row.Builder();
+    method @androidx.car.app.annotations.RequiresCarApi(6) public androidx.car.app.model.Row.Builder addAction(androidx.car.app.model.Action);
     method public androidx.car.app.model.Row.Builder addText(CharSequence);
     method public androidx.car.app.model.Row.Builder addText(androidx.car.app.model.CarText);
     method public androidx.car.app.model.Row build();
@@ -1014,6 +1018,7 @@
     method public androidx.car.app.model.Row.Builder setImage(androidx.car.app.model.CarIcon);
     method public androidx.car.app.model.Row.Builder setImage(androidx.car.app.model.CarIcon, int);
     method public androidx.car.app.model.Row.Builder setMetadata(androidx.car.app.model.Metadata);
+    method @IntRange(from=0) @androidx.car.app.annotations.RequiresCarApi(6) public androidx.car.app.model.Row.Builder setNumericDecoration(int);
     method public androidx.car.app.model.Row.Builder setOnClickListener(androidx.car.app.model.OnClickListener);
     method public androidx.car.app.model.Row.Builder setTitle(CharSequence);
     method public androidx.car.app.model.Row.Builder setTitle(androidx.car.app.model.CarText);
diff --git a/car/app/app/src/main/java/androidx/car/app/constraints/ConstraintManager.java b/car/app/app/src/main/java/androidx/car/app/constraints/ConstraintManager.java
index c8fcccd..e9e8817 100644
--- a/car/app/app/src/main/java/androidx/car/app/constraints/ConstraintManager.java
+++ b/car/app/app/src/main/java/androidx/car/app/constraints/ConstraintManager.java
@@ -31,7 +31,6 @@
 import androidx.car.app.HostDispatcher;
 import androidx.car.app.HostException;
 import androidx.car.app.R;
-import androidx.car.app.annotations.ExperimentalCarApi;
 import androidx.car.app.annotations.RequiresCarApi;
 import androidx.car.app.managers.Manager;
 import androidx.car.app.utils.LogTags;
@@ -149,7 +148,6 @@
      *
      */
     @RequiresCarApi(6)
-    @ExperimentalCarApi
     public boolean isAppDrivenRefreshEnabled() {
         Boolean result;
         try {
diff --git a/car/app/app/src/main/java/androidx/car/app/messaging/model/CarMessage.java b/car/app/app/src/main/java/androidx/car/app/messaging/model/CarMessage.java
index 8614a79..034b5de 100644
--- a/car/app/app/src/main/java/androidx/car/app/messaging/model/CarMessage.java
+++ b/car/app/app/src/main/java/androidx/car/app/messaging/model/CarMessage.java
@@ -16,6 +16,8 @@
 
 package androidx.car.app.messaging.model;
 
+import static androidx.car.app.messaging.model.ConversationItem.validateSender;
+
 import static java.util.Objects.requireNonNull;
 
 import android.os.Bundle;
@@ -72,7 +74,7 @@
     }
 
     CarMessage(@NonNull Builder builder) {
-        this.mSender = builder.mSender == null ? null : requireNonNull(builder.mSender).toBundle();
+        this.mSender = builder.mSender == null ? null : validateSender(builder.mSender).toBundle();
         this.mBody = requireNonNull(builder.mBody);
         this.mReceivedTimeEpochMillis = builder.mReceivedTimeEpochMillis;
         this.mIsRead = builder.mIsRead;
@@ -123,7 +125,13 @@
         long mReceivedTimeEpochMillis;
         boolean mIsRead;
 
-        /** Sets a {@link Person} representing the message sender */
+        /**
+         * Sets a {@link Person} representing the message sender
+         *
+         * <p> The {@link Person} must specify a non-null
+         * {@link Person.Builder#setName(CharSequence)} and
+         * {@link Person.Builder#setKey(String)}.
+         */
         public @NonNull Builder setSender(@Nullable Person sender) {
             mSender = sender;
             return this;
diff --git a/car/app/app/src/main/java/androidx/car/app/messaging/model/ConversationItem.java b/car/app/app/src/main/java/androidx/car/app/messaging/model/ConversationItem.java
index 5956a59..b63b93e 100644
--- a/car/app/app/src/main/java/androidx/car/app/messaging/model/ConversationItem.java
+++ b/car/app/app/src/main/java/androidx/car/app/messaging/model/ConversationItem.java
@@ -95,7 +95,7 @@
     ConversationItem(@NonNull Builder builder) {
         this.mId = requireNonNull(builder.mId);
         this.mTitle = requireNonNull(builder.mTitle);
-        this.mSelf = requireNonNull(builder.mSelf).toBundle();
+        this.mSelf = validateSender(builder.mSelf).toBundle();
         this.mIcon = builder.mIcon;
         this.mIsGroupConversation = builder.mIsGroupConversation;
         this.mMessages = requireNonNull(CollectionUtils.unmodifiableCopy(builder.mMessages));
@@ -175,6 +175,19 @@
         return mConversationCallbackDelegate;
     }
 
+    /**
+     * Verifies that a given {@link Person} has the required fields to be a message sender. Returns
+     * the input {@link Person} if valid, or throws an exception if invalid.
+     *
+     * <p> See also {@link ConversationItem#getSelf()} and {@link CarMessage#getSender()}.
+     */
+    static Person validateSender(@Nullable Person person) {
+        requireNonNull(person);
+        requireNonNull(person.getName());
+        requireNonNull(person.getKey());
+        return person;
+    }
+
     /** A builder for {@link ConversationItem} */
     public static final class Builder {
         @Nullable
@@ -221,7 +234,13 @@
             return this;
         }
 
-        /** Sets a {@link Person} for the conversation */
+        /**
+         * Sets a {@link Person} for the conversation
+         *
+         * <p> The {@link Person} must specify a non-null
+         * {@link Person.Builder#setName(CharSequence)} and
+         * {@link Person.Builder#setKey(String)}.
+         */
         @NonNull
         public Builder setSelf(@NonNull Person self) {
             mSelf = self;
diff --git a/car/app/app/src/main/java/androidx/car/app/model/Row.java b/car/app/app/src/main/java/androidx/car/app/model/Row.java
index 9cee293..857da8b 100644
--- a/car/app/app/src/main/java/androidx/car/app/model/Row.java
+++ b/car/app/app/src/main/java/androidx/car/app/model/Row.java
@@ -30,12 +30,11 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.car.app.annotations.CarProtocol;
-import androidx.car.app.annotations.ExperimentalCarApi;
+import androidx.car.app.annotations.KeepFields;
 import androidx.car.app.annotations.RequiresCarApi;
 import androidx.car.app.model.constraints.ActionsConstraints;
 import androidx.car.app.model.constraints.CarIconConstraints;
 import androidx.car.app.model.constraints.CarTextConstraints;
-import androidx.car.app.annotations.KeepFields;
 import androidx.car.app.utils.CollectionUtils;
 
 import java.lang.annotation.Retention;
@@ -155,7 +154,6 @@
      *
      * @see Builder#addAction(Action)
      */
-    @ExperimentalCarApi
     @NonNull
     @RequiresCarApi(6)
     public List<Action> getActions() {
@@ -173,11 +171,12 @@
      *
      * <p> Numeric decorations are displayed at the end of the row, but before any actions.
      *
+     * <p> Numeric decorations are only allowed in full-width lists.
+     *
      * <p> {@link Row#NO_DECORATION} will be returned if the row does not contain a decoration.
      *
      * @see Builder#setNumericDecoration(int)
      */
-    @ExperimentalCarApi
     @RequiresCarApi(6)
     public int getNumericDecoration() {
         return mNumericDecoration;
@@ -524,8 +523,7 @@
         }
 
         /**
-         * Adds an additional action to the end of the row. Actions are not displayed in
-         * half-list templates.
+         * Adds an additional action to the end of the row.
          *
          * @throws NullPointerException     if {@code action} is {@code null}
          * @throws IllegalArgumentException if {@code action} contains unsupported Action types,
@@ -533,7 +531,6 @@
          *                                  not contain a valid {@link CarIcon}.
          */
         //TODO(b/260557014): Update docs when half-list UX is defined
-        @ExperimentalCarApi
         @NonNull
         @RequiresCarApi(6)
         public Builder addAction(@NonNull Action action) {
@@ -559,7 +556,6 @@
          * @throws IllegalArgumentException if {@code decoration} is invalid
          */
         //TODO(b/260557014): Update docs when half-list UX is defined
-        @ExperimentalCarApi
         @NonNull
         @RequiresCarApi(6)
         @IntRange(from = 0)
@@ -699,4 +695,4 @@
         public Builder() {
         }
     }
-}
+}
\ No newline at end of file
diff --git a/car/app/app/src/main/java/androidx/car/app/model/Tab.java b/car/app/app/src/main/java/androidx/car/app/model/Tab.java
index b6f6089..d99fd60 100644
--- a/car/app/app/src/main/java/androidx/car/app/model/Tab.java
+++ b/car/app/app/src/main/java/androidx/car/app/model/Tab.java
@@ -41,7 +41,6 @@
     /** Content ID for an empty Tab object. */
     private static final String EMPTY_TAB_CONTENT_ID = "EMPTY_TAB_CONTENT_ID";
 
-    private final boolean mIsActive;
     @Nullable
     private final CarText mTitle;
     @Nullable
@@ -80,17 +79,6 @@
         return requireNonNull(mIcon);
     }
 
-    /**
-     * Indicates if this is the currently active tab.
-     *
-     * @see Tab.Builder#setActive(boolean)
-     * @deprecated use {@link TabTemplate#getActiveTabContentId()} instead.
-     */
-    @Deprecated
-    public boolean isActive() {
-        return mIsActive;
-    }
-
     @Override
     @NonNull
     public String toString() {
@@ -100,8 +88,6 @@
                 + mContentId
                 + ", icon: "
                 + mIcon
-                + ", isActive "
-                + mIsActive
                 + "]";
     }
 
@@ -110,8 +96,7 @@
         return Objects.hash(
                 mTitle,
                 mContentId,
-                mIcon,
-                mIsActive);
+                mIcon);
     }
 
     @Override
@@ -126,22 +111,12 @@
 
         return Objects.equals(mTitle, otherTab.mTitle)
                 && Objects.equals(mContentId, otherTab.mContentId)
-                && Objects.equals(mIcon, otherTab.mIcon)
-                && mIsActive == otherTab.isActive();
-    }
-
-    /**
-     * Creates and returns a new {@link Builder} initialized with this {@link Tab}'s data.
-     */
-    @NonNull
-    public Tab.Builder toBuilder() {
-        return new Tab.Builder(this);
+                && Objects.equals(mIcon, otherTab.mIcon);
     }
 
     Tab(Tab.Builder builder) {
         mTitle = builder.mTitle;
         mIcon = builder.mIcon;
-        mIsActive = builder.mIsActive;
 
         if (builder.mContentId != null) {
             mContentId = builder.mContentId;
@@ -155,13 +130,10 @@
         mTitle = null;
         mContentId = EMPTY_TAB_CONTENT_ID;
         mIcon = null;
-        mIsActive = false;
     }
 
     /** A builder of {@link Tab}. */
     public static final class Builder {
-        boolean mIsActive;
-
         @Nullable
         CarText mTitle;
 
@@ -194,6 +166,9 @@
 
         /**
          * Sets the content ID of the tab.
+         *
+         * @throws NullPointerException     if {@code contentId} is {@code null}
+         * @throws IllegalArgumentException if {@code contentId} is empty
          */
         @NonNull
         public Tab.Builder setContentId(@NonNull String contentId) {
@@ -227,18 +202,6 @@
         }
 
         /**
-         * Sets the active state of the tab.
-         *
-         * @deprecated use {@link TabTemplate.Builder#setActiveTabContentId(String)} instead.
-         */
-        @NonNull
-        @Deprecated
-        public Tab.Builder setActive(boolean isActive) {
-            mIsActive = isActive;
-            return this;
-        }
-
-        /**
          * Constructs the {@link Tab} defined by this builder.
          *
          * @throws IllegalStateException if the tab's title, icon or content ID is not set.
@@ -266,9 +229,8 @@
         }
 
         /** Creates a new {@link Builder}, populated from the input {@link Tab} */
-        Builder(@NonNull Tab tab) {
+        public Builder(@NonNull Tab tab) {
             requireNonNull(tab);
-            mIsActive = tab.isActive();
             mContentId = tab.getContentId();
             mIcon = tab.getIcon();
             mTitle = tab.getTitle();
diff --git a/car/app/app/src/test/java/androidx/car/app/messaging/model/CarMessageTest.java b/car/app/app/src/test/java/androidx/car/app/messaging/model/CarMessageTest.java
index a7a2fb2..06caf6b 100644
--- a/car/app/app/src/test/java/androidx/car/app/messaging/model/CarMessageTest.java
+++ b/car/app/app/src/test/java/androidx/car/app/messaging/model/CarMessageTest.java
@@ -21,7 +21,6 @@
 import static org.junit.Assert.assertThrows;
 
 import androidx.car.app.model.CarText;
-import androidx.core.app.Person;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -60,6 +59,28 @@
         );
     }
 
+    public void build_throwsException_ifSenderNameMissing() {
+        assertThrows(
+                NullPointerException.class,
+                () -> TestConversationFactory.createMinimalMessageBuilder()
+                        .setSender(TestConversationFactory.createMinimalMessageSenderBuilder()
+                                .setName(null)
+                                .build())
+                        .build()
+        );
+    }
+
+    public void build_throwsException_ifSenderKeyMissing() {
+        assertThrows(
+                NullPointerException.class,
+                () -> TestConversationFactory.createMinimalMessageBuilder()
+                        .setSender(TestConversationFactory.createMinimalMessageSenderBuilder()
+                                .setKey(null)
+                                .build())
+                        .build()
+        );
+    }
+
     // region .equals() & .hashCode()
     @Test
     public void equalsAndHashCode_areEqual_forMinimalMessage() {
@@ -93,7 +114,7 @@
                         .createFullyPopulatedMessageBuilder()
                         .setSender(
                                 TestConversationFactory
-                                        .createMinimalPersonBuilder()
+                                        .createMinimalMessageSenderBuilder()
                                         .setKey("Modified Key")
                                         .build()
                         )
@@ -124,57 +145,6 @@
         assertNotEqual(fullyPopulatedMessage, modifiedIsRead);
     }
 
-    @Test
-    public void equalsAndHashCode_produceCorrectResult_ifSenderIdMissing() {
-        Person.Builder senderWithoutId = TestConversationFactory
-                .createMinimalPersonBuilder()
-                .setKey(null);
-        Person.Builder senderWithId = TestConversationFactory
-                .createMinimalPersonBuilder()
-                .setKey("Test Sender Key");
-
-        // Create Test Data
-        CarMessage senderKeyMissingWithStandardData =
-                TestConversationFactory.createMinimalMessageBuilder()
-                        .setSender(senderWithoutId.build())
-                        .build();
-        CarMessage senderKeyMissingWithStandardData2 =
-                TestConversationFactory.createMinimalMessageBuilder()
-                        .setSender(senderWithoutId.build())
-                        .build();
-        CarMessage senderKeyMissingWithModifiedData =
-                TestConversationFactory.createMinimalMessageBuilder()
-                        .setSender(senderWithoutId.build())
-                        .setBody(CarText.create("Modified Message Body"))
-                        .build();
-        CarMessage senderKeyProvidedWithStandardData =
-                TestConversationFactory.createMinimalMessageBuilder()
-                        .setSender(senderWithId.build())
-                        .build();
-        CarMessage senderKeyProvidedWithStandardData2 =
-                TestConversationFactory.createMinimalMessageBuilder()
-                        .setSender(senderWithId.build())
-                        .build();
-        CarMessage senderKeyProvidedWithModifiedData =
-                TestConversationFactory.createMinimalMessageBuilder()
-                        .setSender(senderWithId.build())
-                        .setBody(CarText.create("Modified Message Body"))
-                        .build();
-
-        // Verify (in)equality
-
-        // Sender & message content are equal: == EQUAL ==
-        assertEqual(senderKeyMissingWithStandardData, senderKeyMissingWithStandardData2);
-        assertEqual(senderKeyProvidedWithStandardData, senderKeyProvidedWithStandardData2);
-
-        // One sender is missing a key: == NOT EQUAL ==
-        assertNotEqual(senderKeyMissingWithStandardData, senderKeyProvidedWithStandardData);
-
-        // Sender is equal, but message content is not: == NOT EQUAL ==
-        assertNotEqual(senderKeyMissingWithStandardData, senderKeyMissingWithModifiedData);
-        assertNotEqual(senderKeyProvidedWithStandardData, senderKeyProvidedWithModifiedData);
-    }
-
     private void assertEqual(CarMessage message1, CarMessage message2) {
         assertThat(message1).isEqualTo(message2);
         assertThat(message1.hashCode()).isEqualTo(message2.hashCode());
diff --git a/car/app/app/src/test/java/androidx/car/app/messaging/model/ConversationItemTest.java b/car/app/app/src/test/java/androidx/car/app/messaging/model/ConversationItemTest.java
index 2090047..97cea42 100644
--- a/car/app/app/src/test/java/androidx/car/app/messaging/model/ConversationItemTest.java
+++ b/car/app/app/src/test/java/androidx/car/app/messaging/model/ConversationItemTest.java
@@ -62,6 +62,28 @@
         );
     }
 
+    public void build_throwsException_ifSenderNameMissing() {
+        assertThrows(
+                NullPointerException.class,
+                () -> TestConversationFactory.createMinimalConversationItemBuilder()
+                        .setSelf(TestConversationFactory.createMinimalMessageSenderBuilder()
+                                .setName(null)
+                                .build())
+                        .build()
+        );
+    }
+
+    public void build_throwsException_ifSenderKeyMissing() {
+        assertThrows(
+                NullPointerException.class,
+                () -> TestConversationFactory.createMinimalConversationItemBuilder()
+                        .setSelf(TestConversationFactory.createMinimalMessageSenderBuilder()
+                                .setKey(null)
+                                .build())
+                        .build()
+        );
+    }
+
     // region .equals() & .hashCode()
     @Test
     public void equalsAndHashCode_areEqual_forMinimalConversationItem() {
@@ -131,7 +153,8 @@
         ConversationItem modifiedConversationCallback =
                 TestConversationFactory
                         .createFullyPopulatedConversationItemBuilder()
-                        .setSelf(TestConversationFactory.createMinimalPersonBuilder().build())
+                        .setSelf(
+                                TestConversationFactory.createMinimalMessageSenderBuilder().build())
                         .setConversationCallback(new ConversationCallback() {
                             @Override
                             public void onMarkAsRead() {
diff --git a/car/app/app/src/test/java/androidx/car/app/messaging/model/PersonsEqualityHelperTest.java b/car/app/app/src/test/java/androidx/car/app/messaging/model/PersonsEqualityHelperTest.java
index 13b4d4f..eb3791c 100644
--- a/car/app/app/src/test/java/androidx/car/app/messaging/model/PersonsEqualityHelperTest.java
+++ b/car/app/app/src/test/java/androidx/car/app/messaging/model/PersonsEqualityHelperTest.java
@@ -34,10 +34,8 @@
 
     @Test
     public void equalsAndHashCode_minimalPersons_areEqual() {
-        Person person1 =
-                TestConversationFactory.createMinimalPersonBuilder().build();
-        Person person2 =
-                TestConversationFactory.createMinimalPersonBuilder().build();
+        Person person1 = createMinimalPerson();
+        Person person2 = createMinimalPerson();
 
         assertThat(PersonsEqualityHelper.arePersonsEqual(person1, person2)).isTrue();
         assertThat(PersonsEqualityHelper.getPersonHashCode(person1)).isEqualTo(
@@ -53,10 +51,8 @@
 
     @Test
     public void equalsAndHashCode_differentName_areNotEqual() {
-        Person person1 =
-                TestConversationFactory.createMinimalPersonBuilder().setName("Person1").build();
-        Person person2 =
-                TestConversationFactory.createMinimalPersonBuilder().setName("Person2").build();
+        Person person1 = createMinimalPersonBuilder().setName("Person1").build();
+        Person person2 = createMinimalPersonBuilder().setName("Person2").build();
 
         assertThat(PersonsEqualityHelper.arePersonsEqual(person1, person2)).isFalse();
         assertThat(PersonsEqualityHelper.getPersonHashCode(person1)).isNotEqualTo(
@@ -65,10 +61,8 @@
 
     @Test
     public void equalsAndHashCode_differentKey_areNotEqual() {
-        Person person1 =
-                TestConversationFactory.createMinimalPersonBuilder().setKey("Person1").build();
-        Person person2 =
-                TestConversationFactory.createMinimalPersonBuilder().setKey("Person2").build();
+        Person person1 = createMinimalPersonBuilder().setKey("Person1").build();
+        Person person2 = createMinimalPersonBuilder().setKey("Person2").build();
 
         assertThat(PersonsEqualityHelper.arePersonsEqual(person1, person2)).isFalse();
         assertThat(PersonsEqualityHelper.getPersonHashCode(person1)).isNotEqualTo(
@@ -81,11 +75,9 @@
                 Uri.parse("http://foo.com/test/sender/uri1");
         Uri uri2 =
                 Uri.parse("http://foo.com/test/sender/uri2");
-        Person person1 =
-                TestConversationFactory.createMinimalPersonBuilder().setUri(
+        Person person1 = createMinimalPersonBuilder().setUri(
                         uri1.toString()).build();
-        Person person2 =
-                TestConversationFactory.createMinimalPersonBuilder().setName(
+        Person person2 = createMinimalPersonBuilder().setName(
                         uri2.toString()).build();
 
         assertThat(PersonsEqualityHelper.arePersonsEqual(person1, person2)).isFalse();
@@ -95,10 +87,8 @@
 
     @Test
     public void equalsAndHashCode_differentBot_areNotEqual() {
-        Person person1 =
-                TestConversationFactory.createMinimalPersonBuilder().setBot(true).build();
-        Person person2 =
-                TestConversationFactory.createMinimalPersonBuilder().setBot(false).build();
+        Person person1 = createMinimalPersonBuilder().setBot(true).build();
+        Person person2 = createMinimalPersonBuilder().setBot(false).build();
 
         assertThat(PersonsEqualityHelper.arePersonsEqual(person1, person2)).isFalse();
         assertThat(PersonsEqualityHelper.getPersonHashCode(person1)).isNotEqualTo(
@@ -107,13 +97,19 @@
 
     @Test
     public void equalsAndHashCode_differentImportant_areNotEqual() {
-        Person person1 =
-                TestConversationFactory.createMinimalPersonBuilder().setImportant(true).build();
-        Person person2 =
-                TestConversationFactory.createMinimalPersonBuilder().setImportant(false).build();
+        Person person1 = createMinimalPersonBuilder().setImportant(true).build();
+        Person person2 = createMinimalPersonBuilder().setImportant(false).build();
 
         assertThat(PersonsEqualityHelper.arePersonsEqual(person1, person2)).isFalse();
         assertThat(PersonsEqualityHelper.getPersonHashCode(person1)).isNotEqualTo(
                 PersonsEqualityHelper.getPersonHashCode(person2));
     }
+
+    private Person.Builder createMinimalPersonBuilder() {
+        return new Person.Builder();
+    }
+
+    private Person createMinimalPerson() {
+        return createMinimalPersonBuilder().build();
+    }
 }
diff --git a/car/app/app/src/test/java/androidx/car/app/messaging/model/TestConversationFactory.java b/car/app/app/src/test/java/androidx/car/app/messaging/model/TestConversationFactory.java
index dc3097b..bd1274a 100644
--- a/car/app/app/src/test/java/androidx/car/app/messaging/model/TestConversationFactory.java
+++ b/car/app/app/src/test/java/androidx/car/app/messaging/model/TestConversationFactory.java
@@ -53,8 +53,8 @@
      *
      * <p>This method fills in the minimum required data to create a valid {@link Person}.
      */
-    public static Person.Builder createMinimalPersonBuilder() {
-        return new Person.Builder().setName("Person Name");
+    public static Person.Builder createMinimalMessageSenderBuilder() {
+        return new Person.Builder().setName("Person Name").setKey("sender_key");
     }
 
     /**
@@ -62,8 +62,8 @@
      *
      * <p>This method fills in the minimum required data to create a valid {@link Person}.
      */
-    private static Person createMinimalPerson() {
-        return createMinimalPersonBuilder().build();
+    private static Person createMinimalMessageSender() {
+        return createMinimalMessageSenderBuilder().build();
     }
 
     /**
@@ -72,7 +72,7 @@
      * <p>This method fills in the minimum required data to create a valid {@link Person}.
      */
     public static Person.Builder createFullyPopulatedPersonBuilder() {
-        return createMinimalPersonBuilder()
+        return createMinimalMessageSenderBuilder()
                 .setKey("Foo Person")
                 .setIcon(TEST_SENDER_ICON)
                 .setUri(TEST_SENDER_URI.toString())
@@ -146,7 +146,7 @@
         return new ConversationItem.Builder()
                 .setId("conversation_id")
                 .setTitle(CarText.create("Conversation Title"))
-                .setSelf(createMinimalPerson())
+                .setSelf(createMinimalMessageSender())
                 .setMessages(messages)
                 .setConversationCallback(EMPTY_CONVERSATION_CALLBACK);
     }
diff --git a/car/app/app/src/test/java/androidx/car/app/model/TabTest.java b/car/app/app/src/test/java/androidx/car/app/model/TabTest.java
index 14a5e80..2b9251b 100644
--- a/car/app/app/src/test/java/androidx/car/app/model/TabTest.java
+++ b/car/app/app/src/test/java/androidx/car/app/model/TabTest.java
@@ -108,22 +108,22 @@
     }
 
     @Test
-    public void equals_Builder() {
-        Tab tab = TEST_TAB.toBuilder().build();
+    public void equals_copy() {
+        Tab tab = new Tab.Builder(TEST_TAB).build();
 
         assertEquals(tab, TEST_TAB);
     }
 
     @Test
     public void notEquals_differentTitle() {
-        Tab tab = TEST_TAB.toBuilder().setTitle("New Tab").build();
+        Tab tab = new Tab.Builder(TEST_TAB).setTitle("New Tab").build();
 
         assertNotEquals(tab, TEST_TAB);
     }
 
     @Test
     public void notEquals_differentIcon() {
-        Tab tab = TEST_TAB.toBuilder()
+        Tab tab = new Tab.Builder(TEST_TAB)
                 .setIcon(TestUtils.getTestCarIcon(
                         ApplicationProvider.getApplicationContext(),
                         "ic_test_2"))
@@ -134,7 +134,7 @@
 
     @Test
     public void notEquals_differentContentId() {
-        Tab tab = TEST_TAB.toBuilder().setContentId("new id").build();
+        Tab tab = new Tab.Builder(TEST_TAB).setContentId("new id").build();
 
         assertNotEquals(tab, TEST_TAB);
     }
diff --git a/collection/collection/api/api_lint.ignore b/collection/collection/api/api_lint.ignore
index b0605dd..c3a23ac 100644
--- a/collection/collection/api/api_lint.ignore
+++ b/collection/collection/api/api_lint.ignore
@@ -1,14 +1,14 @@
 // Baseline format: 1.0
 ArrayReturn: androidx.collection.ArraySet#ArraySet(E[]) parameter #0:
     Method parameter should be Collection<E> (or subclass) instead of raw array; was `E[]`
-ArrayReturn: androidx.collection.ArraySet#toArray():
-    Method should return Collection<Object> (or subclass) instead of raw array; was `java.lang.Object[]`
-ArrayReturn: androidx.collection.ArraySet#toArray(T[]):
-    Method should return Collection<T> (or subclass) instead of raw array; was `T[]`
 ArrayReturn: androidx.collection.ArraySet#toArray(T[]) parameter #0:
     Method parameter should be Collection<T> (or subclass) instead of raw array; was `T[]`
 
 
+GetterSetterNames: androidx.collection.SparseArrayCompat#getIsEmpty():
+    Getter for boolean property `isEmpty` is named `getIsEmpty` but should match the property name. Use `@get:JvmName` to rename.
+
+
 KotlinOperator: androidx.collection.SparseArrayCompat#get(int, E):
     Note that adding the `operator` keyword would allow calling this method using operator syntax
 
diff --git a/collection/collection/api/current.ignore b/collection/collection/api/current.ignore
index 6397290..7be6378 100644
--- a/collection/collection/api/current.ignore
+++ b/collection/collection/api/current.ignore
@@ -9,6 +9,18 @@
     Method androidx.collection.SparseArrayCompat.clone has changed return type from androidx.collection.SparseArrayCompat<E!> to androidx.collection.SparseArrayCompat<E>
 
 
+InvalidNullConversion: androidx.collection.ArraySet#add(E) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.collection.ArraySet.add(E element)
+InvalidNullConversion: androidx.collection.ArraySet#contains(E) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.collection.ArraySet.contains(E element)
+InvalidNullConversion: androidx.collection.ArraySet#remove(E) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.collection.ArraySet.remove(E element)
+InvalidNullConversion: androidx.collection.SimpleArrayMap#containsKey(K) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.collection.SimpleArrayMap.containsKey(K key)
+InvalidNullConversion: androidx.collection.SimpleArrayMap#indexOfKey(K) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.collection.SimpleArrayMap.indexOfKey(K key)
+
+
 RemovedMethod: androidx.collection.ArraySet#ArraySet(androidx.collection.ArraySet<E>):
     Removed constructor androidx.collection.ArraySet(androidx.collection.ArraySet<E>)
 RemovedMethod: androidx.collection.ArraySet#ArraySet(java.util.Collection<E>):
diff --git a/collection/collection/api/current.txt b/collection/collection/api/current.txt
index 19c0d55..3fbf783 100644
--- a/collection/collection/api/current.txt
+++ b/collection/collection/api/current.txt
@@ -29,25 +29,25 @@
     ctor public ArraySet(androidx.collection.ArraySet<? extends E>? set);
     ctor public ArraySet(java.util.Collection<? extends E>? set);
     ctor public ArraySet(E![]? array);
-    method public boolean add(E? element);
+    method public boolean add(E element);
     method public void addAll(androidx.collection.ArraySet<? extends E> array);
     method public boolean addAll(java.util.Collection<? extends E> elements);
     method public void clear();
-    method public operator boolean contains(E? element);
+    method public operator boolean contains(E element);
     method public boolean containsAll(java.util.Collection<E!> elements);
     method public void ensureCapacity(int minimumCapacity);
     method public int getSize();
     method public int indexOf(Object? key);
     method public boolean isEmpty();
     method public java.util.Iterator<E> iterator();
-    method public boolean remove(E? element);
+    method public boolean remove(E element);
     method public boolean removeAll(androidx.collection.ArraySet<? extends E> array);
     method public boolean removeAll(java.util.Collection<E!> elements);
-    method public E! removeAt(int index);
+    method public E removeAt(int index);
     method public boolean retainAll(java.util.Collection<E!> elements);
     method public Object![] toArray();
     method public <T> T![] toArray(T![] array);
-    method public E! valueAt(int index);
+    method public E valueAt(int index);
     property public int size;
   }
 
@@ -59,15 +59,15 @@
   public final class CircularArray<E> {
     ctor public CircularArray(optional int minCapacity);
     ctor public CircularArray();
-    method public void addFirst(E? element);
-    method public void addLast(E? element);
+    method public void addFirst(E element);
+    method public void addLast(E element);
     method public void clear();
-    method public operator E! get(int index);
+    method public operator E get(int index);
     method public E! getFirst();
     method public E! getLast();
     method public boolean isEmpty();
-    method public E! popFirst();
-    method public E! popLast();
+    method public E popFirst();
+    method public E popLast();
     method public void removeFromEnd(int count);
     method public void removeFromStart(int count);
     method public int size();
@@ -97,42 +97,42 @@
   public class LongSparseArray<E> implements java.lang.Cloneable {
     ctor public LongSparseArray(optional int initialCapacity);
     ctor public LongSparseArray();
-    method public void append(long key, E? value);
+    method public void append(long key, E value);
     method public void clear();
     method public androidx.collection.LongSparseArray<E> clone();
     method public boolean containsKey(long key);
-    method public boolean containsValue(E? value);
+    method public boolean containsValue(E value);
     method @Deprecated public void delete(long key);
     method public operator E? get(long key);
-    method public E! get(long key, E? defaultValue);
+    method public E get(long key, E defaultValue);
     method public int indexOfKey(long key);
-    method public int indexOfValue(E? value);
+    method public int indexOfValue(E value);
     method public boolean isEmpty();
     method public long keyAt(int index);
-    method public void put(long key, E? value);
+    method public void put(long key, E value);
     method public void putAll(androidx.collection.LongSparseArray<? extends E> other);
-    method public E? putIfAbsent(long key, E? value);
+    method public E? putIfAbsent(long key, E value);
     method public void remove(long key);
-    method public boolean remove(long key, E? value);
+    method public boolean remove(long key, E value);
     method public void removeAt(int index);
-    method public E? replace(long key, E? value);
-    method public boolean replace(long key, E? oldValue, E? newValue);
-    method public void setValueAt(int index, E? value);
+    method public E? replace(long key, E value);
+    method public boolean replace(long key, E oldValue, E newValue);
+    method public void setValueAt(int index, E value);
     method public int size();
-    method public E! valueAt(int index);
+    method public E valueAt(int index);
   }
 
   public final class LongSparseArrayKt {
     method public static inline operator <T> boolean contains(androidx.collection.LongSparseArray<T>, long key);
     method public static inline <T> void forEach(androidx.collection.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
-    method public static inline <T> T! getOrDefault(androidx.collection.LongSparseArray<T>, long key, T? defaultValue);
-    method public static inline <T> T! getOrElse(androidx.collection.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public static inline <T> T getOrDefault(androidx.collection.LongSparseArray<T>, long key, T defaultValue);
+    method public static inline <T> T getOrElse(androidx.collection.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public static inline <T> int getSize(androidx.collection.LongSparseArray<T>);
     method public static inline <T> boolean isNotEmpty(androidx.collection.LongSparseArray<T>);
     method public static <T> kotlin.collections.LongIterator keyIterator(androidx.collection.LongSparseArray<T>);
     method public static operator <T> androidx.collection.LongSparseArray<T> plus(androidx.collection.LongSparseArray<T>, androidx.collection.LongSparseArray<T> other);
-    method @Deprecated public static <T> boolean remove(androidx.collection.LongSparseArray<T>, long key, T? value);
-    method public static inline operator <T> void set(androidx.collection.LongSparseArray<T>, long key, T? value);
+    method @Deprecated public static <T> boolean remove(androidx.collection.LongSparseArray<T>, long key, T value);
+    method public static inline operator <T> void set(androidx.collection.LongSparseArray<T>, long key, T value);
     method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.LongSparseArray<T>);
   }
 
@@ -166,69 +166,69 @@
     ctor public SimpleArrayMap();
     ctor public SimpleArrayMap(androidx.collection.SimpleArrayMap<? extends K,? extends V>? map);
     method public void clear();
-    method public boolean containsKey(K? key);
-    method public boolean containsValue(V? value);
+    method public boolean containsKey(K key);
+    method public boolean containsValue(V value);
     method public void ensureCapacity(int minimumCapacity);
-    method public operator V? get(K? key);
-    method public V! getOrDefault(Object? key, V? defaultValue);
-    method public int indexOfKey(K? key);
+    method public operator V? get(K key);
+    method public V getOrDefault(Object? key, V defaultValue);
+    method public int indexOfKey(K key);
     method public boolean isEmpty();
-    method public K! keyAt(int index);
-    method public V? put(K? key, V? value);
+    method public K keyAt(int index);
+    method public V? put(K key, V value);
     method public void putAll(androidx.collection.SimpleArrayMap<? extends K,? extends V> map);
-    method public V? putIfAbsent(K? key, V? value);
-    method public V? remove(K? key);
-    method public boolean remove(K? key, V? value);
-    method public V! removeAt(int index);
-    method public V? replace(K? key, V? value);
-    method public boolean replace(K? key, V? oldValue, V? newValue);
-    method public V! setValueAt(int index, V? value);
+    method public V? putIfAbsent(K key, V value);
+    method public V? remove(K key);
+    method public boolean remove(K key, V value);
+    method public V removeAt(int index);
+    method public V? replace(K key, V value);
+    method public boolean replace(K key, V oldValue, V newValue);
+    method public V setValueAt(int index, V value);
     method public int size();
-    method public V! valueAt(int index);
+    method public V valueAt(int index);
   }
 
   public class SparseArrayCompat<E> implements java.lang.Cloneable {
     ctor public SparseArrayCompat(optional int initialCapacity);
     ctor public SparseArrayCompat();
-    method public void append(int key, E? value);
+    method public void append(int key, E value);
     method public void clear();
     method public androidx.collection.SparseArrayCompat<E> clone();
     method public boolean containsKey(int key);
-    method public boolean containsValue(E? value);
+    method public boolean containsValue(E value);
     method @Deprecated public void delete(int key);
     method public operator E? get(int key);
-    method public E! get(int key, E? defaultValue);
+    method public E get(int key, E defaultValue);
     method public final boolean getIsEmpty();
     method public int indexOfKey(int key);
-    method public int indexOfValue(E? value);
+    method public int indexOfValue(E value);
     method public boolean isEmpty();
     method public int keyAt(int index);
-    method public void put(int key, E? value);
+    method public void put(int key, E value);
     method public void putAll(androidx.collection.SparseArrayCompat<? extends E> other);
-    method public E? putIfAbsent(int key, E? value);
+    method public E? putIfAbsent(int key, E value);
     method public void remove(int key);
     method public boolean remove(int key, Object? value);
     method public void removeAt(int index);
     method public void removeAtRange(int index, int size);
-    method public E? replace(int key, E? value);
-    method public boolean replace(int key, E? oldValue, E? newValue);
-    method public void setValueAt(int index, E? value);
+    method public E? replace(int key, E value);
+    method public boolean replace(int key, E oldValue, E newValue);
+    method public void setValueAt(int index, E value);
     method public int size();
-    method public E! valueAt(int index);
+    method public E valueAt(int index);
     property public final boolean isEmpty;
   }
 
   public final class SparseArrayKt {
     method public static inline operator <T> boolean contains(androidx.collection.SparseArrayCompat<T>, int key);
     method public static inline <T> void forEach(androidx.collection.SparseArrayCompat<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
-    method public static inline <T> T! getOrDefault(androidx.collection.SparseArrayCompat<T>, int key, T? defaultValue);
-    method public static inline <T> T! getOrElse(androidx.collection.SparseArrayCompat<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public static inline <T> T getOrDefault(androidx.collection.SparseArrayCompat<T>, int key, T defaultValue);
+    method public static inline <T> T getOrElse(androidx.collection.SparseArrayCompat<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public static inline <T> int getSize(androidx.collection.SparseArrayCompat<T>);
     method public static inline <T> boolean isNotEmpty(androidx.collection.SparseArrayCompat<T>);
     method public static <T> kotlin.collections.IntIterator keyIterator(androidx.collection.SparseArrayCompat<T>);
     method public static operator <T> androidx.collection.SparseArrayCompat<T> plus(androidx.collection.SparseArrayCompat<T>, androidx.collection.SparseArrayCompat<T> other);
-    method @Deprecated public static <T> boolean remove(androidx.collection.SparseArrayCompat<T>, int key, T? value);
-    method public static inline operator <T> void set(androidx.collection.SparseArrayCompat<T>, int key, T? value);
+    method @Deprecated public static <T> boolean remove(androidx.collection.SparseArrayCompat<T>, int key, T value);
+    method public static inline operator <T> void set(androidx.collection.SparseArrayCompat<T>, int key, T value);
     method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.SparseArrayCompat<T>);
   }
 
diff --git a/collection/collection/api/public_plus_experimental_current.txt b/collection/collection/api/public_plus_experimental_current.txt
index 19c0d55..3fbf783 100644
--- a/collection/collection/api/public_plus_experimental_current.txt
+++ b/collection/collection/api/public_plus_experimental_current.txt
@@ -29,25 +29,25 @@
     ctor public ArraySet(androidx.collection.ArraySet<? extends E>? set);
     ctor public ArraySet(java.util.Collection<? extends E>? set);
     ctor public ArraySet(E![]? array);
-    method public boolean add(E? element);
+    method public boolean add(E element);
     method public void addAll(androidx.collection.ArraySet<? extends E> array);
     method public boolean addAll(java.util.Collection<? extends E> elements);
     method public void clear();
-    method public operator boolean contains(E? element);
+    method public operator boolean contains(E element);
     method public boolean containsAll(java.util.Collection<E!> elements);
     method public void ensureCapacity(int minimumCapacity);
     method public int getSize();
     method public int indexOf(Object? key);
     method public boolean isEmpty();
     method public java.util.Iterator<E> iterator();
-    method public boolean remove(E? element);
+    method public boolean remove(E element);
     method public boolean removeAll(androidx.collection.ArraySet<? extends E> array);
     method public boolean removeAll(java.util.Collection<E!> elements);
-    method public E! removeAt(int index);
+    method public E removeAt(int index);
     method public boolean retainAll(java.util.Collection<E!> elements);
     method public Object![] toArray();
     method public <T> T![] toArray(T![] array);
-    method public E! valueAt(int index);
+    method public E valueAt(int index);
     property public int size;
   }
 
@@ -59,15 +59,15 @@
   public final class CircularArray<E> {
     ctor public CircularArray(optional int minCapacity);
     ctor public CircularArray();
-    method public void addFirst(E? element);
-    method public void addLast(E? element);
+    method public void addFirst(E element);
+    method public void addLast(E element);
     method public void clear();
-    method public operator E! get(int index);
+    method public operator E get(int index);
     method public E! getFirst();
     method public E! getLast();
     method public boolean isEmpty();
-    method public E! popFirst();
-    method public E! popLast();
+    method public E popFirst();
+    method public E popLast();
     method public void removeFromEnd(int count);
     method public void removeFromStart(int count);
     method public int size();
@@ -97,42 +97,42 @@
   public class LongSparseArray<E> implements java.lang.Cloneable {
     ctor public LongSparseArray(optional int initialCapacity);
     ctor public LongSparseArray();
-    method public void append(long key, E? value);
+    method public void append(long key, E value);
     method public void clear();
     method public androidx.collection.LongSparseArray<E> clone();
     method public boolean containsKey(long key);
-    method public boolean containsValue(E? value);
+    method public boolean containsValue(E value);
     method @Deprecated public void delete(long key);
     method public operator E? get(long key);
-    method public E! get(long key, E? defaultValue);
+    method public E get(long key, E defaultValue);
     method public int indexOfKey(long key);
-    method public int indexOfValue(E? value);
+    method public int indexOfValue(E value);
     method public boolean isEmpty();
     method public long keyAt(int index);
-    method public void put(long key, E? value);
+    method public void put(long key, E value);
     method public void putAll(androidx.collection.LongSparseArray<? extends E> other);
-    method public E? putIfAbsent(long key, E? value);
+    method public E? putIfAbsent(long key, E value);
     method public void remove(long key);
-    method public boolean remove(long key, E? value);
+    method public boolean remove(long key, E value);
     method public void removeAt(int index);
-    method public E? replace(long key, E? value);
-    method public boolean replace(long key, E? oldValue, E? newValue);
-    method public void setValueAt(int index, E? value);
+    method public E? replace(long key, E value);
+    method public boolean replace(long key, E oldValue, E newValue);
+    method public void setValueAt(int index, E value);
     method public int size();
-    method public E! valueAt(int index);
+    method public E valueAt(int index);
   }
 
   public final class LongSparseArrayKt {
     method public static inline operator <T> boolean contains(androidx.collection.LongSparseArray<T>, long key);
     method public static inline <T> void forEach(androidx.collection.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
-    method public static inline <T> T! getOrDefault(androidx.collection.LongSparseArray<T>, long key, T? defaultValue);
-    method public static inline <T> T! getOrElse(androidx.collection.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public static inline <T> T getOrDefault(androidx.collection.LongSparseArray<T>, long key, T defaultValue);
+    method public static inline <T> T getOrElse(androidx.collection.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public static inline <T> int getSize(androidx.collection.LongSparseArray<T>);
     method public static inline <T> boolean isNotEmpty(androidx.collection.LongSparseArray<T>);
     method public static <T> kotlin.collections.LongIterator keyIterator(androidx.collection.LongSparseArray<T>);
     method public static operator <T> androidx.collection.LongSparseArray<T> plus(androidx.collection.LongSparseArray<T>, androidx.collection.LongSparseArray<T> other);
-    method @Deprecated public static <T> boolean remove(androidx.collection.LongSparseArray<T>, long key, T? value);
-    method public static inline operator <T> void set(androidx.collection.LongSparseArray<T>, long key, T? value);
+    method @Deprecated public static <T> boolean remove(androidx.collection.LongSparseArray<T>, long key, T value);
+    method public static inline operator <T> void set(androidx.collection.LongSparseArray<T>, long key, T value);
     method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.LongSparseArray<T>);
   }
 
@@ -166,69 +166,69 @@
     ctor public SimpleArrayMap();
     ctor public SimpleArrayMap(androidx.collection.SimpleArrayMap<? extends K,? extends V>? map);
     method public void clear();
-    method public boolean containsKey(K? key);
-    method public boolean containsValue(V? value);
+    method public boolean containsKey(K key);
+    method public boolean containsValue(V value);
     method public void ensureCapacity(int minimumCapacity);
-    method public operator V? get(K? key);
-    method public V! getOrDefault(Object? key, V? defaultValue);
-    method public int indexOfKey(K? key);
+    method public operator V? get(K key);
+    method public V getOrDefault(Object? key, V defaultValue);
+    method public int indexOfKey(K key);
     method public boolean isEmpty();
-    method public K! keyAt(int index);
-    method public V? put(K? key, V? value);
+    method public K keyAt(int index);
+    method public V? put(K key, V value);
     method public void putAll(androidx.collection.SimpleArrayMap<? extends K,? extends V> map);
-    method public V? putIfAbsent(K? key, V? value);
-    method public V? remove(K? key);
-    method public boolean remove(K? key, V? value);
-    method public V! removeAt(int index);
-    method public V? replace(K? key, V? value);
-    method public boolean replace(K? key, V? oldValue, V? newValue);
-    method public V! setValueAt(int index, V? value);
+    method public V? putIfAbsent(K key, V value);
+    method public V? remove(K key);
+    method public boolean remove(K key, V value);
+    method public V removeAt(int index);
+    method public V? replace(K key, V value);
+    method public boolean replace(K key, V oldValue, V newValue);
+    method public V setValueAt(int index, V value);
     method public int size();
-    method public V! valueAt(int index);
+    method public V valueAt(int index);
   }
 
   public class SparseArrayCompat<E> implements java.lang.Cloneable {
     ctor public SparseArrayCompat(optional int initialCapacity);
     ctor public SparseArrayCompat();
-    method public void append(int key, E? value);
+    method public void append(int key, E value);
     method public void clear();
     method public androidx.collection.SparseArrayCompat<E> clone();
     method public boolean containsKey(int key);
-    method public boolean containsValue(E? value);
+    method public boolean containsValue(E value);
     method @Deprecated public void delete(int key);
     method public operator E? get(int key);
-    method public E! get(int key, E? defaultValue);
+    method public E get(int key, E defaultValue);
     method public final boolean getIsEmpty();
     method public int indexOfKey(int key);
-    method public int indexOfValue(E? value);
+    method public int indexOfValue(E value);
     method public boolean isEmpty();
     method public int keyAt(int index);
-    method public void put(int key, E? value);
+    method public void put(int key, E value);
     method public void putAll(androidx.collection.SparseArrayCompat<? extends E> other);
-    method public E? putIfAbsent(int key, E? value);
+    method public E? putIfAbsent(int key, E value);
     method public void remove(int key);
     method public boolean remove(int key, Object? value);
     method public void removeAt(int index);
     method public void removeAtRange(int index, int size);
-    method public E? replace(int key, E? value);
-    method public boolean replace(int key, E? oldValue, E? newValue);
-    method public void setValueAt(int index, E? value);
+    method public E? replace(int key, E value);
+    method public boolean replace(int key, E oldValue, E newValue);
+    method public void setValueAt(int index, E value);
     method public int size();
-    method public E! valueAt(int index);
+    method public E valueAt(int index);
     property public final boolean isEmpty;
   }
 
   public final class SparseArrayKt {
     method public static inline operator <T> boolean contains(androidx.collection.SparseArrayCompat<T>, int key);
     method public static inline <T> void forEach(androidx.collection.SparseArrayCompat<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
-    method public static inline <T> T! getOrDefault(androidx.collection.SparseArrayCompat<T>, int key, T? defaultValue);
-    method public static inline <T> T! getOrElse(androidx.collection.SparseArrayCompat<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public static inline <T> T getOrDefault(androidx.collection.SparseArrayCompat<T>, int key, T defaultValue);
+    method public static inline <T> T getOrElse(androidx.collection.SparseArrayCompat<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public static inline <T> int getSize(androidx.collection.SparseArrayCompat<T>);
     method public static inline <T> boolean isNotEmpty(androidx.collection.SparseArrayCompat<T>);
     method public static <T> kotlin.collections.IntIterator keyIterator(androidx.collection.SparseArrayCompat<T>);
     method public static operator <T> androidx.collection.SparseArrayCompat<T> plus(androidx.collection.SparseArrayCompat<T>, androidx.collection.SparseArrayCompat<T> other);
-    method @Deprecated public static <T> boolean remove(androidx.collection.SparseArrayCompat<T>, int key, T? value);
-    method public static inline operator <T> void set(androidx.collection.SparseArrayCompat<T>, int key, T? value);
+    method @Deprecated public static <T> boolean remove(androidx.collection.SparseArrayCompat<T>, int key, T value);
+    method public static inline operator <T> void set(androidx.collection.SparseArrayCompat<T>, int key, T value);
     method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.SparseArrayCompat<T>);
   }
 
diff --git a/collection/collection/api/restricted_current.ignore b/collection/collection/api/restricted_current.ignore
index 6397290..7be6378 100644
--- a/collection/collection/api/restricted_current.ignore
+++ b/collection/collection/api/restricted_current.ignore
@@ -9,6 +9,18 @@
     Method androidx.collection.SparseArrayCompat.clone has changed return type from androidx.collection.SparseArrayCompat<E!> to androidx.collection.SparseArrayCompat<E>
 
 
+InvalidNullConversion: androidx.collection.ArraySet#add(E) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.collection.ArraySet.add(E element)
+InvalidNullConversion: androidx.collection.ArraySet#contains(E) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.collection.ArraySet.contains(E element)
+InvalidNullConversion: androidx.collection.ArraySet#remove(E) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.collection.ArraySet.remove(E element)
+InvalidNullConversion: androidx.collection.SimpleArrayMap#containsKey(K) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.collection.SimpleArrayMap.containsKey(K key)
+InvalidNullConversion: androidx.collection.SimpleArrayMap#indexOfKey(K) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.collection.SimpleArrayMap.indexOfKey(K key)
+
+
 RemovedMethod: androidx.collection.ArraySet#ArraySet(androidx.collection.ArraySet<E>):
     Removed constructor androidx.collection.ArraySet(androidx.collection.ArraySet<E>)
 RemovedMethod: androidx.collection.ArraySet#ArraySet(java.util.Collection<E>):
diff --git a/collection/collection/api/restricted_current.txt b/collection/collection/api/restricted_current.txt
index 19c0d55..3fbf783 100644
--- a/collection/collection/api/restricted_current.txt
+++ b/collection/collection/api/restricted_current.txt
@@ -29,25 +29,25 @@
     ctor public ArraySet(androidx.collection.ArraySet<? extends E>? set);
     ctor public ArraySet(java.util.Collection<? extends E>? set);
     ctor public ArraySet(E![]? array);
-    method public boolean add(E? element);
+    method public boolean add(E element);
     method public void addAll(androidx.collection.ArraySet<? extends E> array);
     method public boolean addAll(java.util.Collection<? extends E> elements);
     method public void clear();
-    method public operator boolean contains(E? element);
+    method public operator boolean contains(E element);
     method public boolean containsAll(java.util.Collection<E!> elements);
     method public void ensureCapacity(int minimumCapacity);
     method public int getSize();
     method public int indexOf(Object? key);
     method public boolean isEmpty();
     method public java.util.Iterator<E> iterator();
-    method public boolean remove(E? element);
+    method public boolean remove(E element);
     method public boolean removeAll(androidx.collection.ArraySet<? extends E> array);
     method public boolean removeAll(java.util.Collection<E!> elements);
-    method public E! removeAt(int index);
+    method public E removeAt(int index);
     method public boolean retainAll(java.util.Collection<E!> elements);
     method public Object![] toArray();
     method public <T> T![] toArray(T![] array);
-    method public E! valueAt(int index);
+    method public E valueAt(int index);
     property public int size;
   }
 
@@ -59,15 +59,15 @@
   public final class CircularArray<E> {
     ctor public CircularArray(optional int minCapacity);
     ctor public CircularArray();
-    method public void addFirst(E? element);
-    method public void addLast(E? element);
+    method public void addFirst(E element);
+    method public void addLast(E element);
     method public void clear();
-    method public operator E! get(int index);
+    method public operator E get(int index);
     method public E! getFirst();
     method public E! getLast();
     method public boolean isEmpty();
-    method public E! popFirst();
-    method public E! popLast();
+    method public E popFirst();
+    method public E popLast();
     method public void removeFromEnd(int count);
     method public void removeFromStart(int count);
     method public int size();
@@ -97,42 +97,42 @@
   public class LongSparseArray<E> implements java.lang.Cloneable {
     ctor public LongSparseArray(optional int initialCapacity);
     ctor public LongSparseArray();
-    method public void append(long key, E? value);
+    method public void append(long key, E value);
     method public void clear();
     method public androidx.collection.LongSparseArray<E> clone();
     method public boolean containsKey(long key);
-    method public boolean containsValue(E? value);
+    method public boolean containsValue(E value);
     method @Deprecated public void delete(long key);
     method public operator E? get(long key);
-    method public E! get(long key, E? defaultValue);
+    method public E get(long key, E defaultValue);
     method public int indexOfKey(long key);
-    method public int indexOfValue(E? value);
+    method public int indexOfValue(E value);
     method public boolean isEmpty();
     method public long keyAt(int index);
-    method public void put(long key, E? value);
+    method public void put(long key, E value);
     method public void putAll(androidx.collection.LongSparseArray<? extends E> other);
-    method public E? putIfAbsent(long key, E? value);
+    method public E? putIfAbsent(long key, E value);
     method public void remove(long key);
-    method public boolean remove(long key, E? value);
+    method public boolean remove(long key, E value);
     method public void removeAt(int index);
-    method public E? replace(long key, E? value);
-    method public boolean replace(long key, E? oldValue, E? newValue);
-    method public void setValueAt(int index, E? value);
+    method public E? replace(long key, E value);
+    method public boolean replace(long key, E oldValue, E newValue);
+    method public void setValueAt(int index, E value);
     method public int size();
-    method public E! valueAt(int index);
+    method public E valueAt(int index);
   }
 
   public final class LongSparseArrayKt {
     method public static inline operator <T> boolean contains(androidx.collection.LongSparseArray<T>, long key);
     method public static inline <T> void forEach(androidx.collection.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
-    method public static inline <T> T! getOrDefault(androidx.collection.LongSparseArray<T>, long key, T? defaultValue);
-    method public static inline <T> T! getOrElse(androidx.collection.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public static inline <T> T getOrDefault(androidx.collection.LongSparseArray<T>, long key, T defaultValue);
+    method public static inline <T> T getOrElse(androidx.collection.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public static inline <T> int getSize(androidx.collection.LongSparseArray<T>);
     method public static inline <T> boolean isNotEmpty(androidx.collection.LongSparseArray<T>);
     method public static <T> kotlin.collections.LongIterator keyIterator(androidx.collection.LongSparseArray<T>);
     method public static operator <T> androidx.collection.LongSparseArray<T> plus(androidx.collection.LongSparseArray<T>, androidx.collection.LongSparseArray<T> other);
-    method @Deprecated public static <T> boolean remove(androidx.collection.LongSparseArray<T>, long key, T? value);
-    method public static inline operator <T> void set(androidx.collection.LongSparseArray<T>, long key, T? value);
+    method @Deprecated public static <T> boolean remove(androidx.collection.LongSparseArray<T>, long key, T value);
+    method public static inline operator <T> void set(androidx.collection.LongSparseArray<T>, long key, T value);
     method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.LongSparseArray<T>);
   }
 
@@ -166,69 +166,69 @@
     ctor public SimpleArrayMap();
     ctor public SimpleArrayMap(androidx.collection.SimpleArrayMap<? extends K,? extends V>? map);
     method public void clear();
-    method public boolean containsKey(K? key);
-    method public boolean containsValue(V? value);
+    method public boolean containsKey(K key);
+    method public boolean containsValue(V value);
     method public void ensureCapacity(int minimumCapacity);
-    method public operator V? get(K? key);
-    method public V! getOrDefault(Object? key, V? defaultValue);
-    method public int indexOfKey(K? key);
+    method public operator V? get(K key);
+    method public V getOrDefault(Object? key, V defaultValue);
+    method public int indexOfKey(K key);
     method public boolean isEmpty();
-    method public K! keyAt(int index);
-    method public V? put(K? key, V? value);
+    method public K keyAt(int index);
+    method public V? put(K key, V value);
     method public void putAll(androidx.collection.SimpleArrayMap<? extends K,? extends V> map);
-    method public V? putIfAbsent(K? key, V? value);
-    method public V? remove(K? key);
-    method public boolean remove(K? key, V? value);
-    method public V! removeAt(int index);
-    method public V? replace(K? key, V? value);
-    method public boolean replace(K? key, V? oldValue, V? newValue);
-    method public V! setValueAt(int index, V? value);
+    method public V? putIfAbsent(K key, V value);
+    method public V? remove(K key);
+    method public boolean remove(K key, V value);
+    method public V removeAt(int index);
+    method public V? replace(K key, V value);
+    method public boolean replace(K key, V oldValue, V newValue);
+    method public V setValueAt(int index, V value);
     method public int size();
-    method public V! valueAt(int index);
+    method public V valueAt(int index);
   }
 
   public class SparseArrayCompat<E> implements java.lang.Cloneable {
     ctor public SparseArrayCompat(optional int initialCapacity);
     ctor public SparseArrayCompat();
-    method public void append(int key, E? value);
+    method public void append(int key, E value);
     method public void clear();
     method public androidx.collection.SparseArrayCompat<E> clone();
     method public boolean containsKey(int key);
-    method public boolean containsValue(E? value);
+    method public boolean containsValue(E value);
     method @Deprecated public void delete(int key);
     method public operator E? get(int key);
-    method public E! get(int key, E? defaultValue);
+    method public E get(int key, E defaultValue);
     method public final boolean getIsEmpty();
     method public int indexOfKey(int key);
-    method public int indexOfValue(E? value);
+    method public int indexOfValue(E value);
     method public boolean isEmpty();
     method public int keyAt(int index);
-    method public void put(int key, E? value);
+    method public void put(int key, E value);
     method public void putAll(androidx.collection.SparseArrayCompat<? extends E> other);
-    method public E? putIfAbsent(int key, E? value);
+    method public E? putIfAbsent(int key, E value);
     method public void remove(int key);
     method public boolean remove(int key, Object? value);
     method public void removeAt(int index);
     method public void removeAtRange(int index, int size);
-    method public E? replace(int key, E? value);
-    method public boolean replace(int key, E? oldValue, E? newValue);
-    method public void setValueAt(int index, E? value);
+    method public E? replace(int key, E value);
+    method public boolean replace(int key, E oldValue, E newValue);
+    method public void setValueAt(int index, E value);
     method public int size();
-    method public E! valueAt(int index);
+    method public E valueAt(int index);
     property public final boolean isEmpty;
   }
 
   public final class SparseArrayKt {
     method public static inline operator <T> boolean contains(androidx.collection.SparseArrayCompat<T>, int key);
     method public static inline <T> void forEach(androidx.collection.SparseArrayCompat<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
-    method public static inline <T> T! getOrDefault(androidx.collection.SparseArrayCompat<T>, int key, T? defaultValue);
-    method public static inline <T> T! getOrElse(androidx.collection.SparseArrayCompat<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public static inline <T> T getOrDefault(androidx.collection.SparseArrayCompat<T>, int key, T defaultValue);
+    method public static inline <T> T getOrElse(androidx.collection.SparseArrayCompat<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public static inline <T> int getSize(androidx.collection.SparseArrayCompat<T>);
     method public static inline <T> boolean isNotEmpty(androidx.collection.SparseArrayCompat<T>);
     method public static <T> kotlin.collections.IntIterator keyIterator(androidx.collection.SparseArrayCompat<T>);
     method public static operator <T> androidx.collection.SparseArrayCompat<T> plus(androidx.collection.SparseArrayCompat<T>, androidx.collection.SparseArrayCompat<T> other);
-    method @Deprecated public static <T> boolean remove(androidx.collection.SparseArrayCompat<T>, int key, T? value);
-    method public static inline operator <T> void set(androidx.collection.SparseArrayCompat<T>, int key, T? value);
+    method @Deprecated public static <T> boolean remove(androidx.collection.SparseArrayCompat<T>, int key, T value);
+    method public static inline operator <T> void set(androidx.collection.SparseArrayCompat<T>, int key, T value);
     method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.SparseArrayCompat<T>);
   }
 
diff --git a/compose/animation/animation-core/api/current.ignore b/compose/animation/animation-core/api/current.ignore
new file mode 100644
index 0000000..b54a96a
--- /dev/null
+++ b/compose/animation/animation-core/api/current.ignore
@@ -0,0 +1,75 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.animation.core.Animatable#Animatable(T, androidx.compose.animation.core.TwoWayConverter<T,V>, T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T visibilityThreshold)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#Animatable(T, androidx.compose.animation.core.TwoWayConverter<T,V>, T, String) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T visibilityThreshold, String label)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#animateDecay(T, androidx.compose.animation.core.DecayAnimationSpec<T>, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.Animatable.animateDecay(T initialVelocity, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit> block, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>> arg4)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#animateTo(T, androidx.compose.animation.core.AnimationSpec<T>, T, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.Animatable.animateTo(T targetValue, androidx.compose.animation.core.AnimationSpec<T> animationSpec, T initialVelocity, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit> block, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>> arg5)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#animateTo(T, androidx.compose.animation.core.AnimationSpec<T>, T, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.Animatable.animateTo(T targetValue, androidx.compose.animation.core.AnimationSpec<T> animationSpec, T initialVelocity, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit> block, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>> arg5)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#snapTo(T, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.Animatable.snapTo(T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit> arg2)
+InvalidNullConversion: androidx.compose.animation.core.AnimateAsStateKt#animateValueAsState(T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.AnimationSpec<T>, T, String, kotlin.jvm.functions.Function1<? super T,kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.AnimateAsStateKt.animateValueAsState(T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.AnimationSpec<T> animationSpec, T visibilityThreshold, String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> finishedListener)
+InvalidNullConversion: androidx.compose.animation.core.AnimateAsStateKt#animateValueAsState(T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.AnimationSpec<T>, T, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.AnimateAsStateKt.animateValueAsState(T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.AnimationSpec<T> animationSpec, T visibilityThreshold, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> finishedListener)
+InvalidNullConversion: androidx.compose.animation.core.AnimationKt#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.AnimationKt.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.AnimationKt#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T) parameter #3:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.AnimationKt.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.AnimationKt#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T) parameter #4:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.AnimationKt.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.AnimationState#AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V>, T, V, long, long, boolean) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector, long lastFrameTimeNanos, long finishedTimeNanos, boolean isRunning)
+InvalidNullConversion: androidx.compose.animation.core.AnimationStateKt#AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, long, long, boolean) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.AnimationStateKt.AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity, long lastFrameTimeNanos, long finishedTimeNanos, boolean isRunning)
+InvalidNullConversion: androidx.compose.animation.core.AnimationStateKt#AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, long, long, boolean) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.AnimationStateKt.AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity, long lastFrameTimeNanos, long finishedTimeNanos, boolean isRunning)
+InvalidNullConversion: androidx.compose.animation.core.AnimationStateKt#copy(androidx.compose.animation.core.AnimationState<T,V>, T, V, long, long, boolean) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.animation.core.AnimationStateKt.copy(androidx.compose.animation.core.AnimationState<T,V> arg1, T value, V velocityVector, long lastFrameTimeNanos, long finishedTimeNanos, boolean isRunning)
+InvalidNullConversion: androidx.compose.animation.core.AnimationStateKt#createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.animation.core.AnimationStateKt.createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V> arg1, T value)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimation#DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimation#DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T) parameter #3:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimation#DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, V) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimation#DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, V) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimationSpecKt#calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.DecayAnimationSpecKt.calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T> arg1, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimationSpecKt#calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T) parameter #3:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.DecayAnimationSpecKt.calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T> arg1, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.InfiniteTransitionKt#animateValue(androidx.compose.animation.core.InfiniteTransition, T, T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.InfiniteRepeatableSpec<T>) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.InfiniteTransitionKt.animateValue(androidx.compose.animation.core.InfiniteTransition arg1, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec)
+InvalidNullConversion: androidx.compose.animation.core.InfiniteTransitionKt#animateValue(androidx.compose.animation.core.InfiniteTransition, T, T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.InfiniteRepeatableSpec<T>) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.InfiniteTransitionKt.animateValue(androidx.compose.animation.core.InfiniteTransition arg1, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec)
+InvalidNullConversion: androidx.compose.animation.core.InfiniteTransitionKt#animateValue(androidx.compose.animation.core.InfiniteTransition, T, T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.InfiniteRepeatableSpec<T>, String) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.InfiniteTransitionKt.animateValue(androidx.compose.animation.core.InfiniteTransition arg1, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec, String label)
+InvalidNullConversion: androidx.compose.animation.core.InfiniteTransitionKt#animateValue(androidx.compose.animation.core.InfiniteTransition, T, T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.InfiniteRepeatableSpec<T>, String) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.InfiniteTransitionKt.animateValue(androidx.compose.animation.core.InfiniteTransition arg1, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec, String label)
+InvalidNullConversion: androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig#at(T, int) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter arg1 in androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig.at(T arg1, int timeStamp)
+InvalidNullConversion: androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig#atFraction(T, float) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter arg1 in androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig.atFraction(T arg1, float fraction)
+InvalidNullConversion: androidx.compose.animation.core.MutableTransitionState#MutableTransitionState(S) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialState in androidx.compose.animation.core.MutableTransitionState(S initialState)
+InvalidNullConversion: androidx.compose.animation.core.SuspendAnimationKt#animate(androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T, androidx.compose.animation.core.AnimationSpec<T>, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit>, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.SuspendAnimationKt.animate(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity, androidx.compose.animation.core.AnimationSpec<T> animationSpec, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit> arg7)
+InvalidNullConversion: androidx.compose.animation.core.SuspendAnimationKt#animate(androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T, androidx.compose.animation.core.AnimationSpec<T>, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit>, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.SuspendAnimationKt.animate(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity, androidx.compose.animation.core.AnimationSpec<T> animationSpec, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit> arg7)
+InvalidNullConversion: androidx.compose.animation.core.SuspendAnimationKt#animateTo(androidx.compose.animation.core.AnimationState<T,V>, T, androidx.compose.animation.core.AnimationSpec<T>, boolean, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit>, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.SuspendAnimationKt.animateTo(androidx.compose.animation.core.AnimationState<T,V> arg1, T targetValue, androidx.compose.animation.core.AnimationSpec<T> animationSpec, boolean sequentialAnimation, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit> arg6)
+InvalidNullConversion: androidx.compose.animation.core.TargetBasedAnimation#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, V) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, V initialVelocityVector)
+InvalidNullConversion: androidx.compose.animation.core.TargetBasedAnimation#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, V) parameter #3:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, V initialVelocityVector)
+InvalidNullConversion: androidx.compose.animation.core.Transition.Segment#isTransitioningTo(S, S) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter arg1 in androidx.compose.animation.core.Transition.Segment.isTransitioningTo(S arg1, S targetState)
+InvalidNullConversion: androidx.compose.animation.core.Transition.Segment#isTransitioningTo(S, S) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.core.Transition.Segment.isTransitioningTo(S arg1, S targetState)
+InvalidNullConversion: androidx.compose.animation.core.TransitionKt#updateTransition(T, String) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.core.TransitionKt.updateTransition(T targetState, String label)
diff --git a/compose/animation/animation-core/api/current.txt b/compose/animation/animation-core/api/current.txt
index dca6624..ac05bf2 100644
--- a/compose/animation/animation-core/api/current.txt
+++ b/compose/animation/animation-core/api/current.txt
@@ -2,27 +2,27 @@
 package androidx.compose.animation.core {
 
   public final class Animatable<T, V extends androidx.compose.animation.core.AnimationVector> {
-    ctor public Animatable(T? initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold, optional String label);
-    ctor @Deprecated public Animatable(T? initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold);
-    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>>);
+    ctor public Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold, optional String label);
+    ctor @Deprecated public Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold);
+    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 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? 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 T targetValue;
     property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
     property public final T? upperBound;
     property public final T! value;
@@ -51,21 +51,21 @@
     method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<? extends 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,? extends 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<? extends 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,? extends 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<? extends 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,? extends 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<? extends 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,? extends 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 T getTargetValue();
     method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
-    method public T! getValueFromNanos(long playTimeNanos);
+    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 T targetValue;
     property public abstract androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
   }
 
@@ -84,8 +84,8 @@
 
   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);
+    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> {
@@ -101,9 +101,9 @@
     method public long getFinishedTimeNanos();
     method public long getLastFrameTimeNanos();
     method public long getStartTimeNanos();
-    method public T! getTargetValue();
+    method public T getTargetValue();
     method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
-    method public T! getValue();
+    method public T getValue();
     method public T! getVelocity();
     method public V getVelocityVector();
     method public boolean isRunning();
@@ -112,9 +112,9 @@
     property public final boolean isRunning;
     property public final long lastFrameTimeNanos;
     property public final long startTimeNanos;
-    property public final T! targetValue;
+    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 value;
     property public final T! velocity;
     property public final V velocityVector;
   }
@@ -135,11 +135,11 @@
   }
 
   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);
+    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 getValue();
     method public T! getVelocity();
     method public V getVelocityVector();
     method public boolean isRunning();
@@ -147,17 +147,17 @@
     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 T value;
     property public final T! velocity;
     property public final V velocityVector;
   }
 
   public final class AnimationStateKt {
     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 <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 <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> 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 <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 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> V createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V>, T? value);
+    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<?,?>);
   }
 
@@ -213,22 +213,22 @@
   }
 
   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.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, V initialVelocityVector);
-    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.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? initialVelocity);
+    ctor public DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector);
+    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.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity);
     method public long getDurationNanos();
-    method public T! getInitialValue();
+    method public T getInitialValue();
     method public V getInitialVelocityVector();
-    method public T! getTargetValue();
+    method public T getTargetValue();
     method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
-    method public T! getValueFromNanos(long playTimeNanos);
+    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 T initialValue;
     property public final V initialVelocityVector;
     property public boolean isInfinite;
-    property public T! targetValue;
+    property public T targetValue;
     property public androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
   }
 
@@ -237,7 +237,7 @@
   }
 
   public final class DecayAnimationSpecKt {
-    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, 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 float calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>, float initialValue, float 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);
@@ -415,19 +415,19 @@
     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();
+    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;
+    property public T value;
   }
 
   public final class InfiniteTransitionKt {
     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 androidx.compose.runtime.State<? extends 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 <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 <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends 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 <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends 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 androidx.compose.animation.core.InfiniteTransition rememberInfiniteTransition(optional String label);
     method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.animation.core.InfiniteTransition rememberInfiniteTransition();
   }
@@ -444,8 +444,8 @@
 
   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 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);
@@ -456,14 +456,14 @@
   }
 
   public final class MutableTransitionState<S> {
-    ctor public MutableTransitionState(S? initialState);
-    method public S! getCurrentState();
-    method public S! getTargetState();
+    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 S currentState;
     property public final boolean isIdle;
-    property public final S! targetState;
+    property public final S targetState;
   }
 
   public enum RepeatMode {
@@ -543,25 +543,25 @@
 
   public final class SuspendAnimationKt {
     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? 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 <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? 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? 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 <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>);
+    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);
+    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 T getInitialValue();
+    method public T getTargetValue();
     method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
-    method public T! getValueFromNanos(long playTimeNanos);
+    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 T initialValue;
     property public boolean isInfinite;
-    property public T! targetValue;
+    property public T targetValue;
     property public androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
   }
 
@@ -570,7 +570,7 @@
     method public S! getCurrentState();
     method public String? getLabel();
     method public androidx.compose.animation.core.Transition.Segment<S> getSegment();
-    method public S! getTargetState();
+    method public S getTargetState();
     method public long getTotalDurationNanos();
     method public java.util.List<androidx.compose.animation.core.Transition<?>> getTransitions();
     method public boolean isRunning();
@@ -579,17 +579,17 @@
     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 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;
+    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> {
@@ -597,12 +597,12 @@
     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();
+    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;
+    property public T value;
   }
 
   public final class TransitionKt {
@@ -615,7 +615,7 @@
     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.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(T? targetState, optional String? label);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(T targetState, optional 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/api/public_plus_experimental_current.txt b/compose/animation/animation-core/api/public_plus_experimental_current.txt
index 2084af1..03897cb 100644
--- a/compose/animation/animation-core/api/public_plus_experimental_current.txt
+++ b/compose/animation/animation-core/api/public_plus_experimental_current.txt
@@ -2,27 +2,27 @@
 package androidx.compose.animation.core {
 
   public final class Animatable<T, V extends androidx.compose.animation.core.AnimationVector> {
-    ctor public Animatable(T? initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold, optional String label);
-    ctor @Deprecated public Animatable(T? initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold);
-    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>>);
+    ctor public Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold, optional String label);
+    ctor @Deprecated public Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold);
+    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 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? 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 T targetValue;
     property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
     property public final T? upperBound;
     property public final T! value;
@@ -51,21 +51,21 @@
     method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<? extends 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,? extends 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<? extends 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,? extends 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<? extends 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,? extends 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<? extends 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,? extends 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 T getTargetValue();
     method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
-    method public T! getValueFromNanos(long playTimeNanos);
+    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 T targetValue;
     property public abstract androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
   }
 
@@ -84,8 +84,8 @@
 
   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);
+    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> {
@@ -101,9 +101,9 @@
     method public long getFinishedTimeNanos();
     method public long getLastFrameTimeNanos();
     method public long getStartTimeNanos();
-    method public T! getTargetValue();
+    method public T getTargetValue();
     method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
-    method public T! getValue();
+    method public T getValue();
     method public T! getVelocity();
     method public V getVelocityVector();
     method public boolean isRunning();
@@ -112,9 +112,9 @@
     property public final boolean isRunning;
     property public final long lastFrameTimeNanos;
     property public final long startTimeNanos;
-    property public final T! targetValue;
+    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 value;
     property public final T! velocity;
     property public final V velocityVector;
   }
@@ -135,11 +135,11 @@
   }
 
   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);
+    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 getValue();
     method public T! getVelocity();
     method public V getVelocityVector();
     method public boolean isRunning();
@@ -147,17 +147,17 @@
     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 T value;
     property public final T! velocity;
     property public final V velocityVector;
   }
 
   public final class AnimationStateKt {
     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 <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 <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> 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 <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 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> V createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V>, T? value);
+    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<?,?>);
   }
 
@@ -213,22 +213,22 @@
   }
 
   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.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, V initialVelocityVector);
-    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.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? initialVelocity);
+    ctor public DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector);
+    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.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity);
     method public long getDurationNanos();
-    method public T! getInitialValue();
+    method public T getInitialValue();
     method public V getInitialVelocityVector();
-    method public T! getTargetValue();
+    method public T getTargetValue();
     method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
-    method public T! getValueFromNanos(long playTimeNanos);
+    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 T initialValue;
     property public final V initialVelocityVector;
     property public boolean isInfinite;
-    property public T! targetValue;
+    property public T targetValue;
     property public androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
   }
 
@@ -237,7 +237,7 @@
   }
 
   public final class DecayAnimationSpecKt {
-    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, 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 float calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>, float initialValue, float 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);
@@ -418,19 +418,19 @@
     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();
+    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;
+    property public T value;
   }
 
   public final class InfiniteTransitionKt {
     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 androidx.compose.runtime.State<? extends 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 <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 <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends 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 <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends 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 androidx.compose.animation.core.InfiniteTransition rememberInfiniteTransition(optional String label);
     method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.animation.core.InfiniteTransition rememberInfiniteTransition();
   }
@@ -450,8 +450,8 @@
 
   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 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);
@@ -462,14 +462,14 @@
   }
 
   public final class MutableTransitionState<S> {
-    ctor public MutableTransitionState(S? initialState);
-    method public S! getCurrentState();
-    method public S! getTargetState();
+    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 S currentState;
     property public final boolean isIdle;
-    property public final S! targetState;
+    property public final S targetState;
   }
 
   public enum RepeatMode {
@@ -549,25 +549,25 @@
 
   public final class SuspendAnimationKt {
     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? 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 <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? 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? 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 <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>);
+    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);
+    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 T getInitialValue();
+    method public T getTargetValue();
     method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
-    method public T! getValueFromNanos(long playTimeNanos);
+    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 T initialValue;
     property public boolean isInfinite;
-    property public T! targetValue;
+    property public T targetValue;
     property public androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
   }
 
@@ -576,7 +576,7 @@
     method public S! getCurrentState();
     method public String? getLabel();
     method public androidx.compose.animation.core.Transition.Segment<S> getSegment();
-    method public S! getTargetState();
+    method public S getTargetState();
     method public long getTotalDurationNanos();
     method public java.util.List<androidx.compose.animation.core.Transition<?>> getTransitions();
     method public boolean isRunning();
@@ -585,17 +585,17 @@
     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 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;
+    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> {
@@ -603,12 +603,12 @@
     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();
+    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;
+    property public T value;
   }
 
   public final class TransitionKt {
@@ -622,7 +622,7 @@
     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(T? targetState, optional String? label);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(T targetState, optional 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/api/restricted_current.ignore b/compose/animation/animation-core/api/restricted_current.ignore
new file mode 100644
index 0000000..5e16b5b
--- /dev/null
+++ b/compose/animation/animation-core/api/restricted_current.ignore
@@ -0,0 +1,83 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.animation.core.Animatable#Animatable(T, androidx.compose.animation.core.TwoWayConverter<T,V>, T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T visibilityThreshold)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#Animatable(T, androidx.compose.animation.core.TwoWayConverter<T,V>, T, String) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T visibilityThreshold, String label)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#animateDecay(T, androidx.compose.animation.core.DecayAnimationSpec<T>, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.Animatable.animateDecay(T initialVelocity, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit> block, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>> arg4)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#animateTo(T, androidx.compose.animation.core.AnimationSpec<T>, T, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.Animatable.animateTo(T targetValue, androidx.compose.animation.core.AnimationSpec<T> animationSpec, T initialVelocity, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit> block, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>> arg5)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#animateTo(T, androidx.compose.animation.core.AnimationSpec<T>, T, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.Animatable.animateTo(T targetValue, androidx.compose.animation.core.AnimationSpec<T> animationSpec, T initialVelocity, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit> block, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>> arg5)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#snapTo(T, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.Animatable.snapTo(T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit> arg2)
+InvalidNullConversion: androidx.compose.animation.core.AnimateAsStateKt#animateValueAsState(T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.AnimationSpec<T>, T, String, kotlin.jvm.functions.Function1<? super T,kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.AnimateAsStateKt.animateValueAsState(T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.AnimationSpec<T> animationSpec, T visibilityThreshold, String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> finishedListener)
+InvalidNullConversion: androidx.compose.animation.core.AnimateAsStateKt#animateValueAsState(T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.AnimationSpec<T>, T, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.AnimateAsStateKt.animateValueAsState(T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.AnimationSpec<T> animationSpec, T visibilityThreshold, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> finishedListener)
+InvalidNullConversion: androidx.compose.animation.core.AnimationKt#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.AnimationKt.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.AnimationKt#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T) parameter #3:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.AnimationKt.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.AnimationKt#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T) parameter #4:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.AnimationKt.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.AnimationState#AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V>, T, V, long, long, boolean) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector, long lastFrameTimeNanos, long finishedTimeNanos, boolean isRunning)
+InvalidNullConversion: androidx.compose.animation.core.AnimationStateKt#AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, long, long, boolean) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.AnimationStateKt.AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity, long lastFrameTimeNanos, long finishedTimeNanos, boolean isRunning)
+InvalidNullConversion: androidx.compose.animation.core.AnimationStateKt#AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, long, long, boolean) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.AnimationStateKt.AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity, long lastFrameTimeNanos, long finishedTimeNanos, boolean isRunning)
+InvalidNullConversion: androidx.compose.animation.core.AnimationStateKt#copy(androidx.compose.animation.core.AnimationState<T,V>, T, V, long, long, boolean) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.animation.core.AnimationStateKt.copy(androidx.compose.animation.core.AnimationState<T,V> arg1, T value, V velocityVector, long lastFrameTimeNanos, long finishedTimeNanos, boolean isRunning)
+InvalidNullConversion: androidx.compose.animation.core.AnimationStateKt#createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.animation.core.AnimationStateKt.createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V> arg1, T value)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimation#DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimation#DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T) parameter #3:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimation#DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, V) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimation#DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, V) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimationSpecKt#calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.DecayAnimationSpecKt.calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T> arg1, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimationSpecKt#calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T) parameter #3:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.DecayAnimationSpecKt.calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T> arg1, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.InfiniteTransitionKt#animateValue(androidx.compose.animation.core.InfiniteTransition, T, T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.InfiniteRepeatableSpec<T>) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.InfiniteTransitionKt.animateValue(androidx.compose.animation.core.InfiniteTransition arg1, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec)
+InvalidNullConversion: androidx.compose.animation.core.InfiniteTransitionKt#animateValue(androidx.compose.animation.core.InfiniteTransition, T, T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.InfiniteRepeatableSpec<T>) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.InfiniteTransitionKt.animateValue(androidx.compose.animation.core.InfiniteTransition arg1, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec)
+InvalidNullConversion: androidx.compose.animation.core.InfiniteTransitionKt#animateValue(androidx.compose.animation.core.InfiniteTransition, T, T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.InfiniteRepeatableSpec<T>, String) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.InfiniteTransitionKt.animateValue(androidx.compose.animation.core.InfiniteTransition arg1, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec, String label)
+InvalidNullConversion: androidx.compose.animation.core.InfiniteTransitionKt#animateValue(androidx.compose.animation.core.InfiniteTransition, T, T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.InfiniteRepeatableSpec<T>, String) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.InfiniteTransitionKt.animateValue(androidx.compose.animation.core.InfiniteTransition arg1, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec, String label)
+InvalidNullConversion: androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig#at(T, int) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter arg1 in androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig.at(T arg1, int timeStamp)
+InvalidNullConversion: androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig#atFraction(T, float) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter arg1 in androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig.atFraction(T arg1, float fraction)
+InvalidNullConversion: androidx.compose.animation.core.MutableTransitionState#MutableTransitionState(S) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialState in androidx.compose.animation.core.MutableTransitionState(S initialState)
+InvalidNullConversion: androidx.compose.animation.core.SuspendAnimationKt#animate(androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T, androidx.compose.animation.core.AnimationSpec<T>, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit>, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.SuspendAnimationKt.animate(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity, androidx.compose.animation.core.AnimationSpec<T> animationSpec, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit> arg7)
+InvalidNullConversion: androidx.compose.animation.core.SuspendAnimationKt#animate(androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T, androidx.compose.animation.core.AnimationSpec<T>, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit>, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.SuspendAnimationKt.animate(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity, androidx.compose.animation.core.AnimationSpec<T> animationSpec, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit> arg7)
+InvalidNullConversion: androidx.compose.animation.core.SuspendAnimationKt#animateTo(androidx.compose.animation.core.AnimationState<T,V>, T, androidx.compose.animation.core.AnimationSpec<T>, boolean, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit>, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.SuspendAnimationKt.animateTo(androidx.compose.animation.core.AnimationState<T,V> arg1, T targetValue, androidx.compose.animation.core.AnimationSpec<T> animationSpec, boolean sequentialAnimation, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit> arg6)
+InvalidNullConversion: androidx.compose.animation.core.TargetBasedAnimation#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, V) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, V initialVelocityVector)
+InvalidNullConversion: androidx.compose.animation.core.TargetBasedAnimation#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, V) parameter #3:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, V initialVelocityVector)
+InvalidNullConversion: androidx.compose.animation.core.Transition.Segment#isTransitioningTo(S, S) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter arg1 in androidx.compose.animation.core.Transition.Segment.isTransitioningTo(S arg1, S targetState)
+InvalidNullConversion: androidx.compose.animation.core.Transition.Segment#isTransitioningTo(S, S) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.core.Transition.Segment.isTransitioningTo(S arg1, S targetState)
+InvalidNullConversion: androidx.compose.animation.core.TransitionKt#createChildTransitionInternal(androidx.compose.animation.core.Transition<S>, T, T, String) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialState in androidx.compose.animation.core.TransitionKt.createChildTransitionInternal(androidx.compose.animation.core.Transition<S> arg1, T initialState, T targetState, String childLabel)
+InvalidNullConversion: androidx.compose.animation.core.TransitionKt#createChildTransitionInternal(androidx.compose.animation.core.Transition<S>, T, T, String) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.core.TransitionKt.createChildTransitionInternal(androidx.compose.animation.core.Transition<S> arg1, T initialState, T targetState, String childLabel)
+InvalidNullConversion: androidx.compose.animation.core.TransitionKt#createTransitionAnimation(androidx.compose.animation.core.Transition<S>, T, T, androidx.compose.animation.core.FiniteAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, String) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.TransitionKt.createTransitionAnimation(androidx.compose.animation.core.Transition<S> arg1, T initialValue, T targetValue, androidx.compose.animation.core.FiniteAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, String label)
+InvalidNullConversion: androidx.compose.animation.core.TransitionKt#createTransitionAnimation(androidx.compose.animation.core.Transition<S>, T, T, androidx.compose.animation.core.FiniteAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, String) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.TransitionKt.createTransitionAnimation(androidx.compose.animation.core.Transition<S> arg1, T initialValue, T targetValue, androidx.compose.animation.core.FiniteAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, String label)
+InvalidNullConversion: androidx.compose.animation.core.TransitionKt#updateTransition(T, String) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.core.TransitionKt.updateTransition(T targetState, String label)
diff --git a/compose/animation/animation-core/api/restricted_current.txt b/compose/animation/animation-core/api/restricted_current.txt
index 47a6b51..fa302aa 100644
--- a/compose/animation/animation-core/api/restricted_current.txt
+++ b/compose/animation/animation-core/api/restricted_current.txt
@@ -2,27 +2,27 @@
 package androidx.compose.animation.core {
 
   public final class Animatable<T, V extends androidx.compose.animation.core.AnimationVector> {
-    ctor public Animatable(T? initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold, optional String label);
-    ctor @Deprecated public Animatable(T? initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold);
-    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>>);
+    ctor public Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold, optional String label);
+    ctor @Deprecated public Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold);
+    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 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? 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 T targetValue;
     property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
     property public final T? upperBound;
     property public final T! value;
@@ -51,21 +51,21 @@
     method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<? extends 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,? extends 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<? extends 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,? extends 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<? extends 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,? extends 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<? extends 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,? extends 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 T getTargetValue();
     method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
-    method public T! getValueFromNanos(long playTimeNanos);
+    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 T targetValue;
     property public abstract androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
   }
 
@@ -84,8 +84,8 @@
 
   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);
+    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> {
@@ -101,9 +101,9 @@
     method public long getFinishedTimeNanos();
     method public long getLastFrameTimeNanos();
     method public long getStartTimeNanos();
-    method public T! getTargetValue();
+    method public T getTargetValue();
     method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
-    method public T! getValue();
+    method public T getValue();
     method public T! getVelocity();
     method public V getVelocityVector();
     method public boolean isRunning();
@@ -112,9 +112,9 @@
     property public final boolean isRunning;
     property public final long lastFrameTimeNanos;
     property public final long startTimeNanos;
-    property public final T! targetValue;
+    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 value;
     property public final T! velocity;
     property public final V velocityVector;
   }
@@ -135,11 +135,11 @@
   }
 
   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);
+    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 getValue();
     method public T! getVelocity();
     method public V getVelocityVector();
     method public boolean isRunning();
@@ -147,17 +147,17 @@
     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 T value;
     property public final T! velocity;
     property public final V velocityVector;
   }
 
   public final class AnimationStateKt {
     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 <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 <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> 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 <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 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> V createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V>, T? value);
+    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<?,?>);
   }
 
@@ -213,22 +213,22 @@
   }
 
   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.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, V initialVelocityVector);
-    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.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? initialVelocity);
+    ctor public DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector);
+    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.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity);
     method public long getDurationNanos();
-    method public T! getInitialValue();
+    method public T getInitialValue();
     method public V getInitialVelocityVector();
-    method public T! getTargetValue();
+    method public T getTargetValue();
     method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
-    method public T! getValueFromNanos(long playTimeNanos);
+    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 T initialValue;
     property public final V initialVelocityVector;
     property public boolean isInfinite;
-    property public T! targetValue;
+    property public T targetValue;
     property public androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
   }
 
@@ -237,7 +237,7 @@
   }
 
   public final class DecayAnimationSpecKt {
-    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, 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 float calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>, float initialValue, float 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);
@@ -415,19 +415,19 @@
     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();
+    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;
+    property public T value;
   }
 
   public final class InfiniteTransitionKt {
     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 androidx.compose.runtime.State<? extends 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 <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 <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends 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 <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends 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 androidx.compose.animation.core.InfiniteTransition rememberInfiniteTransition(optional String label);
     method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.animation.core.InfiniteTransition rememberInfiniteTransition();
   }
@@ -444,8 +444,8 @@
 
   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 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);
@@ -456,14 +456,14 @@
   }
 
   public final class MutableTransitionState<S> {
-    ctor public MutableTransitionState(S? initialState);
-    method public S! getCurrentState();
-    method public S! getTargetState();
+    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 S currentState;
     property public final boolean isIdle;
-    property public final S! targetState;
+    property public final S targetState;
   }
 
   public enum RepeatMode {
@@ -543,25 +543,25 @@
 
   public final class SuspendAnimationKt {
     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? 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 <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? 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? 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 <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>);
+    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);
+    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 T getInitialValue();
+    method public T getTargetValue();
     method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
-    method public T! getValueFromNanos(long playTimeNanos);
+    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 T initialValue;
     property public boolean isInfinite;
-    property public T! targetValue;
+    property public T targetValue;
     property public androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
   }
 
@@ -571,7 +571,7 @@
     method public S! getCurrentState();
     method public String? getLabel();
     method public androidx.compose.animation.core.Transition.Segment<S> getSegment();
-    method public S! getTargetState();
+    method public S getTargetState();
     method public long getTotalDurationNanos();
     method public java.util.List<androidx.compose.animation.core.Transition<?>> getTransitions();
     method public boolean isRunning();
@@ -580,17 +580,17 @@
     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 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;
+    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> {
@@ -598,12 +598,12 @@
     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();
+    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;
+    property public T value;
   }
 
   public final class TransitionKt {
@@ -616,9 +616,9 @@
     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.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(T? targetState, optional String? label);
+    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(T targetState, optional 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/api/api_lint.ignore b/compose/animation/animation/api/api_lint.ignore
new file mode 100644
index 0000000..b6ae3c2
--- /dev/null
+++ b/compose/animation/animation/api/api_lint.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+GetterSetterNames: field SizeTransform.clip:
+    Invalid name for boolean property `clip`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/compose/animation/animation/api/current.ignore b/compose/animation/animation/api/current.ignore
index a02af1a..029cfad 100644
--- a/compose/animation/animation/api/current.ignore
+++ b/compose/animation/animation/api/current.ignore
@@ -1,3 +1,9 @@
 // Baseline format: 1.0
+InvalidNullConversion: androidx.compose.animation.CrossfadeKt#Crossfade(T, androidx.compose.ui.Modifier, androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float>, String, kotlin.jvm.functions.Function1<? super T,kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.CrossfadeKt.Crossfade(T targetState, androidx.compose.ui.Modifier modifier, androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content)
+InvalidNullConversion: androidx.compose.animation.CrossfadeKt#Crossfade(T, androidx.compose.ui.Modifier, androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float>, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.CrossfadeKt.Crossfade(T targetState, androidx.compose.ui.Modifier modifier, androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> content)
+
+
 RemovedDeprecatedMethod: androidx.compose.animation.SplineBasedFloatDecayAnimationSpec_androidKt#splineBasedDecayDeprecated(androidx.compose.ui.unit.Density):
     Removed deprecated method androidx.compose.animation.SplineBasedFloatDecayAnimationSpec_androidKt.splineBasedDecayDeprecated(androidx.compose.ui.unit.Density)
diff --git a/compose/animation/animation/api/current.txt b/compose/animation/animation/api/current.txt
index 21b8968..c0d2f31 100644
--- a/compose/animation/animation/api/current.txt
+++ b/compose/animation/animation/api/current.txt
@@ -6,7 +6,7 @@
   }
 
   public final class AnimatedContentKt {
-    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 @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 @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 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);
@@ -74,8 +74,8 @@
   }
 
   public final class CrossfadeKt {
-    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,? extends 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,? extends kotlin.Unit> content);
   }
 
   public final class EnterExitTransitionKt {
diff --git a/compose/animation/animation/api/public_plus_experimental_current.txt b/compose/animation/animation/api/public_plus_experimental_current.txt
index 3c78e83..37c2eb3 100644
--- a/compose/animation/animation/api/public_plus_experimental_current.txt
+++ b/compose/animation/animation/api/public_plus_experimental_current.txt
@@ -6,7 +6,7 @@
   }
 
   public final class AnimatedContentKt {
-    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 @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 @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 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);
@@ -80,9 +80,9 @@
   }
 
   public final class CrossfadeKt {
-    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 @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 @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 @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,? extends 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,? extends kotlin.Unit> content);
   }
 
   @androidx.compose.animation.ExperimentalAnimationApi public enum EnterExitState {
diff --git a/compose/animation/animation/api/restricted_current.ignore b/compose/animation/animation/api/restricted_current.ignore
index a02af1a..029cfad 100644
--- a/compose/animation/animation/api/restricted_current.ignore
+++ b/compose/animation/animation/api/restricted_current.ignore
@@ -1,3 +1,9 @@
 // Baseline format: 1.0
+InvalidNullConversion: androidx.compose.animation.CrossfadeKt#Crossfade(T, androidx.compose.ui.Modifier, androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float>, String, kotlin.jvm.functions.Function1<? super T,kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.CrossfadeKt.Crossfade(T targetState, androidx.compose.ui.Modifier modifier, androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content)
+InvalidNullConversion: androidx.compose.animation.CrossfadeKt#Crossfade(T, androidx.compose.ui.Modifier, androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float>, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.CrossfadeKt.Crossfade(T targetState, androidx.compose.ui.Modifier modifier, androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> content)
+
+
 RemovedDeprecatedMethod: androidx.compose.animation.SplineBasedFloatDecayAnimationSpec_androidKt#splineBasedDecayDeprecated(androidx.compose.ui.unit.Density):
     Removed deprecated method androidx.compose.animation.SplineBasedFloatDecayAnimationSpec_androidKt.splineBasedDecayDeprecated(androidx.compose.ui.unit.Density)
diff --git a/compose/animation/animation/api/restricted_current.txt b/compose/animation/animation/api/restricted_current.txt
index 21b8968..c0d2f31 100644
--- a/compose/animation/animation/api/restricted_current.txt
+++ b/compose/animation/animation/api/restricted_current.txt
@@ -6,7 +6,7 @@
   }
 
   public final class AnimatedContentKt {
-    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 @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 @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 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);
@@ -74,8 +74,8 @@
   }
 
   public final class CrossfadeKt {
-    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,? extends 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,? extends kotlin.Unit> content);
   }
 
   public final class EnterExitTransitionKt {
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithFlowRowDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithFlowRowDemo.kt
index a8c89ec..d3756c6 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithFlowRowDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithFlowRowDemo.kt
@@ -18,9 +18,10 @@
 
 import androidx.compose.animation.core.animateFloatAsState
 import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.ExperimentalLayoutApi
+import androidx.compose.foundation.layout.FlowRow
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
@@ -39,15 +40,10 @@
 import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.layout.LookaheadScope
-import androidx.compose.ui.layout.Placeable
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
-import kotlin.math.max
 
-@OptIn(ExperimentalComposeUiApi::class)
+@OptIn(ExperimentalComposeUiApi::class, ExperimentalLayoutApi::class)
 @Composable
 fun LookaheadWithFlowRowDemo() {
     Column(
@@ -67,7 +63,7 @@
         ) {
             Text("LookaheadScope + Modifier.animateBounds")
             LookaheadScope {
-                MyFlowRow(
+                FlowRow(
                     modifier = Modifier
                         .height(200.dp)
                         .fillMaxWidth()
@@ -110,7 +106,7 @@
                 .padding(10.dp)
         ) {
             Text("Animating Width")
-            MyFlowRow(
+            FlowRow(
                 modifier = Modifier
                     .height(200.dp)
                     .fillMaxWidth()
@@ -139,102 +135,6 @@
     }
 }
 
-@Composable
-internal fun MyFlowRow(
-    modifier: Modifier = Modifier,
-    mainAxisSpacing: Dp = 20.dp,
-    crossAxisSpacing: Dp = 20.dp,
-    content: @Composable () -> Unit
-) {
-    Layout(modifier = modifier, content = content) { measurables, constraints ->
-        val sequences = mutableListOf<List<Placeable>>()
-        val crossAxisSizes = mutableListOf<Int>()
-        val crossAxisPositions = mutableListOf<Int>()
-
-        var mainAxisSpace = 0
-        var crossAxisSpace = 0
-
-        val currentSequence = mutableListOf<Placeable>()
-        var currentMainAxisSize = 0
-        var currentCrossAxisSize = 0
-
-        // Return whether the placeable can be added to the current sequence.
-        fun canAddToCurrentSequence(placeable: Placeable) =
-            currentSequence.isEmpty() || currentMainAxisSize + mainAxisSpacing.roundToPx() +
-                placeable.width <= constraints.maxWidth
-
-        // Store current sequence information and start a new sequence.
-        fun startNewSequence() {
-            if (sequences.isNotEmpty()) {
-                crossAxisSpace += crossAxisSpacing.roundToPx()
-            }
-            sequences += currentSequence.toList()
-            crossAxisSizes += currentCrossAxisSize
-            crossAxisPositions += crossAxisSpace
-
-            crossAxisSpace += currentCrossAxisSize
-            mainAxisSpace = max(mainAxisSpace, currentMainAxisSize)
-
-            currentSequence.clear()
-            currentMainAxisSize = 0
-            currentCrossAxisSize = 0
-        }
-
-        for (measurable in measurables) {
-            // Ask the child for its preferred size.
-            val placeable = measurable.measure(constraints)
-
-            // Start a new sequence if there is not enough space.
-            if (!canAddToCurrentSequence(placeable)) startNewSequence()
-
-            // Add the child to the current sequence.
-            if (currentSequence.isNotEmpty()) {
-                currentMainAxisSize += mainAxisSpacing.roundToPx()
-            }
-            currentSequence.add(placeable)
-            currentMainAxisSize += placeable.width
-            currentCrossAxisSize = max(currentCrossAxisSize, placeable.height)
-        }
-
-        if (currentSequence.isNotEmpty()) startNewSequence()
-
-        val mainAxisLayoutSize = max(mainAxisSpace, constraints.minWidth)
-
-        val crossAxisLayoutSize = max(crossAxisSpace, constraints.minHeight)
-
-        val layoutWidth = mainAxisLayoutSize
-
-        val layoutHeight = crossAxisLayoutSize
-
-        layout(layoutWidth, layoutHeight) {
-            sequences.forEachIndexed { i, placeables ->
-                val childrenMainAxisSizes = IntArray(placeables.size) { j ->
-                    placeables[j].width +
-                        if (j < placeables.lastIndex) mainAxisSpacing.roundToPx() else 0
-                }
-                val arrangement = Arrangement.Start
-                // TODO(soboleva): rtl support
-                // Handle vertical direction
-                val mainAxisPositions = IntArray(childrenMainAxisSizes.size) { 0 }
-                with(arrangement) {
-                    arrange(
-                        mainAxisLayoutSize,
-                        childrenMainAxisSizes,
-                        LayoutDirection.Ltr,
-                        mainAxisPositions
-                    )
-                }
-                placeables.forEachIndexed { j, placeable ->
-                    placeable.place(
-                        x = mainAxisPositions[j],
-                        y = crossAxisPositions[i]
-                    )
-                }
-            }
-        }
-    }
-}
-
 private val colors = listOf(
     Color(0xffff6f69),
     Color(0xffffcc5c),
diff --git a/compose/foundation/foundation-layout/api/current.txt b/compose/foundation/foundation-layout/api/current.txt
index c8e0c04..4339957 100644
--- a/compose/foundation/foundation-layout/api/current.txt
+++ b/compose/foundation/foundation-layout/api/current.txt
@@ -111,6 +111,12 @@
     method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier weight(androidx.compose.ui.Modifier, float weight, optional boolean fill);
   }
 
+  @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable @kotlin.jvm.JvmDefaultWithCompatibility public interface FlowColumnScope extends androidx.compose.foundation.layout.ColumnScope {
+  }
+
+  @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable @kotlin.jvm.JvmDefaultWithCompatibility 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);
diff --git a/compose/foundation/foundation-layout/api/public_plus_experimental_current.txt b/compose/foundation/foundation-layout/api/public_plus_experimental_current.txt
index 57c57c0..3e7c323 100644
--- a/compose/foundation/foundation-layout/api/public_plus_experimental_current.txt
+++ b/compose/foundation/foundation-layout/api/public_plus_experimental_current.txt
@@ -114,9 +114,15 @@
   @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.LayoutScopeMarker @androidx.compose.runtime.Immutable @kotlin.jvm.JvmDefaultWithCompatibility 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.ColumnScope,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.RowScope,kotlin.Unit> content);
+    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.LayoutScopeMarker @androidx.compose.runtime.Immutable @kotlin.jvm.JvmDefaultWithCompatibility public interface FlowRowScope extends androidx.compose.foundation.layout.RowScope {
   }
 
   public final class IntrinsicKt {
diff --git a/compose/foundation/foundation-layout/api/restricted_current.txt b/compose/foundation/foundation-layout/api/restricted_current.txt
index 03cdfb3..2b75f19 100644
--- a/compose/foundation/foundation-layout/api/restricted_current.txt
+++ b/compose/foundation/foundation-layout/api/restricted_current.txt
@@ -114,11 +114,17 @@
     method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier weight(androidx.compose.ui.Modifier, float weight, optional boolean fill);
   }
 
+  @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable @kotlin.jvm.JvmDefaultWithCompatibility public interface FlowColumnScope extends androidx.compose.foundation.layout.ColumnScope {
+  }
+
   public final class FlowLayoutKt {
     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.LayoutScopeMarker @androidx.compose.runtime.Immutable @kotlin.jvm.JvmDefaultWithCompatibility 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);
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/FlowRowColumnTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/FlowRowColumnTest.kt
index 39c2067..8142e08 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/FlowRowColumnTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/FlowRowColumnTest.kt
@@ -2482,4 +2482,60 @@
         rule.waitForIdle()
         Truth.assertThat(height).isEqualTo(180)
     }
+
+    @Test
+    fun testFlowRow_constrainsOverflow() {
+        var width = 0
+        rule.setContent {
+            with(LocalDensity.current) {
+                Box(Modifier.size(200.toDp())) {
+                    FlowRow(
+                        Modifier
+                            .fillMaxWidth(1f)
+                            .onSizeChanged {
+                                width = it.width
+                            },
+                        verticalArrangement = Arrangement.spacedBy(20.toDp()),
+                    ) {
+                        repeat(2) {
+                            Box(
+                                Modifier
+                                    .size(250.toDp())
+                            )
+                        }
+                    }
+                }
+            }
+        }
+        rule.waitForIdle()
+        Truth.assertThat(width).isEqualTo(200)
+    }
+
+    @Test
+    fun testFlowColumn_constrainsOverflow() {
+        var height = 0
+        rule.setContent {
+            with(LocalDensity.current) {
+                Box(Modifier.size(200.toDp())) {
+                    FlowColumn(
+                        Modifier
+                            .fillMaxWidth(1f)
+                            .onSizeChanged {
+                                height = it.height
+                            },
+                        horizontalArrangement = Arrangement.spacedBy(20.toDp()),
+                    ) {
+                        repeat(2) {
+                            Box(
+                                Modifier
+                                    .size(250.toDp())
+                            )
+                        }
+                    }
+                }
+            }
+        }
+        rule.waitForIdle()
+        Truth.assertThat(height).isEqualTo(200)
+    }
 }
\ No newline at end of file
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 9ec9beb..5d58064 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
@@ -1,6 +1,7 @@
 package androidx.compose.foundation.layout
 
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.collection.MutableVector
 import androidx.compose.runtime.collection.mutableVectorOf
 import androidx.compose.runtime.remember
@@ -56,7 +57,7 @@
     horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
     verticalArrangement: Arrangement.Vertical = Arrangement.Top,
     maxItemsInEachRow: Int = Int.MAX_VALUE,
-    content: @Composable RowScope.() -> Unit
+    content: @Composable FlowRowScope.() -> Unit
 ) {
     val measurePolicy = rowMeasurementHelper(
         horizontalArrangement,
@@ -64,7 +65,7 @@
         maxItemsInEachRow
     )
     Layout(
-        content = { RowScopeInstance.content() },
+        content = { FlowRowScopeInstance.content() },
         measurePolicy = measurePolicy,
         modifier = modifier
     )
@@ -106,7 +107,7 @@
     verticalArrangement: Arrangement.Vertical = Arrangement.Top,
     horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
     maxItemsInEachColumn: Int = Int.MAX_VALUE,
-    content: @Composable ColumnScope.() -> Unit
+    content: @Composable FlowColumnScope.() -> Unit
 ) {
     val measurePolicy = columnMeasurementHelper(
         verticalArrangement,
@@ -114,12 +115,32 @@
         maxItemsInEachColumn
     )
     Layout(
-        content = { ColumnScopeInstance.content() },
+        content = { FlowColumnScopeInstance.content() },
         measurePolicy = measurePolicy,
         modifier = modifier
     )
 }
 
+/**
+ * Scope for the children of [FlowRow].
+ */
+@LayoutScopeMarker
+@Immutable
+@JvmDefaultWithCompatibility
+interface FlowRowScope : RowScope
+
+/**
+ * Scope for the children of [FlowColumn].
+ */
+@LayoutScopeMarker
+@Immutable
+@JvmDefaultWithCompatibility
+interface FlowColumnScope : ColumnScope
+
+internal object FlowRowScopeInstance : RowScope by RowScopeInstance, FlowRowScope
+
+internal object FlowColumnScopeInstance : ColumnScope by ColumnScopeInstance, FlowColumnScope
+
 private fun getVerticalArrangement(verticalArrangement: Arrangement.Vertical):
         (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit =
     { totalSize: Int, size: IntArray, _, density: Density, outPosition: IntArray ->
@@ -624,6 +645,7 @@
             leftOver - (nextSize ?: 0) < 0
         ) {
             mainAxisTotalSize = maxOf(mainAxisTotalSize, currentLineMainAxisSize)
+            mainAxisTotalSize = minOf(mainAxisTotalSize, mainAxisMax)
             currentLineMainAxisSize = 0
             leftOver = mainAxisMax
             startBreakLineIndex = index + 1
diff --git a/compose/foundation/foundation/api/api_lint.ignore b/compose/foundation/foundation/api/api_lint.ignore
new file mode 100644
index 0000000..0e31469
--- /dev/null
+++ b/compose/foundation/foundation/api/api_lint.ignore
@@ -0,0 +1,33 @@
+// Baseline format: 1.0
+GetterSetterNames: androidx.compose.foundation.ScrollState#getCanScrollBackward():
+    Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.ScrollState#getCanScrollForward():
+    Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.gestures.ScrollableState#getCanScrollBackward():
+    Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.gestures.ScrollableState#getCanScrollForward():
+    Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.lazy.LazyListState#getCanScrollBackward():
+    Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.lazy.LazyListState#getCanScrollForward():
+    Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.lazy.grid.LazyGridState#getCanScrollBackward():
+    Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.lazy.grid.LazyGridState#getCanScrollForward():
+    Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState#getCanScrollBackward():
+    Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState#getCanScrollForward():
+    Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.pager.PagerState#getCanScrollBackward():
+    Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.pager.PagerState#getCanScrollForward():
+    Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.text2.input.TextFieldBufferWithSelection#getHasSelection():
+    Getter for boolean property `hasSelection` is named `getHasSelection` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field KeyboardOptions.autoCorrect:
+    Invalid name for boolean property `autoCorrect`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field LazyGridLayoutInfo.reverseLayout:
+    Invalid name for boolean property `reverseLayout`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field LazyListLayoutInfo.reverseLayout:
+    Invalid name for boolean property `reverseLayout`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/compose/foundation/foundation/api/current.ignore b/compose/foundation/foundation/api/current.ignore
new file mode 100644
index 0000000..feba6f7
--- /dev/null
+++ b/compose/foundation/foundation/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.foundation.MutatorMutex#mutateWith(T, androidx.compose.foundation.MutatePriority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?>, kotlin.coroutines.Continuation<? super R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter receiver in androidx.compose.foundation.MutatorMutex.mutateWith(T receiver, androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R> arg4)
diff --git a/compose/foundation/foundation/api/current.txt b/compose/foundation/foundation/api/current.txt
index f5e2dc7..2a1b29f 100644
--- a/compose/foundation/foundation/api/current.txt
+++ b/compose/foundation/foundation/api/current.txt
@@ -91,7 +91,7 @@
   @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>);
+    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>);
   }
 
   public final class ProgressSemanticsKt {
diff --git a/compose/foundation/foundation/api/public_plus_experimental_current.txt b/compose/foundation/foundation/api/public_plus_experimental_current.txt
index fd47f6e..0ce3cfef 100644
--- a/compose/foundation/foundation/api/public_plus_experimental_current.txt
+++ b/compose/foundation/foundation/api/public_plus_experimental_current.txt
@@ -156,7 +156,7 @@
   @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>);
+    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 {
@@ -746,10 +746,10 @@
   public static final class IntervalList.Interval<T> {
     method public int getSize();
     method public int getStartIndex();
-    method public T! getValue();
+    method public T getValue();
     property public final int size;
     property public final int startIndex;
-    property public final T! value;
+    property public final T value;
   }
 
   @androidx.compose.foundation.ExperimentalFoundationApi public abstract class LazyLayoutIntervalContent<Interval extends androidx.compose.foundation.lazy.layout.LazyLayoutIntervalContent.Interval> {
@@ -832,7 +832,7 @@
 
   @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 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();
diff --git a/compose/foundation/foundation/api/restricted_current.ignore b/compose/foundation/foundation/api/restricted_current.ignore
new file mode 100644
index 0000000..feba6f7
--- /dev/null
+++ b/compose/foundation/foundation/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.foundation.MutatorMutex#mutateWith(T, androidx.compose.foundation.MutatePriority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?>, kotlin.coroutines.Continuation<? super R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter receiver in androidx.compose.foundation.MutatorMutex.mutateWith(T receiver, androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R> arg4)
diff --git a/compose/foundation/foundation/api/restricted_current.txt b/compose/foundation/foundation/api/restricted_current.txt
index f5e2dc7..2a1b29f 100644
--- a/compose/foundation/foundation/api/restricted_current.txt
+++ b/compose/foundation/foundation/api/restricted_current.txt
@@ -91,7 +91,7 @@
   @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>);
+    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>);
   }
 
   public final class ProgressSemanticsKt {
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 f4f50f1..b80442a 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
@@ -1068,7 +1068,7 @@
                 .weight(1f), reverseLayout = reverse) {
             items(items, key = { it }) { item ->
                 val selected = selectedIndexes.getOrDefault(item, false)
-                val modifier = if (selected) Modifier.animateItemPlacement() else Modifier
+                val modifier = Modifier.animateItemPlacement()
                 var height by remember { mutableStateOf(40.dp) }
                 Row(
                     modifier
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateItemPlacementTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateItemPlacementTest.kt
index 809d77a..61ce9f7 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateItemPlacementTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateItemPlacementTest.kt
@@ -72,15 +72,17 @@
     @get:Rule
     val rule = createComposeRule()
 
-    private val itemSize: Float = 50f
+    // the numbers should be divisible by 8 to avoid the rounding issues as we run 4 or 8 frames
+    // of the animation.
+    private val itemSize: Float = 40f
     private var itemSizeDp: Dp = Dp.Infinity
-    private val itemSize2: Float = 30f
+    private val itemSize2: Float = 24f
     private var itemSize2Dp: Dp = Dp.Infinity
-    private val itemSize3: Float = 20f
+    private val itemSize3: Float = 16f
     private var itemSize3Dp: Dp = Dp.Infinity
     private val containerSize: Float = itemSize * 5
     private var containerSizeDp: Dp = Dp.Infinity
-    private val spacing: Float = 10f
+    private val spacing: Float = 8f
     private var spacingDp: Dp = Dp.Infinity
     private val itemSizePlusSpacing = itemSize + spacing
     private var itemSizePlusSpacingDp = Dp.Infinity
@@ -2085,6 +2087,173 @@
         }
     }
 
+    @Test
+    fun scrollIsAffectingItemsMovingWithinViewport() {
+        var list by mutableStateOf(listOf(0, 1, 2, 3))
+        val scrollDelta = spacing
+        rule.setContent {
+            LazyGrid(1, maxSize = itemSizeDp * 2) {
+                items(list, key = { it }) {
+                    Item(it)
+                }
+            }
+        }
+
+        rule.runOnUiThread {
+            list = listOf(0, 2, 1, 3)
+        }
+
+        onAnimationFrame { fraction ->
+            if (fraction == 0f) {
+                assertPositions(
+                    0 to AxisOffset(0f, 0f),
+                    1 to AxisOffset(0f, itemSize),
+                    2 to AxisOffset(0f, itemSize * 2),
+                    fraction = fraction
+                )
+                rule.runOnUiThread {
+                    runBlocking { state.scrollBy(scrollDelta) }
+                }
+            }
+            assertPositions(
+                0 to AxisOffset(0f, -scrollDelta),
+                1 to AxisOffset(0f, itemSize - scrollDelta + itemSize * fraction),
+                2 to AxisOffset(0f, itemSize * 2 - scrollDelta - itemSize * fraction),
+                fraction = fraction
+            )
+        }
+    }
+
+    @Test
+    fun scrollIsNotAffectingItemMovingToTheBottomOutsideOfBounds() {
+        var list by mutableStateOf(listOf(0, 1, 2, 3, 4))
+        val scrollDelta = spacing
+        val containerSizeDp = itemSizeDp * 2
+        val containerSize = itemSize * 2
+        rule.setContent {
+            LazyGrid(1, maxSize = containerSizeDp) {
+                items(list, key = { it }) {
+                    Item(it)
+                }
+            }
+        }
+
+        rule.runOnUiThread {
+            list = listOf(0, 4, 2, 3, 1)
+        }
+
+        onAnimationFrame { fraction ->
+            if (fraction == 0f) {
+                assertPositions(
+                    0 to AxisOffset(0f, 0f),
+                    1 to AxisOffset(0f, itemSize),
+                    fraction = fraction
+                )
+                rule.runOnUiThread {
+                    runBlocking { state.scrollBy(scrollDelta) }
+                }
+            }
+            assertPositions(
+                0 to AxisOffset(0f, -scrollDelta),
+                1 to AxisOffset(0f, itemSize + (containerSize - itemSize) * fraction),
+                fraction = fraction
+            )
+        }
+    }
+
+    @Test
+    fun scrollIsNotAffectingItemMovingToTheTopOutsideOfBounds() {
+        var list by mutableStateOf(listOf(0, 1, 2, 3, 4))
+        val scrollDelta = -spacing
+        val containerSizeDp = itemSizeDp * 2
+        rule.setContent {
+            LazyGrid(1, maxSize = containerSizeDp, startIndex = 2) {
+                items(list, key = { it }) {
+                    Item(it)
+                }
+            }
+        }
+
+        rule.runOnUiThread {
+            list = listOf(3, 0, 1, 2, 4)
+        }
+
+        onAnimationFrame { fraction ->
+            if (fraction == 0f) {
+                assertPositions(
+                    2 to AxisOffset(0f, 0f),
+                    3 to AxisOffset(0f, itemSize),
+                    fraction = fraction
+                )
+                rule.runOnUiThread {
+                    runBlocking { state.scrollBy(scrollDelta) }
+                }
+            }
+            assertPositions(
+                2 to AxisOffset(0f, -scrollDelta),
+                3 to AxisOffset(0f, itemSize - (itemSize * 2 * fraction)),
+                fraction = fraction
+            )
+        }
+    }
+
+    @Test
+    fun afterScrollingEnoughToReachNewPositionScrollDeltasStartAffectingPosition() {
+        var list by mutableStateOf(listOf(0, 1, 2, 3, 4))
+        val containerSizeDp = itemSizeDp * 2
+        val scrollDelta = spacing
+        rule.setContent {
+            LazyGrid(1, maxSize = containerSizeDp) {
+                items(list, key = { it }) {
+                    Item(it)
+                }
+            }
+        }
+
+        rule.runOnUiThread {
+            list = listOf(0, 4, 2, 3, 1)
+        }
+
+        onAnimationFrame { fraction ->
+            if (fraction == 0f) {
+                assertPositions(
+                    0 to AxisOffset(0f, 0f),
+                    1 to AxisOffset(0f, itemSize),
+                    fraction = fraction
+                )
+                rule.runOnUiThread {
+                    runBlocking { state.scrollBy(itemSize * 2) }
+                }
+                assertPositions(
+                    2 to AxisOffset(0f, 0f),
+                    3 to AxisOffset(0f, itemSize),
+                    // after the first scroll the new position of item 1 is still not reached
+                    // so the target didn't change, we still aim to end right after the bounds
+                    1 to AxisOffset(0f, itemSize),
+                    fraction = fraction
+                )
+                rule.runOnUiThread {
+                    runBlocking { state.scrollBy(scrollDelta) }
+                }
+                assertPositions(
+                    2 to AxisOffset(0f, 0f - scrollDelta),
+                    3 to AxisOffset(0f, itemSize - scrollDelta),
+                    // after the second scroll the item 1 is visible, so we know its new target
+                    // position. the animation is now targeting the real end position and now
+                    // we are reacting on the scroll deltas
+                    1 to AxisOffset(0f, itemSize - scrollDelta),
+                    fraction = fraction
+                )
+            }
+            assertPositions(
+                2 to AxisOffset(0f, -scrollDelta),
+                3 to AxisOffset(0f, itemSize - scrollDelta),
+                1 to AxisOffset(0f, itemSize - scrollDelta + itemSize * fraction),
+                fraction = fraction
+            )
+        }
+    }
+
     private fun AxisOffset(crossAxis: Float, mainAxis: Float) =
         if (isVertical) Offset(crossAxis, mainAxis) else Offset(mainAxis, crossAxis)
 
@@ -2224,7 +2393,11 @@
         animSpec: FiniteAnimationSpec<IntOffset>? = AnimSpec
     ) {
         Box(
-            Modifier
+            if (animSpec != null) {
+                Modifier.animateItemPlacement(animSpec)
+            } else {
+                Modifier
+            }
                 .then(
                     if (isVertical) {
                         Modifier.requiredHeight(size)
@@ -2233,13 +2406,6 @@
                     }
                 )
                 .testTag(tag.toString())
-                .then(
-                    if (animSpec != null) {
-                        Modifier.animateItemPlacement(animSpec)
-                    } else {
-                        Modifier
-                    }
-                )
         )
     }
 
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 6f21f95..fa60831 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
@@ -85,15 +85,17 @@
     @get:Rule
     val rule = createComposeRule()
 
-    private val itemSize: Float = 50f
+    // the numbers should be divisible by 8 to avoid the rounding issues as we run 4 or 8 frames
+    // of the animation.
+    private val itemSize: Float = 40f
     private var itemSizeDp: Dp = Dp.Infinity
-    private val itemSize2: Float = 30f
+    private val itemSize2: Float = 24f
     private var itemSize2Dp: Dp = Dp.Infinity
-    private val itemSize3: Float = 20f
+    private val itemSize3: Float = 16f
     private var itemSize3Dp: Dp = Dp.Infinity
     private val containerSize: Float = itemSize * 5
     private var containerSizeDp: Dp = Dp.Infinity
-    private val spacing: Float = 10f
+    private val spacing: Float = 8f
     private var spacingDp: Dp = Dp.Infinity
     private val itemSizePlusSpacing = itemSize + spacing
     private var itemSizePlusSpacingDp = Dp.Infinity
@@ -1534,6 +1536,173 @@
         }
     }
 
+    @Test
+    fun scrollIsAffectingItemsMovingWithinViewport() {
+        var list by mutableStateOf(listOf(0, 1, 2, 3))
+        val scrollDelta = spacing
+        rule.setContent {
+            LazyList(maxSize = itemSizeDp * 2) {
+                items(list, key = { it }) {
+                    Item(it)
+                }
+            }
+        }
+
+        rule.runOnUiThread {
+            list = listOf(0, 2, 1, 3)
+        }
+
+        onAnimationFrame { fraction ->
+            if (fraction == 0f) {
+                assertPositions(
+                    0 to 0f,
+                    1 to itemSize,
+                    2 to itemSize * 2,
+                    fraction = fraction
+                )
+                rule.runOnUiThread {
+                    runBlocking { state.scrollBy(scrollDelta) }
+                }
+            }
+            assertPositions(
+                0 to -scrollDelta,
+                1 to itemSize - scrollDelta + itemSize * fraction,
+                2 to itemSize * 2 - scrollDelta - itemSize * fraction,
+                fraction = fraction
+            )
+        }
+    }
+
+    @Test
+    fun scrollIsNotAffectingItemMovingToTheBottomOutsideOfBounds() {
+        var list by mutableStateOf(listOf(0, 1, 2, 3, 4))
+        val scrollDelta = spacing
+        val containerSizeDp = itemSizeDp * 2
+        val containerSize = itemSize * 2
+        rule.setContent {
+            LazyList(maxSize = containerSizeDp) {
+                items(list, key = { it }) {
+                    Item(it)
+                }
+            }
+        }
+
+        rule.runOnUiThread {
+            list = listOf(0, 4, 2, 3, 1)
+        }
+
+        onAnimationFrame { fraction ->
+            if (fraction == 0f) {
+                assertPositions(
+                    0 to 0f,
+                    1 to itemSize,
+                    fraction = fraction
+                )
+                rule.runOnUiThread {
+                    runBlocking { state.scrollBy(scrollDelta) }
+                }
+            }
+            assertPositions(
+                0 to -scrollDelta,
+                1 to itemSize + (containerSize - itemSize) * fraction,
+                fraction = fraction
+            )
+        }
+    }
+
+    @Test
+    fun scrollIsNotAffectingItemMovingToTheTopOutsideOfBounds() {
+        var list by mutableStateOf(listOf(0, 1, 2, 3, 4))
+        val scrollDelta = -spacing
+        val containerSizeDp = itemSizeDp * 2
+        rule.setContent {
+            LazyList(maxSize = containerSizeDp, startIndex = 2) {
+                items(list, key = { it }) {
+                    Item(it)
+                }
+            }
+        }
+
+        rule.runOnUiThread {
+            list = listOf(3, 0, 1, 2, 4)
+        }
+
+        onAnimationFrame { fraction ->
+            if (fraction == 0f) {
+                assertPositions(
+                    2 to 0f,
+                    3 to itemSize,
+                    fraction = fraction
+                )
+                rule.runOnUiThread {
+                    runBlocking { state.scrollBy(scrollDelta) }
+                }
+            }
+            assertPositions(
+                2 to -scrollDelta,
+                3 to itemSize - (itemSize * 2 * fraction),
+                fraction = fraction
+            )
+        }
+    }
+
+    @Test
+    fun afterScrollingEnoughToReachNewPositionScrollDeltasStartAffectingPosition() {
+        var list by mutableStateOf(listOf(0, 1, 2, 3, 4))
+        val containerSizeDp = itemSizeDp * 2
+        val scrollDelta = spacing
+        rule.setContent {
+            LazyList(maxSize = containerSizeDp) {
+                items(list, key = { it }) {
+                    Item(it)
+                }
+            }
+        }
+
+        rule.runOnUiThread {
+            list = listOf(0, 4, 2, 3, 1)
+        }
+
+        onAnimationFrame { fraction ->
+            if (fraction == 0f) {
+                assertPositions(
+                    0 to 0f,
+                    1 to itemSize,
+                    fraction = fraction
+                )
+                rule.runOnUiThread {
+                    runBlocking { state.scrollBy(itemSize * 2) }
+                }
+                assertPositions(
+                    2 to 0f,
+                    3 to itemSize,
+                    // after the first scroll the new position of item 1 is still not reached
+                    // so the target didn't change, we still aim to end right after the bounds
+                    1 to itemSize,
+                    fraction = fraction
+                )
+                rule.runOnUiThread {
+                    runBlocking { state.scrollBy(scrollDelta) }
+                }
+                assertPositions(
+                    2 to 0f - scrollDelta,
+                    3 to itemSize - scrollDelta,
+                    // after the second scroll the item 1 is visible, so we know its new target
+                    // position. the animation is now targeting the real end position and now
+                    // we are reacting on the scroll deltas
+                    1 to itemSize - scrollDelta,
+                    fraction = fraction
+                )
+            }
+            assertPositions(
+                2 to -scrollDelta,
+                3 to itemSize - scrollDelta,
+                1 to itemSize - scrollDelta + itemSize * fraction,
+                fraction = fraction
+            )
+        }
+    }
+
     private fun assertPositions(
         vararg expected: Pair<Any, Float>,
         crossAxis: List<Pair<Any, Float>>? = null,
@@ -1693,26 +1862,24 @@
         crossAxisSize: Dp = size,
         animSpec: FiniteAnimationSpec<IntOffset>? = AnimSpec
     ) {
-        Box(Modifier
-            .then(
-                if (isVertical) {
-                    Modifier
-                        .requiredHeight(size)
-                        .requiredWidth(crossAxisSize)
-                } else {
-                    Modifier
-                        .requiredWidth(size)
-                        .requiredHeight(crossAxisSize)
-                }
-            )
-            .testTag(tag.toString())
-            .then(
-                if (animSpec != null) {
-                    Modifier.animateItemPlacement(animSpec)
-                } else {
-                    Modifier
-                }
-            )
+        Box(
+            if (animSpec != null) {
+                Modifier.animateItemPlacement(animSpec)
+            } else {
+                Modifier
+            }
+                .then(
+                    if (isVertical) {
+                        Modifier
+                            .requiredHeight(size)
+                            .requiredWidth(crossAxisSize)
+                    } else {
+                        Modifier
+                            .requiredWidth(size)
+                            .requiredHeight(crossAxisSize)
+                    }
+                )
+                .testTag(tag.toString())
         )
     }
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Background.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Background.kt
index 6fa0739..ab0b5f5 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Background.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Background.kt
@@ -17,7 +17,6 @@
 package androidx.compose.foundation
 
 import androidx.compose.ui.graphics.drawscope.ContentDrawScope
-import androidx.compose.ui.draw.DrawModifier
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.graphics.Brush
@@ -26,8 +25,9 @@
 import androidx.compose.ui.graphics.RectangleShape
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.drawOutline
+import androidx.compose.ui.node.DrawModifierNode
+import androidx.compose.ui.node.ModifierNodeElement
 import androidx.compose.ui.platform.InspectorInfo
-import androidx.compose.ui.platform.InspectorValueInfo
 import androidx.compose.ui.platform.debugInspectorInfo
 import androidx.compose.ui.unit.LayoutDirection
 
@@ -42,18 +42,22 @@
 fun Modifier.background(
     color: Color,
     shape: Shape = RectangleShape
-) = this.then(
-    Background(
-        color = color,
-        shape = shape,
-        inspectorInfo = debugInspectorInfo {
-            name = "background"
-            value = color
-            properties["color"] = color
-            properties["shape"] = shape
-        }
+): Modifier {
+    val alpha = 1.0f // for solid colors
+    return this.then(
+        BackgroundElement(
+            color = color,
+            shape = shape,
+            alpha = alpha,
+            inspectorInfo = debugInspectorInfo {
+                name = "background"
+                value = color
+                properties["color"] = color
+                properties["shape"] = shape
+            }
+        )
     )
-)
+}
 
 /**
  * Draws [shape] with [brush] behind the content.
@@ -71,7 +75,7 @@
     /*@FloatRange(from = 0.0, to = 1.0)*/
     alpha: Float = 1.0f
 ) = this.then(
-    Background(
+    BackgroundElement(
         brush = brush,
         alpha = alpha,
         shape = shape,
@@ -84,13 +88,57 @@
     )
 )
 
-private class Background constructor(
+private class BackgroundElement(
     private val color: Color? = null,
     private val brush: Brush? = null,
-    private val alpha: Float = 1.0f,
+    private val alpha: Float,
     private val shape: Shape,
-    inspectorInfo: InspectorInfo.() -> Unit
-) : DrawModifier, InspectorValueInfo(inspectorInfo) {
+    private val inspectorInfo: InspectorInfo.() -> Unit
+) : ModifierNodeElement<BackgroundNode>() {
+    override fun create(): BackgroundNode {
+        return BackgroundNode(
+            color,
+            brush,
+            alpha,
+            shape
+        )
+    }
+
+    override fun update(node: BackgroundNode): BackgroundNode {
+        node.color = color
+        node.brush = brush
+        node.alpha = alpha
+        node.shape = shape
+        return node
+    }
+
+    override fun InspectorInfo.inspectableProperties() {
+        inspectorInfo()
+    }
+
+    override fun hashCode(): Int {
+        var result = color?.hashCode() ?: 0
+        result = 31 * result + (brush?.hashCode() ?: 0)
+        result = 31 * result + alpha.hashCode()
+        result = 31 * result + shape.hashCode()
+        return result
+    }
+
+    override fun equals(other: Any?): Boolean {
+        val otherModifier = other as? BackgroundElement ?: return false
+        return color == otherModifier.color &&
+            brush == otherModifier.brush &&
+            alpha == otherModifier.alpha &&
+            shape == otherModifier.shape
+    }
+}
+
+private class BackgroundNode(
+    var color: Color?,
+    var brush: Brush?,
+    var alpha: Float,
+    var shape: Shape,
+) : DrawModifierNode, Modifier.Node() {
 
     // naive cache outline calculation if size is the same
     private var lastSize: Size? = null
@@ -119,29 +167,10 @@
             } else {
                 shape.createOutline(size, layoutDirection, this)
             }
-        color?.let { drawOutline(outline, color = color) }
-        brush?.let { drawOutline(outline, brush = brush, alpha = alpha) }
+        color?.let { drawOutline(outline, color = it) }
+        brush?.let { drawOutline(outline, brush = it, alpha = alpha) }
         lastOutline = outline
         lastSize = size
         lastLayoutDirection = layoutDirection
     }
-
-    override fun hashCode(): Int {
-        var result = color?.hashCode() ?: 0
-        result = 31 * result + (brush?.hashCode() ?: 0)
-        result = 31 * result + alpha.hashCode()
-        result = 31 * result + shape.hashCode()
-        return result
-    }
-
-    override fun equals(other: Any?): Boolean {
-        val otherModifier = other as? Background ?: return false
-        return color == otherModifier.color &&
-            brush == otherModifier.brush &&
-            alpha == otherModifier.alpha &&
-            shape == otherModifier.shape
-    }
-
-    override fun toString(): String =
-        "Background(color=$color, brush=$brush, alpha = $alpha, shape=$shape)"
 }
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemScopeImpl.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemScopeImpl.kt
index 5d4cbcf..ff2dc1a 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemScopeImpl.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemScopeImpl.kt
@@ -18,6 +18,7 @@
 
 import androidx.compose.animation.core.FiniteAnimationSpec
 import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.lazy.layout.LazyLayoutAnimateItemModifierNode
 import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.State
 import androidx.compose.runtime.mutableStateOf
@@ -25,6 +26,7 @@
 import androidx.compose.ui.layout.Measurable
 import androidx.compose.ui.layout.MeasureResult
 import androidx.compose.ui.layout.MeasureScope
+import androidx.compose.ui.node.DelegatingNode
 import androidx.compose.ui.node.LayoutModifierNode
 import androidx.compose.ui.node.ModifierNodeElement
 import androidx.compose.ui.node.ParentDataModifierNode
@@ -156,10 +158,11 @@
 private class AnimateItemPlacementElement(
     val animationSpec: FiniteAnimationSpec<IntOffset>
 ) : ModifierNodeElement<AnimateItemPlacementNode>() {
+
     override fun create(): AnimateItemPlacementNode = AnimateItemPlacementNode(animationSpec)
 
     override fun update(node: AnimateItemPlacementNode): AnimateItemPlacementNode = node.also {
-        it.animationSpec = animationSpec
+        it.delegatingNode.placementAnimationSpec = animationSpec
     }
 
     override fun equals(other: Any?): Boolean {
@@ -179,7 +182,10 @@
 }
 
 private class AnimateItemPlacementNode(
-    var animationSpec: FiniteAnimationSpec<IntOffset>
-) : Modifier.Node(), ParentDataModifierNode {
-    override fun Density.modifyParentData(parentData: Any?): Any = animationSpec
+    animationSpec: FiniteAnimationSpec<IntOffset>
+) : DelegatingNode(), ParentDataModifierNode {
+
+    val delegatingNode = delegated { LazyLayoutAnimateItemModifierNode(animationSpec) }
+
+    override fun Density.modifyParentData(parentData: Any?): Any = delegatingNode
 }
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 8f6ed38..e606387 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
@@ -29,11 +29,11 @@
 import androidx.compose.foundation.layout.calculateStartPadding
 import androidx.compose.foundation.lazy.layout.LazyLayout
 import androidx.compose.foundation.lazy.layout.LazyLayoutMeasureScope
+import androidx.compose.foundation.lazy.layout.findIndexByKey
 import androidx.compose.foundation.lazy.layout.lazyLayoutSemantics
 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
@@ -44,6 +44,8 @@
 import androidx.compose.ui.unit.constrainHeight
 import androidx.compose.ui.unit.constrainWidth
 import androidx.compose.ui.unit.offset
+import androidx.compose.ui.util.fastForEach
+import kotlin.math.min
 
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
@@ -79,11 +81,6 @@
 
     val semanticState = rememberLazyListSemanticState(state, isVertical)
     val beyondBoundsInfo = remember { LazyListBeyondBoundsInfo() }
-    val scope = rememberCoroutineScope()
-    val placementAnimator = remember(state, isVertical) {
-        LazyListItemPlacementAnimator(scope, isVertical)
-    }
-    state.placementAnimator = placementAnimator
 
     val measurePolicy = rememberLazyListMeasurePolicy(
         itemProvider,
@@ -96,8 +93,7 @@
         horizontalAlignment,
         verticalAlignment,
         horizontalArrangement,
-        verticalArrangement,
-        placementAnimator,
+        verticalArrangement
     )
 
     ScrollPositionUpdater(itemProvider, state)
@@ -116,7 +112,13 @@
                 reverseScrolling = reverseLayout
             )
             .clipScrollableContainer(orientation)
-            .lazyListBeyondBoundsModifier(state, beyondBoundsInfo, reverseLayout, orientation)
+            .lazyListBeyondBoundsModifier(
+                state,
+                beyondBoundsInfo,
+                beyondBoundsItemCount,
+                reverseLayout,
+                orientation
+            )
             .overscroll(overscrollEffect)
             .scrollable(
                 orientation = orientation,
@@ -174,8 +176,6 @@
     horizontalArrangement: Arrangement.Horizontal? = null,
     /** The vertical arrangement for items. Required when isVertical is true */
     verticalArrangement: Arrangement.Vertical? = null,
-    /** Item placement animator. Should be notified with the measuring result */
-    placementAnimator: LazyListItemPlacementAnimator
 ) = remember<LazyLayoutMeasureScope.(Constraints) -> MeasureResult>(
     state,
     beyondBoundsInfo,
@@ -185,8 +185,7 @@
     horizontalAlignment,
     verticalAlignment,
     horizontalArrangement,
-    verticalArrangement,
-    placementAnimator
+    verticalArrangement
 ) {
     { containerConstraints ->
         checkScrollableContainerConstraints(
@@ -284,8 +283,7 @@
                 afterContentPadding = afterContentPadding,
                 spacing = spacing,
                 visualOffset = visualItemOffset,
-                key = key,
-                placementAnimator = placementAnimator
+                key = key
             )
         }
         state.premeasureConstraints = measuredItemProvider.childConstraints
@@ -297,9 +295,29 @@
             firstVisibleScrollOffset = state.firstVisibleItemScrollOffset
         }
 
+        val pinnedItems = if (!beyondBoundsInfo.hasIntervals() && state.pinnedItems.isEmpty()) {
+            emptyList()
+        } else {
+            val pinnedItems = mutableListOf<Int>()
+            val beyondBoundsRange = if (beyondBoundsInfo.hasIntervals()) {
+                beyondBoundsInfo.start..min(beyondBoundsInfo.end, itemsCount - 1)
+            } else {
+                IntRange.EMPTY
+            }
+            state.pinnedItems.fastForEach {
+                val index = itemProvider.findIndexByKey(it.key, it.index)
+                if (index in beyondBoundsRange) return@fastForEach
+                if (index !in 0 until itemsCount) return@fastForEach
+                pinnedItems.add(index)
+            }
+            for (i in beyondBoundsRange) {
+                pinnedItems.add(i)
+            }
+            pinnedItems
+        }
+
         measureLazyList(
             itemsCount = itemsCount,
-            itemProvider = itemProvider,
             measuredItemProvider = measuredItemProvider,
             mainAxisAvailableSize = mainAxisAvailableSize,
             beforeContentPadding = beforeContentPadding,
@@ -315,10 +333,9 @@
             horizontalArrangement = horizontalArrangement,
             reverseLayout = reverseLayout,
             density = this,
-            placementAnimator = placementAnimator,
-            beyondBoundsInfo = beyondBoundsInfo,
+            placementAnimator = state.placementAnimator,
             beyondBoundsItemCount = beyondBoundsItemCount,
-            pinnedItems = state.pinnedItems,
+            pinnedItems = pinnedItems,
             layout = { width, height, placement ->
                 layout(
                     containerConstraints.constrainWidth(width + totalHorizontalPadding),
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListBeyondBoundsModifier.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListBeyondBoundsModifier.kt
index d84e816..c52f75b 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListBeyondBoundsModifier.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListBeyondBoundsModifier.kt
@@ -33,11 +33,14 @@
 internal fun Modifier.lazyListBeyondBoundsModifier(
     state: LazyListState,
     beyondBoundsInfo: LazyListBeyondBoundsInfo,
+    beyondBoundsItemCount: Int,
     reverseLayout: Boolean,
     orientation: Orientation
 ): Modifier {
     val layoutDirection = LocalLayoutDirection.current
-    val beyondBoundsState = remember(state) { LazyListBeyondBoundsState(state) }
+    val beyondBoundsState = remember(state, beyondBoundsItemCount) {
+        LazyListBeyondBoundsState(state, beyondBoundsItemCount)
+    }
     return this then remember(
         beyondBoundsState,
         beyondBoundsInfo,
@@ -55,7 +58,11 @@
     }
 }
 
-internal class LazyListBeyondBoundsState(val state: LazyListState) : BeyondBoundsState {
+internal class LazyListBeyondBoundsState(
+    val state: LazyListState,
+    val beyondBoundsItemCount: Int
+) : BeyondBoundsState {
+
     override fun remeasure() {
         state.remeasurement?.forceRemeasure()
     }
@@ -65,7 +72,10 @@
     override val hasVisibleItems: Boolean
         get() = state.layoutInfo.visibleItemsInfo.isNotEmpty()
     override val firstVisibleIndex: Int
-        get() = state.firstVisibleItemIndex
+        get() = maxOf(0, state.firstVisibleItemIndex - beyondBoundsItemCount)
     override val lastVisibleIndex: Int
-        get() = state.layoutInfo.visibleItemsInfo.last().index
+        get() = minOf(
+            itemCount - 1,
+            state.layoutInfo.visibleItemsInfo.last().index + beyondBoundsItemCount
+        )
 }
\ No newline at end of file
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 3e94392..6e1f924 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
@@ -16,24 +16,11 @@
 
 package androidx.compose.foundation.lazy
 
-import androidx.compose.animation.core.Animatable
-import androidx.compose.animation.core.Spring
-import androidx.compose.animation.core.SpringSpec
-import androidx.compose.animation.core.VectorConverter
-import androidx.compose.animation.core.VisibilityThreshold
-import androidx.compose.animation.core.spring
-import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.lazy.layout.LazyLayoutAnimateItemModifierNode
 import androidx.compose.foundation.lazy.layout.LazyLayoutKeyIndexMap
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.setValue
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.util.fastAny
 import androidx.compose.ui.util.fastForEach
-import androidx.compose.ui.util.fastForEachIndexed
-import kotlinx.coroutines.CancellationException
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
 
 /**
  * Handles the item placement animations when it is set via [LazyItemScope.animateItemPlacement].
@@ -41,13 +28,9 @@
  * This class is responsible for detecting when item position changed, figuring our start/end
  * offsets and starting the animations.
  */
-@OptIn(ExperimentalFoundationApi::class)
-internal class LazyListItemPlacementAnimator(
-    private val scope: CoroutineScope,
-    private val isVertical: Boolean
-) {
-    // state containing an animation and all relevant info for each item.
-    private val keyToItemInfoMap = mutableMapOf<Any, ItemInfo>()
+internal class LazyListItemPlacementAnimator {
+    // contains the keys of the active items with animation node.
+    private val activeKeys = mutableSetOf<Any>()
 
     // snapshot of the key to index map used for the last measuring.
     private var keyToIndexMap: LazyLayoutKeyIndexMap = LazyLayoutKeyIndexMap.Empty
@@ -72,9 +55,10 @@
         layoutWidth: Int,
         layoutHeight: Int,
         positionedItems: MutableList<LazyListPositionedItem>,
-        itemProvider: LazyListMeasuredItemProvider
+        itemProvider: LazyListMeasuredItemProvider,
+        isVertical: Boolean
     ) {
-        if (!positionedItems.fastAny { it.hasAnimations } && keyToItemInfoMap.isEmpty()) {
+        if (!positionedItems.fastAny { it.hasAnimations } && activeKeys.isEmpty()) {
             // no animations specified - no work needed
             reset()
             return
@@ -88,18 +72,21 @@
         val mainAxisLayoutSize = if (isVertical) layoutHeight else layoutWidth
 
         // the consumed scroll is considered as a delta we don't need to animate
-        val notAnimatableDelta = consumedScroll.toOffset()
+        val scrollOffset = if (isVertical) {
+            IntOffset(0, consumedScroll)
+        } else {
+            IntOffset(consumedScroll, 0)
+        }
 
         // first add all items we had in the previous run
-        movingAwayKeys.addAll(keyToItemInfoMap.keys)
+        movingAwayKeys.addAll(activeKeys)
         // iterate through the items which are visible (without animated offsets)
         positionedItems.fastForEach { item ->
             // remove items we have in the current one as they are still visible.
             movingAwayKeys.remove(item.key)
             if (item.hasAnimations) {
-                val itemInfo = keyToItemInfoMap[item.key]
-                // there is no state associated with this item yet
-                if (itemInfo == null) {
+                if (!activeKeys.contains(item.key)) {
+                    activeKeys += item.key
                     val previousIndex = previousKeyToIndexMap[item.key]
                     if (previousIndex != -1 && item.index != previousIndex) {
                         if (previousIndex < previousFirstVisibleIndex) {
@@ -109,16 +96,24 @@
                             movingInFromEndBound.add(item)
                         }
                     } else {
-                       keyToItemInfoMap[item.key] = createItemInfo(item)
+                        initializeNode(
+                            item,
+                            item.getOffset(0).let { if (item.isVertical) it.y else it.x }
+                        )
                     }
                 } else {
-                    // this item was visible and is still visible.
-                    itemInfo.notAnimatableDelta += notAnimatableDelta // apply new scroll delta
-                    startAnimationsIfNeeded(item, itemInfo)
+                    repeat(item.placeablesCount) { placeableIndex ->
+                        item.getParentData(placeableIndex).node?.apply {
+                            if (rawOffset != LazyLayoutAnimateItemModifierNode.NotInitialized) {
+                                rawOffset += scrollOffset
+                            }
+                        }
+                    }
+                    startAnimationsIfNeeded(item)
                 }
             } else {
                 // no animation, clean up if needed
-                keyToItemInfoMap.remove(item.key)
+                activeKeys.remove(item.key)
             }
         }
 
@@ -127,40 +122,43 @@
         movingInFromStartBound.fastForEach { item ->
             val mainAxisOffset = 0 - currentMainAxisOffset - item.size
             currentMainAxisOffset += item.size
-            val itemInfo = createItemInfo(item, mainAxisOffset)
-            keyToItemInfoMap[item.key] = itemInfo
-            startAnimationsIfNeeded(item, itemInfo)
+            initializeNode(item, mainAxisOffset)
+            startAnimationsIfNeeded(item)
         }
         currentMainAxisOffset = 0
         movingInFromEndBound.sortBy { previousKeyToIndexMap[it.key] }
         movingInFromEndBound.fastForEach { item ->
             val mainAxisOffset = mainAxisLayoutSize + currentMainAxisOffset
             currentMainAxisOffset += item.size
-            val itemInfo = createItemInfo(item, mainAxisOffset)
-            keyToItemInfoMap[item.key] = itemInfo
-            startAnimationsIfNeeded(item, itemInfo)
+            initializeNode(item, mainAxisOffset)
+            startAnimationsIfNeeded(item)
         }
 
         movingAwayKeys.forEach { key ->
             // found an item which was in our map previously but is not a part of the
             // positionedItems now
-            val itemInfo = keyToItemInfoMap.getValue(key)
             val newIndex = keyToIndexMap[key]
 
-            // whether the animation associated with the item has been finished or not yet started
-            val inProgress = itemInfo.placeables.fastAny { it.inProgress }
-            if (itemInfo.placeables.isEmpty() ||
-                newIndex == -1 ||
-                (!inProgress && newIndex == previousKeyToIndexMap[key]) ||
-                (!inProgress && !itemInfo.isWithinBounds(mainAxisLayoutSize))
-            ) {
-                keyToItemInfoMap.remove(key)
+            if (newIndex == -1) {
+                activeKeys.remove(key)
             } else {
                 val item = itemProvider.getAndMeasure(DataIndex(newIndex))
-                if (newIndex < firstVisibleIndex) {
-                    movingAwayToStartBound.add(item)
+                // check if we have any active placement animation on the item
+                var inProgress = false
+                repeat(item.placeablesCount) {
+                    if (item.getParentData(it).node?.isAnimationInProgress == true) {
+                        inProgress = true
+                        return@repeat
+                    }
+                }
+                if ((!inProgress && newIndex == previousKeyToIndexMap[key])) {
+                    activeKeys.remove(key)
                 } else {
-                    movingAwayToEndBound.add(item)
+                    if (newIndex < firstVisibleIndex) {
+                        movingAwayToStartBound.add(item)
+                    } else {
+                        movingAwayToEndBound.add(item)
+                    }
                 }
             }
         }
@@ -171,10 +169,9 @@
             val mainAxisOffset = 0 - currentMainAxisOffset - item.size
             currentMainAxisOffset += item.size
 
-            val itemInfo = keyToItemInfoMap.getValue(item.key)
             val positionedItem = item.position(mainAxisOffset, layoutWidth, layoutHeight)
             positionedItems.add(positionedItem)
-            startAnimationsIfNeeded(positionedItem, itemInfo)
+            startAnimationsIfNeeded(positionedItem)
         }
         currentMainAxisOffset = 0
         movingAwayToEndBound.sortBy { keyToIndexMap[it.key] }
@@ -182,10 +179,9 @@
             val mainAxisOffset = mainAxisLayoutSize + currentMainAxisOffset
             currentMainAxisOffset += item.size
 
-            val itemInfo = keyToItemInfoMap.getValue(item.key)
             val positionedItem = item.position(mainAxisOffset, layoutWidth, layoutHeight)
             positionedItems.add(positionedItem)
-            startAnimationsIfNeeded(positionedItem, itemInfo)
+            startAnimationsIfNeeded(positionedItem)
         }
 
         movingInFromStartBound.clear()
@@ -196,157 +192,63 @@
     }
 
     /**
-     * Returns the current animated item placement offset. By calling it only during the layout
-     * phase we can skip doing remeasure on every animation frame.
-     */
-    fun getAnimatedOffset(
-        key: Any,
-        placeableIndex: Int,
-        minOffset: Int,
-        maxOffset: Int,
-        rawOffset: IntOffset
-    ): IntOffset {
-        val itemInfo = keyToItemInfoMap[key] ?: return rawOffset
-        val item = itemInfo.placeables[placeableIndex]
-        val currentValue = item.animatedOffset.value + itemInfo.notAnimatableDelta
-        val currentTarget = item.targetOffset + itemInfo.notAnimatableDelta
-
-        // cancel the animation if it is fully out of the bounds.
-        if (item.inProgress &&
-            ((currentTarget.mainAxis <= minOffset && currentValue.mainAxis <= minOffset) ||
-            (currentTarget.mainAxis >= maxOffset && currentValue.mainAxis >= maxOffset))
-        ) {
-            scope.launch {
-                item.animatedOffset.snapTo(item.targetOffset)
-                item.inProgress = false
-            }
-        }
-
-        return currentValue
-    }
-
-    /**
      * Should be called when the animations are not needed for the next positions change,
      * for example when we snap to a new position.
      */
     fun reset() {
-        keyToItemInfoMap.clear()
+        activeKeys.clear()
         keyToIndexMap = LazyLayoutKeyIndexMap.Empty
         firstVisibleIndex = -1
     }
 
-    private fun createItemInfo(
+    private fun initializeNode(
         item: LazyListPositionedItem,
-        mainAxisOffset: Int = item.getOffset(0).mainAxis
-    ): ItemInfo {
-        val newItemInfo = ItemInfo()
+        mainAxisOffset: Int
+    ) {
         val firstPlaceableOffset = item.getOffset(0)
 
-        val targetFirstPlaceableOffset = if (isVertical) {
+        val targetFirstPlaceableOffset = if (item.isVertical) {
             firstPlaceableOffset.copy(y = mainAxisOffset)
         } else {
             firstPlaceableOffset.copy(x = mainAxisOffset)
         }
 
-        // populate placeable info list
+        // initialize offsets
         repeat(item.placeablesCount) { placeableIndex ->
-            val diffToFirstPlaceableOffset =
-                item.getOffset(placeableIndex) - firstPlaceableOffset
-            newItemInfo.placeables.add(
-                PlaceableInfo(
-                    targetFirstPlaceableOffset + diffToFirstPlaceableOffset,
-                    item.getMainAxisSize(placeableIndex)
-                )
-            )
+            val node = item.getParentData(placeableIndex).node
+            if (node != null) {
+                val diffToFirstPlaceableOffset =
+                    item.getOffset(placeableIndex) - firstPlaceableOffset
+                node.rawOffset = targetFirstPlaceableOffset + diffToFirstPlaceableOffset
+            }
         }
-        return newItemInfo
     }
 
-    private fun startAnimationsIfNeeded(item: LazyListPositionedItem, itemInfo: ItemInfo) {
-        // first we make sure our item info is up to date (has the item placeables count)
-        while (itemInfo.placeables.size > item.placeablesCount) {
-            itemInfo.placeables.removeLast()
-        }
-        while (itemInfo.placeables.size < item.placeablesCount) {
-            val newPlaceableInfoIndex = itemInfo.placeables.size
-            val rawOffset = item.getOffset(newPlaceableInfoIndex)
-            itemInfo.placeables.add(
-                PlaceableInfo(
-                    rawOffset - itemInfo.notAnimatableDelta,
-                    item.getMainAxisSize(newPlaceableInfoIndex)
-                )
-            )
-        }
-
-        itemInfo.placeables.fastForEachIndexed { index, placeableInfo ->
-            val currentTarget = placeableInfo.targetOffset + itemInfo.notAnimatableDelta
-            val currentOffset = item.getOffset(index)
-            placeableInfo.mainAxisSize = item.getMainAxisSize(index)
-            val animationSpec = item.getAnimationSpec(index)
-            if (currentTarget != currentOffset) {
-                placeableInfo.targetOffset = currentOffset - itemInfo.notAnimatableDelta
-                if (animationSpec != null) {
-                    placeableInfo.inProgress = true
-                    scope.launch {
-                        val finalSpec = if (placeableInfo.animatedOffset.isRunning) {
-                            // when interrupted, use the default spring, unless the spec is a spring.
-                            if (animationSpec is SpringSpec<IntOffset>) animationSpec else
-                                InterruptionSpec
-                        } else {
-                            animationSpec
-                        }
-
-                        try {
-                            placeableInfo.animatedOffset.animateTo(
-                                placeableInfo.targetOffset,
-                                finalSpec
-                            )
-                            placeableInfo.inProgress = false
-                        } catch (_: CancellationException) {
-                            // we don't reset inProgress in case of cancellation as it means
-                            // there is a new animation started which would reset it later
-                        }
-                    }
+    private fun startAnimationsIfNeeded(item: LazyListPositionedItem) {
+        repeat(item.placeablesCount) { placeableIndex ->
+            val node = item.getParentData(placeableIndex).node
+            if (node != null) {
+                val newTarget = item.getOffset(placeableIndex)
+                val currentTarget = node.rawOffset
+                if (currentTarget == LazyLayoutAnimateItemModifierNode.NotInitialized) {
+                    node.rawOffset = newTarget
+                } else if (currentTarget != newTarget) {
+                    node.rawOffset = newTarget
+                    node.animatePlacementDelta(newTarget - currentTarget)
                 }
             }
         }
     }
 
-    /**
-     * Whether at least one placeable is within the viewport bounds.
-     */
-    private fun ItemInfo.isWithinBounds(mainAxisLayoutSize: Int): Boolean {
-        return placeables.fastAny {
-            val currentTarget = it.targetOffset + notAnimatableDelta
-            currentTarget.mainAxis + it.mainAxisSize > 0 &&
-                currentTarget.mainAxis < mainAxisLayoutSize
+    private val Any?.node get() = this as? LazyLayoutAnimateItemModifierNode
+
+    private val LazyListPositionedItem.hasAnimations: Boolean
+        get() {
+            repeat(placeablesCount) { index ->
+                if (getParentData(index).node != null) {
+                    return true
+                }
+            }
+            return false
         }
-    }
-
-    private fun Int.toOffset() =
-        IntOffset(if (isVertical) 0 else this, if (!isVertical) 0 else this)
-
-    private val IntOffset.mainAxis get() = if (isVertical) y else x
 }
-
-private class ItemInfo {
-    var notAnimatableDelta: IntOffset = IntOffset.Zero
-    val placeables = mutableListOf<PlaceableInfo>()
-}
-
-private class PlaceableInfo(
-    initialOffset: IntOffset,
-    var mainAxisSize: Int
-) {
-    val animatedOffset = Animatable(initialOffset, IntOffset.VectorConverter)
-    var targetOffset: IntOffset = initialOffset
-    var inProgress by mutableStateOf(false)
-}
-
-/**
- * We switch to this spec when a duration based animation is being interrupted.
- */
-private val InterruptionSpec = spring(
-    stiffness = Spring.StiffnessMediumLow,
-    visibilityThreshold = IntOffset.VisibilityThreshold
-)
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 ac0811d..0c97ea2 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
@@ -20,8 +20,6 @@
 import androidx.compose.foundation.fastFilter
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList
-import androidx.compose.foundation.lazy.layout.findIndexByKey
 import androidx.compose.ui.layout.MeasureResult
 import androidx.compose.ui.layout.Placeable
 import androidx.compose.ui.unit.Constraints
@@ -31,7 +29,6 @@
 import androidx.compose.ui.unit.constrainWidth
 import androidx.compose.ui.util.fastForEach
 import kotlin.math.abs
-import kotlin.math.min
 import kotlin.math.roundToInt
 import kotlin.math.sign
 
@@ -42,7 +39,6 @@
 @OptIn(ExperimentalFoundationApi::class)
 internal fun measureLazyList(
     itemsCount: Int,
-    itemProvider: LazyListItemProvider,
     measuredItemProvider: LazyListMeasuredItemProvider,
     mainAxisAvailableSize: Int,
     beforeContentPadding: Int,
@@ -59,9 +55,8 @@
     reverseLayout: Boolean,
     density: Density,
     placementAnimator: LazyListItemPlacementAnimator,
-    beyondBoundsInfo: LazyListBeyondBoundsInfo,
     beyondBoundsItemCount: Int,
-    pinnedItems: LazyLayoutPinnedItemList,
+    pinnedItems: List<Int>,
     layout: (Int, Int, Placeable.PlacementScope.() -> Unit) -> MeasureResult
 ): LazyListMeasureResult {
     require(beforeContentPadding >= 0)
@@ -235,11 +230,8 @@
 
         // Compose extra items before
         val extraItemsBefore = createItemsBeforeList(
-            beyondBoundsInfo = beyondBoundsInfo,
             currentFirstItemIndex = currentFirstItemIndex,
             measuredItemProvider = measuredItemProvider,
-            itemProvider = itemProvider,
-            itemsCount = itemsCount,
             beyondBoundsItemCount = beyondBoundsItemCount,
             pinnedItems = pinnedItems
         )
@@ -251,10 +243,8 @@
 
         // Compose items after last item
         val extraItemsAfter = createItemsAfterList(
-            beyondBoundsInfo = beyondBoundsInfo,
             visibleItems = visibleItems,
             measuredItemProvider = measuredItemProvider,
-            itemProvider = itemProvider,
             itemsCount = itemsCount,
             beyondBoundsItemCount = beyondBoundsItemCount,
             pinnedItems = pinnedItems
@@ -295,7 +285,8 @@
             layoutWidth = layoutWidth,
             layoutHeight = layoutHeight,
             positionedItems = positionedItems,
-            itemProvider = measuredItemProvider
+            itemProvider = measuredItemProvider,
+            isVertical = isVertical
         )
 
         val headerItem = if (headerIndexes.isNotEmpty()) {
@@ -340,18 +331,13 @@
     }
 }
 
-@OptIn(ExperimentalFoundationApi::class)
 private fun createItemsAfterList(
-    beyondBoundsInfo: LazyListBeyondBoundsInfo,
     visibleItems: MutableList<LazyListMeasuredItem>,
     measuredItemProvider: LazyListMeasuredItemProvider,
-    itemProvider: LazyListItemProvider,
     itemsCount: Int,
     beyondBoundsItemCount: Int,
-    pinnedItems: LazyLayoutPinnedItemList
+    pinnedItems: List<Int>
 ): List<LazyListMeasuredItem> {
-    fun LazyListBeyondBoundsInfo.endIndex() = min(end, itemsCount - 1)
-
     var list: MutableList<LazyListMeasuredItem>? = null
 
     var end = visibleItems.last().index
@@ -363,19 +349,14 @@
         )
     }
 
-    if (beyondBoundsInfo.hasIntervals()) {
-        end = maxOf(beyondBoundsInfo.endIndex(), end)
-    }
-
     end = minOf(end + beyondBoundsItemCount, itemsCount - 1)
 
     for (i in visibleItems.last().index + 1..end) {
         addItem(i)
     }
 
-    pinnedItems.fastForEach { item ->
-        val index = itemProvider.findIndexByKey(item.key, item.index)
-        if (index > end && index < itemsCount) {
+    pinnedItems.fastForEach { index ->
+        if (index > end) {
             addItem(index)
         }
     }
@@ -383,18 +364,12 @@
     return list ?: emptyList()
 }
 
-@OptIn(ExperimentalFoundationApi::class)
 private fun createItemsBeforeList(
-    beyondBoundsInfo: LazyListBeyondBoundsInfo,
     currentFirstItemIndex: DataIndex,
     measuredItemProvider: LazyListMeasuredItemProvider,
-    itemProvider: LazyListItemProvider,
-    itemsCount: Int,
     beyondBoundsItemCount: Int,
-    pinnedItems: LazyLayoutPinnedItemList
+    pinnedItems: List<Int>
 ): List<LazyListMeasuredItem> {
-    fun LazyListBeyondBoundsInfo.startIndex() = min(start, itemsCount - 1)
-
     var list: MutableList<LazyListMeasuredItem>? = null
 
     var start = currentFirstItemIndex.value
@@ -406,18 +381,13 @@
         )
     }
 
-    if (beyondBoundsInfo.hasIntervals()) {
-        start = minOf(beyondBoundsInfo.startIndex(), start)
-    }
-
     start = maxOf(0, start - beyondBoundsItemCount)
 
     for (i in currentFirstItemIndex.value - 1 downTo start) {
         addItem(i)
     }
 
-    pinnedItems.fastForEach { item ->
-        val index = itemProvider.findIndexByKey(item.key, item.index)
+    pinnedItems.fastForEach { index ->
         if (index < start) {
             addItem(index)
         }
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 02bd8ef..443ccee 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
@@ -16,8 +16,8 @@
 
 package androidx.compose.foundation.lazy
 
-import androidx.compose.animation.core.FiniteAnimationSpec
 import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.lazy.layout.LazyLayoutAnimateItemModifierNode
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.layout.Placeable
 import androidx.compose.ui.unit.IntOffset
@@ -38,7 +38,6 @@
     private val reverseLayout: Boolean,
     private val beforeContentPadding: Int,
     private val afterContentPadding: Int,
-    private val placementAnimator: LazyListItemPlacementAnimator,
     /**
      * Extra spacing to be added to [size] aside from the sum of the [placeables] size. It
      * is usually representing the spacing after the item.
@@ -78,6 +77,10 @@
         crossAxisSize = maxCrossAxis
     }
 
+    val placeablesCount: Int get() = placeables.size
+
+    fun getParentData(index: Int) = placeables[index].parentData
+
     /**
      * Calculates positions for the inner placeables at [offset] main axis position.
      * If [reverseOrder] is true the inner placeables would be placed in the inverted order.
@@ -111,7 +114,6 @@
             maxMainAxisOffset = mainAxisLayoutSize + afterContentPadding,
             isVertical = isVertical,
             wrappers = wrappers,
-            placementAnimator = placementAnimator,
             visualOffset = visualOffset,
             reverseLayout = reverseLayout,
             mainAxisLayoutSize = mainAxisLayoutSize
@@ -126,9 +128,8 @@
     override val size: Int,
     private val minMainAxisOffset: Int,
     private val maxMainAxisOffset: Int,
-    private val isVertical: Boolean,
+    val isVertical: Boolean,
     private val wrappers: List<LazyListPlaceableWrapper>,
-    private val placementAnimator: LazyListItemPlacementAnimator,
     private val visualOffset: IntOffset,
     private val reverseLayout: Boolean,
     private val mainAxisLayoutSize: Int
@@ -137,20 +138,7 @@
 
     fun getOffset(index: Int) = wrappers[index].offset
 
-    fun getMainAxisSize(index: Int) = wrappers[index].placeable.mainAxisSize
-
-    @Suppress("UNCHECKED_CAST")
-    fun getAnimationSpec(index: Int) =
-        wrappers[index].placeable.parentData as? FiniteAnimationSpec<IntOffset>?
-
-    val hasAnimations = run {
-        repeat(placeablesCount) { index ->
-            if (getAnimationSpec(index) != null) {
-                return@run true
-            }
-        }
-        false
-    }
+    fun getParentData(index: Int) = wrappers[index].placeable.parentData
 
     fun place(
         scope: Placeable.PlacementScope,
@@ -159,28 +147,33 @@
             val placeable = wrappers[index].placeable
             val minOffset = minMainAxisOffset - placeable.mainAxisSize
             val maxOffset = maxMainAxisOffset
-            val offset = if (getAnimationSpec(index) != null) {
-                placementAnimator.getAnimatedOffset(
-                    key, index, minOffset, maxOffset, getOffset(index)
-                )
-            } else {
-                getOffset(index)
+            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()
+                }
+                offset = animatedOffset
             }
-            val reverseLayoutAwareOffset = if (reverseLayout) {
-                offset.copy { mainAxisOffset ->
+            if (reverseLayout) {
+                offset = offset.copy { mainAxisOffset ->
                     mainAxisLayoutSize - mainAxisOffset - placeable.mainAxisSize
                 }
-            } else {
-                offset
             }
+            offset += visualOffset
             if (isVertical) {
-                placeable.placeWithLayer(reverseLayoutAwareOffset + visualOffset)
+                placeable.placeWithLayer(offset)
             } else {
-                placeable.placeRelativeWithLayer(reverseLayoutAwareOffset + visualOffset)
+                placeable.placeRelativeWithLayer(offset)
             }
         }
     }
 
+    private val IntOffset.mainAxis get() = if (isVertical) y else x
     private val Placeable.mainAxisSize get() = if (isVertical) height else width
     private inline fun IntOffset.copy(mainAxisMap: (Int) -> Int): IntOffset =
         IntOffset(if (isVertical) x else mainAxisMap(x), if (isVertical) mainAxisMap(y) else y)
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 c0756a3..f3d19f1 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
@@ -214,7 +214,7 @@
      */
     internal val awaitLayoutModifier = AwaitFirstLayoutModifier()
 
-    internal var placementAnimator by mutableStateOf<LazyListItemPlacementAnimator?>(null)
+    internal val placementAnimator = LazyListItemPlacementAnimator()
 
     /**
      * Constraints passed to the prefetcher for premeasuring the prefetched items.
@@ -248,7 +248,7 @@
     internal fun snapToItemIndexInternal(index: Int, scrollOffset: Int) {
         scrollPosition.requestPosition(DataIndex(index), scrollOffset)
         // placement animation is not needed because we snap into a new position.
-        placementAnimator?.reset()
+        placementAnimator.reset()
         remeasurement?.forceRemeasure()
     }
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
index 704d6ef..ec71a7b 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
@@ -33,7 +33,6 @@
 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.Modifier
 import androidx.compose.ui.layout.MeasureResult
@@ -79,12 +78,6 @@
 
     val semanticState = rememberLazyGridSemanticState(state, reverseLayout)
 
-    val scope = rememberCoroutineScope()
-    val placementAnimator = remember(state, isVertical) {
-        LazyGridItemPlacementAnimator(scope, isVertical)
-    }
-    state.placementAnimator = placementAnimator
-
     val measurePolicy = rememberLazyGridMeasurePolicy(
         itemProvider,
         state,
@@ -93,8 +86,7 @@
         reverseLayout,
         isVertical,
         horizontalArrangement,
-        verticalArrangement,
-        placementAnimator
+        verticalArrangement
     )
 
     state.isVertical = isVertical
@@ -171,8 +163,6 @@
     horizontalArrangement: Arrangement.Horizontal? = null,
     /** The vertical arrangement for items. Required when isVertical is true */
     verticalArrangement: Arrangement.Vertical? = null,
-    /** Item placement animator. Should be notified with the measuring result */
-    placementAnimator: LazyGridItemPlacementAnimator
 ) = remember<LazyLayoutMeasureScope.(Constraints) -> MeasureResult>(
     state,
     slots,
@@ -180,8 +170,7 @@
     reverseLayout,
     isVertical,
     horizontalArrangement,
-    verticalArrangement,
-    placementAnimator
+    verticalArrangement
 ) {
     { containerConstraints ->
         checkScrollableContainerConstraints(
@@ -273,8 +262,7 @@
                 beforeContentPadding = beforeContentPadding,
                 afterContentPadding = afterContentPadding,
                 visualOffset = visualItemOffset,
-                placeables = placeables,
-                placementAnimator = placementAnimator
+                placeables = placeables
             )
         }
         val measuredLineProvider = LazyGridMeasuredLineProvider(
@@ -344,7 +332,7 @@
             horizontalArrangement = horizontalArrangement,
             reverseLayout = reverseLayout,
             density = this,
-            placementAnimator = placementAnimator,
+            placementAnimator = state.placementAnimator,
             spanLayoutProvider = spanLayoutProvider,
             pinnedItems = state.pinnedItems,
             layout = { width, height, placement ->
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt
index 98ffdb3..5bdc836 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt
@@ -16,45 +16,27 @@
 
 package androidx.compose.foundation.lazy.grid
 
-import androidx.compose.animation.core.Animatable
-import androidx.compose.animation.core.Spring
-import androidx.compose.animation.core.SpringSpec
-import androidx.compose.animation.core.VectorConverter
-import androidx.compose.animation.core.VisibilityThreshold
-import androidx.compose.animation.core.spring
-import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.lazy.layout.LazyLayoutAnimateItemModifierNode
 import androidx.compose.foundation.lazy.layout.LazyLayoutKeyIndexMap
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.setValue
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.util.fastAny
 import androidx.compose.ui.util.fastForEach
-import androidx.compose.ui.util.fastForEachIndexed
-import kotlinx.coroutines.CancellationException
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
 
 /**
- * Handles the item placement animations when it is set via
- * [LazyGridItemScope.animateItemPlacement].
+ * Handles the item placement animations when it is set via [LazyGridItemScope.animateItemPlacement].
  *
  * This class is responsible for detecting when item position changed, figuring our start/end
  * offsets and starting the animations.
  */
-@OptIn(ExperimentalFoundationApi::class)
-internal class LazyGridItemPlacementAnimator(
-    private val scope: CoroutineScope,
-    private val isVertical: Boolean
-) {
-    // state containing an animation and all relevant info for each item.
+internal class LazyGridItemPlacementAnimator {
+    // state containing relevant info for active items.
     private val keyToItemInfoMap = mutableMapOf<Any, ItemInfo>()
 
     // snapshot of the key to index map used for the last measuring.
     private var keyToIndexMap: LazyLayoutKeyIndexMap = LazyLayoutKeyIndexMap.Empty
 
-    // keeps the index of the first visible item.
+    // keeps the index of the first visible item index.
     private var firstVisibleIndex = 0
 
     // stored to not allocate it every pass.
@@ -75,7 +57,8 @@
         layoutHeight: Int,
         positionedItems: MutableList<LazyGridPositionedItem>,
         itemProvider: LazyGridMeasuredItemProvider,
-        spanLayoutProvider: LazyGridSpanLayoutProvider
+        spanLayoutProvider: LazyGridSpanLayoutProvider,
+        isVertical: Boolean
     ) {
         if (!positionedItems.fastAny { it.hasAnimations } && keyToItemInfoMap.isEmpty()) {
             // no animations specified - no work needed
@@ -91,18 +74,24 @@
         val mainAxisLayoutSize = if (isVertical) layoutHeight else layoutWidth
 
         // the consumed scroll is considered as a delta we don't need to animate
-        val notAnimatableDelta = consumedScroll.toOffset()
+        val scrollOffset = if (isVertical) {
+            IntOffset(0, consumedScroll)
+        } else {
+            IntOffset(consumedScroll, 0)
+        }
 
         // first add all items we had in the previous run
         movingAwayKeys.addAll(keyToItemInfoMap.keys)
         // iterate through the items which are visible (without animated offsets)
         positionedItems.fastForEach { item ->
-            // remove items we have in the current one as they are not disappearing.
+            // remove items we have in the current one as they are still visible.
             movingAwayKeys.remove(item.key)
             if (item.hasAnimations) {
                 val itemInfo = keyToItemInfoMap[item.key]
                 // there is no state associated with this item yet
                 if (itemInfo == null) {
+                    keyToItemInfoMap[item.key] =
+                        ItemInfo(item.getCrossAxisSize(), item.getCrossAxisOffset())
                     val previousIndex = previousKeyToIndexMap[item.key]
                     if (previousIndex != -1 && item.index != previousIndex) {
                         if (previousIndex < previousFirstVisibleIndex) {
@@ -112,14 +101,22 @@
                             movingInFromEndBound.add(item)
                         }
                     } else {
-                        keyToItemInfoMap[item.key] = createItemInfo(item)
+                        initializeNode(
+                            item,
+                            item.offset.let { if (item.isVertical) it.y else it.x }
+                        )
                     }
                 } else {
-                    // this item was visible and is still visible.
-                    itemInfo.notAnimatableDelta += notAnimatableDelta // apply new scroll delta
+                    repeat(item.placeablesCount) { placeableIndex ->
+                        item.getParentData(placeableIndex).node?.apply {
+                            if (rawOffset != LazyLayoutAnimateItemModifierNode.NotInitialized) {
+                                rawOffset += scrollOffset
+                            }
+                        }
+                    }
                     itemInfo.crossAxisSize = item.getCrossAxisSize()
                     itemInfo.crossAxisOffset = item.getCrossAxisOffset()
-                    startAnimationsIfNeeded(item, itemInfo)
+                    startAnimationsIfNeeded(item)
                 }
             } else {
                 // no animation, clean up if needed
@@ -128,11 +125,11 @@
         }
 
         var currentMainAxisOffset = 0
-        movingInFromStartBound.sortByDescending { previousKeyToIndexMap[it.key] }
         var previousLine = -1
         var previousLineMainAxisSize = 0
+        movingInFromStartBound.sortByDescending { previousKeyToIndexMap[it.key] }
         movingInFromStartBound.fastForEach { item ->
-            val line = item.line
+            val line = if (isVertical) item.row else item.column
             if (line != -1 && line == previousLine) {
                 previousLineMainAxisSize = maxOf(previousLineMainAxisSize, item.getMainAxisSize())
             } else {
@@ -141,16 +138,15 @@
                 previousLine = line
             }
             val mainAxisOffset = 0 - currentMainAxisOffset - item.getMainAxisSize()
-            val itemInfo = createItemInfo(item, mainAxisOffset)
-            keyToItemInfoMap[item.key] = itemInfo
-            startAnimationsIfNeeded(item, itemInfo)
+            initializeNode(item, mainAxisOffset)
+            startAnimationsIfNeeded(item)
         }
         currentMainAxisOffset = 0
         previousLine = -1
         previousLineMainAxisSize = 0
         movingInFromEndBound.sortBy { previousKeyToIndexMap[it.key] }
         movingInFromEndBound.fastForEach { item ->
-            val line = item.line
+            val line = if (isVertical) item.row else item.column
             if (line != -1 && line == previousLine) {
                 previousLineMainAxisSize = maxOf(previousLineMainAxisSize, item.getMainAxisSize())
             } else {
@@ -159,9 +155,8 @@
                 previousLine = line
             }
             val mainAxisOffset = mainAxisLayoutSize + currentMainAxisOffset
-            val itemInfo = createItemInfo(item, mainAxisOffset)
-            keyToItemInfoMap[item.key] = itemInfo
-            startAnimationsIfNeeded(item, itemInfo)
+            initializeNode(item, mainAxisOffset)
+            startAnimationsIfNeeded(item)
         }
 
         movingAwayKeys.forEach { key ->
@@ -170,13 +165,7 @@
             val itemInfo = keyToItemInfoMap.getValue(key)
             val newIndex = keyToIndexMap[key]
 
-            // whether the animation associated with the item has been finished or not yet started
-            val inProgress = itemInfo.placeables.fastAny { it.inProgress }
-            if (itemInfo.placeables.isEmpty() ||
-                newIndex == -1 ||
-                (!inProgress && newIndex == previousKeyToIndexMap[key]) ||
-                (!inProgress && !itemInfo.isWithinBounds(mainAxisLayoutSize))
-            ) {
+            if (newIndex == -1) {
                 keyToItemInfoMap.remove(key)
             } else {
                 val item = itemProvider.getAndMeasure(
@@ -187,10 +176,22 @@
                         Constraints.fixedHeight(itemInfo.crossAxisSize)
                     }
                 )
-                if (newIndex < firstVisibleIndex) {
-                    movingAwayToStartBound.add(item)
+                // check if we have any active placement animation on the item
+                var inProgress = false
+                repeat(item.placeablesCount) {
+                    if (item.getParentData(it).node?.isAnimationInProgress == true) {
+                        inProgress = true
+                        return@repeat
+                    }
+                }
+                if ((!inProgress && newIndex == previousKeyToIndexMap[key])) {
+                    keyToItemInfoMap.remove(key)
                 } else {
-                    movingAwayToEndBound.add(item)
+                    if (newIndex < firstVisibleIndex) {
+                        movingAwayToStartBound.add(item)
+                    } else {
+                        movingAwayToEndBound.add(item)
+                    }
                 }
             }
         }
@@ -221,7 +222,7 @@
                 LazyGridItemInfo.UnknownColumn
             )
             positionedItems.add(positionedItem)
-            startAnimationsIfNeeded(positionedItem, itemInfo)
+            startAnimationsIfNeeded(positionedItem)
         }
         currentMainAxisOffset = 0
         previousLine = -1
@@ -249,7 +250,7 @@
             )
 
             positionedItems.add(positionedItem)
-            startAnimationsIfNeeded(positionedItem, itemInfo)
+            startAnimationsIfNeeded(positionedItem)
         }
 
         movingInFromStartBound.clear()
@@ -260,36 +261,6 @@
     }
 
     /**
-     * Returns the current animated item placement offset. By calling it only during the layout
-     * phase we can skip doing remeasure on every animation frame.
-     */
-    fun getAnimatedOffset(
-        key: Any,
-        placeableIndex: Int,
-        minOffset: Int,
-        maxOffset: Int,
-        rawOffset: IntOffset
-    ): IntOffset {
-        val itemInfo = keyToItemInfoMap[key] ?: return rawOffset
-        val item = itemInfo.placeables[placeableIndex]
-        val currentValue = item.animatedOffset.value + itemInfo.notAnimatableDelta
-        val currentTarget = item.targetOffset + itemInfo.notAnimatableDelta
-
-        // cancel the animation if it is fully out of the bounds.
-        if (item.inProgress &&
-            ((currentTarget.mainAxis <= minOffset && currentValue.mainAxis < minOffset) ||
-            (currentTarget.mainAxis >= maxOffset && currentValue.mainAxis > maxOffset))
-        ) {
-            scope.launch {
-                item.animatedOffset.snapTo(item.targetOffset)
-                item.inProgress = false
-            }
-        }
-
-        return currentValue
-    }
-
-    /**
      * Should be called when the animations are not needed for the next positions change,
      * for example when we snap to a new position.
      */
@@ -299,116 +270,59 @@
         firstVisibleIndex = -1
     }
 
-    private fun createItemInfo(
+    private fun initializeNode(
         item: LazyGridPositionedItem,
-        mainAxisOffset: Int = item.offset.mainAxis
-    ): ItemInfo {
-        val newItemInfo = ItemInfo(item.getCrossAxisSize(), item.getCrossAxisOffset())
-        val targetOffset = if (isVertical) {
-            item.offset.copy(y = mainAxisOffset)
+        mainAxisOffset: Int
+    ) {
+        val firstPlaceableOffset = item.offset
+
+        val targetFirstPlaceableOffset = if (item.isVertical) {
+            firstPlaceableOffset.copy(y = mainAxisOffset)
         } else {
-            item.offset.copy(x = mainAxisOffset)
+            firstPlaceableOffset.copy(x = mainAxisOffset)
         }
 
-        // populate placeable info list
+        // initialize offsets
         repeat(item.placeablesCount) { placeableIndex ->
-            newItemInfo.placeables.add(
-                PlaceableInfo(
-                    targetOffset,
-                    item.getMainAxisSize(placeableIndex)
-                )
-            )
+            val node = item.getParentData(placeableIndex).node
+            if (node != null) {
+                val diffToFirstPlaceableOffset =
+                    item.offset - firstPlaceableOffset
+                node.rawOffset = targetFirstPlaceableOffset + diffToFirstPlaceableOffset
+            }
         }
-        return newItemInfo
     }
 
-    private fun startAnimationsIfNeeded(item: LazyGridPositionedItem, itemInfo: ItemInfo) {
-        // first we make sure our item info is up to date (has the item placeables count)
-        while (itemInfo.placeables.size > item.placeablesCount) {
-            itemInfo.placeables.removeLast()
-        }
-        while (itemInfo.placeables.size < item.placeablesCount) {
-            val newPlaceableInfoIndex = itemInfo.placeables.size
-            val rawOffset = item.offset
-            itemInfo.placeables.add(
-                PlaceableInfo(
-                    rawOffset - itemInfo.notAnimatableDelta,
-                    item.getMainAxisSize(newPlaceableInfoIndex)
-                )
-            )
-        }
-
-        itemInfo.placeables.fastForEachIndexed { index, placeableInfo ->
-            val currentTarget = placeableInfo.targetOffset + itemInfo.notAnimatableDelta
-            val currentOffset = item.offset
-            placeableInfo.mainAxisSize = item.getMainAxisSize(index)
-            val animationSpec = item.getAnimationSpec(index)
-            if (currentTarget != currentOffset) {
-                placeableInfo.targetOffset = currentOffset - itemInfo.notAnimatableDelta
-                if (animationSpec != null) {
-                    placeableInfo.inProgress = true
-                    scope.launch {
-                        val finalSpec = if (placeableInfo.animatedOffset.isRunning) {
-                            // when interrupted, use the default spring, unless the spec is a spring.
-                            if (animationSpec is SpringSpec<IntOffset>) animationSpec else
-                                InterruptionSpec
-                        } else {
-                            animationSpec
-                        }
-
-                        try {
-                            placeableInfo.animatedOffset.animateTo(
-                                placeableInfo.targetOffset,
-                                finalSpec
-                            )
-                            placeableInfo.inProgress = false
-                        } catch (_: CancellationException) {
-                            // we don't reset inProgress in case of cancellation as it means
-                            // there is a new animation started which would reset it later
-                        }
-                    }
+    private fun startAnimationsIfNeeded(item: LazyGridPositionedItem) {
+        repeat(item.placeablesCount) { placeableIndex ->
+            val node = item.getParentData(placeableIndex).node
+            if (node != null) {
+                val newTarget = item.offset
+                val currentTarget = node.rawOffset
+                if (currentTarget == LazyLayoutAnimateItemModifierNode.NotInitialized) {
+                    node.rawOffset = item.offset
+                } else if (currentTarget != newTarget) {
+                    node.rawOffset = newTarget
+                    node.animatePlacementDelta(item.offset - currentTarget)
                 }
             }
         }
     }
 
-    /**
-     * Whether at least one placeable is within the viewport bounds.
-     */
-    private fun ItemInfo.isWithinBounds(mainAxisLayoutSize: Int): Boolean {
-        return placeables.fastAny {
-            val currentTarget = it.targetOffset + notAnimatableDelta
-            currentTarget.mainAxis + it.mainAxisSize > 0 &&
-                currentTarget.mainAxis < mainAxisLayoutSize
+    private val Any?.node get() = this as? LazyLayoutAnimateItemModifierNode
+
+    private val LazyGridPositionedItem.hasAnimations: Boolean
+        get() {
+            repeat(placeablesCount) { index ->
+                if (getParentData(index).node != null) {
+                    return true
+                }
+            }
+            return false
         }
-    }
-
-    private fun Int.toOffset() =
-        IntOffset(if (isVertical) 0 else this, if (!isVertical) 0 else this)
-
-    private val IntOffset.mainAxis get() = if (isVertical) y else x
-
-    private val LazyGridPositionedItem.line get() = if (isVertical) row else column
 }
 
 private class ItemInfo(
     var crossAxisSize: Int,
     var crossAxisOffset: Int
-) {
-    var notAnimatableDelta: IntOffset = IntOffset.Zero
-    val placeables = mutableListOf<PlaceableInfo>()
-}
-
-private class PlaceableInfo(initialOffset: IntOffset, var mainAxisSize: Int) {
-    val animatedOffset = Animatable(initialOffset, IntOffset.VectorConverter)
-    var targetOffset: IntOffset = initialOffset
-    var inProgress by mutableStateOf(false)
-}
-
-/**
- * We switch to this spec when a duration based animation is being interrupted.
- */
-private val InterruptionSpec = spring(
-    stiffness = Spring.StiffnessMediumLow,
-    visibilityThreshold = IntOffset.VisibilityThreshold
 )
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemScopeImpl.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemScopeImpl.kt
index 79d7926..f8dda36 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemScopeImpl.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemScopeImpl.kt
@@ -18,7 +18,9 @@
 
 import androidx.compose.animation.core.FiniteAnimationSpec
 import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.lazy.layout.LazyLayoutAnimateItemModifierNode
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.node.DelegatingNode
 import androidx.compose.ui.node.ModifierNodeElement
 import androidx.compose.ui.node.ParentDataModifierNode
 import androidx.compose.ui.platform.InspectorInfo
@@ -35,10 +37,11 @@
 private class AnimateItemPlacementElement(
     val animationSpec: FiniteAnimationSpec<IntOffset>
 ) : ModifierNodeElement<AnimateItemPlacementNode>() {
+
     override fun create(): AnimateItemPlacementNode = AnimateItemPlacementNode(animationSpec)
 
     override fun update(node: AnimateItemPlacementNode): AnimateItemPlacementNode = node.also {
-        it.animationSpec = animationSpec
+        it.delegatingNode.placementAnimationSpec = animationSpec
     }
 
     override fun equals(other: Any?): Boolean {
@@ -58,7 +61,10 @@
 }
 
 private class AnimateItemPlacementNode(
-    var animationSpec: FiniteAnimationSpec<IntOffset>
-) : Modifier.Node(), ParentDataModifierNode {
-    override fun Density.modifyParentData(parentData: Any?): Any = animationSpec
+    animationSpec: FiniteAnimationSpec<IntOffset>
+) : DelegatingNode(), ParentDataModifierNode {
+
+    val delegatingNode = delegated { LazyLayoutAnimateItemModifierNode(animationSpec) }
+
+    override fun Density.modifyParentData(parentData: Any?): Any = delegatingNode
 }
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 6d18f7b..b22522a 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
@@ -274,7 +274,8 @@
             layoutHeight = layoutHeight,
             positionedItems = positionedItems,
             itemProvider = measuredItemProvider,
-            spanLayoutProvider = spanLayoutProvider
+            spanLayoutProvider = spanLayoutProvider,
+            isVertical = isVertical
         )
 
         return LazyGridMeasureResult(
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt
index eff4278..481564d 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt
@@ -16,8 +16,7 @@
 
 package androidx.compose.foundation.lazy.grid
 
-import androidx.compose.animation.core.FiniteAnimationSpec
-import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.lazy.layout.LazyLayoutAnimateItemModifierNode
 import androidx.compose.ui.layout.Placeable
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.IntSize
@@ -28,7 +27,6 @@
  * Represents one measured item of the lazy grid. It can in fact consist of multiple placeables
  * if the user emit multiple layout nodes in the item callback.
  */
-@OptIn(ExperimentalFoundationApi::class)
 internal class LazyGridMeasuredItem(
     val index: ItemIndex,
     val key: Any,
@@ -44,7 +42,6 @@
     private val beforeContentPadding: Int,
     private val afterContentPadding: Int,
     val placeables: List<Placeable>,
-    private val placementAnimator: LazyGridItemPlacementAnimator,
     /**
      * The offset which shouldn't affect any calculations but needs to be applied for the final
      * value passed into the place() call.
@@ -61,6 +58,10 @@
      */
     val mainAxisSizeWithSpacings: Int
 
+    val placeablesCount: Int get() = placeables.size
+
+    fun getParentData(index: Int) = placeables[index].parentData
+
     init {
         var maxMainAxis = 0
         placeables.fastForEach {
@@ -112,7 +113,6 @@
             maxMainAxisOffset = mainAxisLayoutSize + afterContentPadding,
             isVertical = isVertical,
             placeables = placeables,
-            placementAnimator = placementAnimator,
             visualOffset = visualOffset,
             mainAxisLayoutSize = mainAxisLayoutSize,
             reverseLayout = reverseLayout
@@ -129,35 +129,21 @@
     override val size: IntSize,
     private val minMainAxisOffset: Int,
     private val maxMainAxisOffset: Int,
-    private val isVertical: Boolean,
+    val isVertical: Boolean,
     private val placeables: List<Placeable>,
-    private val placementAnimator: LazyGridItemPlacementAnimator,
     private val visualOffset: IntOffset,
     private val mainAxisLayoutSize: Int,
     private val reverseLayout: Boolean
 ) : LazyGridItemInfo {
     val placeablesCount: Int get() = placeables.size
 
-    fun getMainAxisSize(index: Int) = placeables[index].mainAxisSize
-
     fun getMainAxisSize() = if (isVertical) size.height else size.width
 
     fun getCrossAxisSize() = if (isVertical) size.width else size.height
 
     fun getCrossAxisOffset() = if (isVertical) offset.x else offset.y
 
-    @Suppress("UNCHECKED_CAST")
-    fun getAnimationSpec(index: Int) =
-        placeables[index].parentData as? FiniteAnimationSpec<IntOffset>?
-
-    val hasAnimations = run {
-        repeat(placeablesCount) { index ->
-            if (getAnimationSpec(index) != null) {
-                return@run true
-            }
-        }
-        false
-    }
+    fun getParentData(index: Int) = placeables[index].parentData
 
     fun place(
         scope: Placeable.PlacementScope,
@@ -166,29 +152,34 @@
             val placeable = placeables[index]
             val minOffset = minMainAxisOffset - placeable.mainAxisSize
             val maxOffset = maxMainAxisOffset
-            val offset = if (getAnimationSpec(index) != null) {
-                placementAnimator.getAnimatedOffset(
-                    key, index, minOffset, maxOffset, offset
-                )
-            } else {
-                offset
-            }
 
-            val reverseLayoutAwareOffset = if (reverseLayout) {
-                offset.copy { mainAxisOffset ->
+            var offset = offset
+            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()
+                }
+                offset = animatedOffset
+            }
+            if (reverseLayout) {
+                offset = offset.copy { mainAxisOffset ->
                     mainAxisLayoutSize - mainAxisOffset - placeable.mainAxisSize
                 }
-            } else {
-                offset
             }
+            offset += visualOffset
             if (isVertical) {
-                placeable.placeWithLayer(reverseLayoutAwareOffset + visualOffset)
+                placeable.placeWithLayer(offset)
             } else {
-                placeable.placeRelativeWithLayer(reverseLayoutAwareOffset + visualOffset)
+                placeable.placeRelativeWithLayer(offset)
             }
         }
     }
 
+    private val IntOffset.mainAxis get() = if (isVertical) y else x
     private val Placeable.mainAxisSize get() = if (isVertical) height else width
     private inline fun IntOffset.copy(mainAxisMap: (Int) -> Int): IntOffset =
         IntOffset(if (isVertical) x else mainAxisMap(x), if (isVertical) mainAxisMap(y) else y)
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 25fd5f5..87934a4 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,7 @@
     internal var prefetchInfoRetriever: (line: LineIndex) -> List<Pair<Int, Constraints>> by
         mutableStateOf({ emptyList() })
 
-    internal var placementAnimator by mutableStateOf<LazyGridItemPlacementAnimator?>(null)
+    internal val placementAnimator = LazyGridItemPlacementAnimator()
 
     private val animateScrollScope = LazyGridAnimateScrollScope(this)
 
@@ -254,7 +254,7 @@
     internal fun snapToItemIndexInternal(index: Int, scrollOffset: Int) {
         scrollPosition.requestPosition(ItemIndex(index), scrollOffset)
         // placement animation is not needed because we snap into a new position.
-        placementAnimator?.reset()
+        placementAnimator.reset()
         remeasurement?.forceRemeasure()
     }
 
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
new file mode 100644
index 0000000..5623db2
--- /dev/null
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutAnimateItemModifierNode.kt
@@ -0,0 +1,127 @@
+/*
+ * 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.foundation.lazy.layout
+
+import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.FiniteAnimationSpec
+import androidx.compose.animation.core.Spring
+import androidx.compose.animation.core.SpringSpec
+import androidx.compose.animation.core.VectorConverter
+import androidx.compose.animation.core.VisibilityThreshold
+import androidx.compose.animation.core.spring
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.IntOffset
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.launch
+
+internal class LazyLayoutAnimateItemModifierNode(
+    var placementAnimationSpec: FiniteAnimationSpec<IntOffset>
+) : Modifier.Node() {
+
+    /**
+     * Returns true when the placement animation is currently in progress so the parent
+     * should continue composing this item.
+     */
+    var isAnimationInProgress by mutableStateOf(false)
+        private set
+
+    /**
+     * This property is managed by the animation manager and is not directly used by this class.
+     * It represents the last known offset of this item in the lazy layout coordinate space.
+     * It will be updated on every scroll and is allowing the manager to track when the item
+     * position changes not because of the scroll event in order to start the animation.
+     * When there is an active animation it represents the final/target offset.
+     */
+    var rawOffset: IntOffset = NotInitialized
+
+    private val placementDeltaAnimation = Animatable(IntOffset.Zero, IntOffset.VectorConverter)
+
+    /**
+     * Current delta to apply for a placement offset. Updates every animation frame.
+     * The settled value is [IntOffset.Zero] so the animation is always targeting this value.
+     */
+    var placementDelta by mutableStateOf(IntOffset.Zero)
+        private set
+
+    /**
+     * Cancels the ongoing animation if there is one.
+     */
+    fun cancelAnimation() {
+        if (isAnimationInProgress) {
+            coroutineScope.launch {
+                placementDeltaAnimation.snapTo(IntOffset.Zero)
+                placementDelta = IntOffset.Zero
+                isAnimationInProgress = false
+            }
+        }
+    }
+
+    /**
+     * Animate the placement by the given [delta] offset.
+     */
+    fun animatePlacementDelta(delta: IntOffset) {
+        val totalDelta = placementDelta - delta
+        placementDelta = totalDelta
+        isAnimationInProgress = true
+        coroutineScope.launch {
+            try {
+                val spec = if (placementDeltaAnimation.isRunning) {
+                    // when interrupted, use the default spring, unless the spec is a spring.
+                    if (placementAnimationSpec is SpringSpec<IntOffset>) {
+                        placementAnimationSpec
+                    } else {
+                        InterruptionSpec
+                    }
+                } else {
+                    placementAnimationSpec
+                }
+                val startVelocity = placementDeltaAnimation.velocity
+                placementDeltaAnimation.snapTo(totalDelta)
+                placementDeltaAnimation.animateTo(IntOffset.Zero, spec, startVelocity) {
+                    placementDelta = value
+                }
+
+                isAnimationInProgress = false
+            } catch (_: CancellationException) {
+                // we don't reset inProgress in case of cancellation as it means
+                // there is a new animation started which would reset it later
+            }
+        }
+    }
+
+    override fun onDetach() {
+        placementDelta = IntOffset.Zero
+        isAnimationInProgress = false
+        rawOffset = NotInitialized
+        // placementDeltaAnimation will be canceled because coroutineScope will be canceled.
+    }
+
+    companion object {
+        val NotInitialized = IntOffset(Int.MAX_VALUE, Int.MAX_VALUE)
+    }
+}
+
+/**
+ * We switch to this spec when a duration based animation is being interrupted.
+ */
+private val InterruptionSpec = spring(
+    stiffness = Spring.StiffnessMediumLow,
+    visibilityThreshold = IntOffset.VisibilityThreshold
+)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutBeyondBoundsModifierLocal.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutBeyondBoundsModifierLocal.kt
index 939fe3e..822a91c 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutBeyondBoundsModifierLocal.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutBeyondBoundsModifierLocal.kt
@@ -62,11 +62,12 @@
         }
 
         // We use a new interval each time because this function is re-entrant.
-        var interval = beyondBoundsInfo.addInterval(
-            state.firstVisibleIndex,
+        val startIndex = if (direction.isForward()) {
             state.lastVisibleIndex
-        )
-
+        } else {
+            state.firstVisibleIndex
+        }
+        var interval = beyondBoundsInfo.addInterval(startIndex, startIndex)
         var found: T? = null
         while (found == null && interval.hasMoreContent(direction)) {
 
@@ -91,49 +92,40 @@
         return found
     }
 
+    private fun BeyondBoundsLayout.LayoutDirection.isForward(): Boolean =
+        when (this) {
+            Before -> false
+            After -> true
+            Above -> reverseLayout
+            Below -> !reverseLayout
+            Left -> when (layoutDirection) {
+                Ltr -> reverseLayout
+                Rtl -> !reverseLayout
+            }
+            Right -> when (layoutDirection) {
+                Ltr -> !reverseLayout
+                Rtl -> reverseLayout
+            }
+            else -> unsupportedDirection()
+        }
+
     private fun addNextInterval(
         currentInterval: Interval,
         direction: BeyondBoundsLayout.LayoutDirection
     ): Interval {
         var start = currentInterval.start
         var end = currentInterval.end
-        when (direction) {
-            Before -> start--
-            After -> end++
-            Above -> if (reverseLayout) end++ else start--
-            Below -> if (reverseLayout) start-- else end++
-            Left -> when (layoutDirection) {
-                Ltr -> if (reverseLayout) end++ else start--
-                Rtl -> if (reverseLayout) start-- else end++
-            }
-            Right -> when (layoutDirection) {
-                Ltr -> if (reverseLayout) start-- else end++
-                Rtl -> if (reverseLayout) end++ else start--
-            }
-            else -> unsupportedDirection()
+        if (direction.isForward()) {
+            end++
+        } else {
+            start--
         }
         return beyondBoundsInfo.addInterval(start, end)
     }
 
     private fun Interval.hasMoreContent(direction: BeyondBoundsLayout.LayoutDirection): Boolean {
-        fun hasMoreItemsBefore() = start > 0
-        fun hasMoreItemsAfter() = end < state.itemCount - 1
         if (direction.isOppositeToOrientation()) return false
-        return when (direction) {
-            Before -> hasMoreItemsBefore()
-            After -> hasMoreItemsAfter()
-            Above -> if (reverseLayout) hasMoreItemsAfter() else hasMoreItemsBefore()
-            Below -> if (reverseLayout) hasMoreItemsBefore() else hasMoreItemsAfter()
-            Left -> when (layoutDirection) {
-                Ltr -> if (reverseLayout) hasMoreItemsAfter() else hasMoreItemsBefore()
-                Rtl -> if (reverseLayout) hasMoreItemsBefore() else hasMoreItemsAfter()
-            }
-            Right -> when (layoutDirection) {
-                Ltr -> if (reverseLayout) hasMoreItemsBefore() else hasMoreItemsAfter()
-                Rtl -> if (reverseLayout) hasMoreItemsAfter() else hasMoreItemsBefore()
-            }
-            else -> unsupportedDirection()
-        }
+        return if (direction.isForward()) end < state.itemCount - 1 else start > 0
     }
 
     private fun BeyondBoundsLayout.LayoutDirection.isOppositeToOrientation(): Boolean {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/LongPressTextDragObserver.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/LongPressTextDragObserver.kt
index 49c2cb8..d848b79 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/LongPressTextDragObserver.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/LongPressTextDragObserver.kt
@@ -23,6 +23,7 @@
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.input.pointer.PointerInputScope
 import androidx.compose.ui.util.fastAny
+import kotlinx.coroutines.CoroutineStart
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.launch
 
@@ -78,10 +79,10 @@
     observer: TextDragObserver
 ) {
     coroutineScope {
-        launch {
+        launch(start = CoroutineStart.UNDISPATCHED) {
             detectPreDragGesturesWithObserver(observer)
         }
-        launch {
+        launch(start = CoroutineStart.UNDISPATCHED) {
             detectDragGesturesWithObserver(observer)
         }
     }
diff --git a/compose/material/material/api/public_plus_experimental_current.txt b/compose/material/material/api/public_plus_experimental_current.txt
index 7f65e18..0a71de1 100644
--- a/compose/material/material/api/public_plus_experimental_current.txt
+++ b/compose/material/material/api/public_plus_experimental_current.txt
@@ -76,7 +76,7 @@
   }
 
   @androidx.compose.material.ExperimentalMaterialApi public final class BottomDrawerState {
-    ctor public BottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
+    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();
@@ -96,7 +96,8 @@
   }
 
   public static final class BottomDrawerState.Companion {
-    method 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);
+    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 {
@@ -129,6 +130,7 @@
   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);
   }
@@ -144,7 +146,7 @@
   }
 
   @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BottomSheetState {
-    ctor 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);
+    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();
@@ -162,7 +164,8 @@
   }
 
   public static final class BottomSheetState.Companion {
-    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);
+    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);
+    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);
   }
 
   @androidx.compose.material.ExperimentalMaterialApi public enum BottomSheetValue {
@@ -370,6 +373,7 @@
 
   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);
@@ -528,7 +532,8 @@
 
   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 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 @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 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 @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);
     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);
@@ -549,7 +554,8 @@
   }
 
   public static final class ModalBottomSheetState.Companion {
-    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);
+    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);
+    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 @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);
   }
 
@@ -733,13 +739,13 @@
   }
 
   @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class SwipeProgress<T> {
-    ctor public SwipeProgress(T? from, T? to, float fraction);
+    ctor public SwipeProgress(T from, T to, float fraction);
     method public float getFraction();
-    method public T! getFrom();
-    method public T! getTo();
+    method public T getFrom();
+    method public T getTo();
     property public final float fraction;
-    property public final T! from;
-    property public final T! to;
+    property public final T from;
+    property public final T to;
   }
 
   public final class SwipeToDismissKt {
@@ -764,9 +770,9 @@
   }
 
   @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();
+    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();
@@ -775,8 +781,8 @@
     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;
+    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;
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BackdropScaffoldTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BackdropScaffoldTest.kt
index 5e68ba7..274fd8d 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BackdropScaffoldTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BackdropScaffoldTest.kt
@@ -89,7 +89,10 @@
                 headerHeight = headerHeight,
                 appBar = { Box(Modifier.height(peekHeight)) },
                 backLayerContent = { Box(Modifier.height(contentHeight)) },
-                frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+                frontLayerContent = { Box(
+                    Modifier
+                        .fillMaxSize()
+                        .testTag(frontLayer)) }
             )
         }
 
@@ -107,7 +110,10 @@
                 headerHeight = headerHeight,
                 appBar = { Box(Modifier.height(peekHeight)) },
                 backLayerContent = { Box(Modifier.height(contentHeight)) },
-                frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+                frontLayerContent = { Box(
+                    Modifier
+                        .fillMaxSize()
+                        .testTag(frontLayer)) }
             )
         }
 
@@ -131,7 +137,10 @@
                 headerHeight = headerHeight,
                 appBar = { Box(Modifier.height(peekHeight)) },
                 backLayerContent = { Box(Modifier.height(contentHeight)) },
-                frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+                frontLayerContent = { Box(
+                    Modifier
+                        .fillMaxSize()
+                        .testTag(frontLayer)) }
             )
         }
 
@@ -149,7 +158,10 @@
                 headerHeight = headerHeight,
                 appBar = { Box(Modifier.height(peekHeight)) },
                 backLayerContent = { Box(Modifier.height(contentHeight)) },
-                frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+                frontLayerContent = { Box(
+                    Modifier
+                        .fillMaxSize()
+                        .testTag(frontLayer)) }
             )
         }
 
@@ -173,7 +185,10 @@
                 headerHeight = headerHeight,
                 appBar = { Box(Modifier.height(peekHeight)) },
                 backLayerContent = { Box(Modifier.fillMaxHeight()) },
-                frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+                frontLayerContent = { Box(
+                    Modifier
+                        .fillMaxSize()
+                        .testTag(frontLayer)) }
             )
         }
 
@@ -191,7 +206,10 @@
                 persistentAppBar = false,
                 appBar = { Box(Modifier.height(peekHeight)) },
                 backLayerContent = { Box(Modifier.height(contentHeight)) },
-                frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+                frontLayerContent = { Box(
+                    Modifier
+                        .fillMaxSize()
+                        .testTag(frontLayer)) }
             )
         }
 
@@ -209,7 +227,10 @@
                 stickyFrontLayer = false,
                 appBar = { Box(Modifier.height(peekHeight)) },
                 backLayerContent = { Box(Modifier.height(contentHeight)) },
-                frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+                frontLayerContent = { Box(
+                    Modifier
+                        .fillMaxSize()
+                        .testTag(frontLayer)) }
             )
         }
 
@@ -229,7 +250,10 @@
                 headerHeight = headerHeight,
                 appBar = { Box(Modifier.height(peekHeight)) },
                 backLayerContent = { Box(Modifier.height(contentHeight)) },
-                frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+                frontLayerContent = { Box(
+                    Modifier
+                        .fillMaxSize()
+                        .testTag(frontLayer)) }
             )
         }
 
@@ -262,7 +286,10 @@
                 headerHeight = headerHeight,
                 appBar = { Box(Modifier.height(peekHeight)) },
                 backLayerContent = { Box(Modifier.height(contentHeight)) },
-                frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+                frontLayerContent = { Box(
+                    Modifier
+                        .fillMaxSize()
+                        .testTag(frontLayer)) }
             )
         }
 
@@ -296,7 +323,10 @@
                 headerHeight = headerHeight,
                 appBar = { Box(Modifier.height(peekHeight)) },
                 backLayerContent = { Box(Modifier.height(contentHeight)) },
-                frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+                frontLayerContent = { Box(
+                    Modifier
+                        .fillMaxSize()
+                        .testTag(frontLayer)) }
             )
         }
 
@@ -334,7 +364,11 @@
                     )
                 },
                 frontLayerContent = {
-                    Box(Modifier.height(1000.dp).testTag(frontLayer).background(Color.Yellow))
+                    Box(
+                        Modifier
+                            .height(1000.dp)
+                            .testTag(frontLayer)
+                            .background(Color.Yellow))
                 }
             )
         }
@@ -361,7 +395,10 @@
     @Test
     fun backdropScaffold_animatesAsSideEffect() {
         lateinit var scope: CoroutineScope
-        val bottomSheetState = ModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)
+        val bottomSheetState = ModalBottomSheetState(
+            initialValue = ModalBottomSheetValue.Hidden,
+            density = rule.density
+        )
 
         @Composable
         fun BottomSheet(message: String?) {
@@ -483,7 +520,10 @@
                 frontLayerScrimColor = Color.Red,
                 appBar = { Box(Modifier.height(peekHeight)) },
                 backLayerContent = { Box(Modifier.height(contentHeight)) },
-                frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+                frontLayerContent = { Box(
+                    Modifier
+                        .fillMaxSize()
+                        .testTag(frontLayer)) }
             )
         }
 
@@ -513,7 +553,10 @@
                 frontLayerScrimColor = Color.Unspecified,
                 appBar = { Box(Modifier.height(peekHeight)) },
                 backLayerContent = { Box(Modifier.height(contentHeight)) },
-                frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+                frontLayerContent = { Box(
+                    Modifier
+                        .fillMaxSize()
+                        .testTag(frontLayer)) }
             )
         }
 
@@ -549,7 +592,10 @@
                 frontLayerScrimColor = Color.Red,
                 appBar = { Box(Modifier.height(peekHeight)) },
                 backLayerContent = { Box(Modifier.height(contentHeight)) },
-                frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+                frontLayerContent = { Box(
+                    Modifier
+                        .fillMaxSize()
+                        .testTag(frontLayer)) }
             )
         }
 
@@ -582,9 +628,12 @@
                 backLayerContent = { Box(Modifier.height(contentHeight)) },
                 frontLayerContent = {
                     Box(
-                        Modifier.fillMaxSize().testTag(frontLayer).clickable {
-                            frontLayerClicks += 1
-                        }
+                        Modifier
+                            .fillMaxSize()
+                            .testTag(frontLayer)
+                            .clickable {
+                                frontLayerClicks += 1
+                            }
                     )
                 }
             )
@@ -621,9 +670,12 @@
                 backLayerContent = { Box(Modifier.height(contentHeight)) },
                 frontLayerContent = {
                     Box(
-                        Modifier.fillMaxSize().testTag(frontLayer).clickable {
-                            frontLayerClicks += 1
-                        }
+                        Modifier
+                            .fillMaxSize()
+                            .testTag(frontLayer)
+                            .clickable {
+                                frontLayerClicks += 1
+                            }
                     )
                 }
             )
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/DrawerTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/DrawerTest.kt
index 3328ced..d72ea8f 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/DrawerTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/DrawerTest.kt
@@ -1397,7 +1397,7 @@
     fun bottomDrawer_shortSheet_sizeChanges_snapsToNewTarget() {
         var size by mutableStateOf(56.dp)
 
-        val state = BottomDrawerState(BottomDrawerValue.Expanded)
+        val state = BottomDrawerState(BottomDrawerValue.Expanded, density = rule.density)
         rule.setMaterialContent {
             BottomDrawer(
                 drawerState = state,
@@ -1425,7 +1425,7 @@
     @OptIn(ExperimentalMaterialApi::class)
     @Test
     fun bottomDrawer_shortDrawer_anchorChangeHandler_previousTargetNotInAnchors_reconciles() {
-        val drawerState = BottomDrawerState(BottomDrawerValue.Closed)
+        val drawerState = BottomDrawerState(BottomDrawerValue.Closed, density = rule.density)
         var hasDrawerContent by mutableStateOf(false) // Start out with empty drawer content
         lateinit var scope: CoroutineScope
         rule.setMaterialContent {
@@ -1461,7 +1461,7 @@
     @OptIn(ExperimentalMaterialApi::class)
     @Test
     fun bottomDrawer_tallDrawer_anchorChangeHandler_previousTargetNotInAnchors_reconciles() {
-        val drawerState = BottomDrawerState(BottomDrawerValue.Closed)
+        val drawerState = BottomDrawerState(BottomDrawerValue.Closed, density = rule.density)
         var hasDrawerContent by mutableStateOf(false) // Start out with empty drawer content
         lateinit var scope: CoroutineScope
         rule.setContent {
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetStateTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetStateTest.kt
index e4e6e99..15f9365 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetStateTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetStateTest.kt
@@ -105,8 +105,9 @@
         density: Density
     ) = ModalBottomSheetState(
         initialValue,
+        density,
         animationSpec,
         confirmValueChange,
         isSkipHalfExpanded,
-    ).apply { swipeableState.density = density }
+    )
 }
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetTest.kt
index 86c4206..ec5503d 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetTest.kt
@@ -550,14 +550,20 @@
                 modifier = Modifier.testTag(topTag),
                 scrimColor = scrimColor.value,
                 sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.HalfExpanded),
-                content = { Box(
-                    Modifier
-                        .fillMaxSize()
-                        .testTag(contentTag)) },
-                sheetContent = { Box(
-                    Modifier
-                        .fillMaxSize()
-                        .testTag(sheetTag)) }
+                content = {
+                    Box(
+                        Modifier
+                            .fillMaxSize()
+                            .testTag(contentTag)
+                    )
+                },
+                sheetContent = {
+                    Box(
+                        Modifier
+                            .fillMaxSize()
+                            .testTag(sheetTag)
+                    )
+                }
             )
             closeSheet = getString(Strings.CloseSheet)
         }
@@ -714,14 +720,20 @@
             ModalBottomSheetLayout(
                 modifier = Modifier.testTag(topTag),
                 sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.HalfExpanded),
-                content = { Box(
-                    Modifier
-                        .fillMaxSize()
-                        .testTag(contentTag)) },
-                sheetContent = { Box(
-                    Modifier
-                        .fillMaxSize()
-                        .testTag(sheetTag)) }
+                content = {
+                    Box(
+                        Modifier
+                            .fillMaxSize()
+                            .testTag(contentTag)
+                    )
+                },
+                sheetContent = {
+                    Box(
+                        Modifier
+                            .fillMaxSize()
+                            .testTag(sheetTag)
+                    )
+                }
             )
         }
 
@@ -751,10 +763,13 @@
             ModalBottomSheetLayout(
                 modifier = Modifier.testTag(topTag),
                 sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden),
-                content = { Box(
-                    Modifier
-                        .fillMaxSize()
-                        .testTag(contentTag)) },
+                content = {
+                    Box(
+                        Modifier
+                            .fillMaxSize()
+                            .testTag(contentTag)
+                    )
+                },
                 sheetContent = {
                     Box(
                         Modifier
@@ -780,17 +795,23 @@
     fun modalBottomSheet_missingAnchors_findsClosest() {
         val topTag = "ModalBottomSheetLayout"
         var showShortContent by mutableStateOf(false)
-        val sheetState = ModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)
+        val sheetState = ModalBottomSheetState(
+            initialValue = ModalBottomSheetValue.Hidden,
+            density = rule.density
+        )
         lateinit var scope: CoroutineScope
         rule.setMaterialContent {
             scope = rememberCoroutineScope()
             ModalBottomSheetLayout(
                 modifier = Modifier.testTag(topTag),
                 sheetState = sheetState,
-                content = { Box(
-                    Modifier
-                        .fillMaxSize()
-                        .testTag(contentTag)) },
+                content = {
+                    Box(
+                        Modifier
+                            .fillMaxSize()
+                            .testTag(contentTag)
+                    )
+                },
                 sheetContent = {
                     if (showShortContent) {
                         Box(
@@ -1140,7 +1161,7 @@
 
     @Test
     fun modalBottomSheet_shortSheet_anchorChangeHandler_previousTargetNotInAnchors_reconciles() {
-        val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden)
+        val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden, density = rule.density)
         var hasSheetContent by mutableStateOf(false) // Start out with empty sheet content
         lateinit var scope: CoroutineScope
         rule.setContent {
@@ -1175,7 +1196,7 @@
 
     @Test
     fun modalBottomSheet_tallSheet_anchorChangeHandler_previousTargetNotInAnchors_reconciles() {
-        val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden)
+        val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden, density = rule.density)
         var hasSheetContent by mutableStateOf(false) // Start out with empty sheet content
         lateinit var scope: CoroutineScope
         rule.setContent {
@@ -1214,7 +1235,8 @@
         val stateRestorationTester = StateRestorationTester(rule)
 
         // Not backed by state as we don't want changes to cause recompositions
-        var sheetState = ModalBottomSheetState(ModalBottomSheetValue.HalfExpanded)
+        var sheetState =
+            ModalBottomSheetState(ModalBottomSheetValue.HalfExpanded, density = rule.density)
         var tallSheetContent = true
 
         stateRestorationTester.setContent {
@@ -1232,7 +1254,8 @@
 
         tallSheetContent = false
         // Recreate the sheet state so it doesn't have anchors or an offset yet
-        sheetState = ModalBottomSheetState(ModalBottomSheetValue.HalfExpanded)
+        sheetState =
+            ModalBottomSheetState(ModalBottomSheetValue.HalfExpanded, density = rule.density)
 
         assertThat(sheetState.swipeableState.anchors).isEmpty()
         assertThat(sheetState.swipeableState.offset).isNull()
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableBox.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableBox.kt
deleted file mode 100644
index 6ea5bee..0000000
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableBox.kt
+++ /dev/null
@@ -1,111 +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:OptIn(ExperimentalMaterialApi::class)
-
-package androidx.compose.material.swipeable
-
-import androidx.compose.foundation.background
-import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.offset
-import androidx.compose.foundation.layout.requiredSize
-import androidx.compose.material.ExperimentalMaterialApi
-import androidx.compose.material.SwipeableV2State
-import androidx.compose.material.swipeAnchors
-import androidx.compose.material.swipeableV2
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.platform.testTag
-import androidx.compose.ui.unit.IntOffset
-import androidx.compose.ui.unit.IntSize
-import androidx.compose.ui.unit.dp
-import kotlin.math.roundToInt
-
-@Composable
-internal fun SwipeableBox(
-    swipeableState: SwipeableV2State<TestState>,
-    orientation: Orientation = Orientation.Horizontal,
-    possibleStates: Set<TestState> = setOf(
-        TestState.A,
-        TestState.B,
-        TestState.C
-    ),
-    enabled: Boolean = true,
-    reverseDirection: Boolean = false,
-    anchors: Map<TestState, Float>
-) = SwipeableBox(
-    swipeableState = swipeableState,
-    orientation = orientation,
-    possibleStates = possibleStates,
-    enabled = enabled,
-    reverseDirection = reverseDirection,
-    calculateAnchor = { anchor, _ -> anchors[anchor] }
-)
-
-@Composable
-internal fun SwipeableBox(
-    swipeableState: SwipeableV2State<TestState>,
-    orientation: Orientation = Orientation.Horizontal,
-    possibleStates: Set<TestState> = setOf(
-        TestState.A,
-        TestState.B,
-        TestState.C
-    ),
-    enabled: Boolean = true,
-    reverseDirection: Boolean = false,
-    calculateAnchor: (anchor: TestState, layoutSize: IntSize) -> Float? = { state, layoutSize ->
-        val size = (
-            if (orientation == Orientation.Horizontal) layoutSize.width else layoutSize.height
-            ).toFloat()
-        when (state) {
-            TestState.A -> 0f
-            TestState.B -> size / 2
-            TestState.C -> size
-        }
-    }
-) = Box(Modifier.fillMaxSize()) {
-    Box(
-        Modifier
-            .requiredSize(swipeableSize)
-            .testTag(swipeableTestTag)
-            .swipeableV2(
-                state = swipeableState,
-                orientation = orientation,
-                enabled = enabled,
-                reverseDirection = reverseDirection
-            )
-            .swipeAnchors(
-                state = swipeableState,
-                possibleValues = possibleStates,
-                calculateAnchor = calculateAnchor
-            )
-            .offset {
-                val currentOffset = (swipeableState.offset ?: 0f).roundToInt()
-                val x = if (orientation == Orientation.Horizontal) currentOffset else 0
-                val y = if (orientation == Orientation.Vertical) currentOffset else 0
-                IntOffset(x, y)
-            }
-            .background(Color.Red)
-    )
-}
-
-internal const val swipeableTestTag = "swipebox"
-internal val swipeableSize = 200.dp
-
-internal enum class TestState { A, B, C }
\ No newline at end of file
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableTestValue.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableTestValue.kt
new file mode 100644
index 0000000..e24c752
--- /dev/null
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableTestValue.kt
@@ -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.
+ */
+
+@file:OptIn(ExperimentalMaterialApi::class)
+
+package androidx.compose.material.swipeable
+
+import androidx.compose.material.ExperimentalMaterialApi
+
+internal enum class SwipeableTestValue { A, B, C }
\ No newline at end of file
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2AnchorTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2AnchorTest.kt
index 8e50ab4..3285fcc 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2AnchorTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2AnchorTest.kt
@@ -19,27 +19,22 @@
 import androidx.compose.animation.core.LinearEasing
 import androidx.compose.animation.core.tween
 import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.requiredHeight
 import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.foundation.layout.size
-import androidx.compose.material.AnchorChangeHandler
+import androidx.compose.material.SwipeableV2State.AnchorChangedCallback
 import androidx.compose.material.ExperimentalMaterialApi
-import androidx.compose.material.SwipeableV2Defaults
+import androidx.compose.material.SwipeableV2Defaults.ReconcileAnimationOnAnchorChangedCallback
 import androidx.compose.material.SwipeableV2State
-import androidx.compose.material.fractionalPositionalThreshold
-import androidx.compose.material.rememberSwipeableV2State
-import androidx.compose.material.swipeAnchors
-import androidx.compose.material.swipeable.TestState.A
-import androidx.compose.material.swipeable.TestState.B
-import androidx.compose.material.swipeable.TestState.C
+import androidx.compose.material.swipeable.SwipeableTestValue.A
+import androidx.compose.material.swipeable.SwipeableTestValue.B
+import androidx.compose.material.swipeable.SwipeableTestValue.C
 import androidx.compose.runtime.getValue
-import androidx.compose.runtime.key
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.onSizeChanged
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.IntSize
@@ -62,107 +57,9 @@
     val rule = createComposeRule()
 
     @Test
-    fun swipeable_swipeAnchors_updatedInSameFrame() {
-        rule.mainClock.autoAdvance = false
-
-        var compositionCounter = 0
-        lateinit var state: SwipeableV2State<TestState>
-
-        rule.setContent {
-            state = rememberSwipeableV2State(initialValue = A)
-            compositionCounter++
-            Box(
-                Modifier
-                    .height(200.dp)
-                    .swipeAnchors(
-                        state,
-                        possibleValues = setOf(A, B, C)
-                    ) { state, layoutSize ->
-                        when (state) {
-                            A -> 0f
-                            B -> layoutSize.height.toFloat() / 2
-                            C -> layoutSize.height.toFloat()
-                        }
-                    }
-            )
-        }
-        // Verify composed initially but didn't recompose
-        assertThat(compositionCounter).isEqualTo(1)
-        // Verify that the anchors are present after one composition
-        assertThat(state.anchors).containsKey(A)
-        assertThat(state.anchors).containsKey(B)
-        assertThat(state.anchors).containsKey(C)
-    }
-
-    @Test
-    fun swipeable_swipeAnchors_calculatedCorrectlyFromLayoutSize() {
-        lateinit var state: SwipeableV2State<TestState>
-
-        fun anchorA() = 0f
-        fun anchorB(layoutHeight: Int) = layoutHeight / 2f
-        fun anchorC(layoutHeight: Int) = layoutHeight.toFloat()
-
-        val swipeableSize = 200.dp
-
-        rule.setContent {
-            state = rememberSwipeableV2State(initialValue = A)
-            Box(
-                Modifier
-                    .requiredHeight(swipeableSize)
-                    .swipeAnchors(
-                        state,
-                        possibleValues = setOf(A, B, C)
-                    ) { state, layoutSize ->
-                        when (state) {
-                            A -> 0f
-                            B -> anchorB(layoutSize.height)
-                            C -> anchorC(layoutSize.height)
-                        }
-                    }
-            )
-        }
-
-        val expectedHeight = with(rule.density) { swipeableSize.roundToPx() }
-        assertThat(state.anchors[A]).isEqualTo(anchorA())
-        assertThat(state.anchors[B]).isEqualTo(anchorB(expectedHeight))
-        assertThat(state.anchors[C]).isEqualTo(anchorC(expectedHeight))
-    }
-
-    @Test
-    fun swipeable_swipeAnchors_updateOnSizeChange() {
-        lateinit var state: SwipeableV2State<TestState>
-
-        val firstAnchors = mapOf(A to 0f, B to 100f, C to 200f)
-        val secondAnchors = mapOf(B to 300f, C to 600f)
-        var anchors = firstAnchors
-        var size by mutableStateOf(100)
-
-        rule.setContent {
-            state = rememberSwipeableV2State(A)
-            Box(
-                Modifier
-                    .size(size.dp) // Trigger remeasure when size changes
-                    .swipeAnchors(
-                        state,
-                        possibleValues = setOf(A, B, C),
-                        calculateAnchor = { state, _ -> anchors[state] }
-                    )
-            )
-        }
-
-        assertThat(state.anchors).isEqualTo(firstAnchors)
-
-        anchors = secondAnchors
-        size = 200
-        rule.waitForIdle()
-
-        assertThat(state.anchors).isEqualTo(secondAnchors)
-    }
-
-    @Test
     fun swipeable_reconcileAnchorChangeHandler_retargetsAnimationWhenOffsetChanged() {
         val animationDurationMillis = 2000
-        lateinit var state: SwipeableV2State<TestState>
+        lateinit var state: SwipeableV2State<SwipeableTestValue>
         lateinit var scope: CoroutineScope
 
         val firstAnchors = mapOf(A to 0f, B to 100f, C to 200f)
@@ -177,33 +74,21 @@
                 SwipeableV2State(
                     initialValue = A,
                     animationSpec = tween(animationDurationMillis, easing = LinearEasing),
-                    positionalThreshold = fractionalPositionalThreshold(0.5f)
+                    positionalThreshold = defaultPositionalThreshold(),
+                    velocityThreshold = defaultVelocityThreshold()
                 )
             }
             scope = rememberCoroutineScope()
             val anchorChangeHandler = remember(state, scope) {
-                SwipeableV2Defaults.ReconcileAnimationOnAnchorChangeHandler(
-                    state = state,
-                    animate = { target, velocity ->
-                        scope.launch {
-                            state.animateTo(
-                                target,
-                                velocity
-                            )
-                        }
-                    },
-                    snap = { target -> scope.launch { state.snapTo(target) } }
+                ReconcileAnimationOnAnchorChangedCallback(
+                    state,
+                    scope
                 )
             }
             Box(
                 Modifier
                     .size(size.dp) // Trigger anchor recalculation when size changes
-                    .swipeAnchors(
-                        state = state,
-                        possibleValues = setOf(A, B, C),
-                        anchorChangeHandler = anchorChangeHandler,
-                        calculateAnchor = { state, _ -> anchors[state] }
-                    )
+                    .onSizeChanged { state.updateAnchors(anchors, anchorChangeHandler) }
             )
         }
 
@@ -223,8 +108,11 @@
 
     @Test
     fun swipeable_reconcileAnchorChangeHandler_snapsWhenPreviousAnchorRemoved() {
-        val state = SwipeableV2State(initialValue = A)
-        lateinit var scope: CoroutineScope
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = defaultPositionalThreshold(),
+            velocityThreshold = defaultVelocityThreshold()
+        )
 
         val firstAnchors = mapOf(A to 0f, B to 100f, C to 200f)
         val secondAnchors = mapOf(B to 400f, C to 600f)
@@ -232,25 +120,14 @@
         var size by mutableStateOf(100)
 
         rule.setContent {
-            scope = rememberCoroutineScope()
+            val scope = rememberCoroutineScope()
             val anchorChangeHandler = remember(state, scope) {
-                SwipeableV2Defaults.ReconcileAnimationOnAnchorChangeHandler(
-                    state = state,
-                    animate = { target, velocity ->
-                        scope.launch { state.animateTo(target, velocity) }
-                    },
-                    snap = { target -> scope.launch { state.snapTo(target) } }
-                )
+                ReconcileAnimationOnAnchorChangedCallback(state, scope)
             }
             Box(
                 Modifier
                     .size(size.dp) // Trigger anchor recalculation when size changes
-                    .swipeAnchors(
-                        state = state,
-                        possibleValues = setOf(A, B, C),
-                        anchorChangeHandler = anchorChangeHandler,
-                        calculateAnchor = { state, _ -> anchors[state] }
-                    )
+                    .onSizeChanged { state.updateAnchors(anchors, anchorChangeHandler) }
             )
         }
 
@@ -265,32 +142,35 @@
 
     @Test
     fun swipeable_anchorChangeHandler_calledWithUpdatedAnchorsWhenChanged() {
-        val state = SwipeableV2State(initialValue = A)
-        val initialSize = 100.dp
-        var size: Dp by mutableStateOf(initialSize)
         var anchorChangeHandlerInvocationCount = 0
-        var actualPreviousAnchors: Map<TestState, Float>? = null
-        var actualNewAnchors: Map<TestState, Float>? = null
-        val testChangeHandler = AnchorChangeHandler { _, previousAnchors, newAnchors ->
+        var actualPreviousAnchors: Map<SwipeableTestValue, Float>? = null
+        var actualNewAnchors: Map<SwipeableTestValue, Float>? = null
+        val testChangeHandler = AnchorChangedCallback { _, previousAnchors, newAnchors ->
             anchorChangeHandlerInvocationCount++
             actualPreviousAnchors = previousAnchors
             actualNewAnchors = newAnchors
         }
-        fun calculateAnchor(value: TestState, layoutSize: IntSize) = when (value) {
-            A -> 0f
-            B -> layoutSize.height / 2f
-            C -> layoutSize.height.toFloat()
-        }
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = defaultPositionalThreshold(),
+            velocityThreshold = defaultVelocityThreshold()
+        )
+        val initialSize = 100.dp
+        var size: Dp by mutableStateOf(initialSize)
         rule.setContent {
             Box(
                 Modifier
                     .requiredSize(size) // Trigger anchor recalculation when size changes
-                    .swipeAnchors(
-                        state = state,
-                        possibleValues = setOf(A, B, C),
-                        anchorChangeHandler = testChangeHandler,
-                        calculateAnchor = ::calculateAnchor
-                    )
+                    .onSizeChanged { layoutSize ->
+                        state.updateAnchors(
+                            mapOf(
+                                A to 0f,
+                                B to layoutSize.height / 2f,
+                                C to layoutSize.height.toFloat()
+                            ),
+                            testChangeHandler
+                        )
+                    }
             )
         }
 
@@ -302,9 +182,9 @@
         val sizePx = with(rule.density) { size.roundToPx() }
         val layoutSize = IntSize(sizePx, sizePx)
         val expectedNewAnchors = mapOf(
-            A to calculateAnchor(A, layoutSize),
-            B to calculateAnchor(B, layoutSize),
-            C to calculateAnchor(C, layoutSize),
+            A to 0f,
+            B to layoutSize.height / 2f,
+            C to layoutSize.height.toFloat()
         )
         rule.waitForIdle()
 
@@ -315,64 +195,50 @@
 
     @Test
     fun swipeable_anchorChangeHandler_invokedWithPreviousTarget() {
+        var recordedPreviousTargetValue: SwipeableTestValue? = null
+        val testChangeHandler =
+            AnchorChangedCallback<SwipeableTestValue> { previousTarget, _, _ ->
+                recordedPreviousTargetValue = previousTarget
+            }
         val state = SwipeableV2State(
             initialValue = A,
-            positionalThreshold = fractionalPositionalThreshold(0.5f)
+            positionalThreshold = { totalDistance -> totalDistance * 0.5f },
+            velocityThreshold = defaultVelocityThreshold()
         )
-        var recordedPreviousTargetValue: TestState? = null
-        val testChangeHandler = AnchorChangeHandler<TestState> { previousTarget, _, _ ->
-            recordedPreviousTargetValue = previousTarget
-        }
         var anchors = mapOf(
             A to 0f,
             B to 100f,
             C to 200f
         )
-        var recompose by mutableStateOf(false)
-
-        rule.setContent {
-            Box(
-                key(recompose) {
-                    Modifier
-                        .swipeAnchors(
-                            state = state,
-                            possibleValues = setOf(A, B, C),
-                            anchorChangeHandler = testChangeHandler,
-                            calculateAnchor = { value, _ -> anchors[value] }
-                        )
-                }
-            )
-        }
+        state.updateAnchors(anchors, testChangeHandler)
 
         assertThat(state.targetValue).isEqualTo(A)
         anchors = mapOf(B to 500f)
-        recompose = true
-        rule.waitForIdle()
+        state.updateAnchors(anchors, testChangeHandler)
         assertThat(recordedPreviousTargetValue).isEqualTo(A) // A is not in the anchors anymore, so
         // we can be sure that is not the targetValue calculated from the new anchors
     }
 
     @Test
     fun swipeable_anchorChangeHandler_invokedIfInitialValueNotInInitialAnchors() {
-        val state = SwipeableV2State(initialValue = A)
         var anchorChangeHandlerInvocationCount = 0
-        val testChangeHandler = AnchorChangeHandler<TestState> { _, _, _ ->
+        val testChangeHandler = AnchorChangedCallback<SwipeableTestValue> { _, _, _ ->
             anchorChangeHandlerInvocationCount++
         }
-        val anchors = mapOf(B to 100f, C to 200f)
-
-        rule.setContent {
-            Box(
-                Modifier
-                    .swipeAnchors(
-                        state = state,
-                        possibleValues = setOf(B, C),
-                        anchorChangeHandler = testChangeHandler,
-                        calculateAnchor = { value, _ -> anchors[value] }
-                    )
-            )
-        }
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = defaultPositionalThreshold(),
+            velocityThreshold = defaultVelocityThreshold()
+        )
+        state.updateAnchors(mapOf(B to 100f, C to 200f), testChangeHandler)
 
         assertThat(anchorChangeHandlerInvocationCount).isEqualTo(1)
     }
+
+    private fun defaultPositionalThreshold(): (totalDistance: Float) -> Float = with(rule.density) {
+        { 56.dp.toPx() }
+    }
+    private fun defaultVelocityThreshold(): () -> Float = with(rule.density) {
+        { 125.dp.toPx() }
+    }
 }
\ No newline at end of file
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2GestureTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2GestureTest.kt
index 7840ba1..cf2c3f5 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2GestureTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2GestureTest.kt
@@ -16,24 +16,28 @@
 
 package androidx.compose.material.swipeable
 
-import androidx.compose.animation.core.AnimationSpec
-import androidx.compose.animation.core.LinearEasing
-import androidx.compose.animation.core.tween
+import androidx.compose.foundation.background
 import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.offset
+import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.material.AutoTestFrameClock
 import androidx.compose.material.ExperimentalMaterialApi
-import androidx.compose.material.SwipeableV2Defaults
 import androidx.compose.material.SwipeableV2State
-import androidx.compose.material.fixedPositionalThreshold
-import androidx.compose.material.fractionalPositionalThreshold
-import androidx.compose.material.swipeable.TestState.A
-import androidx.compose.material.swipeable.TestState.B
-import androidx.compose.material.swipeable.TestState.C
+import androidx.compose.material.swipeable.SwipeableTestValue.A
+import androidx.compose.material.swipeable.SwipeableTestValue.B
+import androidx.compose.material.swipeable.SwipeableTestValue.C
+import androidx.compose.material.swipeableV2
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.testutils.WithTouchSlop
+import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.onSizeChanged
 import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performTouchInput
@@ -43,12 +47,13 @@
 import androidx.compose.ui.test.swipeUp
 import androidx.compose.ui.test.swipeWithVelocity
 import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
 import com.google.common.truth.Truth.assertThat
 import kotlin.math.abs
+import kotlin.math.roundToInt
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
@@ -64,50 +69,72 @@
     @get:Rule
     val rule = createComposeRule()
 
+    private val SwipeableTestTag = "swipebox"
+    private val SwipeableBoxSize = 200.dp
+
     @Test
     fun swipeable_swipe_horizontal() {
-        val state = SwipeableTestState(initialState = A)
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = DefaultPositionalThreshold,
+            velocityThreshold = DefaultVelocityThreshold
+        )
         val anchors = mapOf(
             A to 0f,
             B to 250f,
             C to 500f
         )
+        state.updateAnchors(anchors)
 
         rule.setContent {
             CompositionLocalProvider(LocalDensity provides NoOpDensity) {
                 WithTouchSlop(0f) {
-                    SwipeableBox(
-                        swipeableState = state,
-                        orientation = Orientation.Horizontal,
-                        anchors = anchors
-                    )
+                    Box(Modifier.fillMaxSize()) {
+                        Box(
+                            Modifier
+                                .requiredSize(SwipeableBoxSize)
+                                .testTag(SwipeableTestTag)
+                                .swipeableV2(
+                                    state = state,
+                                    orientation = Orientation.Horizontal
+                                )
+                                .offset {
+                                    IntOffset(
+                                        state
+                                            .requireOffset()
+                                            .roundToInt(), 0
+                                    )
+                                }
+                                .background(Color.Red)
+                        )
+                    }
                 }
             }
         }
 
         assertThat(state.currentValue).isEqualTo(A)
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeRight(endX = right / 2) }
         rule.waitForIdle()
 
         assertThat(state.currentValue).isEqualTo(B)
         assertThat(state.offset).isEqualTo(anchors.getValue(B))
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeRight(startX = right / 2, endX = right) }
         rule.waitForIdle()
         assertThat(state.currentValue).isEqualTo(C)
         assertThat(state.offset).isEqualTo(anchors.getValue(C))
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeLeft(endX = right / 2) }
         rule.waitForIdle()
 
         assertThat(state.currentValue).isEqualTo(B)
         assertThat(state.offset).isEqualTo(anchors.getValue(B))
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeLeft(startX = right / 2) }
         rule.waitForIdle()
 
@@ -117,48 +144,67 @@
 
     @Test
     fun swipeable_swipe_vertical() {
-        val state = SwipeableTestState(initialState = A)
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = DefaultPositionalThreshold,
+            velocityThreshold = DefaultVelocityThreshold
+        )
         val anchors = mapOf(
             A to 0f,
             B to 250f,
             C to 500f
         )
+        state.updateAnchors(anchors)
 
         rule.setContent {
             CompositionLocalProvider(LocalDensity provides NoOpDensity) {
                 WithTouchSlop(0f) {
-                    SwipeableBox(
-                        swipeableState = state,
-                        orientation = Orientation.Vertical,
-                        anchors = anchors
-                    )
+                    Box(Modifier.fillMaxSize()) {
+                        Box(
+                            Modifier
+                                .requiredSize(SwipeableBoxSize)
+                                .testTag(SwipeableTestTag)
+                                .swipeableV2(
+                                    state = state,
+                                    orientation = Orientation.Vertical
+                                )
+                                .offset {
+                                    IntOffset(
+                                        state
+                                            .requireOffset()
+                                            .roundToInt(), 0
+                                    )
+                                }
+                                .background(Color.Red)
+                        )
+                    }
                 }
             }
         }
 
         assertThat(state.currentValue).isEqualTo(A)
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeDown(startY = top, endY = bottom / 2) }
         rule.waitForIdle()
 
         assertThat(state.currentValue).isEqualTo(B)
         assertThat(state.offset).isEqualTo(anchors.getValue(B))
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeDown(startY = bottom / 2, endY = bottom) }
         rule.waitForIdle()
         assertThat(state.currentValue).isEqualTo(C)
         assertThat(state.offset).isEqualTo(anchors.getValue(C))
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeUp(startY = bottom, endY = bottom / 2) }
         rule.waitForIdle()
 
         assertThat(state.currentValue).isEqualTo(B)
         assertThat(state.offset).isEqualTo(anchors.getValue(B))
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeUp(startY = bottom / 2, endY = top) }
         rule.waitForIdle()
 
@@ -168,29 +214,48 @@
 
     @Test
     fun swipeable_swipe_disabled_horizontal() {
-        val state = SwipeableTestState(initialState = A)
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = DefaultPositionalThreshold,
+            velocityThreshold = DefaultVelocityThreshold
+        )
         val anchors = mapOf(
             A to 0f,
             B to 250f,
             C to 500f
         )
+        state.updateAnchors(anchors)
 
         rule.setContent {
             CompositionLocalProvider(LocalDensity provides NoOpDensity) {
                 WithTouchSlop(0f) {
-                    SwipeableBox(
-                        swipeableState = state,
-                        orientation = Orientation.Horizontal,
-                        anchors = anchors,
-                        enabled = false
-                    )
+                    Box(Modifier.fillMaxSize()) {
+                        Box(
+                            Modifier
+                                .requiredSize(SwipeableBoxSize)
+                                .testTag(SwipeableTestTag)
+                                .swipeableV2(
+                                    state = state,
+                                    orientation = Orientation.Horizontal,
+                                    enabled = false
+                                )
+                                .offset {
+                                    IntOffset(
+                                        state
+                                            .requireOffset()
+                                            .roundToInt(), 0
+                                    )
+                                }
+                                .background(Color.Red)
+                        )
+                    }
                 }
             }
         }
 
         assertThat(state.currentValue).isEqualTo(A)
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeRight(startX = left, endX = right) }
         rule.waitForIdle()
 
@@ -200,29 +265,48 @@
 
     @Test
     fun swipeable_swipe_disabled_vertical() {
-        val state = SwipeableTestState(initialState = A)
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = DefaultPositionalThreshold,
+            velocityThreshold = DefaultVelocityThreshold
+        )
         val anchors = mapOf(
             A to 0f,
             B to 250f,
             C to 500f
         )
+        state.updateAnchors(anchors)
 
         rule.setContent {
             CompositionLocalProvider(LocalDensity provides NoOpDensity) {
                 WithTouchSlop(0f) {
-                    SwipeableBox(
-                        swipeableState = state,
-                        orientation = Orientation.Vertical,
-                        anchors = anchors,
-                        enabled = false
-                    )
+                    Box(Modifier.fillMaxSize()) {
+                        Box(
+                            Modifier
+                                .requiredSize(SwipeableBoxSize)
+                                .testTag(SwipeableTestTag)
+                                .swipeableV2(
+                                    state = state,
+                                    orientation = Orientation.Vertical,
+                                    enabled = false
+                                )
+                                .offset {
+                                    IntOffset(
+                                        state
+                                            .requireOffset()
+                                            .roundToInt(), 0
+                                    )
+                                }
+                                .background(Color.Red)
+                        )
+                    }
                 }
             }
         }
 
         assertThat(state.currentValue).isEqualTo(A)
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeDown(startY = top, endY = bottom) }
         rule.waitForIdle()
 
@@ -234,11 +318,40 @@
     fun swipeable_positionalThresholds_fractional_targetState() {
         val positionalThreshold = 0.5f
         val absThreshold = abs(positionalThreshold)
-        val state = SwipeableTestState(
-            initialState = A,
-            positionalThreshold = fractionalPositionalThreshold(positionalThreshold)
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = { totalDistance -> totalDistance * positionalThreshold },
+            velocityThreshold = DefaultVelocityThreshold
         )
-        rule.setContent { SwipeableBox(state) }
+        rule.setContent {
+            Box(Modifier.fillMaxSize()) {
+                Box(
+                    Modifier
+                        .requiredSize(SwipeableBoxSize)
+                        .testTag(SwipeableTestTag)
+                        .swipeableV2(
+                            state = state,
+                            orientation = Orientation.Horizontal
+                        )
+                        .onSizeChanged { layoutSize ->
+                            val anchors = mapOf(
+                                A to 0f,
+                                B to layoutSize.width / 2f,
+                                C to layoutSize.width.toFloat()
+                            )
+                            state.updateAnchors(anchors)
+                        }
+                        .offset {
+                            IntOffset(
+                                state
+                                    .requireOffset()
+                                    .roundToInt(), 0
+                            )
+                        }
+                        .background(Color.Red)
+                )
+            }
+        }
 
         val positionOfA = state.anchors.getValue(A)
         val positionOfB = state.anchors.getValue(B)
@@ -284,11 +397,40 @@
     fun swipeable_positionalThresholds_fractional_negativeThreshold_targetState() {
         val positionalThreshold = -0.5f
         val absThreshold = abs(positionalThreshold)
-        val state = SwipeableTestState(
-            initialState = A,
-            positionalThreshold = fractionalPositionalThreshold(positionalThreshold)
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = { totalDistance -> totalDistance * positionalThreshold },
+            velocityThreshold = DefaultVelocityThreshold
         )
-        rule.setContent { SwipeableBox(state) }
+        rule.setContent {
+            Box(Modifier.fillMaxSize()) {
+                Box(
+                    Modifier
+                        .requiredSize(SwipeableBoxSize)
+                        .testTag(SwipeableTestTag)
+                        .swipeableV2(
+                            state = state,
+                            orientation = Orientation.Horizontal
+                        )
+                        .onSizeChanged { layoutSize ->
+                            val anchors = mapOf(
+                                A to 0f,
+                                B to layoutSize.width / 2f,
+                                C to layoutSize.width.toFloat()
+                            )
+                            state.updateAnchors(anchors)
+                        }
+                        .offset {
+                            IntOffset(
+                                state
+                                    .requireOffset()
+                                    .roundToInt(), 0
+                            )
+                        }
+                        .background(Color.Red)
+                )
+            }
+        }
 
         val positionOfA = state.anchors.getValue(A)
         val positionOfB = state.anchors.getValue(B)
@@ -333,12 +475,42 @@
     @Test
     fun swipeable_positionalThresholds_fixed_targetState() {
         val positionalThreshold = 56.dp
-        val absThreshold = with(rule.density) { abs(positionalThreshold.toPx()) }
-        val state = SwipeableTestState(
-            initialState = A,
-            positionalThreshold = fixedPositionalThreshold(positionalThreshold)
+        val positionalThresholdPx = with(rule.density) { positionalThreshold.toPx() }
+        val absThreshold = abs(positionalThresholdPx)
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = { positionalThresholdPx },
+            velocityThreshold = DefaultVelocityThreshold
         )
-        rule.setContent { SwipeableBox(state) }
+        rule.setContent {
+            Box(Modifier.fillMaxSize()) {
+                Box(
+                    Modifier
+                        .requiredSize(SwipeableBoxSize)
+                        .testTag(SwipeableTestTag)
+                        .swipeableV2(
+                            state = state,
+                            orientation = Orientation.Horizontal
+                        )
+                        .onSizeChanged { layoutSize ->
+                            val anchors = mapOf(
+                                A to 0f,
+                                B to layoutSize.width / 2f,
+                                C to layoutSize.width.toFloat()
+                            )
+                            state.updateAnchors(anchors)
+                        }
+                        .offset {
+                            IntOffset(
+                                state
+                                    .requireOffset()
+                                    .roundToInt(), 0
+                            )
+                        }
+                        .background(Color.Red)
+                )
+            }
+        }
 
         val initialOffset = state.requireOffset()
 
@@ -386,12 +558,42 @@
     @Test
     fun swipeable_positionalThresholds_fixed_negativeThreshold_targetState() {
         val positionalThreshold = (-56).dp
-        val absThreshold = with(rule.density) { abs(positionalThreshold.toPx()) }
-        val state = SwipeableTestState(
-            initialState = A,
-            positionalThreshold = fixedPositionalThreshold(positionalThreshold)
+        val positionalThresholdPx = with(rule.density) { positionalThreshold.toPx() }
+        val absThreshold = abs(positionalThresholdPx)
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = { positionalThresholdPx },
+            velocityThreshold = DefaultVelocityThreshold
         )
-        rule.setContent { SwipeableBox(state) }
+        rule.setContent {
+            Box(Modifier.fillMaxSize()) {
+                Box(
+                    Modifier
+                        .requiredSize(SwipeableBoxSize)
+                        .testTag(SwipeableTestTag)
+                        .swipeableV2(
+                            state = state,
+                            orientation = Orientation.Horizontal
+                        )
+                        .onSizeChanged { layoutSize ->
+                            val anchors = mapOf(
+                                A to 0f,
+                                B to layoutSize.width / 2f,
+                                C to layoutSize.width.toFloat()
+                            )
+                            state.updateAnchors(anchors)
+                        }
+                        .offset {
+                            IntOffset(
+                                state
+                                    .requireOffset()
+                                    .roundToInt(), 0
+                            )
+                        }
+                        .background(Color.Red)
+                )
+            }
+        }
 
         val initialOffset = state.requireOffset()
 
@@ -441,14 +643,17 @@
         runBlocking(AutoTestFrameClock()) {
             val velocity = 100.dp
             val velocityPx = with(rule.density) { velocity.toPx() }
-            val state = SwipeableTestState(
-                initialState = A,
-                anchors = mapOf(
+            val state = SwipeableV2State(
+                initialValue = A,
+                positionalThreshold = DefaultPositionalThreshold,
+                velocityThreshold = { velocityPx / 2f }
+            )
+            state.updateAnchors(
+                mapOf(
                     A to 0f,
                     B to 100f,
                     C to 200f
-                ),
-                velocityThreshold = velocity / 2
+                )
             )
             state.dispatchRawDelta(60f)
             state.settle(velocityPx)
@@ -461,15 +666,17 @@
         runBlocking(AutoTestFrameClock()) {
             val velocity = 100.dp
             val velocityPx = with(rule.density) { velocity.toPx() }
-            val state = SwipeableTestState(
-                initialState = A,
-                anchors = mapOf(
+            val state = SwipeableV2State(
+                initialValue = A,
+                velocityThreshold = { velocityPx },
+                positionalThreshold = { Float.POSITIVE_INFINITY }
+            )
+            state.updateAnchors(
+                mapOf(
                     A to 0f,
                     B to 100f,
                     C to 200f
-                ),
-                velocityThreshold = velocity,
-                positionalThreshold = { Float.POSITIVE_INFINITY }
+                )
             )
             state.dispatchRawDelta(60f)
             state.settle(velocityPx / 2)
@@ -479,13 +686,42 @@
     @Test
     fun swipeable_velocityThreshold_swipe_velocityHigherThanThreshold_advances() {
         val velocityThreshold = 100.dp
-        val state = SwipeableTestState(
-            initialState = A,
-            velocityThreshold = velocityThreshold
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = DefaultPositionalThreshold,
+            velocityThreshold = { with(rule.density) { velocityThreshold.toPx() } }
         )
-        rule.setContent { SwipeableBox(state) }
+        rule.setContent {
+            Box(Modifier.fillMaxSize()) {
+                Box(
+                    Modifier
+                        .requiredSize(SwipeableBoxSize)
+                        .testTag(SwipeableTestTag)
+                        .swipeableV2(
+                            state = state,
+                            orientation = Orientation.Horizontal
+                        )
+                        .onSizeChanged { layoutSize ->
+                            val anchors = mapOf(
+                                A to 0f,
+                                B to layoutSize.width / 2f,
+                                C to layoutSize.width.toFloat()
+                            )
+                            state.updateAnchors(anchors)
+                        }
+                        .offset {
+                            IntOffset(
+                                state
+                                    .requireOffset()
+                                    .roundToInt(), 0
+                            )
+                        }
+                        .background(Color.Red)
+                )
+            }
+        }
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput {
                 swipeWithVelocity(
                     start = Offset(left, 0f),
@@ -501,14 +737,42 @@
     @Test
     fun swipeable_velocityThreshold_swipe_velocityLowerThanThreshold_doesntAdvance() {
         val velocityThreshold = 100.dp
-        val state = SwipeableTestState(
-            initialState = A,
-            velocityThreshold = velocityThreshold,
+        val state = SwipeableV2State(
+            initialValue = A,
+            velocityThreshold = { with(rule.density) { velocityThreshold.toPx() } },
             positionalThreshold = { Float.POSITIVE_INFINITY }
         )
-        rule.setContent { SwipeableBox(state) }
+        rule.setContent {
+            Box(Modifier.fillMaxSize()) {
+                Box(
+                    Modifier
+                        .requiredSize(SwipeableBoxSize)
+                        .testTag(SwipeableTestTag)
+                        .swipeableV2(
+                            state = state,
+                            orientation = Orientation.Horizontal
+                        )
+                        .onSizeChanged { layoutSize ->
+                            val anchors = mapOf(
+                                A to 0f,
+                                B to layoutSize.width / 2f,
+                                C to layoutSize.width.toFloat()
+                            )
+                            state.updateAnchors(anchors)
+                        }
+                        .offset {
+                            IntOffset(
+                                state
+                                    .requireOffset()
+                                    .roundToInt(), 0
+                            )
+                        }
+                        .background(Color.Red)
+                )
+            }
+        }
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput {
                 swipeWithVelocity(
                     start = Offset(left, 0f),
@@ -527,23 +791,38 @@
             A to 0f,
             C to 500f
         )
-        val state = SwipeableTestState(
-            initialState = A,
-            velocityThreshold = 0.dp
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = DefaultPositionalThreshold,
+            velocityThreshold = { 0f }
         )
+        state.updateAnchors(anchors)
         rule.setContent {
-            SwipeableBox(
-                state,
-                calculateAnchor = { state, _ ->
-                    anchors[state]
-                }
-            )
+            Box(Modifier.fillMaxSize()) {
+                Box(
+                    Modifier
+                        .requiredSize(SwipeableBoxSize)
+                        .testTag(SwipeableTestTag)
+                        .swipeableV2(
+                            state = state,
+                            orientation = Orientation.Horizontal
+                        )
+                        .offset {
+                            IntOffset(
+                                state
+                                    .requireOffset()
+                                    .roundToInt(), 0
+                            )
+                        }
+                        .background(Color.Red)
+                )
+            }
         }
 
         val overdrag = 100f
         val maxBound = state.anchors.getValue(C)
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput {
                 down(Offset(0f, 0f))
                 moveBy(Offset(x = maxBound + overdrag, y = 0f))
@@ -562,30 +841,40 @@
     @Test
     fun swipeable_animationCancelledByDrag_resetsTargetValueToClosest() {
         rule.mainClock.autoAdvance = false
-        val animationDurationMillis = 500
-        val offsetAtB = animationDurationMillis / 2f
-        val offsetAtC = animationDurationMillis.toFloat()
         val anchors = mapOf(
             A to 0f,
-            B to offsetAtB,
-            C to offsetAtC
+            B to 250f,
+            C to 500f
         )
-        val state = SwipeableTestState(
-            initialState = A,
-            animationSpec = tween(animationDurationMillis, easing = LinearEasing),
-            positionalThreshold = fractionalPositionalThreshold(0.5f)
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = { totalDistance -> totalDistance * 0.5f },
+            velocityThreshold = DefaultVelocityThreshold
         )
+        state.updateAnchors(anchors)
         lateinit var scope: CoroutineScope
         rule.setContent {
             WithTouchSlop(touchSlop = 0f) {
                 scope = rememberCoroutineScope()
-                SwipeableBox(
-                    swipeableState = state,
-                    orientation = Orientation.Horizontal,
-                    calculateAnchor = { state, _ ->
-                        anchors[state]
-                    }
-                )
+                Box(Modifier.fillMaxSize()) {
+                    Box(
+                        Modifier
+                            .requiredSize(SwipeableBoxSize)
+                            .testTag(SwipeableTestTag)
+                            .swipeableV2(
+                                state = state,
+                                orientation = Orientation.Horizontal
+                            )
+                            .offset {
+                                IntOffset(
+                                    state
+                                        .requireOffset()
+                                        .roundToInt(), 0
+                                )
+                            }
+                            .background(Color.Red)
+                    )
+                }
             }
         }
 
@@ -595,11 +884,11 @@
         scope.launch { state.animateTo(C) }
 
         rule.mainClock.advanceTimeUntil {
-            state.requireOffset() > abs(state.requireOffset() - offsetAtB)
+            state.requireOffset() > abs(state.requireOffset() - anchors.getValue(B))
         } // Advance until our closest anchor is B
         assertThat(state.targetValue).isEqualTo(C)
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput {
                 down(Offset.Zero)
             }
@@ -607,22 +896,11 @@
         assertThat(state.targetValue).isEqualTo(B) // B is the closest now so we should target it
     }
 
-    private fun SwipeableTestState(
-        initialState: TestState,
-        density: Density = rule.density,
-        positionalThreshold: Density.(distance: Float) -> Float = { 56.dp.toPx() },
-        velocityThreshold: Dp = 125.dp,
-        anchors: Map<TestState, Float>? = null,
-        animationSpec: AnimationSpec<Float> = SwipeableV2Defaults.AnimationSpec
-    ) = SwipeableV2State(
-        initialValue = initialState,
-        positionalThreshold = positionalThreshold,
-        velocityThreshold = velocityThreshold,
-        animationSpec = animationSpec
-    ).apply {
-        if (anchors != null) updateAnchors(anchors)
-        this.density = density
+    private val DefaultPositionalThreshold: (totalDistance: Float) -> Float = {
+        with(rule.density) { 56.dp.toPx() }
     }
+
+    private val DefaultVelocityThreshold: () -> Float = { with(rule.density) { 125.dp.toPx() } }
 }
 
 private val NoOpDensity = object : Density {
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2StateTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2StateTest.kt
index 5fcdcc9..4bba7ee 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2StateTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2StateTest.kt
@@ -20,19 +20,24 @@
 import androidx.compose.animation.core.LinearEasing
 import androidx.compose.animation.core.Spring
 import androidx.compose.animation.core.tween
+import androidx.compose.foundation.background
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.offset
+import androidx.compose.foundation.layout.requiredSize
+import androidx.compose.material.SwipeableV2State.AnchorChangedCallback
 import androidx.compose.material.ExperimentalMaterialApi
+import androidx.compose.material.SwipeableV2Defaults
 import androidx.compose.material.SwipeableV2State
-import androidx.compose.material.fractionalPositionalThreshold
 import androidx.compose.material.rememberSwipeableV2State
-import androidx.compose.material.swipeAnchors
-import androidx.compose.material.swipeable.TestState.A
-import androidx.compose.material.swipeable.TestState.B
-import androidx.compose.material.swipeable.TestState.C
+import androidx.compose.material.swipeable.SwipeableTestValue.A
+import androidx.compose.material.swipeable.SwipeableTestValue.B
+import androidx.compose.material.swipeable.SwipeableTestValue.C
+import androidx.compose.material.swipeableV2
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.MonotonicFrameClock
+import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
@@ -40,18 +45,23 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.testutils.WithTouchSlop
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.onSizeChanged
+import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.junit4.StateRestorationTester
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performTouchInput
 import androidx.compose.ui.test.swipeDown
 import androidx.compose.ui.test.swipeUp
+import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
 import java.util.concurrent.TimeUnit
+import kotlin.math.roundToInt
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.CoroutineStart
 import kotlinx.coroutines.channels.Channel
@@ -70,19 +80,45 @@
     @get:Rule
     val rule = createComposeRule()
 
+    private val SwipeableTestTag = "swipebox"
+    private val SwipeableBoxSize = 200.dp
+
     @Test
     fun swipeable_state_canSkipStateByFling() {
-        lateinit var state: SwipeableV2State<TestState>
+        lateinit var state: SwipeableV2State<SwipeableTestValue>
         rule.setContent {
             state = rememberSwipeableV2State(initialValue = A)
-            SwipeableBox(
-                swipeableState = state,
-                orientation = Orientation.Vertical,
-                possibleStates = setOf(A, B, C)
-            )
+            Box(Modifier.fillMaxSize()) {
+                Box(
+                    Modifier
+                        .requiredSize(SwipeableBoxSize)
+                        .testTag(SwipeableTestTag)
+                        .swipeableV2(
+                            state = state,
+                            orientation = Orientation.Vertical
+                        )
+                        .onSizeChanged { layoutSize ->
+                            state.updateAnchors(
+                                mapOf(
+                                    A to 0f,
+                                    B to layoutSize.width / 2f,
+                                    C to layoutSize.width.toFloat()
+                                )
+                            )
+                        }
+                        .offset {
+                            IntOffset(
+                                state
+                                    .requireOffset()
+                                    .roundToInt(), 0
+                            )
+                        }
+                        .background(Color.Red)
+                )
+            }
         }
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeDown() }
 
         rule.waitForIdle()
@@ -92,39 +128,62 @@
 
     @Test
     fun swipeable_targetState_updatedOnSwipe() {
-        lateinit var state: SwipeableV2State<TestState>
+        lateinit var state: SwipeableV2State<SwipeableTestValue>
         rule.setContent {
             state = rememberSwipeableV2State(initialValue = A)
-            SwipeableBox(
-                swipeableState = state,
-                orientation = Orientation.Vertical,
-                possibleStates = setOf(A, B, C)
-            )
+            Box(Modifier.fillMaxSize()) {
+                Box(
+                    Modifier
+                        .requiredSize(SwipeableBoxSize)
+                        .testTag(SwipeableTestTag)
+                        .swipeableV2(
+                            state = state,
+                            orientation = Orientation.Vertical
+                        )
+                        .onSizeChanged { layoutSize ->
+                            state.updateAnchors(
+                                mapOf(
+                                    A to 0f,
+                                    B to layoutSize.width / 2f,
+                                    C to layoutSize.width.toFloat()
+                                )
+                            )
+                        }
+                        .offset {
+                            IntOffset(
+                                state
+                                    .requireOffset()
+                                    .roundToInt(), 0
+                            )
+                        }
+                        .background(Color.Red)
+                )
+            }
         }
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeDown(endY = bottom * 0.45f) }
         rule.waitForIdle()
         assertThat(state.targetValue).isEqualTo(B)
 
         // Assert that swipe below threshold upward settles at current state
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeUp(endY = bottom * 0.95f, durationMillis = 1000) }
         rule.waitForIdle()
         assertThat(state.targetValue).isEqualTo(B)
 
         // Assert that swipe below threshold downward settles at current state
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeDown(endY = bottom * 0.05f) }
         rule.waitForIdle()
         assertThat(state.targetValue).isEqualTo(B)
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeDown(endY = bottom * 0.9f) }
         rule.waitForIdle()
         assertThat(state.targetValue).isEqualTo(C)
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeUp(endY = top * 1.1f) }
         rule.waitForIdle()
         assertThat(state.targetValue).isEqualTo(A)
@@ -135,22 +194,47 @@
         rule.mainClock.autoAdvance = false
         val animationDuration = 300
         val frameLengthMillis = 16L
-        lateinit var state: SwipeableV2State<TestState>
+        lateinit var state: SwipeableV2State<SwipeableTestValue>
         lateinit var scope: CoroutineScope
         rule.setContent {
-            state = remember {
+            val velocityThreshold = SwipeableV2Defaults.velocityThreshold
+            state = remember(velocityThreshold) {
                 SwipeableV2State(
                     initialValue = A,
                     animationSpec = tween(animationDuration, easing = LinearEasing),
-                    positionalThreshold = fractionalPositionalThreshold(0.5f)
+                    positionalThreshold = { distance -> distance * 0.5f },
+                    velocityThreshold = velocityThreshold
                 )
             }
             scope = rememberCoroutineScope()
-            SwipeableBox(
-                swipeableState = state,
-                orientation = Orientation.Vertical,
-                possibleStates = setOf(A, B, C)
-            )
+            Box(Modifier.fillMaxSize()) {
+                Box(
+                    Modifier
+                        .requiredSize(SwipeableBoxSize)
+                        .testTag(SwipeableTestTag)
+                        .swipeableV2(
+                            state = state,
+                            orientation = Orientation.Vertical
+                        )
+                        .onSizeChanged { layoutSize ->
+                            state.updateAnchors(
+                                mapOf(
+                                    A to 0f,
+                                    B to layoutSize.width / 2f,
+                                    C to layoutSize.width.toFloat()
+                                )
+                            )
+                        }
+                        .offset {
+                            IntOffset(
+                                state
+                                    .requireOffset()
+                                    .roundToInt(), 0
+                            )
+                        }
+                        .background(Color.Red)
+                )
+            }
         }
 
         scope.launch {
@@ -178,14 +262,38 @@
 
     @Test
     fun swipeable_progress_matchesSwipePosition() {
-        lateinit var state: SwipeableV2State<TestState>
+        lateinit var state: SwipeableV2State<SwipeableTestValue>
         rule.setContent {
             state = rememberSwipeableV2State(initialValue = A)
             WithTouchSlop(touchSlop = 0f) {
-                SwipeableBox(
-                    swipeableState = state,
-                    orientation = Orientation.Vertical
-                )
+                Box(Modifier.fillMaxSize()) {
+                    Box(
+                        Modifier
+                            .requiredSize(SwipeableBoxSize)
+                            .testTag(SwipeableTestTag)
+                            .swipeableV2(
+                                state = state,
+                                orientation = Orientation.Vertical
+                            )
+                            .onSizeChanged { layoutSize ->
+                                state.updateAnchors(
+                                    mapOf(
+                                        A to 0f,
+                                        B to layoutSize.width / 2f,
+                                        C to layoutSize.width.toFloat()
+                                    )
+                                )
+                            }
+                            .offset {
+                                IntOffset(
+                                    state
+                                        .requireOffset()
+                                        .roundToInt(), 0
+                                )
+                            }
+                            .background(Color.Red)
+                    )
+                }
             }
         }
 
@@ -194,7 +302,7 @@
         val almostAnchorB = anchorB * 0.9f
         var expectedProgress = almostAnchorB / (anchorB - anchorA)
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeDown(endY = almostAnchorB) }
 
         assertThat(state.targetValue).isEqualTo(B)
@@ -203,7 +311,7 @@
         val almostAnchorA = anchorA + ((anchorB - anchorA) * 0.1f)
         expectedProgress = 1 - (almostAnchorA / (anchorB - anchorA))
 
-        rule.onNodeWithTag(swipeableTestTag)
+        rule.onNodeWithTag(SwipeableTestTag)
             .performTouchInput { swipeUp(startY = anchorB, endY = almostAnchorA) }
 
         assertThat(state.targetValue).isEqualTo(A)
@@ -212,13 +320,37 @@
 
     @Test
     fun swipeable_snapTo_updatesImmediately() = runBlocking {
-        lateinit var state: SwipeableV2State<TestState>
+        lateinit var state: SwipeableV2State<SwipeableTestValue>
         rule.setContent {
             state = rememberSwipeableV2State(initialValue = A)
-            SwipeableBox(
-                swipeableState = state,
-                orientation = Orientation.Vertical
-            )
+            Box(Modifier.fillMaxSize()) {
+                Box(
+                    Modifier
+                        .requiredSize(SwipeableBoxSize)
+                        .testTag(SwipeableTestTag)
+                        .swipeableV2(
+                            state = state,
+                            orientation = Orientation.Vertical
+                        )
+                        .onSizeChanged { layoutSize ->
+                            state.updateAnchors(
+                                mapOf(
+                                    A to 0f,
+                                    B to layoutSize.width / 2f,
+                                    C to layoutSize.width.toFloat()
+                                )
+                            )
+                        }
+                        .offset {
+                            IntOffset(
+                                state
+                                    .requireOffset()
+                                    .roundToInt(), 0
+                            )
+                        }
+                        .background(Color.Red)
+                )
+            }
         }
 
         state.snapTo(C)
@@ -232,12 +364,14 @@
 
         val initialState = C
         val animationSpec = tween<Float>(durationMillis = 1000)
-        lateinit var state: SwipeableV2State<TestState>
+        lateinit var state: SwipeableV2State<SwipeableTestValue>
         lateinit var scope: CoroutineScope
 
         restorationTester.setContent {
             state = rememberSwipeableV2State(initialState, animationSpec)
-            state.updateAnchors(mapOf(A to 0f, B to 100f, C to 200f))
+            SideEffect {
+                state.updateAnchors(mapOf(A to 0f, B to 100f, C to 200f))
+            }
             scope = rememberCoroutineScope()
         }
 
@@ -258,13 +392,40 @@
 
     @Test
     fun swipeable_targetState_accessedInInitialComposition() {
-        lateinit var targetState: TestState
+        lateinit var targetState: SwipeableTestValue
         rule.setContent {
             val state = rememberSwipeableV2State(initialValue = B)
             LaunchedEffect(state.targetValue) {
                 targetState = state.targetValue
             }
-            SwipeableBox(state)
+            Box(Modifier.fillMaxSize()) {
+                Box(
+                    Modifier
+                        .requiredSize(SwipeableBoxSize)
+                        .testTag(SwipeableTestTag)
+                        .swipeableV2(
+                            state = state,
+                            orientation = Orientation.Horizontal
+                        )
+                        .onSizeChanged { layoutSize ->
+                            state.updateAnchors(
+                                mapOf(
+                                    A to 0f,
+                                    B to layoutSize.width / 2f,
+                                    C to layoutSize.width.toFloat()
+                                )
+                            )
+                        }
+                        .offset {
+                            IntOffset(
+                                state
+                                    .requireOffset()
+                                    .roundToInt(), 0
+                            )
+                        }
+                        .background(Color.Red)
+                )
+            }
         }
 
         assertThat(targetState).isEqualTo(B)
@@ -278,7 +439,34 @@
             LaunchedEffect(state.progress) {
                 progress = state.progress
             }
-            SwipeableBox(state)
+            Box(Modifier.fillMaxSize()) {
+                Box(
+                    Modifier
+                        .requiredSize(SwipeableBoxSize)
+                        .testTag(SwipeableTestTag)
+                        .swipeableV2(
+                            state = state,
+                            orientation = Orientation.Horizontal
+                        )
+                        .onSizeChanged { layoutSize ->
+                            state.updateAnchors(
+                                mapOf(
+                                    A to 0f,
+                                    B to layoutSize.width / 2f,
+                                    C to layoutSize.width.toFloat()
+                                )
+                            )
+                        }
+                        .offset {
+                            IntOffset(
+                                state
+                                    .requireOffset()
+                                    .roundToInt(), 0
+                            )
+                        }
+                        .background(Color.Red)
+                )
+            }
         }
 
         assertThat(progress).isEqualTo(1f)
@@ -288,11 +476,38 @@
     @Ignore("Todo: Fix differences between tests and real code - this shouldn't work :)")
     fun swipeable_requireOffset_accessedInInitialComposition_throws() {
         var exception: Throwable? = null
-        lateinit var state: SwipeableV2State<TestState>
+        lateinit var state: SwipeableV2State<SwipeableTestValue>
         var offset: Float? = null
         rule.setContent {
             state = rememberSwipeableV2State(initialValue = B)
-            SwipeableBox(state)
+            Box(Modifier.fillMaxSize()) {
+                Box(
+                    Modifier
+                        .requiredSize(SwipeableBoxSize)
+                        .testTag(SwipeableTestTag)
+                        .swipeableV2(
+                            state = state,
+                            orientation = Orientation.Horizontal
+                        )
+                        .onSizeChanged { layoutSize ->
+                            state.updateAnchors(
+                                mapOf(
+                                    A to 0f,
+                                    B to layoutSize.width / 2f,
+                                    C to layoutSize.width.toFloat()
+                                )
+                            )
+                        }
+                        .offset {
+                            IntOffset(
+                                state
+                                    .requireOffset()
+                                    .roundToInt(), 0
+                            )
+                        }
+                        .background(Color.Red)
+                )
+            }
             exception = runCatching { offset = state.requireOffset() }.exceptionOrNull()
         }
 
@@ -334,7 +549,7 @@
             initialVelocity = 0f
         ).let { TimeUnit.NANOSECONDS.toMillis(it) }
 
-        lateinit var state: SwipeableV2State<TestState>
+        lateinit var state: SwipeableV2State<SwipeableTestValue>
         lateinit var scope: CoroutineScope
 
         rule.setContent {
@@ -343,11 +558,30 @@
                 initialValue = A,
                 animationSpec = animationSpec
             )
-            SwipeableBox(
-                state,
-                calculateAnchor = { state, _ -> anchors[state] }
-            )
+            SideEffect {
+                state.updateAnchors(anchors)
+            }
+            Box(Modifier.fillMaxSize()) {
+                Box(
+                    Modifier
+                        .requiredSize(SwipeableBoxSize)
+                        .testTag(SwipeableTestTag)
+                        .swipeableV2(
+                            state = state,
+                            orientation = Orientation.Vertical
+                        )
+                        .offset {
+                            IntOffset(
+                                state
+                                    .requireOffset()
+                                    .roundToInt(), 0
+                            )
+                        }
+                        .background(Color.Red)
+                )
+            }
         }
+
         scope.launch {
             state.animateTo(C)
         }
@@ -363,34 +597,30 @@
     fun swipeable_bounds_minBoundIsSmallestAnchor() {
         var minBound = 0f
         var maxBound = 500f
-        var anchors = mapOf(
-            A to minBound,
-            B to maxBound / 2,
-            C to maxBound
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = defaultPositionalThreshold,
+            velocityThreshold = defaultVelocityThreshold
         )
-        val state = SwipeableV2State(initialValue = A)
-        var size by mutableStateOf(100.dp)
-
-        rule.setContent {
-            Box(
-                Modifier
-                    .size(size)
-                    .swipeAnchors(
-                        state = state,
-                        possibleValues = anchors.keys,
-                        calculateAnchor = { state, _ -> anchors[state] }
-                    )
+        state.updateAnchors(
+            mapOf(
+                A to minBound,
+                B to maxBound / 2,
+                C to maxBound
             )
-        }
+        )
+        var size by mutableStateOf(100.dp)
 
         assertThat(state.minOffset).isEqualTo(minBound)
         assertThat(state.maxOffset).isEqualTo(maxBound)
 
         minBound *= 3
         maxBound *= 10
-        anchors = mapOf(
-            A to minBound,
-            C to maxBound
+        state.updateAnchors(
+            mapOf(
+                A to minBound,
+                C to maxBound
+            )
         )
         size = 200.dp
         rule.waitForIdle()
@@ -401,7 +631,11 @@
 
     @Test
     fun swipeable_targetNotInAnchors_animateTo_updatesCurrentValue() {
-        val state = SwipeableV2State(initialValue = A)
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = defaultPositionalThreshold,
+            velocityThreshold = defaultVelocityThreshold
+        )
         assertThat(state.anchors).isEmpty()
         assertThat(state.currentValue).isEqualTo(A)
         runBlocking { state.animateTo(B) }
@@ -410,7 +644,11 @@
 
     @Test
     fun swipeable_targetNotInAnchors_snapTo_updatesCurrentValue() {
-        val state = SwipeableV2State(initialValue = A)
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = defaultPositionalThreshold,
+            velocityThreshold = defaultVelocityThreshold
+        )
         assertThat(state.anchors).isEmpty()
         assertThat(state.currentValue).isEqualTo(A)
         runBlocking { state.snapTo(B) }
@@ -419,30 +657,54 @@
 
     @Test
     fun swipeable_updateAnchors_initialUpdate_initialValueInAnchors_shouldntUpdate() {
-        val state = SwipeableV2State(initialValue = A)
+        var anchorChangeHandlerInvoked = false
+        val testAnchorChangeHandler = AnchorChangedCallback<SwipeableTestValue> { _, _, _ ->
+            anchorChangeHandlerInvoked = true
+        }
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = defaultPositionalThreshold,
+            velocityThreshold = defaultVelocityThreshold
+        )
         val anchors = mapOf(A to 200f, C to 300f)
-        val shouldInvokeChangeHandler = state.updateAnchors(anchors)
-        assertThat(shouldInvokeChangeHandler).isFalse()
+        state.updateAnchors(anchors, testAnchorChangeHandler)
+        assertThat(anchorChangeHandlerInvoked).isFalse()
     }
 
     @Test
     fun swipeable_updateAnchors_initialUpdate_initialValueNotInAnchors_shouldUpdate() {
-        val state = SwipeableV2State(initialValue = A)
+        var anchorChangeHandlerInvoked = false
+        val testAnchorChangedCallback = AnchorChangedCallback<SwipeableTestValue> { _, _, _ ->
+            anchorChangeHandlerInvoked = true
+        }
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = defaultPositionalThreshold,
+            velocityThreshold = defaultVelocityThreshold
+        )
         val anchors = mapOf(B to 200f, C to 300f)
-        val shouldInvokeChangeHandler = state.updateAnchors(anchors)
-        assertThat(shouldInvokeChangeHandler).isTrue()
+        state.updateAnchors(anchors, testAnchorChangedCallback)
+        assertThat(anchorChangeHandlerInvoked).isTrue()
     }
 
     @Test
     fun swipeable_updateAnchors_updateExistingAnchors_shouldUpdate() {
-        val state = SwipeableV2State(initialValue = A)
+        var anchorChangeHandlerInvoked = false
+        val testAnchorChangedCallback = AnchorChangedCallback<SwipeableTestValue> { _, _, _ ->
+            anchorChangeHandlerInvoked = true
+        }
+        val state = SwipeableV2State(
+            initialValue = A,
+            positionalThreshold = defaultPositionalThreshold,
+            velocityThreshold = defaultVelocityThreshold
+        )
         val anchors = mapOf(A to 0f, B to 200f, C to 300f)
 
-        var shouldInvokeChangeHandler = state.updateAnchors(anchors)
-        assertThat(shouldInvokeChangeHandler).isFalse()
+        state.updateAnchors(anchors, testAnchorChangedCallback)
+        assertThat(anchorChangeHandlerInvoked).isFalse()
 
-        shouldInvokeChangeHandler = state.updateAnchors(mapOf(A to 100f, B to 500f, C to 700f))
-        assertThat(shouldInvokeChangeHandler).isTrue()
+        state.updateAnchors(mapOf(A to 100f, B to 500f, C to 700f), testAnchorChangedCallback)
+        assertThat(anchorChangeHandlerInvoked).isTrue()
     }
 
     @Test
@@ -450,10 +712,20 @@
         val clock = HandPumpTestFrameClock()
         val animationScope = CoroutineScope(clock)
         val animationDuration = 2000
-        val state = SwipeableV2State(initialValue = A, animationSpec = tween(animationDuration))
+
+        var anchorChangeHandlerInvoked = false
+        val testAnchorChangedCallback = AnchorChangedCallback<SwipeableTestValue> { _, _, _ ->
+            anchorChangeHandlerInvoked = true
+        }
+        val state = SwipeableV2State(
+            initialValue = A,
+            animationSpec = tween(animationDuration),
+            positionalThreshold = defaultPositionalThreshold,
+            velocityThreshold = defaultVelocityThreshold
+        )
         val anchors = mapOf(A to 0f, B to 200f, C to 300f)
 
-        state.updateAnchors(anchors)
+        state.updateAnchors(anchors, testAnchorChangedCallback)
         animationScope.launch(start = CoroutineStart.UNDISPATCHED) {
             state.animateTo(B)
         }
@@ -462,9 +734,9 @@
         assertThat(state.isAnimationRunning).isTrue()
 
         val offsetBeforeAnchorUpdate = state.offset
-        val shouldInvokeChangeHandler = state.updateAnchors(mapOf(A to 100f, B to 500f, C to 700f))
+        state.updateAnchors(mapOf(A to 100f, B to 500f, C to 700f), testAnchorChangedCallback)
         assertThat(offsetBeforeAnchorUpdate).isEqualTo(state.offset)
-        assertThat(shouldInvokeChangeHandler).isTrue()
+        assertThat(anchorChangeHandlerInvoked).isTrue()
     }
 
     private class HandPumpTestFrameClock : MonotonicFrameClock {
@@ -478,4 +750,10 @@
             return onFrame(frameCh.receive())
         }
     }
+
+    private val defaultPositionalThreshold: (totalDistance: Float) -> Float = {
+        with(rule.density) { 56.dp.toPx() }
+    }
+
+    private val defaultVelocityThreshold: () -> Float = { with(rule.density) { 125.dp.toPx() } }
 }
\ No newline at end of file
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 d564f3f..93603b9 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
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 package androidx.compose.material
+
 import androidx.compose.animation.core.AnimationSpec
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.layout.Column
@@ -24,7 +25,9 @@
 import androidx.compose.foundation.layout.requiredHeightIn
 import androidx.compose.material.BottomSheetValue.Collapsed
 import androidx.compose.material.BottomSheetValue.Expanded
+import androidx.compose.material.SwipeableV2State.AnchorChangedCallback
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
@@ -38,10 +41,12 @@
 import androidx.compose.ui.input.nestedscroll.NestedScrollSource
 import androidx.compose.ui.input.nestedscroll.nestedScroll
 import androidx.compose.ui.layout.SubcomposeLayout
+import androidx.compose.ui.layout.onSizeChanged
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.semantics.collapse
 import androidx.compose.ui.semantics.expand
 import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.Velocity
@@ -50,6 +55,7 @@
 import androidx.compose.ui.util.fastMaxBy
 import kotlin.math.roundToInt
 import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
 
 /**
@@ -61,6 +67,7 @@
      * The bottom sheet is visible, but only showing its peek height.
      */
     Collapsed,
+
     /**
      * The bottom sheet is visible at its maximum height.
      */
@@ -70,9 +77,12 @@
 @Deprecated(
     message = "This constructor is deprecated. confirmStateChange has been renamed to " +
         "confirmValueChange.",
-    replaceWith = ReplaceWith("BottomSheetScaffoldState(initialValue, animationSpec, " +
-        "confirmStateChange)")
+    replaceWith = ReplaceWith(
+        "BottomSheetScaffoldState(initialValue, animationSpec, " +
+            "confirmStateChange)"
+    )
 )
+@Suppress("Deprecation")
 @ExperimentalMaterialApi
 fun BottomSheetScaffoldState(
     initialValue: BottomSheetValue,
@@ -88,20 +98,64 @@
  * State of the persistent bottom sheet in [BottomSheetScaffold].
  *
  * @param initialValue The initial value of the state.
+ * @param density The density that this state can use to convert values to and from dp.
+ * @param animationSpec The default animation that will be used to animate to a new state.
+ * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.
+ */
+@Suppress("Deprecation")
+@ExperimentalMaterialApi
+@Stable
+fun BottomSheetState(
+    initialValue: BottomSheetValue,
+    density: Density,
+    animationSpec: AnimationSpec<Float> = SwipeableDefaults.AnimationSpec,
+    confirmValueChange: (BottomSheetValue) -> Boolean = { true }
+) = BottomSheetState(initialValue, animationSpec, confirmValueChange).also {
+    it.density = density
+}
+
+/**
+ * State of the persistent bottom sheet in [BottomSheetScaffold].
+ *
+ * @param initialValue The initial value of the state.
  * @param animationSpec The default animation that will be used to animate to a new state.
  * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.
  */
 @ExperimentalMaterialApi
 @Stable
-class BottomSheetState(
+class BottomSheetState @Deprecated(
+    "This constructor is deprecated. Density must be provided by the component. " +
+        "Please use the constructor that provides a [Density].",
+    ReplaceWith(
+        """
+            BottomSheetState(
+                initialValue = initialValue,
+                density = LocalDensity.current,
+                animationSpec = animationSpec,
+                confirmValueChange = confirmValueChange
+            )
+            """
+    )
+) constructor(
     initialValue: BottomSheetValue,
     animationSpec: AnimationSpec<Float> = SwipeableDefaults.AnimationSpec,
     confirmValueChange: (BottomSheetValue) -> Boolean = { true }
 ) {
+
     internal val swipeableState = SwipeableV2State(
         initialValue = initialValue,
         animationSpec = animationSpec,
-        confirmValueChange = confirmValueChange
+        confirmValueChange = confirmValueChange,
+        positionalThreshold = {
+            with(requireDensity()) {
+                BottomSheetScaffoldPositionalThreshold.toPx()
+            }
+        },
+        velocityThreshold = {
+            with(requireDensity()) {
+                BottomSheetScaffoldVelocityThreshold.toPx()
+            }
+        }
     )
 
     val currentValue: BottomSheetValue
@@ -171,12 +225,48 @@
 
     internal val isAnimationRunning: Boolean get() = swipeableState.isAnimationRunning
 
+    internal var density: Density? = null
+    private fun requireDensity() = requireNotNull(density) {
+        "The density on BottomSheetState ($this) was not set. Did you use BottomSheetState with " +
+            "the BottomSheetScaffold composable?"
+    }
+
+    internal val lastVelocity: Float get() = swipeableState.lastVelocity
+
     companion object {
+
         /**
          * The default [Saver] implementation for [BottomSheetState].
          */
         fun Saver(
             animationSpec: AnimationSpec<Float>,
+            confirmStateChange: (BottomSheetValue) -> Boolean,
+            density: Density
+        ): Saver<BottomSheetState, *> = Saver(
+            save = { it.swipeableState.currentValue },
+            restore = {
+                BottomSheetState(
+                    initialValue = it,
+                    density = density,
+                    animationSpec = animationSpec,
+                    confirmValueChange = confirmStateChange
+                )
+            }
+        )
+
+        /**
+         * The default [Saver] implementation for [BottomSheetState].
+         */
+        @Deprecated(
+            message = "This function is deprecated. Please use the overload where Density is" +
+                " provided.",
+            replaceWith = ReplaceWith(
+                "Saver(animationSpec, confirmStateChange, density)"
+            )
+        )
+        @Suppress("Deprecation")
+        fun Saver(
+            animationSpec: AnimationSpec<Float>,
             confirmStateChange: (BottomSheetValue) -> Boolean
         ): Saver<BottomSheetState, *> = Saver(
             save = { it.swipeableState.currentValue },
@@ -190,6 +280,7 @@
         )
     }
 }
+
 /**
  * Create a [BottomSheetState] and [remember] it.
  *
@@ -204,20 +295,24 @@
     animationSpec: AnimationSpec<Float> = SwipeableDefaults.AnimationSpec,
     confirmStateChange: (BottomSheetValue) -> Boolean = { true }
 ): BottomSheetState {
+    val density = LocalDensity.current
     return rememberSaveable(
         animationSpec,
         saver = BottomSheetState.Saver(
             animationSpec = animationSpec,
-            confirmStateChange = confirmStateChange
+            confirmStateChange = confirmStateChange,
+            density = density
         )
     ) {
         BottomSheetState(
             initialValue = initialValue,
             animationSpec = animationSpec,
-            confirmValueChange = confirmStateChange
+            confirmValueChange = confirmStateChange,
+            density = density
         )
     }
 }
+
 /**
  * State of the [BottomSheetScaffold] composable.
  *
@@ -232,6 +327,7 @@
     val bottomSheetState: BottomSheetState,
     val snackbarHostState: SnackbarHostState
 )
+
 /**
  * Create and [remember] a [BottomSheetScaffoldState].
  *
@@ -254,6 +350,7 @@
         )
     }
 }
+
 /**
  * <a href="https://material.io/components/sheets-bottom#standard-bottom-sheet" class="external" target="_blank">Material Design standard bottom sheet</a>.
  *
@@ -329,6 +426,14 @@
     contentColor: Color = contentColorFor(backgroundColor),
     content: @Composable (PaddingValues) -> Unit
 ) {
+    // b/278692145 Remove this once deprecated methods without density are removed
+    if (scaffoldState.bottomSheetState.density == null) {
+        val density = LocalDensity.current
+        SideEffect {
+            scaffoldState.bottomSheetState.density = density
+        }
+    }
+
     val peekHeightPx = with(LocalDensity.current) { sheetPeekHeight.toPx() }
     val child = @Composable {
         BottomSheetScaffoldLayout(
@@ -351,14 +456,16 @@
                     modifier = nestedScroll
                         .fillMaxWidth()
                         .requiredHeightIn(min = sheetPeekHeight),
-                    anchors = { state, sheetSize ->
-                        when (state) {
-                            Collapsed -> layoutHeight - peekHeightPx
-                            Expanded -> if (sheetSize.height == peekHeightPx.roundToInt()) {
-                                null
-                            } else {
-                                layoutHeight - sheetSize.height.toFloat()
-                            }
+                    calculateAnchors = { sheetSize ->
+                        val sheetHeight = sheetSize.height.toFloat()
+                        val collapsedHeight = layoutHeight - peekHeightPx
+                        if (sheetHeight == 0f || sheetHeight == peekHeightPx) {
+                            mapOf(Collapsed to collapsedHeight)
+                        } else {
+                            mapOf(
+                                Collapsed to collapsedHeight,
+                                Expanded to layoutHeight - sheetHeight
+                            )
                         }
                     },
                     sheetBackgroundColor = sheetBackgroundColor,
@@ -402,12 +509,13 @@
         }
     }
 }
+
 @OptIn(ExperimentalMaterialApi::class)
 @Composable
 private fun BottomSheet(
     state: BottomSheetState,
     sheetGesturesEnabled: Boolean,
-    anchors: (state: BottomSheetValue, sheetSize: IntSize) -> Float?,
+    calculateAnchors: (sheetSize: IntSize) -> Map<BottomSheetValue, Float>,
     sheetShape: Shape,
     sheetElevation: Dp,
     sheetBackgroundColor: Color,
@@ -416,17 +524,8 @@
     content: @Composable ColumnScope.() -> Unit
 ) {
     val scope = rememberCoroutineScope()
-    val anchorChangeHandler = remember(state, scope) {
-        BottomSheetScaffoldAnchorChangeHandler(
-            state = state,
-            animateTo = { target -> scope.launch { state.animateTo(target) } },
-            snapTo = { target ->
-                val didSnapImmediately = state.trySnapTo(target)
-                if (!didSnapImmediately) {
-                    scope.launch { state.snapTo(target) }
-                }
-            }
-        )
+    val anchorChangeCallback = remember(state, scope) {
+        BottomSheetScaffoldAnchorChangeCallback(state, scope)
     }
     Surface(
         modifier
@@ -435,12 +534,12 @@
                 orientation = Orientation.Vertical,
                 enabled = sheetGesturesEnabled,
             )
-            .swipeAnchors(
-                state = state.swipeableState,
-                possibleValues = setOf(Collapsed, Expanded),
-                calculateAnchor = anchors,
-                anchorChangeHandler = anchorChangeHandler
-            )
+            .onSizeChanged { layoutSize ->
+                state.swipeableState.updateAnchors(
+                    newAnchors = calculateAnchors(layoutSize),
+                    onAnchorsChanged = anchorChangeCallback
+                )
+            }
             .semantics {
                 // If we don't have anchors yet, or have only one anchor we don't want any
                 // accessibility actions
@@ -478,12 +577,15 @@
      * The default elevation used by [BottomSheetScaffold].
      */
     val SheetElevation = 8.dp
+
     /**
      * The default peek height used by [BottomSheetScaffold].
      */
     val SheetPeekHeight = 56.dp
 }
+
 private enum class BottomSheetScaffoldLayoutSlot { TopBar, Body, Sheet, Fab, Snackbar }
+
 @OptIn(ExperimentalMaterialApi::class)
 @Composable
 private fun BottomSheetScaffoldLayout(
@@ -608,13 +710,12 @@
 }
 
 @OptIn(ExperimentalMaterialApi::class)
-private fun BottomSheetScaffoldAnchorChangeHandler(
+private fun BottomSheetScaffoldAnchorChangeCallback(
     state: BottomSheetState,
-    animateTo: (target: BottomSheetValue) -> Unit,
-    snapTo: (target: BottomSheetValue) -> Unit,
-) = AnchorChangeHandler<BottomSheetValue> { previousTarget, previousAnchors, newAnchors ->
-    val previousTargetOffset = previousAnchors[previousTarget]
-    val newTarget = when (previousTarget) {
+    scope: CoroutineScope
+) = AnchorChangedCallback<BottomSheetValue> { prevTarget, prevAnchors, newAnchors ->
+    val previousTargetOffset = prevAnchors[prevTarget]
+    val newTarget = when (prevTarget) {
         Collapsed -> Collapsed
         Expanded -> if (newAnchors.containsKey(Expanded)) Expanded else Collapsed
     }
@@ -622,12 +723,15 @@
     if (newTargetOffset != previousTargetOffset) {
         if (state.isAnimationRunning) {
             // Re-target the animation to the new offset if it changed
-            animateTo(newTarget)
+            scope.launch { state.animateTo(newTarget, velocity = state.lastVelocity) }
         } else {
             // Snap to the new offset value of the target if no animation was running
-            snapTo(newTarget)
+            val didSnapSynchronously = state.trySnapTo(newTarget)
+            if (!didSnapSynchronously) scope.launch { state.snapTo(newTarget) }
         }
     }
 }
 
-private val FabSpacing = 16.dp
\ No newline at end of file
+private val FabSpacing = 16.dp
+private val BottomSheetScaffoldPositionalThreshold = 56.dp
+private val BottomSheetScaffoldVelocityThreshold = 125.dp
\ No newline at end of file
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 d5afce0..a47a55e 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
@@ -33,7 +33,9 @@
 import androidx.compose.material.BottomDrawerValue.Closed
 import androidx.compose.material.BottomDrawerValue.Expanded
 import androidx.compose.material.BottomDrawerValue.Open
+import androidx.compose.material.SwipeableV2State.AnchorChangedCallback
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
@@ -49,6 +51,7 @@
 import androidx.compose.ui.input.nestedscroll.NestedScrollSource
 import androidx.compose.ui.input.nestedscroll.nestedScroll
 import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.layout.onSizeChanged
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.semantics.contentDescription
@@ -56,6 +59,7 @@
 import androidx.compose.ui.semantics.onClick
 import androidx.compose.ui.semantics.paneTitle
 import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.LayoutDirection
@@ -121,7 +125,8 @@
         initialValue = initialValue,
         animationSpec = AnimationSpec,
         confirmValueChange = confirmStateChange,
-        velocityThreshold = DrawerVelocityThreshold
+        positionalThreshold = { with(requireDensity()) { DrawerPositionalThreshold.toPx() } },
+        velocityThreshold = { with(requireDensity()) { DrawerVelocityThreshold.toPx() } },
     )
 
     /**
@@ -229,6 +234,12 @@
 
     internal fun requireOffset(): Float = swipeableState.requireOffset()
 
+    internal var density: Density? = null
+    private fun requireDensity() = requireNotNull(density) {
+        "The density on DrawerState ($this) was not set. Did you use DrawerState with the Drawer " +
+            "composable?"
+    }
+
     companion object {
         /**
          * The default [Saver] implementation for [DrawerState].
@@ -245,11 +256,43 @@
  * State of the [BottomDrawer] composable.
  *
  * @param initialValue The initial value of the state.
+ * @param density The density that this state can use to convert values to and from dp.
+ * @param confirmStateChange Optional callback invoked to confirm or veto a pending state change.
+ */
+@Suppress("NotCloseable", "Deprecation")
+@ExperimentalMaterialApi
+fun BottomDrawerState(
+    initialValue: BottomDrawerValue,
+    density: Density,
+    confirmStateChange: (BottomDrawerValue) -> Boolean = { true }
+) = BottomDrawerState(
+    initialValue = initialValue,
+    confirmStateChange = confirmStateChange
+).also {
+    it.density = density
+}
+
+/**
+ * State of the [BottomDrawer] composable.
+ *
+ * @param initialValue The initial value of the state.
  * @param confirmStateChange Optional callback invoked to confirm or veto a pending state change.
  */
 @Suppress("NotCloseable")
 @ExperimentalMaterialApi
-class BottomDrawerState(
+class BottomDrawerState @Deprecated(
+    "This constructor is deprecated. Density must be provided by the component. Please use " +
+        "the constructor that provides a [Density].",
+    ReplaceWith(
+        """
+            BottomDrawerState(
+                initialValue = initialValue,
+                density =,
+                confirmStateChange = confirmStateChange
+            )
+            """
+    )
+) constructor(
     initialValue: BottomDrawerValue,
     confirmStateChange: (BottomDrawerValue) -> Boolean = { true }
 ) {
@@ -257,7 +300,8 @@
         initialValue = initialValue,
         animationSpec = AnimationSpec,
         confirmValueChange = confirmStateChange,
-        velocityThreshold = DrawerVelocityThreshold
+        positionalThreshold = { with(requireDensity()) { DrawerPositionalThreshold.toPx() } },
+        velocityThreshold = { with(requireDensity()) { DrawerVelocityThreshold.toPx() } },
     )
 
     /**
@@ -332,6 +376,16 @@
      *
      */
     suspend fun expand() = swipeableState.animateTo(Expanded)
+
+    internal suspend fun animateTo(
+        target: BottomDrawerValue,
+        velocity: Float = swipeableState.lastVelocity
+    ) = swipeableState.animateTo(target, velocity)
+
+    internal suspend fun snapTo(target: BottomDrawerValue) = swipeableState.snapTo(target)
+
+    internal fun trySnapTo(target: BottomDrawerValue) = swipeableState.trySnapTo(target)
+
     internal fun confirmStateChange(value: BottomDrawerValue): Boolean =
         swipeableState.confirmValueChange(value)
 
@@ -342,10 +396,37 @@
         swipeableState
     )
 
+    internal var density: Density? = null
+
+    private fun requireDensity() = requireNotNull(density) {
+        "The density on BottomDrawerState ($this) was not set. Did you use BottomDrawer" +
+            " with the BottomDrawer composable?"
+    }
+
+    internal val isAnimationRunning: Boolean get() = swipeableState.isAnimationRunning
+    internal val lastVelocity: Float get() = swipeableState.lastVelocity
+
     companion object {
         /**
          * The default [Saver] implementation for [BottomDrawerState].
          */
+        fun Saver(density: Density, confirmStateChange: (BottomDrawerValue) -> Boolean) =
+            Saver<BottomDrawerState, BottomDrawerValue>(
+                save = { it.swipeableState.currentValue },
+                restore = { BottomDrawerState(it, density, confirmStateChange) }
+            )
+
+        /**
+         * The default [Saver] implementation for [BottomDrawerState].
+         */
+        @Deprecated(
+            message = "This function is deprecated. Please use the overload where Density is" +
+                " provided.",
+            replaceWith = ReplaceWith(
+                "Saver(density, confirmValueChange)"
+            )
+        )
+        @Suppress("Deprecation")
         fun Saver(confirmStateChange: (BottomDrawerValue) -> Boolean) =
             Saver<BottomDrawerState, BottomDrawerValue>(
                 save = { it.swipeableState.currentValue },
@@ -382,8 +463,9 @@
     initialValue: BottomDrawerValue,
     confirmStateChange: (BottomDrawerValue) -> Boolean = { true }
 ): BottomDrawerState {
-    return rememberSaveable(saver = BottomDrawerState.Saver(confirmStateChange)) {
-        BottomDrawerState(initialValue, confirmStateChange)
+    val density = LocalDensity.current
+    return rememberSaveable(density, saver = BottomDrawerState.Saver(density, confirmStateChange)) {
+        BottomDrawerState(initialValue, density, confirmStateChange)
     }
 }
 
@@ -437,10 +519,16 @@
         if (!modalDrawerConstraints.hasBoundedWidth) {
             throw IllegalStateException("Drawer shouldn't have infinite width")
         }
-
         val minValue = -modalDrawerConstraints.maxWidth.toFloat()
         val maxValue = 0f
 
+        val density = LocalDensity.current
+        SideEffect {
+            drawerState.density = density
+            val anchors = mapOf(DrawerValue.Closed to minValue, DrawerValue.Open to maxValue)
+            drawerState.swipeableState.updateAnchors(anchors)
+        }
+
         val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
         Box(
             Modifier
@@ -450,15 +538,6 @@
                     enabled = gesturesEnabled,
                     reverseDirection = isRtl
                 )
-                .swipeAnchors(
-                    drawerState.swipeableState,
-                    possibleValues = setOf(DrawerValue.Closed, DrawerValue.Open)
-                ) { value, _ ->
-                    when (value) {
-                        DrawerValue.Closed -> minValue
-                        DrawerValue.Open -> maxValue
-                    }
-                }
         ) {
             Box {
                 content()
@@ -564,6 +643,13 @@
     scrimColor: Color = DrawerDefaults.scrimColor,
     content: @Composable () -> Unit
 ) {
+    // b/278692145 Remove this once deprecated methods without density are removed
+    if (drawerState.density == null) {
+        val density = LocalDensity.current
+        SideEffect {
+            drawerState.density = density
+        }
+    }
     val scope = rememberCoroutineScope()
 
     BoxWithConstraints(modifier.fillMaxSize()) {
@@ -607,26 +693,24 @@
                 visible = drawerState.targetValue != Closed
             )
             val navigationMenu = getString(Strings.NavigationMenu)
-
+            val anchorChangeCallback = remember(drawerState, scope) {
+                BottomDrawerAnchorChangeCallback(drawerState, scope)
+            }
             Surface(
                 drawerConstraints
-                    .swipeAnchors(
-                        drawerState.swipeableState,
-                        possibleValues = setOf(
-                            Closed,
-                            Open,
-                            Expanded
-                        ),
-                        anchorChangeHandler = remember(drawerState, scope) {
-                            BottomDrawerAnchorChangeHandler(state = drawerState, scope = scope)
+                    .onSizeChanged { drawerSize ->
+                        val drawerHeight = drawerSize.height.toFloat()
+                        val anchors = buildMap {
+                            put(Closed, fullHeight)
+                            val peekHeight = fullHeight * BottomDrawerOpenFraction
+                            if (drawerHeight > peekHeight || isLandscape) {
+                                put(Open, peekHeight)
+                            }
+                            if (drawerHeight > 0f) {
+                                put(Expanded, max(0f, fullHeight - drawerHeight))
+                            }
                         }
-                    ) { value, layoutSize ->
-                        val drawerHeight = layoutSize.height.toFloat()
-                        calculateAnchors(
-                            fullHeight = fullHeight,
-                            drawerHeight = drawerHeight,
-                            isLandscape = isLandscape
-                        )[value]
+                        drawerState.swipeableState.updateAnchors(anchors, anchorChangeCallback)
                     }
                     .offset {
                         IntOffset(
@@ -767,6 +851,7 @@
 }
 
 private val EndDrawerPadding = 56.dp
+private val DrawerPositionalThreshold = 56.dp
 private val DrawerVelocityThreshold = 400.dp
 
 // TODO: b/177571613 this should be a proper decay settling
@@ -832,50 +917,31 @@
 }
 
 @OptIn(ExperimentalMaterialApi::class)
-private fun BottomDrawerAnchorChangeHandler(
-    state: BottomDrawerState,
-    scope: CoroutineScope
-) = AnchorChangeHandler<BottomDrawerValue> { previousTarget, previousAnchors, newAnchors ->
-    fun animateTo(target: BottomDrawerValue, velocity: Float) {
-        scope.launch {
-            state.swipeableState.animateTo(
-                target,
-                velocity = velocity
-            )
-        }
-    }
+private fun BottomDrawerAnchorChangeCallback(state: BottomDrawerState, scope: CoroutineScope) =
+    AnchorChangedCallback<BottomDrawerValue> { previousTarget, previousAnchors, newAnchors ->
+        val previousTargetOffset = previousAnchors[previousTarget]
+        val newTarget = when (previousTarget) {
+            Closed -> Closed
+            Open, Expanded -> {
+                val hasHalfExpandedState = newAnchors.containsKey(Open)
+                val newTarget = if (hasHalfExpandedState) {
+                    Open
+                } else {
+                    if (newAnchors.containsKey(Expanded)) Expanded else Closed
+                }
 
-    fun snapTo(target: BottomDrawerValue) {
-        val didSnapSynchronously = state.swipeableState.trySnapTo(target)
-        if (!didSnapSynchronously) scope.launch {
-            state.swipeableState.snapTo(
-                target
-            )
-        }
-    }
-
-    val previousTargetOffset = previousAnchors[previousTarget]
-    val newTarget = when (previousTarget) {
-        Closed -> Closed
-        Open, Expanded -> {
-            val hasHalfExpandedState = newAnchors.containsKey(Open)
-            val newTarget = if (hasHalfExpandedState) {
-                Open
-            } else {
-                if (newAnchors.containsKey(Expanded)) Expanded else Closed
+                newTarget
             }
-
-            newTarget
         }
-    }
-    val newTargetOffset = newAnchors.getValue(newTarget)
-    if (newTargetOffset != previousTargetOffset) {
-        if (state.swipeableState.isAnimationRunning) {
-            // Re-target the animation to the new offset if it changed
-            animateTo(newTarget, state.swipeableState.lastVelocity)
-        } else {
-            // Snap to the new offset value of the target if no animation was running
-            snapTo(newTarget)
+        val newTargetOffset = newAnchors.getValue(newTarget)
+        if (newTargetOffset != previousTargetOffset) {
+            if (state.isAnimationRunning) {
+                // Re-target the animation to the new offset if it changed
+                scope.launch { state.animateTo(newTarget, velocity = state.lastVelocity) }
+            } else {
+                // Snap to the new offset value of the target if no animation was running
+                val didSnapSynchronously = state.trySnapTo(newTarget)
+                if (!didSnapSynchronously) scope.launch { state.snapTo(newTarget) }
+            }
         }
-    }
-}
\ No newline at end of file
+    }
\ No newline at end of file
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt
index 5bd062c..5807196 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt
@@ -34,7 +34,9 @@
 import androidx.compose.material.ModalBottomSheetValue.Expanded
 import androidx.compose.material.ModalBottomSheetValue.HalfExpanded
 import androidx.compose.material.ModalBottomSheetValue.Hidden
+import androidx.compose.material.SwipeableV2State.AnchorChangedCallback
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.key
 import androidx.compose.runtime.remember
@@ -51,6 +53,8 @@
 import androidx.compose.ui.input.nestedscroll.NestedScrollSource
 import androidx.compose.ui.input.nestedscroll.nestedScroll
 import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.layout.onSizeChanged
+import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.semantics.collapse
 import androidx.compose.ui.semantics.contentDescription
 import androidx.compose.ui.semantics.dismiss
@@ -65,6 +69,7 @@
 import kotlin.math.max
 import kotlin.math.roundToInt
 import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
 
 /**
@@ -94,6 +99,7 @@
  *
  * @param initialValue The initial value of the state. <b>Must not be set to
  * [ModalBottomSheetValue.HalfExpanded] if [isSkipHalfExpanded] is set to true.</b>
+ * @param density The density that this state can use to convert values to and from dp.
  * @param animationSpec The default animation that will be used to animate to a new state.
  * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.
  * @param isSkipHalfExpanded Whether the half expanded state, if the sheet is tall enough, should
@@ -107,6 +113,53 @@
 @Suppress("Deprecation")
 fun ModalBottomSheetState(
     initialValue: ModalBottomSheetValue,
+    density: Density,
+    animationSpec: AnimationSpec<Float> = SwipeableDefaults.AnimationSpec,
+    confirmValueChange: (ModalBottomSheetValue) -> Boolean = { true },
+    isSkipHalfExpanded: Boolean = false,
+) = ModalBottomSheetState(
+    initialValue = initialValue,
+    animationSpec = animationSpec,
+    isSkipHalfExpanded = isSkipHalfExpanded,
+    confirmStateChange = confirmValueChange
+).also {
+    it.density = density
+}
+
+/**
+ * State of the [ModalBottomSheetLayout] composable.
+ *
+ * @param initialValue The initial value of the state. <b>Must not be set to
+ * [ModalBottomSheetValue.HalfExpanded] if [isSkipHalfExpanded] is set to true.</b>
+ * @param animationSpec The default animation that will be used to animate to a new state.
+ * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.
+ * @param isSkipHalfExpanded Whether the half expanded state, if the sheet is tall enough, should
+ * be skipped. If true, the sheet will always expand to the [Expanded] state and move to the
+ * [Hidden] state when hiding the sheet, either programmatically or by user interaction.
+ * <b>Must not be set to true if the initialValue is [ModalBottomSheetValue.HalfExpanded].</b>
+ * If supplied with [ModalBottomSheetValue.HalfExpanded] for the initialValue, an
+ * [IllegalArgumentException] will be thrown.
+ */
+@ExperimentalMaterialApi
+@Deprecated(
+    "This constructor is deprecated. Density must be provided by the component. " +
+        "Please use the constructor that provides a [Density].",
+    ReplaceWith(
+        """
+            ModalBottomSheetState(
+                initialValue = initialValue,
+                density =,
+                animationSpec = animationSpec,
+                isSkipHalfExpanded = isSkipHalfExpanded,
+                confirmStateChange = confirmValueChange
+            )
+            """
+
+    )
+)
+@Suppress("Deprecation")
+fun ModalBottomSheetState(
+    initialValue: ModalBottomSheetValue,
     animationSpec: AnimationSpec<Float> = SwipeableDefaults.AnimationSpec,
     confirmValueChange: (ModalBottomSheetValue) -> Boolean = { true },
     isSkipHalfExpanded: Boolean = false
@@ -135,8 +188,10 @@
 class ModalBottomSheetState @Deprecated(
     message = "This constructor is deprecated. confirmStateChange has been renamed to " +
         "confirmValueChange.",
-    replaceWith = ReplaceWith("ModalBottomSheetState(" +
-        "initialValue, animationSpec, confirmStateChange, isSkipHalfExpanded)")
+    replaceWith = ReplaceWith(
+        "ModalBottomSheetState(" +
+            "initialValue, animationSpec, confirmStateChange, isSkipHalfExpanded)"
+    )
 ) constructor(
     initialValue: ModalBottomSheetValue,
     internal val animationSpec: AnimationSpec<Float> = SwipeableDefaults.AnimationSpec,
@@ -148,8 +203,12 @@
         initialValue = initialValue,
         animationSpec = animationSpec,
         confirmValueChange = confirmStateChange,
-        positionalThreshold = PositionalThreshold,
-        velocityThreshold = VelocityThreshold
+        positionalThreshold = {
+            with(requireDensity()) {
+                ModalBottomSheetPositionalThreshold.toPx()
+            }
+        },
+        velocityThreshold = { with(requireDensity()) { ModalBottomSheetVelocityThreshold.toPx() } }
     )
 
     val currentValue: ModalBottomSheetValue
@@ -170,8 +229,10 @@
     @Deprecated(
         message = "This constructor is deprecated. confirmStateChange has been renamed to " +
             "confirmValueChange.",
-        replaceWith = ReplaceWith("ModalBottomSheetState(" +
-            "initialValue, animationSpec, confirmStateChange, false)")
+        replaceWith = ReplaceWith(
+            "ModalBottomSheetState(" +
+                "initialValue, animationSpec, confirmStateChange, false)"
+        )
     )
     @Suppress("Deprecation")
     constructor(
@@ -255,6 +316,12 @@
 
     internal val isAnimationRunning: Boolean get() = swipeableState.isAnimationRunning
 
+    internal var density: Density? = null
+    private fun requireDensity() = requireNotNull(density) {
+        "The density on ModalBottomSheetState ($this) was not set. Did you use " +
+            "ModalBottomSheetState with the ModalBottomSheetLayout composable?"
+    }
+
     companion object {
         /**
          * The default [Saver] implementation for [ModalBottomSheetState].
@@ -265,6 +332,38 @@
             animationSpec: AnimationSpec<Float>,
             confirmValueChange: (ModalBottomSheetValue) -> Boolean,
             skipHalfExpanded: Boolean,
+            density: Density
+        ): Saver<ModalBottomSheetState, *> = Saver(
+            save = { it.currentValue },
+            restore = {
+                ModalBottomSheetState(
+                    initialValue = it,
+                    density = density,
+                    animationSpec = animationSpec,
+                    isSkipHalfExpanded = skipHalfExpanded,
+                    confirmValueChange = confirmValueChange
+                )
+            }
+        )
+
+        /**
+         * The default [Saver] implementation for [ModalBottomSheetState].
+         * Saves the [currentValue] and recreates a [ModalBottomSheetState] with the saved value as
+         * initial value.
+         */
+        @Deprecated(
+            message = "This function is deprecated. Please use the overload where Density is" +
+                " provided.",
+            replaceWith = ReplaceWith(
+                "Saver(animationSpec, confirmValueChange, density, " +
+                    "skipHalfExpanded)"
+            )
+        )
+        @Suppress("Deprecation")
+        fun Saver(
+            animationSpec: AnimationSpec<Float>,
+            confirmValueChange: (ModalBottomSheetValue) -> Boolean,
+            skipHalfExpanded: Boolean,
         ): Saver<ModalBottomSheetState, *> = Saver(
             save = { it.currentValue },
             restore = {
@@ -285,9 +384,12 @@
         @Deprecated(
             message = "This function is deprecated. confirmStateChange has been renamed to " +
                 "confirmValueChange.",
-            replaceWith = ReplaceWith("Saver(animationSpec, confirmStateChange, " +
-                "skipHalfExpanded)")
+            replaceWith = ReplaceWith(
+                "Saver(animationSpec, confirmStateChange, " +
+                    "skipHalfExpanded)"
+            )
         )
+        @Suppress("Deprecation")
         fun Saver(
             animationSpec: AnimationSpec<Float>,
             skipHalfExpanded: Boolean,
@@ -321,19 +423,22 @@
     confirmValueChange: (ModalBottomSheetValue) -> Boolean = { true },
     skipHalfExpanded: Boolean = false,
 ): ModalBottomSheetState {
+    val density = LocalDensity.current
     // Key the rememberSaveable against the initial value. If it changed we don't want to attempt
     // to restore as the restored value could have been saved with a now invalid set of anchors.
     // b/152014032
     return key(initialValue) {
         rememberSaveable(
-            initialValue, animationSpec, skipHalfExpanded, confirmValueChange,
+            initialValue, animationSpec, skipHalfExpanded, confirmValueChange, density,
             saver = Saver(
+                density = density,
                 animationSpec = animationSpec,
                 skipHalfExpanded = skipHalfExpanded,
                 confirmValueChange = confirmValueChange
             )
         ) {
             ModalBottomSheetState(
+                density = density,
                 initialValue = initialValue,
                 animationSpec = animationSpec,
                 isSkipHalfExpanded = skipHalfExpanded,
@@ -359,8 +464,10 @@
 @Deprecated(
     message = "This function is deprecated. confirmStateChange has been renamed to " +
         "confirmValueChange.",
-    replaceWith = ReplaceWith("rememberModalBottomSheetState(" +
-        "initialValue, animationSpec, confirmStateChange, false)")
+    replaceWith = ReplaceWith(
+        "rememberModalBottomSheetState(" +
+            "initialValue, animationSpec, confirmStateChange, false)"
+    )
 )
 @Composable
 @ExperimentalMaterialApi
@@ -386,8 +493,10 @@
 @Deprecated(
     message = "This function is deprecated. confirmStateChange has been renamed to " +
         "confirmValueChange.",
-    replaceWith = ReplaceWith("rememberModalBottomSheetState(" +
-        "initialValue, animationSpec, confirmValueChange = confirmStateChange)")
+    replaceWith = ReplaceWith(
+        "rememberModalBottomSheetState(" +
+            "initialValue, animationSpec, confirmValueChange = confirmStateChange)"
+    )
 )
 @Composable
 @ExperimentalMaterialApi
@@ -444,19 +553,17 @@
     scrimColor: Color = ModalBottomSheetDefaults.scrimColor,
     content: @Composable () -> Unit
 ) {
+    // b/278692145 Remove this once deprecated methods without density are removed
+    if (sheetState.density == null) {
+        val density = LocalDensity.current
+        SideEffect {
+            sheetState.density = density
+        }
+    }
     val scope = rememberCoroutineScope()
     val orientation = Orientation.Vertical
-    val anchorChangeHandler = remember(sheetState, scope) {
-        ModalBottomSheetAnchorChangeHandler(
-            state = sheetState,
-            animateTo = { target, velocity ->
-                scope.launch { sheetState.animateTo(target, velocity = velocity) }
-            },
-            snapTo = { target ->
-                val didSnapSynchronously = sheetState.trySnapTo(target)
-                if (!didSnapSynchronously) scope.launch { sheetState.snapTo(target) }
-            }
-        )
+    val anchorChangeCallback = remember(sheetState, scope) {
+        ModalBottomSheetAnchorChangeCallback(sheetState, scope)
     }
     BoxWithConstraints(modifier) {
         val fullHeight = constraints.maxHeight.toFloat()
@@ -498,23 +605,18 @@
                     orientation = orientation,
                     enabled = sheetState.swipeableState.currentValue != Hidden,
                 )
-                .swipeAnchors(
-                    state = sheetState.swipeableState,
-                    possibleValues = setOf(Hidden, HalfExpanded, Expanded),
-                    anchorChangeHandler = anchorChangeHandler
-                ) { state, sheetSize ->
-                    when (state) {
-                        Hidden -> fullHeight
-                        HalfExpanded -> when {
-                            sheetSize.height < fullHeight / 2f -> null
-                            sheetState.isSkipHalfExpanded -> null
-                            else -> fullHeight / 2f
+                .onSizeChanged { sheetSize ->
+                    val anchors = buildMap {
+                        put(Hidden, fullHeight)
+                        val halfHeight = fullHeight / 2f
+                        if (!sheetState.isSkipHalfExpanded && sheetSize.height > halfHeight) {
+                            put(HalfExpanded, halfHeight)
                         }
-
-                        Expanded -> if (sheetSize.height != 0) {
-                            max(0f, fullHeight - sheetSize.height)
-                        } else null
+                        if (sheetSize.height != 0) {
+                            put(Expanded, max(0f, fullHeight - sheetSize.height))
+                        }
                     }
+                    sheetState.swipeableState.updateAnchors(anchors, anchorChangeCallback)
                 }
                 .semantics {
                     if (sheetState.isVisible) {
@@ -658,18 +760,17 @@
 }
 
 @OptIn(ExperimentalMaterialApi::class)
-private fun ModalBottomSheetAnchorChangeHandler(
+private fun ModalBottomSheetAnchorChangeCallback(
     state: ModalBottomSheetState,
-    animateTo: (target: ModalBottomSheetValue, velocity: Float) -> Unit,
-    snapTo: (target: ModalBottomSheetValue) -> Unit,
-) = AnchorChangeHandler<ModalBottomSheetValue> { previousTarget, previousAnchors, newAnchors ->
-    val previousTargetOffset = previousAnchors[previousTarget]
-    val newTarget = when (previousTarget) {
+    scope: CoroutineScope
+) = AnchorChangedCallback<ModalBottomSheetValue> { prevTarget, prevAnchors, newAnchors ->
+    val previousTargetOffset = prevAnchors[prevTarget]
+    val newTarget = when (prevTarget) {
         Hidden -> Hidden
         HalfExpanded, Expanded -> {
             val hasHalfExpandedState = newAnchors.containsKey(HalfExpanded)
             val newTarget = if (hasHalfExpandedState) HalfExpanded
-                else if (newAnchors.containsKey(Expanded)) Expanded else Hidden
+            else if (newAnchors.containsKey(Expanded)) Expanded else Hidden
             newTarget
         }
     }
@@ -677,14 +778,15 @@
     if (newTargetOffset != previousTargetOffset) {
         if (state.isAnimationRunning) {
             // Re-target the animation to the new offset if it changed
-            animateTo(newTarget, state.lastVelocity)
+            scope.launch { state.animateTo(newTarget, velocity = state.lastVelocity) }
         } else {
             // Snap to the new offset value of the target if no animation was running
-            snapTo(newTarget)
+            val didSnapSynchronously = state.trySnapTo(newTarget)
+            if (!didSnapSynchronously) scope.launch { state.snapTo(newTarget) }
         }
     }
 }
 
-private val PositionalThreshold: Density.(Float) -> Float = { 56.dp.toPx() }
-private val VelocityThreshold = 125.dp
+private val ModalBottomSheetPositionalThreshold = 56.dp
+private val ModalBottomSheetVelocityThreshold = 125.dp
 private val MaxModalBottomSheetWidth = 640.dp
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeableV2.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeableV2.kt
index d5d27ae..b467da0 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeableV2.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeableV2.kt
@@ -26,6 +26,7 @@
 import androidx.compose.foundation.gestures.draggable
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.offset
+import androidx.compose.material.SwipeableV2State.AnchorChangedCallback
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.derivedStateOf
@@ -35,21 +36,11 @@
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.layout.LayoutModifier
-import androidx.compose.ui.layout.Measurable
-import androidx.compose.ui.layout.MeasureResult
-import androidx.compose.ui.layout.MeasureScope
-import androidx.compose.ui.layout.OnRemeasuredModifier
-import androidx.compose.ui.platform.InspectorInfo
-import androidx.compose.ui.platform.InspectorValueInfo
-import androidx.compose.ui.platform.debugInspectorInfo
-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.platform.LocalDensity
 import androidx.compose.ui.unit.dp
 import kotlin.math.abs
 import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.launch
 
@@ -90,57 +81,6 @@
 )
 
 /**
- * Define anchor points for a given [SwipeableV2State] based on this node's layout size and update
- * the state with them.
- *
- * @param state The associated [SwipeableV2State]
- * @param possibleValues All possible values the [SwipeableV2State] could be in.
- * @param anchorChangeHandler A callback to be invoked when the anchors have changed,
- * `null` by default. Components with custom reconciliation logic should implement this callback,
- * i.e. to re-target an in-progress animation.
- * @param calculateAnchor This method will be invoked to calculate the position of all
- * [possibleValues], given this node's layout size. Return the anchor's offset from the initial
- * anchor, or `null` to indicate that a value does not have an anchor.
- */
-@ExperimentalMaterialApi
-internal fun <T> Modifier.swipeAnchors(
-    state: SwipeableV2State<T>,
-    possibleValues: Set<T>,
-    anchorChangeHandler: AnchorChangeHandler<T>? = null,
-    calculateAnchor: (value: T, layoutSize: IntSize) -> Float?,
-) = this.then(SwipeAnchorsModifier(
-    onDensityChanged = { state.density = it },
-    onSizeChanged = { layoutSize ->
-        val previousAnchors = state.anchors
-        val newAnchors = mutableMapOf<T, Float>()
-        possibleValues.forEach {
-            val anchorValue = calculateAnchor(it, layoutSize)
-            if (anchorValue != null) {
-                newAnchors[it] = anchorValue
-            }
-        }
-        if (previousAnchors != newAnchors) {
-            val previousTarget = state.targetValue
-            val stateRequiresCleanup = state.updateAnchors(newAnchors)
-            if (stateRequiresCleanup) {
-                anchorChangeHandler?.onAnchorsChanged(
-                    previousTarget,
-                    previousAnchors,
-                    newAnchors
-                )
-            }
-        }
-    },
-    inspectorInfo = debugInspectorInfo {
-        name = "swipeAnchors"
-        properties["state"] = state
-        properties["possibleValues"] = possibleValues
-        properties["anchorChangeHandler"] = anchorChangeHandler
-        properties["calculateAnchor"] = calculateAnchor
-    }
-))
-
-/**
  * State of the [swipeableV2] modifier.
  *
  * This contains necessary information about any ongoing swipe or animation and provides methods
@@ -150,12 +90,11 @@
  * @param initialValue The initial value of the state.
  * @param animationSpec The default animation that will be used to animate to a new state.
  * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.
- * @param positionalThreshold The positional threshold to be used when calculating the target state
- * while a swipe is in progress and when settling after the swipe ends. This is the distance from
- * the start of a transition. It will be, depending on the direction of the interaction, added or
- * subtracted from/to the origin offset. It should always be a positive value. See the
- * [fractionalPositionalThreshold] and [fixedPositionalThreshold] methods.
- * @param velocityThreshold The velocity threshold (in dp per second) that the end velocity has to
+ * @param positionalThreshold The positional threshold, in px, to be used when calculating the
+ * target state while a swipe is in progress and when settling after the swipe ends. This is the
+ * distance from the start of a transition. It will be, depending on the direction of the
+ * interaction, added or subtracted from/to the origin offset. It should always be a positive value.
+ * @param velocityThreshold The velocity threshold (in px per second) that the end velocity has to
  * exceed in order to animate to the next state, even if the [positionalThreshold] has not been
  * reached.
  */
@@ -163,11 +102,10 @@
 @ExperimentalMaterialApi
 internal class SwipeableV2State<T>(
     initialValue: T,
+    internal val positionalThreshold: (totalDistance: Float) -> Float,
+    internal val velocityThreshold: () -> Float,
     internal val animationSpec: AnimationSpec<Float> = SwipeableV2Defaults.AnimationSpec,
-    internal val confirmValueChange: (newValue: T) -> Boolean = { true },
-    internal val positionalThreshold: Density.(totalDistance: Float) -> Float =
-        SwipeableV2Defaults.PositionalThreshold,
-    internal val velocityThreshold: Dp = SwipeableV2Defaults.VelocityThreshold,
+    internal val confirmValueChange: (newValue: T) -> Boolean = { true }
 ) {
 
     private val swipeMutex = InternalMutatorMutex()
@@ -284,28 +222,43 @@
 
     internal var anchors by mutableStateOf(emptyMap<T, Float>())
 
-    internal var density: Density? = null
-
     /**
      * Update the anchors.
      * If the previous set of anchors was empty, attempt to update the offset to match the initial
-     * value's anchor.
+     * value's anchor. If the [newAnchors] are different to the existing anchors, or there is no
+     * anchor for the [currentValue], the [onAnchorsChanged] callback will be invoked.
      *
-     * @return true if the state needs to be adjusted after updating the anchors, e.g. if the
-     * initial value is not found in the initial set of anchors. false if no further updates are
-     * needed.
+     * <b>If your anchors depend on the size of the layout, updateAnchors should be called in the
+     * layout (placement) phase, e.g. through Modifier.onSizeChanged.</b> This ensures that the
+     * state is set up within the same frame.
+     * For static anchors, or anchors with different data dependencies, updateAnchors is safe to be
+     * called any time, for example from a side effect.
+     *
+     * @param newAnchors The new anchors
+     * @param onAnchorsChanged Optional callback to be invoked if the state needs to be updated
+     * after updating the anchors, for example if the anchor for the [currentValue] has been removed
      */
-    internal fun updateAnchors(newAnchors: Map<T, Float>): Boolean {
-        val previousAnchorsEmpty = anchors.isEmpty()
-        anchors = newAnchors
-        val initialValueHasAnchor = if (previousAnchorsEmpty) {
-            val initialValue = currentValue
-            val initialValueAnchor = anchors[initialValue]
-            val initialValueHasAnchor = initialValueAnchor != null
-            if (initialValueHasAnchor) trySnapTo(initialValue)
-            initialValueHasAnchor
-        } else true
-        return !initialValueHasAnchor || !previousAnchorsEmpty
+    internal fun updateAnchors(
+        newAnchors: Map<T, Float>,
+        onAnchorsChanged: AnchorChangedCallback<T>? = null
+    ) {
+        if (anchors != newAnchors) {
+            val previousAnchors = anchors
+            val previousTarget = targetValue
+            val previousAnchorsEmpty = anchors.isEmpty()
+            anchors = newAnchors
+
+            val currentValueHasAnchor = anchors[currentValue] != null
+            if (previousAnchorsEmpty && currentValueHasAnchor) {
+                snap(currentValue)
+            } else {
+                onAnchorsChanged?.onAnchorsChanged(
+                    previousTargetValue = previousTarget,
+                    previousAnchors = previousAnchors,
+                    newAnchors = newAnchors
+                )
+            }
+        }
     }
 
     /**
@@ -414,8 +367,7 @@
     ): T {
         val currentAnchors = anchors
         val currentAnchor = currentAnchors[currentValue]
-        val currentDensity = requireDensity()
-        val velocityThresholdPx = with(currentDensity) { velocityThreshold.toPx() }
+        val velocityThresholdPx = velocityThreshold()
         return if (currentAnchor == offset || currentAnchor == null) {
             currentValue
         } else if (currentAnchor < offset) {
@@ -425,7 +377,7 @@
             } else {
                 val upper = currentAnchors.closestAnchor(offset, true)
                 val distance = abs(currentAnchors.getValue(upper) - currentAnchor)
-                val relativeThreshold = abs(positionalThreshold(currentDensity, distance))
+                val relativeThreshold = abs(positionalThreshold(distance))
                 val absoluteThreshold = abs(currentAnchor + relativeThreshold)
                 if (offset < absoluteThreshold) currentValue else upper
             }
@@ -436,7 +388,7 @@
             } else {
                 val lower = currentAnchors.closestAnchor(offset, false)
                 val distance = abs(currentAnchor - currentAnchors.getValue(lower))
-                val relativeThreshold = abs(positionalThreshold(currentDensity, distance))
+                val relativeThreshold = abs(positionalThreshold(distance))
                 val absoluteThreshold = abs(currentAnchor - relativeThreshold)
                 if (offset < 0) {
                     // For negative offsets, larger absolute thresholds are closer to lower anchors
@@ -449,11 +401,6 @@
         }
     }
 
-    private fun requireDensity() = requireNotNull(density) {
-        "SwipeableState did not have a density attached. Are you using Modifier.swipeable with " +
-            "this=$this SwipeableState?"
-    }
-
     private suspend fun swipe(
         swipePriority: MutatePriority = MutatePriority.Default,
         action: suspend () -> Unit
@@ -487,8 +434,8 @@
         fun <T : Any> Saver(
             animationSpec: AnimationSpec<Float>,
             confirmValueChange: (T) -> Boolean,
-            positionalThreshold: Density.(distance: Float) -> Float,
-            velocityThreshold: Dp
+            positionalThreshold: (distance: Float) -> Float,
+            velocityThreshold: () -> Float
         ) = Saver<SwipeableV2State<T>, T>(
             save = { it.currentValue },
             restore = {
@@ -502,6 +449,34 @@
             }
         )
     }
+
+    /**
+     * Defines a callback that is invoked when the anchors have changed.
+     *
+     * Components with custom reconciliation logic should implement this callback, for example to
+     * re-target an in-progress animation when the anchors change.
+     *
+     * @see SwipeableV2Defaults.ReconcileAnimationOnAnchorChangedCallback for a default
+     * implementation
+     */
+    @ExperimentalMaterialApi
+    fun interface AnchorChangedCallback<T> {
+
+        /**
+         * Callback that is invoked when the anchors have changed, after the [SwipeableV2State] has
+         * been updated with them. Use this hook to re-launch animations or interrupt them if
+         * needed.
+         *
+         * @param previousTargetValue The target value before the anchors were updated
+         * @param previousAnchors The previously set anchors
+         * @param newAnchors The newly set anchors
+         */
+        fun onAnchorsChanged(
+            previousTargetValue: T,
+            previousAnchors: Map<T, Float>,
+            newAnchors: Map<T, Float>,
+        )
+    }
 }
 
 /**
@@ -518,49 +493,28 @@
     animationSpec: AnimationSpec<Float> = SwipeableV2Defaults.AnimationSpec,
     confirmValueChange: (newValue: T) -> Boolean = { true }
 ): SwipeableV2State<T> {
+    val positionalThreshold = SwipeableV2Defaults.positionalThreshold
+    val velocityThreshold = SwipeableV2Defaults.velocityThreshold
     return rememberSaveable(
-        initialValue, animationSpec, confirmValueChange,
+        initialValue, animationSpec, confirmValueChange, positionalThreshold, velocityThreshold,
         saver = SwipeableV2State.Saver(
             animationSpec = animationSpec,
             confirmValueChange = confirmValueChange,
-            positionalThreshold = SwipeableV2Defaults.PositionalThreshold,
-            velocityThreshold = SwipeableV2Defaults.VelocityThreshold
+            positionalThreshold = positionalThreshold,
+            velocityThreshold = velocityThreshold
         ),
     ) {
         SwipeableV2State(
             initialValue = initialValue,
             animationSpec = animationSpec,
             confirmValueChange = confirmValueChange,
-            positionalThreshold = SwipeableV2Defaults.PositionalThreshold,
-            velocityThreshold = SwipeableV2Defaults.VelocityThreshold
+            positionalThreshold = positionalThreshold,
+            velocityThreshold = velocityThreshold
         )
     }
 }
 
 /**
- * Expresses a fixed positional threshold of [threshold] dp. This will be the distance from an
- * anchor that needs to be reached for [SwipeableV2State] to settle to the next closest anchor.
- *
- * @see [fractionalPositionalThreshold] for a fractional positional threshold
- */
-@ExperimentalMaterialApi
-internal fun fixedPositionalThreshold(threshold: Dp): Density.(distance: Float) -> Float = {
-    threshold.toPx()
-}
-
-/**
- * Expresses a relative positional threshold of the [fraction] of the distance to the closest anchor
- * in the current direction. This will be the distance from an anchor that needs to be reached for
- * [SwipeableV2State] to settle to the next closest anchor.
- *
- * @see [fixedPositionalThreshold] for a fixed positional threshold
- */
-@ExperimentalMaterialApi
-internal fun fractionalPositionalThreshold(
-    fraction: Float
-): Density.(distance: Float) -> Float = { distance -> distance * fraction }
-
-/**
  * Contains useful defaults for [swipeableV2] and [SwipeableV2State].
  */
 @Stable
@@ -576,102 +530,45 @@
      * The default velocity threshold (1.8 dp per millisecond) used by [rememberSwipeableV2State].
      */
     @ExperimentalMaterialApi
-    val VelocityThreshold: Dp = 125.dp
+    val velocityThreshold: () -> Float
+        @Composable get() = with(LocalDensity.current) { { 125.dp.toPx() } }
 
     /**
      * The default positional threshold (56 dp) used by [rememberSwipeableV2State]
      */
     @ExperimentalMaterialApi
-    val PositionalThreshold: Density.(totalDistance: Float) -> Float =
-        fixedPositionalThreshold(56.dp)
+    val positionalThreshold: (totalDistance: Float) -> Float
+        @Composable get() = with(LocalDensity.current) {
+            { 56.dp.toPx() }
+        }
 
     /**
-     * A [AnchorChangeHandler] implementation that attempts to reconcile an in-progress animation
+     * A [AnchorChangedCallback] implementation that attempts to reconcile an in-progress animation
      * by re-targeting it if necessary or finding the closest new anchor.
      * If the previous anchor is not in the new set of anchors, this implementation will snap to the
      * closest anchor.
      *
      * Consider implementing a custom handler for more complex components like sheets.
-     * The [animate] and [snap] lambdas hoist the animation and snap logic. Usually these will just
-     * delegate to [SwipeableV2State].
-     *
-     * @param state The [SwipeableV2State] the change handler will read from
-     * @param animate A lambda that gets invoked to start an animation to a new target
-     * @param snap A lambda that gets invoked to snap to a new target
      */
     @ExperimentalMaterialApi
-    internal fun <T> ReconcileAnimationOnAnchorChangeHandler(
+    internal fun <T> ReconcileAnimationOnAnchorChangedCallback(
         state: SwipeableV2State<T>,
-        animate: (target: T, velocity: Float) -> Unit,
-        snap: (target: T) -> Unit
-    ) = AnchorChangeHandler { previousTarget, previousAnchors, newAnchors ->
-        val previousTargetOffset = previousAnchors[previousTarget]
-        val newTargetOffset = newAnchors[previousTarget]
-        if (previousTargetOffset != newTargetOffset) {
-            if (newTargetOffset != null) {
-                animate(previousTarget, state.lastVelocity)
-            } else {
-                snap(newAnchors.closestAnchor(offset = state.requireOffset()))
+        scope: CoroutineScope
+    ) = AnchorChangedCallback<T> { previousTarget, previousAnchors, newAnchors ->
+            val previousTargetOffset = previousAnchors[previousTarget]
+            val newTargetOffset = newAnchors[previousTarget]
+            if (previousTargetOffset != newTargetOffset) {
+                if (newTargetOffset != null) {
+                    scope.launch {
+                        state.animateTo(previousTarget, state.lastVelocity)
+                    }
+                } else {
+                    scope.launch {
+                        state.snapTo(newAnchors.closestAnchor(offset = state.requireOffset()))
+                    }
+                }
             }
         }
-    }
-}
-
-/**
- * Defines a callback that is invoked when the anchors have changed.
- *
- * Components with custom reconciliation logic should implement this callback, for example to
- * re-target an in-progress animation when the anchors change.
- *
- * @see SwipeableV2Defaults.ReconcileAnimationOnAnchorChangeHandler for a default implementation
- */
-@ExperimentalMaterialApi
-internal fun interface AnchorChangeHandler<T> {
-
-    /**
-     * Callback that is invoked when the anchors have changed, after the [SwipeableV2State] has been
-     * updated with them. Use this hook to re-launch animations or interrupt them if needed.
-     *
-     * @param previousTargetValue The target value before the anchors were updated
-     * @param previousAnchors The previously set anchors
-     * @param newAnchors The newly set anchors
-     */
-    fun onAnchorsChanged(
-        previousTargetValue: T,
-        previousAnchors: Map<T, Float>,
-        newAnchors: Map<T, Float>
-    )
-}
-
-@Stable
-private class SwipeAnchorsModifier(
-    private val onDensityChanged: (density: Density) -> Unit,
-    private val onSizeChanged: (layoutSize: IntSize) -> Unit,
-    inspectorInfo: InspectorInfo.() -> Unit,
-) : LayoutModifier, OnRemeasuredModifier, InspectorValueInfo(inspectorInfo) {
-
-    private var lastDensity: Float = -1f
-    private var lastFontScale: Float = -1f
-
-    override fun MeasureScope.measure(
-        measurable: Measurable,
-        constraints: Constraints
-    ): MeasureResult {
-        if (density != lastDensity || fontScale != lastFontScale) {
-            onDensityChanged(Density(density, fontScale))
-            lastDensity = density
-            lastFontScale = fontScale
-        }
-        val placeable = measurable.measure(constraints)
-        return layout(placeable.width, placeable.height) { placeable.place(0, 0) }
-    }
-
-    override fun onRemeasured(size: IntSize) {
-        onSizeChanged(size)
-    }
-
-    override fun toString() = "SwipeAnchorsModifierImpl(updateDensity=$onDensityChanged, " +
-        "onSizeChanged=$onSizeChanged)"
 }
 
 private fun <T> Map<T, Float>.closestAnchor(
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 0b16d7c..006f13f 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
@@ -107,22 +107,19 @@
     // the animation state through this, animating back to the previous value if we don't receive
     // a new checked value.
     var forceAnimationCheck by remember { mutableStateOf(false) }
-    val swipeableState = remember {
+    val switchVelocityThresholdPx = with(LocalDensity.current) { SwitchVelocityThreshold.toPx() }
+    val swipeableState = remember(switchVelocityThresholdPx) {
         SwipeableV2State(
             initialValue = checked,
-            positionalThreshold = SwitchThreshold,
-            animationSpec = AnimationSpec
+            animationSpec = AnimationSpec,
+            positionalThreshold = { distance -> distance * SwitchPositionalThreshold },
+            velocityThreshold = { switchVelocityThresholdPx }
         )
     }
     val currentOnCheckedChange by rememberUpdatedState(onCheckedChange)
     val currentChecked by rememberUpdatedState(checked)
-
-    // Todo: Offer static anchors Modifier.swipeable overload b/265435207
-    val density = LocalDensity.current
     SideEffect {
-        swipeableState.density = density
-        val anchors = mapOf(false to minBound, true to maxBound)
-        swipeableState.updateAnchors(anchors)
+        swipeableState.updateAnchors(mapOf(false to minBound, true to maxBound))
     }
     LaunchedEffect(swipeableState) {
         snapshotFlow { swipeableState.currentValue }
@@ -419,5 +416,5 @@
     }
 }
 
-@OptIn(ExperimentalMaterialApi::class)
-private val SwitchThreshold = fractionalPositionalThreshold(0.7f)
+private const val SwitchPositionalThreshold = 0.7f
+private val SwitchVelocityThreshold = 125.dp
diff --git a/compose/material3/benchmark/build.gradle b/compose/material3/benchmark/build.gradle
index c21a27e..df3e144 100644
--- a/compose/material3/benchmark/build.gradle
+++ b/compose/material3/benchmark/build.gradle
@@ -24,6 +24,7 @@
 
 dependencies {
 
+    androidTestImplementation(project(":compose:material:material-icons-core"))
     androidTestImplementation(project(":compose:material3:material3"))
     androidTestImplementation(project(":benchmark:benchmark-junit4"))
     androidTestImplementation(project(":compose:runtime:runtime"))
diff --git a/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/ChipBenchmark.kt b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/ChipBenchmark.kt
new file mode 100644
index 0000000..d190cbf
--- /dev/null
+++ b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/ChipBenchmark.kt
@@ -0,0 +1,96 @@
+/*
+ * 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.benchmark
+
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Settings
+import androidx.compose.material3.AssistChip
+import androidx.compose.material3.AssistChipDefaults
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.testutils.LayeredComposeTestCase
+import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
+import androidx.compose.testutils.benchmark.benchmarkFirstCompose
+import androidx.compose.testutils.benchmark.benchmarkFirstDraw
+import androidx.compose.testutils.benchmark.benchmarkFirstLayout
+import androidx.compose.testutils.benchmark.benchmarkFirstMeasure
+import androidx.compose.ui.Modifier
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+class ChipBenchmark {
+
+    @get:Rule
+    val benchmarkRule = ComposeBenchmarkRule()
+
+    private val chipTestCaseFactory = { ChipTestCase() }
+
+    @Test
+    fun first_compose() {
+        benchmarkRule.benchmarkFirstCompose(chipTestCaseFactory)
+    }
+
+    @Test
+    fun chip_measure() {
+        benchmarkRule.benchmarkFirstMeasure(chipTestCaseFactory)
+    }
+
+    @Test
+    fun chip_layout() {
+        benchmarkRule.benchmarkFirstLayout(chipTestCaseFactory)
+    }
+
+    @Test
+    fun chip_draw() {
+        benchmarkRule.benchmarkFirstDraw(chipTestCaseFactory)
+    }
+}
+
+internal class ChipTestCase : LayeredComposeTestCase() {
+
+    @OptIn(ExperimentalMaterial3Api::class)
+    @Composable
+    override fun MeasuredContent() {
+        AssistChip(
+            onClick = { /* Do something! */ },
+            label = { Text("Assist Chip") },
+            leadingIcon = {
+                Icon(
+                    Icons.Filled.Settings,
+                    contentDescription = "Localized description",
+                    Modifier.size(AssistChipDefaults.IconSize)
+                )
+            }
+        )
+    }
+
+    @Composable
+    override fun ContentWrappers(content: @Composable () -> Unit) {
+        MaterialTheme {
+            content()
+        }
+    }
+}
diff --git a/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/DatePickerBenchmark.kt b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/DatePickerBenchmark.kt
new file mode 100644
index 0000000..d047879
--- /dev/null
+++ b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/DatePickerBenchmark.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.compose.material3.benchmark
+
+import androidx.compose.material3.DatePicker
+import androidx.compose.material3.DisplayMode
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.rememberDatePickerState
+import androidx.compose.runtime.Composable
+import androidx.compose.testutils.LayeredComposeTestCase
+import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
+import androidx.compose.testutils.benchmark.benchmarkFirstCompose
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+class DatePickerBenchmark {
+
+    @get:Rule
+    val benchmarkRule = ComposeBenchmarkRule()
+
+    private val datePickerTestCaseFactory = { DatePickerTestCase() }
+    private val dateInputTestCaseFactory = { DateInputTestCase() }
+
+    @Test
+    fun first_compose_pickerMode() {
+        benchmarkRule.benchmarkFirstCompose(datePickerTestCaseFactory)
+    }
+
+    @Test
+    fun first_compose_inputMode() {
+        benchmarkRule.benchmarkFirstCompose(dateInputTestCaseFactory)
+    }
+
+    @Test
+    fun datePicker_measure() {
+        benchmarkRule.benchmarkFirstMeasure(
+            caseFactory = datePickerTestCaseFactory,
+            allowPendingChanges = true
+        )
+    }
+
+    @Test
+    fun dateInput_measure() {
+        benchmarkRule.benchmarkFirstMeasure(
+            caseFactory = dateInputTestCaseFactory,
+            allowPendingChanges = true
+        )
+    }
+
+    @Test
+    fun datePicker_layout() {
+        benchmarkRule.benchmarkFirstLayout(
+            caseFactory = datePickerTestCaseFactory,
+            allowPendingChanges = true
+        )
+    }
+
+    @Test
+    fun dateInput_layout() {
+        benchmarkRule.benchmarkFirstLayout(
+            caseFactory = dateInputTestCaseFactory,
+            allowPendingChanges = true
+        )
+    }
+
+    @Test
+    fun datePicker_draw() {
+        benchmarkRule.benchmarkFirstDraw(
+            caseFactory = datePickerTestCaseFactory,
+            allowPendingChanges = true
+        )
+    }
+
+    @Test
+    fun dateInput_draw() {
+        benchmarkRule.benchmarkFirstDraw(
+            caseFactory = dateInputTestCaseFactory,
+            allowPendingChanges = true
+        )
+    }
+}
+
+/**
+ * A [DatePicker] test case when initiated in its default picker mode.
+ */
+internal class DatePickerTestCase : LayeredComposeTestCase() {
+
+    @OptIn(ExperimentalMaterial3Api::class)
+    @Composable
+    override fun MeasuredContent() {
+        DatePicker(state = rememberDatePickerState())
+    }
+
+    @Composable
+    override fun ContentWrappers(content: @Composable () -> Unit) {
+        MaterialTheme {
+            content()
+        }
+    }
+}
+
+/**
+ * A [DatePicker] test case when initiated in an input mode.
+ */
+internal class DateInputTestCase : LayeredComposeTestCase() {
+
+    @OptIn(ExperimentalMaterial3Api::class)
+    @Composable
+    override fun MeasuredContent() {
+        DatePicker(state = rememberDatePickerState(initialDisplayMode = DisplayMode.Input))
+    }
+
+    @Composable
+    override fun ContentWrappers(content: @Composable () -> Unit) {
+        MaterialTheme {
+            content()
+        }
+    }
+}
diff --git a/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/DateRangePickerBenchmark.kt b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/DateRangePickerBenchmark.kt
new file mode 100644
index 0000000..d8a46d8
--- /dev/null
+++ b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/DateRangePickerBenchmark.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.compose.material3.benchmark
+
+import androidx.compose.material3.DateRangePicker
+import androidx.compose.material3.DisplayMode
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.rememberDateRangePickerState
+import androidx.compose.runtime.Composable
+import androidx.compose.testutils.LayeredComposeTestCase
+import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
+import androidx.compose.testutils.benchmark.benchmarkFirstCompose
+import androidx.compose.testutils.benchmark.benchmarkFirstDraw
+import androidx.compose.testutils.benchmark.benchmarkFirstLayout
+import androidx.compose.testutils.benchmark.benchmarkFirstMeasure
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+class DateRangePickerBenchmark {
+
+    @get:Rule
+    val benchmarkRule = ComposeBenchmarkRule()
+
+    private val dateRangePickerTestCaseFactory = { DateRangePickerTestCase() }
+    private val dateRangeInputTestCaseFactory = { DateRangeInputTestCase() }
+
+    @Test
+    fun first_compose_pickerMode() {
+        benchmarkRule.benchmarkFirstCompose(dateRangePickerTestCaseFactory)
+    }
+
+    @Test
+    fun first_compose_inputMode() {
+        benchmarkRule.benchmarkFirstCompose(dateRangeInputTestCaseFactory)
+    }
+
+    @Test
+    fun dateRangePicker_measure() {
+        benchmarkRule.benchmarkFirstMeasure(dateRangePickerTestCaseFactory)
+    }
+
+    @Test
+    fun dateRangeInput_measure() {
+        benchmarkRule.benchmarkFirstMeasure(
+            caseFactory = dateRangeInputTestCaseFactory,
+            allowPendingChanges = true
+        )
+    }
+
+    @Test
+    fun dateRangePicker_layout() {
+        benchmarkRule.benchmarkFirstLayout(dateRangePickerTestCaseFactory)
+    }
+
+    @Test
+    fun dateRangeInput_layout() {
+        benchmarkRule.benchmarkFirstLayout(
+            caseFactory = dateRangeInputTestCaseFactory,
+            allowPendingChanges = true
+        )
+    }
+
+    @Test
+    fun dateRangePicker_draw() {
+        benchmarkRule.benchmarkFirstDraw(dateRangePickerTestCaseFactory)
+    }
+
+    @Test
+    fun dateRangeInput_draw() {
+        benchmarkRule.benchmarkFirstDraw(
+            caseFactory = dateRangeInputTestCaseFactory,
+            allowPendingChanges = true
+        )
+    }
+}
+
+/**
+ * A [DateRangePicker] test case when initiated in its default picker mode.
+ */
+internal class DateRangePickerTestCase : LayeredComposeTestCase() {
+
+    @OptIn(ExperimentalMaterial3Api::class)
+    @Composable
+    override fun MeasuredContent() {
+        DateRangePicker(state = rememberDateRangePickerState())
+    }
+
+    @Composable
+    override fun ContentWrappers(content: @Composable () -> Unit) {
+        MaterialTheme {
+            content()
+        }
+    }
+}
+
+/**
+ * A [DateRangePicker] test case when initiated in an input mode.
+ */
+internal class DateRangeInputTestCase : LayeredComposeTestCase() {
+
+    @OptIn(ExperimentalMaterial3Api::class)
+    @Composable
+    override fun MeasuredContent() {
+        DateRangePicker(
+            state = rememberDateRangePickerState(initialDisplayMode = DisplayMode.Input)
+        )
+    }
+
+    @Composable
+    override fun ContentWrappers(content: @Composable () -> Unit) {
+        MaterialTheme {
+            content()
+        }
+    }
+}
diff --git a/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/MaterialBenchmarkExtensions.kt b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/MaterialBenchmarkExtensions.kt
new file mode 100644
index 0000000..5eaa7df
--- /dev/null
+++ b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/MaterialBenchmarkExtensions.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.
+ */
+
+package androidx.compose.material3.benchmark
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.testutils.ComposeTestCase
+import androidx.compose.testutils.LayeredComposeTestCase
+import androidx.compose.testutils.assertNoPendingChanges
+import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
+import androidx.compose.testutils.benchmark.recomposeUntilNoChangesPending
+import androidx.compose.testutils.doFramesUntilNoChangesPending
+import org.junit.Assert
+
+/**
+ * Measures the time of the first draw right after the given test case is added to an already
+ * existing hierarchy.
+ *
+ * @param caseFactory a factory for [LayeredComposeTestCase]
+ * @param allowPendingChanges in case `true`, the benchmark will allow pending changes after the
+ * first draw. Otherwise, an [assertNoPendingChanges] will be called.
+ */
+internal fun ComposeBenchmarkRule.benchmarkFirstDraw(
+    caseFactory: () -> LayeredComposeTestCase,
+    allowPendingChanges: Boolean
+) {
+    runBenchmarkFor(LayeredCaseAdapter.of(caseFactory)) {
+        measureRepeated {
+            runWithTimingDisabled {
+                doFramesUntilNoChangesPending()
+                // Add the content to benchmark
+                getTestCase().addMeasuredContent()
+                recomposeUntilNoChangesPending()
+                requestLayout()
+                measure()
+                layout()
+                drawPrepare()
+            }
+
+            draw()
+
+            runWithTimingDisabled {
+                drawFinish()
+                if (!allowPendingChanges) assertNoPendingChanges()
+                disposeContent()
+            }
+        }
+    }
+}
+
+/**
+ * Measures the time of the first measure right after the given test case is added to an already
+ * existing hierarchy.
+ *
+ * @param caseFactory a factory for [LayeredComposeTestCase]
+ * @param allowPendingChanges in case `true`, the benchmark will allow pending changes after the
+ * first measure. Otherwise, an [assertNoPendingChanges] will be called.
+ */
+internal fun ComposeBenchmarkRule.benchmarkFirstMeasure(
+    caseFactory: () -> LayeredComposeTestCase,
+    allowPendingChanges: Boolean
+) {
+    runBenchmarkFor(LayeredCaseAdapter.of(caseFactory)) {
+        measureRepeated {
+            runWithTimingDisabled {
+                doFramesUntilNoChangesPending()
+                // Add the content to benchmark
+                getTestCase().addMeasuredContent()
+                recomposeUntilNoChangesPending()
+                requestLayout()
+            }
+
+            measure()
+
+            runWithTimingDisabled {
+                if (!allowPendingChanges) assertNoPendingChanges()
+                disposeContent()
+            }
+        }
+    }
+}
+
+/**
+ * Measures the time of the first layout right after the given test case is added to an already
+ * existing hierarchy.
+ *
+ * @param caseFactory a factory for [LayeredComposeTestCase]
+ * @param allowPendingChanges in case `true`, the benchmark will allow pending changes after the
+ * first layout. Otherwise, an [assertNoPendingChanges] will be called.
+ */
+internal fun ComposeBenchmarkRule.benchmarkFirstLayout(
+    caseFactory: () -> LayeredComposeTestCase,
+    allowPendingChanges: Boolean
+) {
+    runBenchmarkFor(LayeredCaseAdapter.of(caseFactory)) {
+        measureRepeated {
+            runWithTimingDisabled {
+                doFramesUntilNoChangesPending()
+                // Add the content to benchmark
+                getTestCase().addMeasuredContent()
+                recomposeUntilNoChangesPending()
+                requestLayout()
+                measure()
+            }
+
+            layout()
+
+            runWithTimingDisabled {
+                if (!allowPendingChanges) assertNoPendingChanges()
+                disposeContent()
+            }
+        }
+    }
+}
+
+private class LayeredCaseAdapter(private val innerCase: LayeredComposeTestCase) : ComposeTestCase {
+
+    companion object {
+        fun of(caseFactory: () -> LayeredComposeTestCase): () -> LayeredCaseAdapter = {
+            LayeredCaseAdapter(caseFactory())
+        }
+    }
+
+    var isComposed by mutableStateOf(false)
+
+    @Composable
+    override fun Content() {
+        innerCase.ContentWrappers {
+            if (isComposed) {
+                innerCase.MeasuredContent()
+            }
+        }
+    }
+
+    fun addMeasuredContent() {
+        Assert.assertTrue(!isComposed)
+        isComposed = true
+    }
+}
+
+private const val MaxAmountOfRecompositions = 10
diff --git a/compose/material3/material3/api/api_lint.ignore b/compose/material3/material3/api/api_lint.ignore
index 21a0335..29ca5ed 100644
--- a/compose/material3/material3/api/api_lint.ignore
+++ b/compose/material3/material3/api/api_lint.ignore
@@ -1,3 +1,11 @@
 // Baseline format: 1.0
 AutoBoxing: androidx.compose.material3.DatePickerState#setSelectedDateMillis(Long) parameter #0:
     Must avoid boxed primitives (`java.lang.Long`)
+
+
+GetterSetterNames: androidx.compose.material3.SheetState#getHasExpandedState():
+    Getter for boolean property `hasExpandedState` is named `getHasExpandedState` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.material3.SheetState#getHasPartiallyExpandedState():
+    Getter for boolean property `hasPartiallyExpandedState` is named `getHasPartiallyExpandedState` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field SnackbarVisuals.withDismissAction:
+    Invalid name for boolean property `withDismissAction`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/compose/material3/material3/build.gradle b/compose/material3/material3/build.gradle
index 1624518..10979b6 100644
--- a/compose/material3/material3/build.gradle
+++ b/compose/material3/material3/build.gradle
@@ -37,16 +37,16 @@
          */
         implementation(libs.kotlinStdlibCommon)
         implementation("androidx.activity:activity-compose:1.5.0")
-        implementation("androidx.compose.animation:animation-core:1.4.1")
-        implementation("androidx.compose.foundation:foundation-layout:1.4.1")
-        implementation("androidx.compose.ui:ui-util:1.4.1")
-        api("androidx.compose.foundation:foundation:1.4.1")
-        api("androidx.compose.material:material-icons-core:1.4.1")
-        api("androidx.compose.material:material-ripple:1.4.1")
-        api("androidx.compose.runtime:runtime:1.4.1")
-        api("androidx.compose.ui:ui-graphics:1.4.1")
-        api("androidx.compose.ui:ui:1.4.1")
-        api("androidx.compose.ui:ui-text:1.4.1")
+        implementation("androidx.compose.animation:animation-core:1.4.2")
+        implementation("androidx.compose.foundation:foundation-layout:1.4.2")
+        implementation("androidx.compose.ui:ui-util:1.4.2")
+        api("androidx.compose.foundation:foundation:1.4.2")
+        api("androidx.compose.material:material-icons-core:1.4.2")
+        api("androidx.compose.material:material-ripple:1.4.2")
+        api("androidx.compose.runtime:runtime:1.4.2")
+        api("androidx.compose.ui:ui-graphics:1.4.2")
+        api("androidx.compose.ui:ui:1.4.2")
+        api("androidx.compose.ui:ui-text:1.4.2")
 
         // TODO: remove next 3 dependencies when b/202810604 is fixed
         implementation("androidx.savedstate:savedstate-ktx:1.2.1")
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/BottomSheetSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/BottomSheetSamples.kt
index bae18fe..226ffc70 100644
--- a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/BottomSheetSamples.kt
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/BottomSheetSamples.kt
@@ -41,6 +41,7 @@
 import androidx.compose.material3.IconButton
 import androidx.compose.material3.ListItem
 import androidx.compose.material3.ModalBottomSheet
+import androidx.compose.material3.OutlinedTextField
 import androidx.compose.material3.Text
 import androidx.compose.material3.TopAppBar
 import androidx.compose.material3.TopAppBarDefaults
@@ -117,6 +118,8 @@
                     Text("Hide Bottom Sheet")
                 }
             }
+            var text by remember { mutableStateOf("") }
+            OutlinedTextField(value = text, onValueChange = { text = it })
             LazyColumn {
                 items(50) {
                     ListItem(
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 b80c1c4..1abb4ea 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
@@ -22,7 +22,6 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.ImageBitmap
-import androidx.compose.ui.layout.FirstBaseline
 import androidx.compose.ui.layout.LayoutCoordinates
 import androidx.compose.ui.layout.onGloballyPositioned
 import androidx.compose.ui.node.Ref
@@ -152,20 +151,18 @@
 
         val ds = rule.onRoot().getUnclippedBoundsInRoot()
         rule.runOnIdleWithDensity {
-            assertThat(textPosition.value!!.x).isEqualTo(
-                expectedStartPadding.roundToPx()
-                    .toFloat()
+            assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+                expectedStartPadding.toPx()
             )
-            assertThat(textPosition.value!!.y).isEqualTo(
-                ((listItemHeight.roundToPx() - textSize.value!!.height) / 2f).roundToInt().toFloat()
+            assertThat(textPosition.value!!.y).isWithin(0.5f).of(
+                (listItemHeight.toPx() - textSize.value!!.height) / 2f
             )
-            assertThat(trailingPosition.value!!.x).isEqualTo(
-                ds.width.roundToPx() - trailingSize.value!!.width -
-                    expectedEndPadding.roundToPx().toFloat()
+
+            assertThat(trailingPosition.value!!.x).isWithin(0.5f).of(
+                ds.width.toPx() - trailingSize.value!!.width - expectedEndPadding.toPx()
             )
-            assertThat(trailingPosition.value!!.y).isEqualTo(
-                ((listItemHeight.roundToPx() - trailingSize.value!!.height) / 2f).roundToInt()
-                    .toFloat()
+            assertThat(trailingPosition.value!!.y).isWithin(0.5f).of(
+                (listItemHeight.toPx() - trailingSize.value!!.height) / 2f
             )
         }
     }
@@ -196,36 +193,35 @@
             }
         }
         rule.runOnIdleWithDensity {
-            assertThat(iconPosition.value!!.x).isEqualTo(
-                expectedStartPadding.roundToPx().toFloat()
+            assertThat(iconPosition.value!!.x).isWithin(0.5f).of(
+                expectedStartPadding.toPx()
             )
-            assertThat(iconPosition.value!!.y).isEqualTo(
-                ((listItemHeight.roundToPx() - iconSize.value!!.height) / 2f).roundToInt().toFloat()
+            assertThat(iconPosition.value!!.y).isWithin(0.5f).of(
+                (listItemHeight.toPx() - iconSize.value!!.height) / 2f
             )
-            assertThat(textPosition.value!!.x).isEqualTo(
-                expectedStartPadding.roundToPx().toFloat() +
+
+            assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+                expectedStartPadding.toPx() +
                     iconSize.value!!.width +
-                    expectedTextStartPadding.roundToPx().toFloat()
+                    expectedTextStartPadding.toPx()
             )
-            assertThat(textPosition.value!!.y).isEqualTo(
-                ((listItemHeight.roundToPx() - textSize.value!!.height) / 2f).roundToInt().toFloat()
+            assertThat(textPosition.value!!.y).isWithin(0.5f).of(
+                (listItemHeight.toPx() - textSize.value!!.height) / 2f
             )
         }
     }
 
     @Test
     fun listItem_twoLine_positioning_noIcon() {
+        val listItemHeight = ListTokens.ListItemTwoLineContainerHeight
         val expectedStartPadding = 16.dp
         val expectedEndPadding = 24.dp
 
         val textPosition = Ref<Offset>()
-        val textBaseline = Ref<Float>()
         val textSize = Ref<IntSize>()
         val secondaryTextPosition = Ref<Offset>()
-        val secondaryTextBaseline = Ref<Float>()
         val secondaryTextSize = Ref<IntSize>()
         val trailingPosition = Ref<Offset>()
-        val trailingBaseline = Ref<Float>()
         val trailingSize = Ref<IntSize>()
         rule.setMaterialContent(lightColorScheme()) {
             Box {
@@ -233,23 +229,19 @@
                     headlineContent = {
                         Text(
                             "Primary text",
-                            Modifier.saveLayout(textPosition, textSize, textBaseline)
+                            Modifier.saveLayout(textPosition, textSize)
                         )
                     },
                     supportingContent = {
                         Text(
                             "Secondary text",
-                            Modifier.saveLayout(
-                                secondaryTextPosition,
-                                secondaryTextSize,
-                                secondaryTextBaseline
-                            )
+                            Modifier.saveLayout(secondaryTextPosition, secondaryTextSize)
                         )
                     },
                     trailingContent = {
                         Text(
                             "meta",
-                            Modifier.saveLayout(trailingPosition, trailingSize, trailingBaseline)
+                            Modifier.saveLayout(trailingPosition, trailingSize)
                         )
                     }
                 )
@@ -257,29 +249,41 @@
         }
         val ds = rule.onRoot().getUnclippedBoundsInRoot()
         rule.runOnIdleWithDensity {
-            assertThat(textPosition.value!!.x).isEqualTo(
-                expectedStartPadding.roundToPx().toFloat()
+            val totalTextHeight = textSize.value!!.height + secondaryTextSize.value!!.height
+
+            assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+                expectedStartPadding.toPx()
             )
-            assertThat(secondaryTextPosition.value!!.x).isEqualTo(
-                expectedStartPadding.roundToPx().toFloat()
+            assertThat(textPosition.value!!.y).isWithin(0.5f).of(
+                (listItemHeight.toPx() - totalTextHeight) / 2f
             )
-            assertThat(trailingPosition.value!!.x).isEqualTo(
-                ds.width.roundToPx() - trailingSize.value!!.width -
-                    expectedEndPadding.roundToPx().toFloat()
+
+            assertThat(secondaryTextPosition.value!!.x).isWithin(0.5f).of(
+                expectedStartPadding.toPx()
+            )
+            assertThat(secondaryTextPosition.value!!.y).isWithin(0.5f).of(
+                (listItemHeight.toPx() - totalTextHeight) / 2f + textSize.value!!.height
+            )
+
+            assertThat(trailingPosition.value!!.x).isWithin(0.5f).of(
+                ds.width.toPx() - trailingSize.value!!.width -
+                    expectedEndPadding.toPx()
+            )
+            assertThat(trailingPosition.value!!.y).isWithin(0.5f).of(
+                (listItemHeight.toPx() - trailingSize.value!!.height) / 2f
             )
         }
     }
 
     @Test
     fun listItem_twoLine_positioning_withIcon() {
+        val listItemHeight = ListTokens.ListItemTwoLineContainerHeight
         val expectedStartPadding = 16.dp
         val expectedContentStartPadding = 16.dp
 
         val textPosition = Ref<Offset>()
-        val textBaseline = Ref<Float>()
         val textSize = Ref<IntSize>()
         val secondaryTextPosition = Ref<Offset>()
-        val secondaryTextBaseline = Ref<Float>()
         val secondaryTextSize = Ref<IntSize>()
         val iconPosition = Ref<Offset>()
         val iconSize = Ref<IntSize>()
@@ -289,17 +293,13 @@
                     headlineContent = {
                         Text(
                             "Primary text",
-                            Modifier.saveLayout(textPosition, textSize, textBaseline)
+                            Modifier.saveLayout(textPosition, textSize)
                         )
                     },
                     supportingContent = {
                         Text(
                             "Secondary text",
-                            Modifier.saveLayout(
-                                secondaryTextPosition,
-                                secondaryTextSize,
-                                secondaryTextBaseline
-                            )
+                            Modifier.saveLayout(secondaryTextPosition, secondaryTextSize)
                         )
                     },
                     leadingContent = {
@@ -309,17 +309,29 @@
             }
         }
         rule.runOnIdleWithDensity {
-            assertThat(textPosition.value!!.x).isEqualTo(
-                expectedStartPadding.roundToPx().toFloat() + iconSize.value!!.width +
-                    expectedContentStartPadding.roundToPx().toFloat()
+            val totalTextHeight = textSize.value!!.height + secondaryTextSize.value!!.height
+
+            assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+                expectedStartPadding.toPx() + iconSize.value!!.width +
+                    expectedContentStartPadding.toPx()
             )
-            assertThat(secondaryTextPosition.value!!.x).isEqualTo(
-                expectedStartPadding.roundToPx().toFloat() +
-                    iconSize.value!!.width +
-                    expectedContentStartPadding.roundToPx().toFloat()
+            assertThat(textPosition.value!!.y).isWithin(0.5f).of(
+                (listItemHeight.toPx() - totalTextHeight) / 2f
             )
-            assertThat(iconPosition.value!!.x).isEqualTo(
-                expectedStartPadding.roundToPx().toFloat()
+
+            assertThat(secondaryTextPosition.value!!.x).isWithin(0.5f).of(
+                expectedStartPadding.toPx() + iconSize.value!!.width +
+                    expectedContentStartPadding.toPx()
+            )
+            assertThat(secondaryTextPosition.value!!.y).isWithin(0.5f).of(
+                (listItemHeight.toPx() - totalTextHeight) / 2f + textSize.value!!.height
+            )
+
+            assertThat(iconPosition.value!!.x).isWithin(0.5f).of(
+                expectedStartPadding.toPx()
+            )
+            assertThat(iconPosition.value!!.y).isWithin(0.5f).of(
+                (listItemHeight.toPx() - iconSize.value!!.height) / 2f
             )
         }
     }
@@ -331,10 +343,8 @@
         val expectedEndPadding = 24.dp
 
         val textPosition = Ref<Offset>()
-        val textBaseline = Ref<Float>()
         val textSize = Ref<IntSize>()
         val secondaryTextPosition = Ref<Offset>()
-        val secondaryTextBaseline = Ref<Float>()
         val secondaryTextSize = Ref<IntSize>()
         val iconPosition = Ref<Offset>()
         val iconSize = Ref<IntSize>()
@@ -346,17 +356,13 @@
                     headlineContent = {
                         Text(
                             "Primary text",
-                            Modifier.saveLayout(textPosition, textSize, textBaseline)
+                            Modifier.saveLayout(textPosition, textSize)
                         )
                     },
                     supportingContent = {
                         Text(
                             "Very long supporting text which will span two lines",
-                            Modifier.saveLayout(
-                                secondaryTextPosition,
-                                secondaryTextSize,
-                                secondaryTextBaseline
-                            )
+                            Modifier.saveLayout(secondaryTextPosition, secondaryTextSize)
                         )
                     },
                     leadingContent = {
@@ -370,70 +376,64 @@
         }
         val ds = rule.onRoot().getUnclippedBoundsInRoot()
         rule.runOnIdleWithDensity {
-            assertThat(textPosition.value!!.x).isEqualTo(
-                expectedStartPadding.roundToPx().toFloat() + iconSize.value!!.width +
-                    expectedContentStartPadding.roundToPx().toFloat()
+            // TODO(b/233782301): Test y positions when this is implemented as a 3-line ListItem
+            assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+                expectedStartPadding.toPx() + iconSize.value!!.width +
+                    expectedContentStartPadding.toPx()
             )
-            assertThat(secondaryTextPosition.value!!.x).isEqualTo(
-                expectedStartPadding.roundToPx().toFloat() + iconSize.value!!.width +
-                    expectedContentStartPadding.roundToPx().toFloat()
+
+            assertThat(secondaryTextPosition.value!!.x).isWithin(0.5f).of(
+                expectedStartPadding.toPx() + iconSize.value!!.width +
+                    expectedContentStartPadding.toPx()
             )
-            assertThat(iconPosition.value!!.x).isEqualTo(expectedStartPadding.roundToPx().toFloat())
-            assertThat(trailingPosition.value!!.x).isEqualTo(
-                ds.width.roundToPx() - trailingSize.value!!.width.toFloat() -
-                    expectedEndPadding.roundToPx().toFloat()
+
+            assertThat(iconPosition.value!!.x).isWithin(0.5f).of(
+                expectedStartPadding.toPx()
+            )
+
+            assertThat(trailingPosition.value!!.x).isWithin(0.5f).of(
+                ds.width.toPx() - trailingSize.value!!.width -
+                    expectedEndPadding.toPx()
             )
         }
     }
 
     @Test
     fun listItem_threeLine_positioning_overline_trailingIcon() {
-        val expectedTopPadding = 16.dp
+        val expectedTopPadding = 12.dp
         val expectedStartPadding = 16.dp
         val expectedContentStartPadding = 16.dp
         val expectedEndPadding = 24.dp
 
         val textPosition = Ref<Offset>()
-        val textBaseline = Ref<Float>()
         val textSize = Ref<IntSize>()
         val overlineTextPosition = Ref<Offset>()
-        val overlineTextBaseline = Ref<Float>()
         val overlineTextSize = Ref<IntSize>()
         val secondaryTextPosition = Ref<Offset>()
-        val secondaryTextBaseline = Ref<Float>()
         val secondaryTextSize = Ref<IntSize>()
         val iconPosition = Ref<Offset>()
         val iconSize = Ref<IntSize>()
         val trailingPosition = Ref<Offset>()
         val trailingSize = Ref<IntSize>()
-        val trailingBaseline = Ref<Float>()
         rule.setMaterialContent(lightColorScheme()) {
             Box {
                 ListItem(
                     overlineContent = {
                         Text(
                             "OVERLINE",
-                            Modifier.saveLayout(
-                                overlineTextPosition,
-                                overlineTextSize,
-                                overlineTextBaseline
-                            )
+                            Modifier.saveLayout(overlineTextPosition, overlineTextSize)
                         )
                     },
                     headlineContent = {
                         Text(
                             "Primary text",
-                            Modifier.saveLayout(textPosition, textSize, textBaseline)
+                            Modifier.saveLayout(textPosition, textSize)
                         )
                     },
                     supportingContent = {
                         Text(
                             "Secondary text",
-                            Modifier.saveLayout(
-                                secondaryTextPosition,
-                                secondaryTextSize,
-                                secondaryTextBaseline
-                            )
+                            Modifier.saveLayout(secondaryTextPosition, secondaryTextSize)
                         )
                     },
                     leadingContent = {
@@ -446,11 +446,7 @@
                     trailingContent = {
                         Text(
                             "meta",
-                            Modifier.saveLayout(
-                                trailingPosition,
-                                trailingSize,
-                                trailingBaseline
-                            )
+                            Modifier.saveLayout(trailingPosition, trailingSize)
                         )
                     }
                 )
@@ -459,30 +455,44 @@
 
         val ds = rule.onRoot().getUnclippedBoundsInRoot()
         rule.runOnIdleWithDensity {
-            assertThat(textPosition.value!!.x).isEqualTo(
-                expectedStartPadding.roundToPx().toFloat() +
-                    iconSize.value!!.width +
-                    expectedContentStartPadding.roundToPx().toFloat()
+            assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+                expectedStartPadding.toPx() + iconSize.value!!.width +
+                    expectedContentStartPadding.toPx()
             )
-            assertThat(secondaryTextPosition.value!!.x).isEqualTo(
-                expectedStartPadding.roundToPx().toFloat() +
-                    iconSize.value!!.width +
-                    expectedContentStartPadding.roundToPx().toFloat()
+            assertThat(textPosition.value!!.y).isWithin(0.5f).of(
+                expectedTopPadding.toPx() + overlineTextSize.value!!.height
             )
-            assertThat(iconPosition.value!!.x).isEqualTo(
-                expectedStartPadding.roundToPx().toFloat()
+
+            assertThat(secondaryTextPosition.value!!.x).isWithin(0.5f).of(
+                expectedStartPadding.toPx() + iconSize.value!!.width +
+                    expectedContentStartPadding.toPx()
             )
-            assertThat(trailingPosition.value!!.x).isEqualTo(
-                ds.width.roundToPx() - trailingSize.value!!.width -
-                    expectedEndPadding.roundToPx().toFloat()
+            assertThat(secondaryTextPosition.value!!.y).isWithin(0.5f).of(
+                expectedTopPadding.toPx() + overlineTextSize.value!!.height +
+                textSize.value!!.height
             )
-            assertThat(overlineTextPosition.value!!.x).isEqualTo(
-                expectedStartPadding.roundToPx().toFloat() +
-                    iconSize.value!!.width +
-                    expectedContentStartPadding.roundToPx().toFloat()
+
+            assertThat(iconPosition.value!!.x).isWithin(0.5f).of(
+                expectedStartPadding.toPx()
             )
-            assertThat(overlineTextPosition.value!!.y).isEqualTo(
-                expectedTopPadding.roundToPx().toFloat()
+            assertThat(iconPosition.value!!.y).isWithin(0.5f).of(
+                expectedTopPadding.toPx()
+            )
+
+            assertThat(trailingPosition.value!!.x).isWithin(0.5f).of(
+                ds.width.toPx() - trailingSize.value!!.width -
+                    expectedEndPadding.toPx()
+            )
+            assertThat(trailingPosition.value!!.y).isWithin(0.5f).of(
+                expectedTopPadding.toPx()
+            )
+
+            assertThat(overlineTextPosition.value!!.x).isWithin(0.5f).of(
+                expectedStartPadding.toPx() + iconSize.value!!.width +
+                    expectedContentStartPadding.toPx()
+            )
+            assertThat(overlineTextPosition.value!!.y).isWithin(0.5f).of(
+                expectedTopPadding.toPx()
             )
         }
     }
@@ -492,10 +502,8 @@
     private fun Modifier.saveLayout(
         coords: Ref<Offset>,
         size: Ref<IntSize>,
-        baseline: Ref<Float> = Ref()
     ): Modifier = onGloballyPositioned { coordinates: LayoutCoordinates ->
         coords.value = coordinates.localToRoot(Offset.Zero)
-        baseline.value = coordinates[FirstBaseline].toFloat() + coords.value!!.y
         size.value = coordinates.size
     }
 }
\ No newline at end of file
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 1c5ef84..b2c7357 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
@@ -43,12 +43,14 @@
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.State
+import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberUpdatedState
+import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.graphicsLayer
@@ -1493,6 +1495,7 @@
         interactionSource: InteractionSource
     ): State<Dp> {
         val interactions = remember { mutableStateListOf<Interaction>() }
+        var lastInteraction by remember { mutableStateOf<Interaction?>(null) }
         LaunchedEffect(interactionSource) {
             interactionSource.interactions.collect { interaction ->
                 when (interaction) {
@@ -1546,22 +1549,16 @@
 
         val animatable = remember { Animatable(target, Dp.VectorConverter) }
 
-        if (!enabled) {
-            // No transition when moving to a disabled state
-            LaunchedEffect(target) { animatable.snapTo(target) }
-        } else {
-            LaunchedEffect(target) {
-                val lastInteraction = when (animatable.targetValue) {
-                    pressedElevation -> PressInteraction.Press(Offset.Zero)
-                    hoveredElevation -> HoverInteraction.Enter()
-                    focusedElevation -> FocusInteraction.Focus()
-                    draggedElevation -> DragInteraction.Start()
-                    else -> null
-                }
+        LaunchedEffect(target) {
+            if (!enabled) {
+                // No transition when moving to a disabled state
+                animatable.snapTo(target)
+            } else {
                 animatable.animateElevation(
                     from = lastInteraction, to = interaction, target = target
                 )
             }
+            lastInteraction = interaction
         }
 
         return animatable.asState()
@@ -1653,6 +1650,7 @@
         interactionSource: InteractionSource
     ): State<Dp> {
         val interactions = remember { mutableStateListOf<Interaction>() }
+        var lastInteraction by remember { mutableStateOf<Interaction?>(null) }
         LaunchedEffect(interactionSource) {
             interactionSource.interactions.collect { interaction ->
                 when (interaction) {
@@ -1706,22 +1704,16 @@
 
         val animatable = remember { Animatable(target, Dp.VectorConverter) }
 
-        if (!enabled) {
-            // No transition when moving to a disabled state
-            LaunchedEffect(target) { animatable.snapTo(target) }
-        } else {
-            LaunchedEffect(target) {
-                val lastInteraction = when (animatable.targetValue) {
-                    pressedElevation -> PressInteraction.Press(Offset.Zero)
-                    hoveredElevation -> HoverInteraction.Enter()
-                    focusedElevation -> FocusInteraction.Focus()
-                    draggedElevation -> DragInteraction.Start()
-                    else -> null
-                }
+        LaunchedEffect(target) {
+            if (!enabled) {
+                // No transition when moving to a disabled state
+                animatable.snapTo(target)
+            } else {
                 animatable.animateElevation(
                     from = lastInteraction, to = interaction, target = target
                 )
             }
+            lastInteraction = interaction
         }
 
         return animatable.asState()
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 114fe42..a770a50 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
@@ -112,12 +112,13 @@
         hasOverline = decoratedOverlineContent != null,
         hasSupporting = decoratedSupportingContent != null
     )
+    val isThreeLine = listItemType == ListItemType.ThreeLine
 
     val decoratedLeadingContent: @Composable (RowScope.() -> Unit)? = leadingContent?.let {
         {
             LeadingContent(
                 contentColor = colors.leadingIconColor(enabled = true).value,
-                topAlign = listItemType == ListItemType.ThreeLine,
+                topAlign = isThreeLine,
                 content = it
             )
         }
@@ -127,7 +128,7 @@
         {
             TrailingContent(
                 contentColor = colors.trailingIconColor(enabled = true).value,
-                topAlign = listItemType == ListItemType.ThreeLine,
+                topAlign = isThreeLine,
                 content = it
             )
         }
@@ -137,19 +138,15 @@
         ListItemType.TwoLine -> ListTokens.ListItemTwoLineContainerHeight
         else -> ListTokens.ListItemThreeLineContainerHeight // 3
     }
+    val verticalPadding = if (isThreeLine) ListItemThreeLineVerticalPadding else
+        ListItemVerticalPadding
     val outerPaddingValues =
         PaddingValues(
-            horizontal = ListItemHorizontalPadding,
-            vertical = if (listItemType == ListItemType.ThreeLine)
-                ListItemThreeLineVerticalPadding else ListItemVerticalPadding
+            start = ListItemStartPadding,
+            top = verticalPadding,
+            end = ListItemEndPadding,
+            bottom = verticalPadding,
         )
-    val contentPaddingValues = PaddingValues(
-        end = if (listItemType == ListItemType.ThreeLine) ContentEndPadding else 0.dp
-    )
-    val columnArrangement = if (listItemType == ListItemType.ThreeLine)
-        Arrangement.Top else Arrangement.Center
-    val boxAlignment = if (listItemType == ListItemType.ThreeLine)
-        Alignment.Top else CenterVertically
 
     ListItem(
         modifier = modifier,
@@ -166,9 +163,8 @@
         Column(
             modifier = Modifier
                 .weight(1f)
-                .padding(contentPaddingValues)
-                .align(boxAlignment),
-            verticalArrangement = columnArrangement
+                .align(if (isThreeLine) Alignment.Top else CenterVertically),
+            verticalArrangement = if (isThreeLine) Arrangement.Top else Arrangement.Center
         ) {
             if (decoratedOverlineContent != null) {
                 decoratedOverlineContent()
@@ -249,7 +245,7 @@
     content: @Composable () -> Unit,
 ) = Box(
     Modifier
-        .padding(horizontal = TrailingHorizontalPadding)
+        .padding(start = TrailingContentStartPadding)
         .then(if (!topAlign) Modifier.align(CenterVertically) else Modifier),
     ) {
         ProvideTextStyleFromToken(
@@ -430,17 +426,14 @@
 // Container related defaults
 // TODO: Make sure these values stay up to date until replaced with tokens.
 private val ListItemVerticalPadding = 8.dp
-private val ListItemThreeLineVerticalPadding = 16.dp
-private val ListItemHorizontalPadding = 16.dp
+private val ListItemThreeLineVerticalPadding = 12.dp
+private val ListItemStartPadding = 16.dp
+private 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
 
-// Content related defaults.
-// TODO: Make sure these values stay up to date until replaced with tokens.
-private val ContentEndPadding = 8.dp
-
 // Trailing related defaults.
 // TODO: Make sure these values stay up to date until replaced with tokens.
-private val TrailingHorizontalPadding = 8.dp
+private val TrailingContentStartPadding = 16.dp
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetector.kt
new file mode 100644
index 0000000..ed2aafe2
--- /dev/null
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetector.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.
+ */
+
+package androidx.compose.runtime.lint
+
+import com.android.tools.lint.detector.api.AnnotationUsageType
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.LintFix
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.android.tools.lint.detector.api.UastLintUtils
+import com.intellij.psi.PsiMethod
+import java.util.EnumSet
+import org.jetbrains.uast.UAnnotation
+import org.jetbrains.uast.UElement
+import org.jetbrains.uast.USimpleNameReferenceExpression
+
+@Suppress("UnstableApiUsage")
+class AutoboxingStateValuePropertyDetector : Detector(), SourceCodeScanner {
+
+    private val UAnnotation.preferredPropertyName: String?
+        get() = UastLintUtils.getAnnotationStringValue(this, "preferredPropertyName")
+
+    private val UElement.identifier: String?
+        get() = (this as? USimpleNameReferenceExpression)?.identifier
+
+    private val UElement.resolvedName: String?
+        get() = (this as? USimpleNameReferenceExpression)?.resolvedName
+
+    override fun applicableAnnotations(): List<String> {
+        return listOf("androidx.compose.runtime.snapshots.AutoboxingStateValueProperty")
+    }
+
+    override fun visitAnnotationUsage(
+        context: JavaContext,
+        usage: UElement,
+        type: AnnotationUsageType,
+        annotation: UAnnotation,
+        qualifiedName: String,
+        method: PsiMethod?,
+        annotations: List<UAnnotation>,
+        allMemberAnnotations: List<UAnnotation>,
+        allClassAnnotations: List<UAnnotation>,
+        allPackageAnnotations: List<UAnnotation>
+    ) {
+        if (type != AnnotationUsageType.FIELD_REFERENCE) {
+            return
+        }
+
+        val resolvedPropertyName = usage.identifier ?: "<unknown identifier>"
+        val preferredPropertyName = annotation.preferredPropertyName ?: "<unknown replacement>"
+
+        val accessKind = when (usage.resolvedName?.takeWhile { it.isLowerCase() }) {
+            "get" -> "Reading"
+            "set" -> "Assigning"
+            else -> "Accessing"
+        }
+
+        context.report(
+            AutoboxingStateValueProperty,
+            usage,
+            context.getLocation(usage),
+            "$accessKind `$resolvedPropertyName` will cause an autoboxing operation. " +
+                "Use `$preferredPropertyName` to avoid unnecessary allocations.",
+            createPropertyReplacementQuickFix(
+                resolvedPropertyName = resolvedPropertyName,
+                preferredPropertyName = preferredPropertyName
+            )
+        )
+    }
+
+    private fun createPropertyReplacementQuickFix(
+        resolvedPropertyName: String,
+        preferredPropertyName: String
+    ): LintFix {
+        return fix().name("Replace with `$preferredPropertyName`")
+            .replace()
+            .text(resolvedPropertyName)
+            .with(preferredPropertyName)
+            .build()
+    }
+
+    companion object {
+
+        val AutoboxingStateValueProperty = Issue.create(
+            "AutoboxingStateValueProperty",
+            "State access causes value to be autoboxed",
+            "Avoid using the generic value accessor when using a State objects with a " +
+                "specialized types. Usages of the generic value property result in an " +
+                "unnecessary autoboxing operation whenever the state's value is read or " +
+                "written to. Use the specialized value accessor or property delegation to " +
+                "avoid unnecessary allocations.",
+            Category.PERFORMANCE, 3, Severity.WARNING,
+            Implementation(
+                AutoboxingStateValuePropertyDetector::class.java,
+                EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES)
+            )
+        )
+    }
+}
\ No newline at end of file
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt
index edc16ae..bc749d0 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt
@@ -30,6 +30,7 @@
     override val api = 14
     override val minApi = CURRENT_API
     override val issues get() = listOf(
+        AutoboxingStateValuePropertyDetector.AutoboxingStateValueProperty,
         ComposableCoroutineCreationDetector.CoroutineCreationDuringComposition,
         ComposableFlowOperatorDetector.FlowOperatorInvokedInComposition,
         ComposableLambdaParameterDetector.ComposableLambdaParameterNaming,
diff --git a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetectorTest.kt b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetectorTest.kt
new file mode 100644
index 0000000..6f99bf7
--- /dev/null
+++ b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetectorTest.kt
@@ -0,0 +1,161 @@
+/*
+ * 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.runtime.lint
+
+import androidx.compose.lint.test.Stubs
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+/* ktlint-disable max-line-length */
+@RunWith(JUnit4::class)
+class AutoboxingStateValuePropertyDetectorTest : LintDetectorTest() {
+
+    override fun getDetector(): Detector = AutoboxingStateValuePropertyDetector()
+
+    override fun getIssues(): MutableList<Issue> =
+        mutableListOf(AutoboxingStateValuePropertyDetector.AutoboxingStateValueProperty)
+
+    @Test
+    fun testReadAutoboxingPropertyAsVariableAssignment() {
+        lint().files(
+            AutoboxingStateValuePropertyStub,
+            StateWithAutoboxingPropertyStub,
+            Stubs.SnapshotState,
+            kotlin(
+                """
+                    package androidx.compose.runtime.lint.test
+
+                    import androidx.compose.runtime.sandbox.MutableIntState
+                    import androidx.compose.runtime.getValue
+                    import androidx.compose.runtime.setValue
+
+                    fun valueAssignment() {
+                        val state = MutableIntState()
+                        val value = state.value
+                    }
+                """.trimIndent()
+            )
+        ).run().expect(
+            """
+src/androidx/compose/runtime/lint/test/test.kt:9: Warning: Reading value will cause an autoboxing operation. Use intValue to avoid unnecessary allocations. [AutoboxingStateValueProperty]
+    val value = state.value
+                      ~~~~~
+0 errors, 1 warnings
+            """
+        ).expectFixDiffs(
+            """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 9: Replace with `intValue`:
+@@ -9 +9
+-     val value = state.value
++     val value = state.intValue
+            """
+        )
+    }
+
+    @Test
+    fun testTrivialAssignAutoboxingProperty() {
+        lint().files(
+            AutoboxingStateValuePropertyStub,
+            StateWithAutoboxingPropertyStub,
+            Stubs.SnapshotState,
+            kotlin(
+                """
+                    package androidx.compose.runtime.lint.test
+
+                    import androidx.compose.runtime.sandbox.MutableIntState
+                    import androidx.compose.runtime.getValue
+                    import androidx.compose.runtime.setValue
+
+                    fun valueAssignment() {
+                        val state = MutableIntState()
+                        state.value = 42
+                    }
+                """.trimIndent()
+            )
+        ).run().expect(
+            """
+src/androidx/compose/runtime/lint/test/test.kt:9: Warning: Assigning value will cause an autoboxing operation. Use intValue to avoid unnecessary allocations. [AutoboxingStateValueProperty]
+    state.value = 42
+          ~~~~~
+0 errors, 1 warnings
+            """
+        ).expectFixDiffs(
+            """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 9: Replace with `intValue`:
+@@ -9 +9
+-     state.value = 42
++     state.intValue = 42
+            """
+        )
+    }
+
+    companion object {
+        private val StateWithAutoboxingPropertyStub = kotlin(
+            """
+            package androidx.compose.runtime.sandbox
+
+            import androidx.compose.runtime.snapshots.AutoboxingStateValueProperty
+
+            class MutableIntState {
+
+                @AutoboxingStateValueProperty(
+                    preferredPropertyName = "intValue",
+                    delegatePackageDirective = "androidx.compose.runtime.sandbox"
+                )
+                var value: Int?
+                    get() = intValue
+                    set(value) = value?.let { intValue = it }
+
+                var intValue: Int = 0
+            }
+
+            @Suppress("NOTHING_TO_INLINE")
+            inline operator fun MutableIntState.getValue(
+                thisObj: Any?,
+                property: KProperty<*>
+            ): Int = intValue
+
+            @Suppress("NOTHING_TO_INLINE")
+            inline operator fun MutableIntState.setValue(
+                thisObj: Any?,
+                property: KProperty<*>,
+                value: Int
+            ) {
+                intValue = value
+            }
+            """
+        )
+
+        private val AutoboxingStateValuePropertyStub = kotlin(
+            """
+                package androidx.compose.runtime.snapshots
+
+                @Retention(AnnotationRetention.BINARY)
+                @Target(AnnotationTarget.PROPERTY)
+                annotation class AutoboxingStateValueProperty(
+                    val preferredPropertyName: String,
+                    val delegatePackageDirective: String
+                )
+            """
+        )
+    }
+}
+/* ktlint-enable max-line-length */
\ No newline at end of file
diff --git a/compose/runtime/runtime-livedata/api/current.ignore b/compose/runtime/runtime-livedata/api/current.ignore
new file mode 100644
index 0000000..8e26508
--- /dev/null
+++ b/compose/runtime/runtime-livedata/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.runtime.livedata.LiveDataAdapterKt#observeAsState(androidx.lifecycle.LiveData<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.livedata.LiveDataAdapterKt.observeAsState(androidx.lifecycle.LiveData<T> arg1, R initial)
diff --git a/compose/runtime/runtime-livedata/api/current.txt b/compose/runtime/runtime-livedata/api/current.txt
index e004a29..192cf6a 100644
--- a/compose/runtime/runtime-livedata/api/current.txt
+++ b/compose/runtime/runtime-livedata/api/current.txt
@@ -3,7 +3,7 @@
 
   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);
+    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-livedata/api/public_plus_experimental_current.txt b/compose/runtime/runtime-livedata/api/public_plus_experimental_current.txt
index e004a29..192cf6a 100644
--- a/compose/runtime/runtime-livedata/api/public_plus_experimental_current.txt
+++ b/compose/runtime/runtime-livedata/api/public_plus_experimental_current.txt
@@ -3,7 +3,7 @@
 
   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);
+    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-livedata/api/restricted_current.ignore b/compose/runtime/runtime-livedata/api/restricted_current.ignore
new file mode 100644
index 0000000..8e26508
--- /dev/null
+++ b/compose/runtime/runtime-livedata/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.runtime.livedata.LiveDataAdapterKt#observeAsState(androidx.lifecycle.LiveData<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.livedata.LiveDataAdapterKt.observeAsState(androidx.lifecycle.LiveData<T> arg1, R initial)
diff --git a/compose/runtime/runtime-livedata/api/restricted_current.txt b/compose/runtime/runtime-livedata/api/restricted_current.txt
index e004a29..192cf6a 100644
--- a/compose/runtime/runtime-livedata/api/restricted_current.txt
+++ b/compose/runtime/runtime-livedata/api/restricted_current.txt
@@ -3,7 +3,7 @@
 
   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);
+    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/current.ignore b/compose/runtime/runtime-rxjava2/api/current.ignore
new file mode 100644
index 0000000..3d56c37
--- /dev/null
+++ b/compose/runtime/runtime-rxjava2/api/current.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.runtime.rxjava2.RxJava2AdapterKt#subscribeAsState(io.reactivex.Flowable<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava2.RxJava2AdapterKt.subscribeAsState(io.reactivex.Flowable<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava2.RxJava2AdapterKt#subscribeAsState(io.reactivex.Maybe<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava2.RxJava2AdapterKt.subscribeAsState(io.reactivex.Maybe<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava2.RxJava2AdapterKt#subscribeAsState(io.reactivex.Observable<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava2.RxJava2AdapterKt.subscribeAsState(io.reactivex.Observable<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava2.RxJava2AdapterKt#subscribeAsState(io.reactivex.Single<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava2.RxJava2AdapterKt.subscribeAsState(io.reactivex.Single<T> arg1, R initial)
diff --git a/compose/runtime/runtime-rxjava2/api/current.txt b/compose/runtime/runtime-rxjava2/api/current.txt
index fb30f38..ea20020 100644
--- a/compose/runtime/runtime-rxjava2/api/current.txt
+++ b/compose/runtime/runtime-rxjava2/api/current.txt
@@ -2,10 +2,10 @@
 package androidx.compose.runtime.rxjava2 {
 
   public final class RxJava2AdapterKt {
-    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.Flowable<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);
-    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.Flowable<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);
+    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 androidx.compose.runtime.State<java.lang.Boolean> subscribeAsState(io.reactivex.Completable);
   }
 
diff --git a/compose/runtime/runtime-rxjava2/api/public_plus_experimental_current.txt b/compose/runtime/runtime-rxjava2/api/public_plus_experimental_current.txt
index fb30f38..ea20020 100644
--- a/compose/runtime/runtime-rxjava2/api/public_plus_experimental_current.txt
+++ b/compose/runtime/runtime-rxjava2/api/public_plus_experimental_current.txt
@@ -2,10 +2,10 @@
 package androidx.compose.runtime.rxjava2 {
 
   public final class RxJava2AdapterKt {
-    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.Flowable<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);
-    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.Flowable<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);
+    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 androidx.compose.runtime.State<java.lang.Boolean> subscribeAsState(io.reactivex.Completable);
   }
 
diff --git a/compose/runtime/runtime-rxjava2/api/restricted_current.ignore b/compose/runtime/runtime-rxjava2/api/restricted_current.ignore
new file mode 100644
index 0000000..3d56c37
--- /dev/null
+++ b/compose/runtime/runtime-rxjava2/api/restricted_current.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.runtime.rxjava2.RxJava2AdapterKt#subscribeAsState(io.reactivex.Flowable<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava2.RxJava2AdapterKt.subscribeAsState(io.reactivex.Flowable<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava2.RxJava2AdapterKt#subscribeAsState(io.reactivex.Maybe<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava2.RxJava2AdapterKt.subscribeAsState(io.reactivex.Maybe<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava2.RxJava2AdapterKt#subscribeAsState(io.reactivex.Observable<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava2.RxJava2AdapterKt.subscribeAsState(io.reactivex.Observable<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava2.RxJava2AdapterKt#subscribeAsState(io.reactivex.Single<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava2.RxJava2AdapterKt.subscribeAsState(io.reactivex.Single<T> arg1, R initial)
diff --git a/compose/runtime/runtime-rxjava2/api/restricted_current.txt b/compose/runtime/runtime-rxjava2/api/restricted_current.txt
index fb30f38..ea20020 100644
--- a/compose/runtime/runtime-rxjava2/api/restricted_current.txt
+++ b/compose/runtime/runtime-rxjava2/api/restricted_current.txt
@@ -2,10 +2,10 @@
 package androidx.compose.runtime.rxjava2 {
 
   public final class RxJava2AdapterKt {
-    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.Flowable<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);
-    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.Flowable<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);
+    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 androidx.compose.runtime.State<java.lang.Boolean> subscribeAsState(io.reactivex.Completable);
   }
 
diff --git a/compose/runtime/runtime-rxjava3/api/current.ignore b/compose/runtime/runtime-rxjava3/api/current.ignore
new file mode 100644
index 0000000..33b8519
--- /dev/null
+++ b/compose/runtime/runtime-rxjava3/api/current.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.runtime.rxjava3.RxJava3AdapterKt#subscribeAsState(io.reactivex.rxjava3.core.Flowable<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava3.RxJava3AdapterKt.subscribeAsState(io.reactivex.rxjava3.core.Flowable<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava3.RxJava3AdapterKt#subscribeAsState(io.reactivex.rxjava3.core.Maybe<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava3.RxJava3AdapterKt.subscribeAsState(io.reactivex.rxjava3.core.Maybe<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava3.RxJava3AdapterKt#subscribeAsState(io.reactivex.rxjava3.core.Observable<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava3.RxJava3AdapterKt.subscribeAsState(io.reactivex.rxjava3.core.Observable<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava3.RxJava3AdapterKt#subscribeAsState(io.reactivex.rxjava3.core.Single<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava3.RxJava3AdapterKt.subscribeAsState(io.reactivex.rxjava3.core.Single<T> arg1, R initial)
diff --git a/compose/runtime/runtime-rxjava3/api/current.txt b/compose/runtime/runtime-rxjava3/api/current.txt
index 1930cc8..aa5ec91 100644
--- a/compose/runtime/runtime-rxjava3/api/current.txt
+++ b/compose/runtime/runtime-rxjava3/api/current.txt
@@ -2,10 +2,10 @@
 package androidx.compose.runtime.rxjava3 {
 
   public final class RxJava3AdapterKt {
-    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.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.Single<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.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.Single<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 androidx.compose.runtime.State<java.lang.Boolean> subscribeAsState(io.reactivex.rxjava3.core.Completable);
   }
 
diff --git a/compose/runtime/runtime-rxjava3/api/public_plus_experimental_current.txt b/compose/runtime/runtime-rxjava3/api/public_plus_experimental_current.txt
index 1930cc8..aa5ec91 100644
--- a/compose/runtime/runtime-rxjava3/api/public_plus_experimental_current.txt
+++ b/compose/runtime/runtime-rxjava3/api/public_plus_experimental_current.txt
@@ -2,10 +2,10 @@
 package androidx.compose.runtime.rxjava3 {
 
   public final class RxJava3AdapterKt {
-    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.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.Single<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.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.Single<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 androidx.compose.runtime.State<java.lang.Boolean> subscribeAsState(io.reactivex.rxjava3.core.Completable);
   }
 
diff --git a/compose/runtime/runtime-rxjava3/api/restricted_current.ignore b/compose/runtime/runtime-rxjava3/api/restricted_current.ignore
new file mode 100644
index 0000000..33b8519
--- /dev/null
+++ b/compose/runtime/runtime-rxjava3/api/restricted_current.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.runtime.rxjava3.RxJava3AdapterKt#subscribeAsState(io.reactivex.rxjava3.core.Flowable<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava3.RxJava3AdapterKt.subscribeAsState(io.reactivex.rxjava3.core.Flowable<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava3.RxJava3AdapterKt#subscribeAsState(io.reactivex.rxjava3.core.Maybe<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava3.RxJava3AdapterKt.subscribeAsState(io.reactivex.rxjava3.core.Maybe<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava3.RxJava3AdapterKt#subscribeAsState(io.reactivex.rxjava3.core.Observable<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava3.RxJava3AdapterKt.subscribeAsState(io.reactivex.rxjava3.core.Observable<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava3.RxJava3AdapterKt#subscribeAsState(io.reactivex.rxjava3.core.Single<T>, R) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava3.RxJava3AdapterKt.subscribeAsState(io.reactivex.rxjava3.core.Single<T> arg1, R initial)
diff --git a/compose/runtime/runtime-rxjava3/api/restricted_current.txt b/compose/runtime/runtime-rxjava3/api/restricted_current.txt
index 1930cc8..aa5ec91 100644
--- a/compose/runtime/runtime-rxjava3/api/restricted_current.txt
+++ b/compose/runtime/runtime-rxjava3/api/restricted_current.txt
@@ -2,10 +2,10 @@
 package androidx.compose.runtime.rxjava3 {
 
   public final class RxJava3AdapterKt {
-    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.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.Single<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.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.Single<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 androidx.compose.runtime.State<java.lang.Boolean> subscribeAsState(io.reactivex.rxjava3.core.Completable);
   }
 
diff --git a/compose/runtime/runtime-saveable/api/current.ignore b/compose/runtime/runtime-saveable/api/current.ignore
new file mode 100644
index 0000000..bc98d1f
--- /dev/null
+++ b/compose/runtime/runtime-saveable/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.runtime.saveable.Saver#save(androidx.compose.runtime.saveable.SaverScope, Original) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.saveable.Saver.save(androidx.compose.runtime.saveable.SaverScope arg1, Original value)
diff --git a/compose/runtime/runtime-saveable/api/current.txt b/compose/runtime/runtime-saveable/api/current.txt
index ce5d51b..bdc843c 100644
--- a/compose/runtime/runtime-saveable/api/current.txt
+++ b/compose/runtime/runtime-saveable/api/current.txt
@@ -42,7 +42,7 @@
 
   public interface Saver<Original, Saveable> {
     method public Original? restore(Saveable value);
-    method public Saveable? save(androidx.compose.runtime.saveable.SaverScope, Original? value);
+    method public Saveable? save(androidx.compose.runtime.saveable.SaverScope, Original value);
   }
 
   public final class SaverKt {
diff --git a/compose/runtime/runtime-saveable/api/public_plus_experimental_current.txt b/compose/runtime/runtime-saveable/api/public_plus_experimental_current.txt
index ce5d51b..bdc843c 100644
--- a/compose/runtime/runtime-saveable/api/public_plus_experimental_current.txt
+++ b/compose/runtime/runtime-saveable/api/public_plus_experimental_current.txt
@@ -42,7 +42,7 @@
 
   public interface Saver<Original, Saveable> {
     method public Original? restore(Saveable value);
-    method public Saveable? save(androidx.compose.runtime.saveable.SaverScope, Original? value);
+    method public Saveable? save(androidx.compose.runtime.saveable.SaverScope, Original value);
   }
 
   public final class SaverKt {
diff --git a/compose/runtime/runtime-saveable/api/restricted_current.ignore b/compose/runtime/runtime-saveable/api/restricted_current.ignore
new file mode 100644
index 0000000..bc98d1f
--- /dev/null
+++ b/compose/runtime/runtime-saveable/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.runtime.saveable.Saver#save(androidx.compose.runtime.saveable.SaverScope, Original) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.saveable.Saver.save(androidx.compose.runtime.saveable.SaverScope arg1, Original value)
diff --git a/compose/runtime/runtime-saveable/api/restricted_current.txt b/compose/runtime/runtime-saveable/api/restricted_current.txt
index ce5d51b..bdc843c 100644
--- a/compose/runtime/runtime-saveable/api/restricted_current.txt
+++ b/compose/runtime/runtime-saveable/api/restricted_current.txt
@@ -42,7 +42,7 @@
 
   public interface Saver<Original, Saveable> {
     method public Original? restore(Saveable value);
-    method public Saveable? save(androidx.compose.runtime.saveable.SaverScope, Original? value);
+    method public Saveable? save(androidx.compose.runtime.saveable.SaverScope, Original value);
   }
 
   public final class SaverKt {
diff --git a/compose/runtime/runtime/api/api_lint.ignore b/compose/runtime/runtime/api/api_lint.ignore
index d1ce6c3..936df8e 100644
--- a/compose/runtime/runtime/api/api_lint.ignore
+++ b/compose/runtime/runtime/api/api_lint.ignore
@@ -9,6 +9,34 @@
     Method Failure.check appears to be throwing androidx.compose.runtime.snapshots.SnapshotApplyConflictException; this should be recorded with a @Throws annotation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
 
 
+GetterSetterNames: androidx.compose.runtime.BroadcastFrameClock#getHasAwaiters():
+    Getter for boolean property `hasAwaiters` is named `getHasAwaiters` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.runtime.Composition#getHasInvalidations():
+    Getter for boolean property `hasInvalidations` is named `getHasInvalidations` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.runtime.ControlledComposition#getHasPendingChanges():
+    Getter for boolean property `hasPendingChanges` is named `getHasPendingChanges` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.runtime.Recomposer#getHasPendingWork():
+    Getter for boolean property `hasPendingWork` is named `getHasPendingWork` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.runtime.RecomposerInfo#getHasPendingWork():
+    Getter for boolean property `hasPendingWork` is named `getHasPendingWork` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field Composer.defaultsInvalid:
+    Invalid name for boolean property `defaultsInvalid`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Composer.inserting:
+    Invalid name for boolean property `inserting`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Composer.skipping:
+    Invalid name for boolean property `skipping`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field MutableSnapshot.readOnly:
+    Invalid name for boolean property `readOnly`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Snapshot.readOnly:
+    Invalid name for boolean property `readOnly`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field SnapshotApplyResult.Failure.succeeded:
+    Invalid name for boolean property `succeeded`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field SnapshotApplyResult.Success.succeeded:
+    Invalid name for boolean property `succeeded`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field SnapshotApplyResult.succeeded:
+    Invalid name for boolean property `succeeded`. Should start with one of `has`, `can`, `should`, `is`.
+
+
 KotlinOperator: androidx.compose.runtime.Updater#set(V, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit>):
     Note that adding the `operator` keyword would allow calling this method using operator syntax
 KotlinOperator: androidx.compose.runtime.Updater#set(int, kotlin.jvm.functions.Function2<? super T,? super java.lang.Integer,kotlin.Unit>):
@@ -17,18 +45,14 @@
     Note that adding the `operator` keyword would allow calling this method using operator syntax
 
 
-MissingNullability: androidx.compose.runtime.collection.MutableVector#mapIndexedNotNull(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,? extends R>):
-    Missing nullability on method `mapIndexedNotNull` return
-MissingNullability: androidx.compose.runtime.collection.MutableVector#mapNotNull(kotlin.jvm.functions.Function1<? super T,? extends R>):
-    Missing nullability on method `mapNotNull` return
 MissingNullability: androidx.compose.runtime.collection.MutableVectorKt#MutableVector(int):
     Missing nullability on method `MutableVector` return
-MissingNullability: androidx.compose.runtime.collection.MutableVectorKt#MutableVector(int, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends T>):
-    Missing nullability on method `MutableVector` return
 MissingNullability: androidx.compose.runtime.collection.MutableVectorKt#mutableVectorOf():
     Missing nullability on method `mutableVectorOf` return
-MissingNullability: androidx.compose.runtime.collection.MutableVectorKt#mutableVectorOf(T):
-    Missing nullability on method `mutableVectorOf` return
+MissingNullability: androidx.compose.runtime.snapshots.SnapshotStateMap#get(Object) parameter #0:
+    Missing nullability on parameter `key` in method `get`
+MissingNullability: androidx.compose.runtime.snapshots.SnapshotStateMap#remove(Object) parameter #0:
+    Missing nullability on parameter `key` in method `remove`
 
 
 NoByteOrShort: androidx.compose.runtime.Composer#changed(byte) parameter #0:
diff --git a/compose/runtime/runtime/api/current.ignore b/compose/runtime/runtime/api/current.ignore
index 1589837..1e4b20b 100644
--- a/compose/runtime/runtime/api/current.ignore
+++ b/compose/runtime/runtime/api/current.ignore
@@ -1,8 +1,108 @@
 // Baseline format: 1.0
 AddedAbstractMethod: androidx.compose.runtime.Composer#getCurrentCompositionLocalMap():
     Added method androidx.compose.runtime.Composer.getCurrentCompositionLocalMap()
-AddedAbstractMethod: androidx.compose.runtime.CompositionContext#getEffectCoroutineContext():
-    Added method androidx.compose.runtime.CompositionContext.getEffectCoroutineContext()
+
+
+InvalidNullConversion: androidx.compose.runtime.AbstractApplier#AbstractApplier(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter root in androidx.compose.runtime.AbstractApplier(T root)
+InvalidNullConversion: androidx.compose.runtime.AbstractApplier#down(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter node in androidx.compose.runtime.AbstractApplier.down(T node)
+InvalidNullConversion: androidx.compose.runtime.Applier#down(N) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter node in androidx.compose.runtime.Applier.down(N node)
+InvalidNullConversion: androidx.compose.runtime.Applier#insertBottomUp(int, N) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter instance in androidx.compose.runtime.Applier.insertBottomUp(int index, N instance)
+InvalidNullConversion: androidx.compose.runtime.Applier#insertTopDown(int, N) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter instance in androidx.compose.runtime.Applier.insertTopDown(int index, N instance)
+InvalidNullConversion: androidx.compose.runtime.Composer#apply(V, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.Composer.apply(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block)
+InvalidNullConversion: androidx.compose.runtime.ProvidableCompositionLocal#provides(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.ProvidableCompositionLocal.provides(T value)
+InvalidNullConversion: androidx.compose.runtime.ProvidableCompositionLocal#providesDefault(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.ProvidableCompositionLocal.providesDefault(T value)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#equivalent(T, T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter a in androidx.compose.runtime.SnapshotMutationPolicy.equivalent(T a, T b)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#equivalent(T, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter b in androidx.compose.runtime.SnapshotMutationPolicy.equivalent(T a, T b)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#merge(T, T, T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter previous in androidx.compose.runtime.SnapshotMutationPolicy.merge(T previous, T current, T applied)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#merge(T, T, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter current in androidx.compose.runtime.SnapshotMutationPolicy.merge(T previous, T current, T applied)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#merge(T, T, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter applied in androidx.compose.runtime.SnapshotMutationPolicy.merge(T previous, T current, T applied)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R, kotlin.coroutines.CoroutineContext) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.SnapshotStateKt.collectAsState(kotlinx.coroutines.flow.Flow<? extends T> arg1, R initial, kotlin.coroutines.CoroutineContext context)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#mutableStateOf(T, androidx.compose.runtime.SnapshotMutationPolicy<T>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.SnapshotStateKt.mutableStateOf(T value, androidx.compose.runtime.SnapshotMutationPolicy<T> policy)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, Object, Object, Object, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.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)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, Object, Object, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.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)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, Object, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.produceState(T initialValue, Object key1, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, Object[], kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.produceState(T initialValue, Object[] keys, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.produceState(T initialValue, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#rememberUpdatedState(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter newValue in androidx.compose.runtime.SnapshotStateKt.rememberUpdatedState(T newValue)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#setValue(androidx.compose.runtime.MutableState<T>, Object, kotlin.reflect.KProperty<?>, T) parameter #3:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.SnapshotStateKt.setValue(androidx.compose.runtime.MutableState<T> arg1, Object thisObj, kotlin.reflect.KProperty<?> property, T value)
+InvalidNullConversion: androidx.compose.runtime.Updater#set(V, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.Updater.set(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block)
+InvalidNullConversion: androidx.compose.runtime.Updater#update(V, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.Updater.update(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#add(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.add(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#add(int, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.add(int index, T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#contains(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.contains(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#fold(R, kotlin.jvm.functions.Function2<? super R,? super T,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.collection.MutableVector.fold(R initial, kotlin.jvm.functions.Function2<? super R,? super T,? extends R> operation)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#foldIndexed(R, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super T,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.collection.MutableVector.foldIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super T,? extends R> operation)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#foldRight(R, kotlin.jvm.functions.Function2<? super T,? super R,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.collection.MutableVector.foldRight(R initial, kotlin.jvm.functions.Function2<? super T,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#foldRightIndexed(R, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super T,? super R,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.collection.MutableVector.foldRightIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super T,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#indexOf(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.indexOf(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#lastIndexOf(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.lastIndexOf(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#minusAssign(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.minusAssign(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#plusAssign(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.plusAssign(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#remove(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.remove(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#set(int, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.set(int index, T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#add(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.add(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#add(int, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.add(int index, T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#contains(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.contains(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#indexOf(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.indexOf(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#lastIndexOf(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.lastIndexOf(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#remove(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.remove(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#set(int, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.set(int index, T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#containsKey(K) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.compose.runtime.snapshots.SnapshotStateMap.containsKey(K key)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#containsValue(V) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.snapshots.SnapshotStateMap.containsValue(V value)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#get(Object) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.compose.runtime.snapshots.SnapshotStateMap.get(Object key)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#put(K, V) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.compose.runtime.snapshots.SnapshotStateMap.put(K key, V value)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#put(K, V) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.snapshots.SnapshotStateMap.put(K key, V value)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#remove(Object) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.compose.runtime.snapshots.SnapshotStateMap.remove(Object key)
 
 
 RemovedClass: androidx.compose.runtime.SnapshotStateKt:
diff --git a/compose/runtime/runtime/api/current.txt b/compose/runtime/runtime/api/current.txt
index 852d95f..59a556b 100644
--- a/compose/runtime/runtime/api/current.txt
+++ b/compose/runtime/runtime/api/current.txt
@@ -2,18 +2,18 @@
 package androidx.compose.runtime {
 
   public abstract class AbstractApplier<T> implements androidx.compose.runtime.Applier<T> {
-    ctor public AbstractApplier(T? root);
+    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 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;
+    property public T current;
+    property public final T root;
   }
 
   public final class ActualAndroid_androidKt {
@@ -23,16 +23,16 @@
 
   @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 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;
+    property public abstract N current;
   }
 
   public final class BroadcastFrameClock implements androidx.compose.runtime.MonotonicFrameClock {
@@ -75,12 +75,12 @@
     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(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? key1, Object? key2, kotlin.jvm.functions.Function0<? extends T> calculation);
-    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![]? keys, kotlin.jvm.functions.Function0<? extends T> calculation);
+    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(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? key1, Object? key2, kotlin.jvm.functions.Function0<? extends T> calculation);
+    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![]? keys, 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;
@@ -98,7 +98,7 @@
   }
 
   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.ComposeCompilerApi public <V, T> void apply(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
     method @androidx.compose.runtime.ComposeCompilerApi public boolean changed(Object? value);
     method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(boolean value);
     method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(char value);
@@ -170,7 +170,7 @@
   }
 
   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 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);
@@ -215,7 +215,7 @@
   }
 
   public sealed interface CompositionLocalMap {
-    method public operator <T> T! get(androidx.compose.runtime.CompositionLocal<T> key);
+    method public operator <T> T get(androidx.compose.runtime.CompositionLocal<T> key);
     field public static final androidx.compose.runtime.CompositionLocalMap.Companion Companion;
   }
 
@@ -229,7 +229,7 @@
     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 public <R> R delegateInvalidations(androidx.compose.runtime.ControlledComposition? to, int groupIndex, kotlin.jvm.functions.Function0<? extends R> block);
     method public boolean getHasPendingChanges();
     method public void invalidateAll();
     method public boolean isComposing();
@@ -259,7 +259,7 @@
     method public double getDoubleValue();
     method public default Double getValue();
     property public abstract double doubleValue;
-    property public default Double value;
+    property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="doubleValue") public default Double value;
   }
 
   public final class EffectsKt {
@@ -284,7 +284,7 @@
     method public float getFloatValue();
     method public default Float getValue();
     property public abstract float floatValue;
-    property public default Float value;
+    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 {
@@ -294,14 +294,14 @@
     method public int getIntValue();
     method public default Integer getValue();
     property public abstract int intValue;
-    property public default Integer value;
+    property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="intValue") public default Integer value;
   }
 
   @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 public default Long value;
+    property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="longValue") public default Long value;
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface MonotonicFrameClock extends kotlin.coroutines.CoroutineContext.Element {
@@ -337,35 +337,35 @@
     method public void setDoubleValue(double);
     method public default void setValue(double);
     property public abstract double doubleValue;
-    property public default Double value;
+    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 public default Float value;
+    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 public default Integer value;
+    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 public default Long value;
+    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 T component1();
     method public operator kotlin.jvm.functions.Function1<T,kotlin.Unit> component2();
     method public void setValue(T!);
-    property public abstract T! value;
+    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 {
@@ -394,17 +394,17 @@
   }
 
   @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);
+    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();
+    method public T getValue();
     property public final boolean canOverride;
     property public final androidx.compose.runtime.CompositionLocal<T> compositionLocal;
-    property public final T! value;
+    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 {
@@ -500,8 +500,8 @@
   }
 
   @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);
+    method public boolean equivalent(T a, T b);
+    method public default T? merge(T previous, T current, T applied);
   }
 
   public final class SnapshotStateExtensionsKt {
@@ -513,24 +513,24 @@
 
   public final class SnapshotStateKt {
     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.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 extends R, R> androidx.compose.runtime.State<R> collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R initial, optional kotlin.coroutines.CoroutineContext context);
     method public static <T> androidx.compose.runtime.State<T> derivedStateOf(kotlin.jvm.functions.Function0<? extends T> calculation);
     method public static <T> androidx.compose.runtime.State<T> derivedStateOf(androidx.compose.runtime.SnapshotMutationPolicy<T> policy, 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 public static inline operator <T> T getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<?> property);
     method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf();
     method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf(T?... elements);
     method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf();
     method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
-    method 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.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, 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? 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, 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![]? 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 @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? 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, 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![]? keys, 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 @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>);
@@ -544,8 +544,8 @@
   }
 
   @androidx.compose.runtime.Stable public interface State<T> {
-    method public T! getValue();
-    property public abstract T! value;
+    method public T getValue();
+    property public abstract T value;
   }
 
   @kotlin.jvm.JvmInline public final value class Updater<T> {
@@ -553,9 +553,9 @@
     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 <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);
+    method public <V> void update(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
   }
 
 }
@@ -563,8 +563,8 @@
 package androidx.compose.runtime.collection {
 
   public final class MutableVector<T> implements java.util.RandomAccess {
-    method public boolean add(T? element);
-    method public void add(int index, T? element);
+    method public boolean add(T element);
+    method public void add(int index, T element);
     method public boolean addAll(int index, java.util.List<? extends T> elements);
     method public boolean addAll(int index, androidx.compose.runtime.collection.MutableVector<T> elements);
     method public inline boolean addAll(java.util.List<? extends T> elements);
@@ -575,53 +575,53 @@
     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 operator boolean contains(T element);
     method public boolean containsAll(java.util.List<? extends T> elements);
     method public boolean containsAll(java.util.Collection<? extends T> elements);
     method public boolean containsAll(androidx.compose.runtime.collection.MutableVector<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 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 <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 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 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 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 inline operator void minusAssign(T element);
+    method public inline operator void plusAssign(T element);
+    method public boolean remove(T element);
     method public boolean removeAll(java.util.List<? extends T> elements);
     method public boolean removeAll(androidx.compose.runtime.collection.MutableVector<T> elements);
     method public boolean removeAll(java.util.Collection<? extends T> elements);
-    method public T! removeAt(int index);
+    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 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;
@@ -724,6 +724,11 @@
 
 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();
@@ -745,7 +750,7 @@
 
   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 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();
@@ -759,16 +764,16 @@
 
   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 inline <T> T global(kotlin.jvm.functions.Function0<? extends T> block);
     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 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 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);
+    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;
   }
 
@@ -803,9 +808,9 @@
   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);
+    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> {
@@ -815,29 +820,29 @@
 
   @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 boolean add(T? element);
-    method public void add(int index, T? element);
+    method public boolean add(T element);
+    method public void add(int index, 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 contains(T element);
     method public boolean containsAll(java.util.Collection<E!> elements);
-    method public T! get(int index);
+    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 int indexOf(T element);
     method public boolean isEmpty();
     method public java.util.Iterator<T> iterator();
-    method public int lastIndexOf(T? element);
+    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 remove(T element);
     method public boolean removeAll(java.util.Collection<E!> elements);
-    method public T! removeAt(int index);
+    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 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;
@@ -847,9 +852,9 @@
   @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 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();
@@ -857,9 +862,9 @@
     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 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 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;
diff --git a/compose/runtime/runtime/api/public_plus_experimental_current.txt b/compose/runtime/runtime/api/public_plus_experimental_current.txt
index 881f541..9ce9384 100644
--- a/compose/runtime/runtime/api/public_plus_experimental_current.txt
+++ b/compose/runtime/runtime/api/public_plus_experimental_current.txt
@@ -2,18 +2,18 @@
 package androidx.compose.runtime {
 
   public abstract class AbstractApplier<T> implements androidx.compose.runtime.Applier<T> {
-    ctor public AbstractApplier(T? root);
+    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 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;
+    property public T current;
+    property public final T root;
   }
 
   public final class ActualAndroid_androidKt {
@@ -23,16 +23,16 @@
 
   @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 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;
+    property public abstract N current;
   }
 
   public final class BroadcastFrameClock implements androidx.compose.runtime.MonotonicFrameClock {
@@ -80,12 +80,12 @@
     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(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? key1, Object? key2, kotlin.jvm.functions.Function0<? extends T> calculation);
-    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![]? keys, kotlin.jvm.functions.Function0<? extends T> calculation);
+    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(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? key1, Object? key2, kotlin.jvm.functions.Function0<? extends T> calculation);
+    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![]? keys, 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;
@@ -103,7 +103,7 @@
   }
 
   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.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 boolean changed(Object? value);
     method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(boolean value);
@@ -116,7 +116,7 @@
     method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(double 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.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();
@@ -185,7 +185,7 @@
   }
 
   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 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);
@@ -233,7 +233,7 @@
   }
 
   public sealed interface CompositionLocalMap {
-    method public operator <T> T! get(androidx.compose.runtime.CompositionLocal<T> key);
+    method public operator <T> T get(androidx.compose.runtime.CompositionLocal<T> key);
     field public static final androidx.compose.runtime.CompositionLocalMap.Companion Companion;
   }
 
@@ -253,7 +253,7 @@
     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 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);
@@ -286,7 +286,7 @@
     method public double getDoubleValue();
     method public default Double getValue();
     property public abstract double doubleValue;
-    property public default Double value;
+    property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="doubleValue") public default Double value;
   }
 
   public final class EffectsKt {
@@ -314,7 +314,7 @@
     method public float getFloatValue();
     method public default Float getValue();
     property public abstract float floatValue;
-    property public default Float value;
+    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 {
@@ -324,7 +324,7 @@
     method public int getIntValue();
     method public default Integer getValue();
     property public abstract int intValue;
-    property public default Integer value;
+    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 {
@@ -337,7 +337,7 @@
     method public long getLongValue();
     method public default Long getValue();
     property public abstract long longValue;
-    property public default Long value;
+    property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="longValue") public default Long value;
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface MonotonicFrameClock extends kotlin.coroutines.CoroutineContext.Element {
@@ -385,35 +385,35 @@
     method public void setDoubleValue(double);
     method public default void setValue(double);
     property public abstract double doubleValue;
-    property public default Double value;
+    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 public default Float value;
+    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 public default Integer value;
+    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 public default Long value;
+    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 T component1();
     method public operator kotlin.jvm.functions.Function1<T,kotlin.Unit> component2();
     method public void setValue(T!);
-    property public abstract T! value;
+    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 {
@@ -442,17 +442,17 @@
   }
 
   @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);
+    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();
+    method public T getValue();
     property public final boolean canOverride;
     property public final androidx.compose.runtime.CompositionLocal<T> compositionLocal;
-    property public final T! value;
+    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 {
@@ -549,8 +549,8 @@
   }
 
   @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);
+    method public boolean equivalent(T a, T b);
+    method public default T? merge(T previous, T current, T applied);
   }
 
   public final class SnapshotStateExtensionsKt {
@@ -562,24 +562,24 @@
 
   public final class SnapshotStateKt {
     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.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 extends R, R> androidx.compose.runtime.State<R> collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R initial, optional kotlin.coroutines.CoroutineContext context);
     method public static <T> androidx.compose.runtime.State<T> derivedStateOf(kotlin.jvm.functions.Function0<? extends T> calculation);
     method public static <T> androidx.compose.runtime.State<T> derivedStateOf(androidx.compose.runtime.SnapshotMutationPolicy<T> policy, 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 public static inline operator <T> T getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<?> property);
     method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf();
     method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf(T?... elements);
     method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf();
     method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
-    method 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.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, 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? 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, 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![]? 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 @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? 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, 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![]? keys, 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 @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>);
@@ -593,8 +593,8 @@
   }
 
   @androidx.compose.runtime.Stable public interface State<T> {
-    method public T! getValue();
-    property public abstract T! value;
+    method public T getValue();
+    property public abstract T value;
   }
 
   @kotlin.jvm.JvmInline public final value class Updater<T> {
@@ -602,9 +602,9 @@
     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 <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);
+    method public <V> void update(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
   }
 
 }
@@ -612,8 +612,8 @@
 package androidx.compose.runtime.collection {
 
   public final class MutableVector<T> implements java.util.RandomAccess {
-    method public boolean add(T? element);
-    method public void add(int index, T? element);
+    method public boolean add(T element);
+    method public void add(int index, T element);
     method public boolean addAll(int index, java.util.List<? extends T> elements);
     method public boolean addAll(int index, androidx.compose.runtime.collection.MutableVector<T> elements);
     method public inline boolean addAll(java.util.List<? extends T> elements);
@@ -624,53 +624,53 @@
     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 operator boolean contains(T element);
     method public boolean containsAll(java.util.List<? extends T> elements);
     method public boolean containsAll(java.util.Collection<? extends T> elements);
     method public boolean containsAll(androidx.compose.runtime.collection.MutableVector<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 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 <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 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 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 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 inline operator void minusAssign(T element);
+    method public inline operator void plusAssign(T element);
+    method public boolean remove(T element);
     method public boolean removeAll(java.util.List<? extends T> elements);
     method public boolean removeAll(androidx.compose.runtime.collection.MutableVector<T> elements);
     method public boolean removeAll(java.util.Collection<? extends T> elements);
-    method public T! removeAt(int index);
+    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 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;
@@ -756,7 +756,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.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;
   }
@@ -790,6 +790,11 @@
 
 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();
@@ -811,7 +816,7 @@
 
   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 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();
@@ -827,17 +832,17 @@
 
   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 inline <T> T global(kotlin.jvm.functions.Function0<? extends T> block);
     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 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);
+    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;
   }
 
@@ -883,9 +888,9 @@
   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);
+    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> {
@@ -895,29 +900,29 @@
 
   @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 boolean add(T? element);
-    method public void add(int index, T? element);
+    method public boolean add(T element);
+    method public void add(int index, 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 contains(T element);
     method public boolean containsAll(java.util.Collection<E!> elements);
-    method public T! get(int index);
+    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 int indexOf(T element);
     method public boolean isEmpty();
     method public java.util.Iterator<T> iterator();
-    method public int lastIndexOf(T? element);
+    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 remove(T element);
     method public boolean removeAll(java.util.Collection<E!> elements);
-    method public T! removeAt(int index);
+    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 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;
@@ -927,9 +932,9 @@
   @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 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();
@@ -937,9 +942,9 @@
     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 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 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;
diff --git a/compose/runtime/runtime/api/restricted_current.ignore b/compose/runtime/runtime/api/restricted_current.ignore
index 1589837..1e4b20b 100644
--- a/compose/runtime/runtime/api/restricted_current.ignore
+++ b/compose/runtime/runtime/api/restricted_current.ignore
@@ -1,8 +1,108 @@
 // Baseline format: 1.0
 AddedAbstractMethod: androidx.compose.runtime.Composer#getCurrentCompositionLocalMap():
     Added method androidx.compose.runtime.Composer.getCurrentCompositionLocalMap()
-AddedAbstractMethod: androidx.compose.runtime.CompositionContext#getEffectCoroutineContext():
-    Added method androidx.compose.runtime.CompositionContext.getEffectCoroutineContext()
+
+
+InvalidNullConversion: androidx.compose.runtime.AbstractApplier#AbstractApplier(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter root in androidx.compose.runtime.AbstractApplier(T root)
+InvalidNullConversion: androidx.compose.runtime.AbstractApplier#down(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter node in androidx.compose.runtime.AbstractApplier.down(T node)
+InvalidNullConversion: androidx.compose.runtime.Applier#down(N) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter node in androidx.compose.runtime.Applier.down(N node)
+InvalidNullConversion: androidx.compose.runtime.Applier#insertBottomUp(int, N) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter instance in androidx.compose.runtime.Applier.insertBottomUp(int index, N instance)
+InvalidNullConversion: androidx.compose.runtime.Applier#insertTopDown(int, N) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter instance in androidx.compose.runtime.Applier.insertTopDown(int index, N instance)
+InvalidNullConversion: androidx.compose.runtime.Composer#apply(V, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.Composer.apply(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block)
+InvalidNullConversion: androidx.compose.runtime.ProvidableCompositionLocal#provides(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.ProvidableCompositionLocal.provides(T value)
+InvalidNullConversion: androidx.compose.runtime.ProvidableCompositionLocal#providesDefault(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.ProvidableCompositionLocal.providesDefault(T value)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#equivalent(T, T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter a in androidx.compose.runtime.SnapshotMutationPolicy.equivalent(T a, T b)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#equivalent(T, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter b in androidx.compose.runtime.SnapshotMutationPolicy.equivalent(T a, T b)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#merge(T, T, T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter previous in androidx.compose.runtime.SnapshotMutationPolicy.merge(T previous, T current, T applied)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#merge(T, T, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter current in androidx.compose.runtime.SnapshotMutationPolicy.merge(T previous, T current, T applied)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#merge(T, T, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter applied in androidx.compose.runtime.SnapshotMutationPolicy.merge(T previous, T current, T applied)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R, kotlin.coroutines.CoroutineContext) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.SnapshotStateKt.collectAsState(kotlinx.coroutines.flow.Flow<? extends T> arg1, R initial, kotlin.coroutines.CoroutineContext context)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#mutableStateOf(T, androidx.compose.runtime.SnapshotMutationPolicy<T>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.SnapshotStateKt.mutableStateOf(T value, androidx.compose.runtime.SnapshotMutationPolicy<T> policy)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, Object, Object, Object, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.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)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, Object, Object, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.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)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, Object, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.produceState(T initialValue, Object key1, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, Object[], kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.produceState(T initialValue, Object[] keys, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.produceState(T initialValue, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#rememberUpdatedState(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter newValue in androidx.compose.runtime.SnapshotStateKt.rememberUpdatedState(T newValue)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#setValue(androidx.compose.runtime.MutableState<T>, Object, kotlin.reflect.KProperty<?>, T) parameter #3:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.SnapshotStateKt.setValue(androidx.compose.runtime.MutableState<T> arg1, Object thisObj, kotlin.reflect.KProperty<?> property, T value)
+InvalidNullConversion: androidx.compose.runtime.Updater#set(V, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.Updater.set(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block)
+InvalidNullConversion: androidx.compose.runtime.Updater#update(V, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.Updater.update(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#add(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.add(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#add(int, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.add(int index, T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#contains(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.contains(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#fold(R, kotlin.jvm.functions.Function2<? super R,? super T,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.collection.MutableVector.fold(R initial, kotlin.jvm.functions.Function2<? super R,? super T,? extends R> operation)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#foldIndexed(R, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super T,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.collection.MutableVector.foldIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super T,? extends R> operation)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#foldRight(R, kotlin.jvm.functions.Function2<? super T,? super R,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.collection.MutableVector.foldRight(R initial, kotlin.jvm.functions.Function2<? super T,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#foldRightIndexed(R, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super T,? super R,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.collection.MutableVector.foldRightIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super T,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#indexOf(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.indexOf(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#lastIndexOf(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.lastIndexOf(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#minusAssign(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.minusAssign(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#plusAssign(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.plusAssign(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#remove(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.remove(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#set(int, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.set(int index, T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#add(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.add(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#add(int, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.add(int index, T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#contains(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.contains(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#indexOf(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.indexOf(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#lastIndexOf(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.lastIndexOf(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#remove(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.remove(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#set(int, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.set(int index, T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#containsKey(K) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.compose.runtime.snapshots.SnapshotStateMap.containsKey(K key)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#containsValue(V) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.snapshots.SnapshotStateMap.containsValue(V value)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#get(Object) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.compose.runtime.snapshots.SnapshotStateMap.get(Object key)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#put(K, V) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.compose.runtime.snapshots.SnapshotStateMap.put(K key, V value)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#put(K, V) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.snapshots.SnapshotStateMap.put(K key, V value)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#remove(Object) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.compose.runtime.snapshots.SnapshotStateMap.remove(Object key)
 
 
 RemovedClass: androidx.compose.runtime.SnapshotStateKt:
diff --git a/compose/runtime/runtime/api/restricted_current.txt b/compose/runtime/runtime/api/restricted_current.txt
index a65d447..366b6db 100644
--- a/compose/runtime/runtime/api/restricted_current.txt
+++ b/compose/runtime/runtime/api/restricted_current.txt
@@ -2,18 +2,18 @@
 package androidx.compose.runtime {
 
   public abstract class AbstractApplier<T> implements androidx.compose.runtime.Applier<T> {
-    ctor public AbstractApplier(T? root);
+    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 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;
+    property public T current;
+    property public final T root;
   }
 
   public final class ActualAndroid_androidKt {
@@ -22,21 +22,21 @@
   }
 
   public final class ActualJvm_jvmKt {
-    method @kotlin.PublishedApi internal static inline <R> R! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends R> block);
+    method @kotlin.PublishedApi internal static inline <R> R synchronized(Object lock, kotlin.jvm.functions.Function0<? extends R> block);
   }
 
   @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 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;
+    property public abstract N current;
   }
 
   public final class BroadcastFrameClock implements androidx.compose.runtime.MonotonicFrameClock {
@@ -80,12 +80,12 @@
     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 @kotlin.PublishedApi internal static void invalidApplier();
-    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(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? key1, Object? key2, kotlin.jvm.functions.Function0<? extends T> calculation);
-    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![]? keys, kotlin.jvm.functions.Function0<? extends T> calculation);
+    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(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? key1, Object? key2, kotlin.jvm.functions.Function0<? extends T> calculation);
+    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![]? keys, 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;
@@ -103,7 +103,7 @@
   }
 
   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.ComposeCompilerApi public <V, T> void apply(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
     method @androidx.compose.runtime.ComposeCompilerApi public boolean changed(Object? value);
     method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(boolean value);
     method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(char value);
@@ -175,7 +175,7 @@
   }
 
   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 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);
@@ -233,7 +233,7 @@
   }
 
   public sealed interface CompositionLocalMap {
-    method public operator <T> T! get(androidx.compose.runtime.CompositionLocal<T> key);
+    method public operator <T> T get(androidx.compose.runtime.CompositionLocal<T> key);
     field public static final androidx.compose.runtime.CompositionLocalMap.Companion Companion;
   }
 
@@ -256,7 +256,7 @@
     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 public <R> R delegateInvalidations(androidx.compose.runtime.ControlledComposition? to, int groupIndex, kotlin.jvm.functions.Function0<? extends R> block);
     method public boolean getHasPendingChanges();
     method public void invalidateAll();
     method public boolean isComposing();
@@ -286,7 +286,7 @@
     method public double getDoubleValue();
     method public default Double getValue();
     property public abstract double doubleValue;
-    property public default Double value;
+    property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="doubleValue") public default Double value;
   }
 
   public final class EffectsKt {
@@ -306,7 +306,7 @@
   }
 
   public final class ExpectKt {
-    method @kotlin.PublishedApi internal static inline <R> R? synchronized(Object lock, kotlin.jvm.functions.Function0<? extends R> block);
+    method @kotlin.PublishedApi internal static inline <R> R synchronized(Object lock, kotlin.jvm.functions.Function0<? extends R> block);
   }
 
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ExplicitGroupsComposable {
@@ -316,7 +316,7 @@
     method public float getFloatValue();
     method public default Float getValue();
     property public abstract float floatValue;
-    property public default Float value;
+    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 {
@@ -326,14 +326,14 @@
     method public int getIntValue();
     method public default Integer getValue();
     property public abstract int intValue;
-    property public default Integer value;
+    property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="intValue") public default Integer value;
   }
 
   @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 public default Long value;
+    property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="longValue") public default Long value;
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface MonotonicFrameClock extends kotlin.coroutines.CoroutineContext.Element {
@@ -369,35 +369,35 @@
     method public void setDoubleValue(double);
     method public default void setValue(double);
     property public abstract double doubleValue;
-    property public default Double value;
+    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 public default Float value;
+    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 public default Integer value;
+    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 public default Long value;
+    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 T component1();
     method public operator kotlin.jvm.functions.Function1<T,kotlin.Unit> component2();
     method public void setValue(T!);
-    property public abstract T! value;
+    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 {
@@ -426,17 +426,17 @@
   }
 
   @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);
+    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();
+    method public T getValue();
     property public final boolean canOverride;
     property public final androidx.compose.runtime.CompositionLocal<T> compositionLocal;
-    property public final T! value;
+    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 {
@@ -536,8 +536,8 @@
   }
 
   @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);
+    method public boolean equivalent(T a, T b);
+    method public default T? merge(T previous, T current, T applied);
   }
 
   public final class SnapshotStateExtensionsKt {
@@ -549,24 +549,24 @@
 
   public final class SnapshotStateKt {
     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.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 extends R, R> androidx.compose.runtime.State<R> collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R initial, optional kotlin.coroutines.CoroutineContext context);
     method public static <T> androidx.compose.runtime.State<T> derivedStateOf(kotlin.jvm.functions.Function0<? extends T> calculation);
     method public static <T> androidx.compose.runtime.State<T> derivedStateOf(androidx.compose.runtime.SnapshotMutationPolicy<T> policy, 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 public static inline operator <T> T getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<?> property);
     method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf();
     method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf(T?... elements);
     method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf();
     method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
-    method 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.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, 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? 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, 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![]? 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 @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? 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, 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![]? keys, 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 @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>);
@@ -580,8 +580,8 @@
   }
 
   @androidx.compose.runtime.Stable public interface State<T> {
-    method public T! getValue();
-    property public abstract T! value;
+    method public T getValue();
+    property public abstract T value;
   }
 
   @kotlin.jvm.JvmInline public final value class Updater<T> {
@@ -589,9 +589,9 @@
     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 <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);
+    method public <V> void update(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
   }
 
 }
@@ -600,8 +600,8 @@
 
   public final class MutableVector<T> implements java.util.RandomAccess {
     ctor @kotlin.PublishedApi internal MutableVector(@kotlin.PublishedApi T![] content, int size);
-    method public boolean add(T? element);
-    method public void add(int index, T? element);
+    method public boolean add(T element);
+    method public void add(int index, T element);
     method public boolean addAll(int index, java.util.List<? extends T> elements);
     method public boolean addAll(int index, androidx.compose.runtime.collection.MutableVector<T> elements);
     method public inline boolean addAll(java.util.List<? extends T> elements);
@@ -612,53 +612,53 @@
     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 operator boolean contains(T element);
     method public boolean containsAll(java.util.List<? extends T> elements);
     method public boolean containsAll(java.util.Collection<? extends T> elements);
     method public boolean containsAll(androidx.compose.runtime.collection.MutableVector<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 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 <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 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 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 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 inline operator void minusAssign(T element);
+    method public inline operator void plusAssign(T element);
+    method public boolean remove(T element);
     method public boolean removeAll(java.util.List<? extends T> elements);
     method public boolean removeAll(androidx.compose.runtime.collection.MutableVector<T> elements);
     method public boolean removeAll(java.util.Collection<? extends T> elements);
-    method public T! removeAt(int index);
+    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 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);
     method @kotlin.PublishedApi internal Void throwNoSuchElementException();
@@ -762,6 +762,11 @@
 
 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();
@@ -783,7 +788,7 @@
 
   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 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();
@@ -800,9 +805,9 @@
   public static final class Snapshot.Companion {
     method @kotlin.PublishedApi internal androidx.compose.runtime.snapshots.Snapshot createNonObservableSnapshot();
     method public androidx.compose.runtime.snapshots.Snapshot getCurrent();
-    method public inline <T> T! global(kotlin.jvm.functions.Function0<? extends T> block);
+    method public inline <T> T global(kotlin.jvm.functions.Function0<? extends T> block);
     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 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 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();
@@ -810,8 +815,8 @@
     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);
+    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;
   }
 
@@ -849,10 +854,10 @@
     method @kotlin.PublishedApi internal static void notifyWrite(androidx.compose.runtime.snapshots.Snapshot snapshot, 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);
     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 @kotlin.PublishedApi internal static inline <T> T! sync(kotlin.jvm.functions.Function0<? extends T> block);
-    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);
+    method @kotlin.PublishedApi internal static inline <T> T sync(kotlin.jvm.functions.Function0<? extends T> block);
+    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);
     method @kotlin.PublishedApi internal static <T extends androidx.compose.runtime.snapshots.StateRecord> T writableRecord(T, androidx.compose.runtime.snapshots.StateObject state, androidx.compose.runtime.snapshots.Snapshot snapshot);
     field @kotlin.PublishedApi internal static final Object lock;
     field @kotlin.PublishedApi internal static final androidx.compose.runtime.snapshots.Snapshot snapshotInitializer;
@@ -865,29 +870,29 @@
 
   @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 boolean add(T? element);
-    method public void add(int index, T? element);
+    method public boolean add(T element);
+    method public void add(int index, 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 contains(T element);
     method public boolean containsAll(java.util.Collection<E!> elements);
-    method public T! get(int index);
+    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 int indexOf(T element);
     method public boolean isEmpty();
     method public java.util.Iterator<T> iterator();
-    method public int lastIndexOf(T? element);
+    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 remove(T element);
     method public boolean removeAll(java.util.Collection<E!> elements);
-    method public T! removeAt(int index);
+    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 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;
@@ -897,9 +902,9 @@
   @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 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();
@@ -907,9 +912,9 @@
     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 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 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;
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotDoubleState.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotDoubleState.kt
index 723f147..71de1aa 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotDoubleState.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotDoubleState.kt
@@ -19,6 +19,7 @@
 package androidx.compose.runtime
 
 import androidx.compose.runtime.internal.JvmDefaultWithCompatibility
+import androidx.compose.runtime.snapshots.AutoboxingStateValueProperty
 import androidx.compose.runtime.snapshots.Snapshot
 import androidx.compose.runtime.snapshots.SnapshotMutableState
 import androidx.compose.runtime.snapshots.StateObject
@@ -55,6 +56,7 @@
 @Stable
 @JvmDefaultWithCompatibility
 interface DoubleState : State<Double> {
+    @AutoboxingStateValueProperty("doubleValue")
     override val value: Double
         @Suppress("AutoBoxing") get() = doubleValue
 
@@ -83,6 +85,7 @@
 @Stable
 @JvmDefaultWithCompatibility
 interface MutableDoubleState : DoubleState, MutableState<Double> {
+    @AutoboxingStateValueProperty("doubleValue")
     override var value: Double
         @Suppress("AutoBoxing") get() = doubleValue
         set(value) { doubleValue = value }
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotFloatState.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotFloatState.kt
index a31d255..b48a3fb 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotFloatState.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotFloatState.kt
@@ -18,6 +18,7 @@
 @file:JvmMultifileClass
 package androidx.compose.runtime
 
+import androidx.compose.runtime.snapshots.AutoboxingStateValueProperty
 import androidx.compose.runtime.snapshots.Snapshot
 import androidx.compose.runtime.snapshots.SnapshotMutableState
 import androidx.compose.runtime.snapshots.StateObject
@@ -54,6 +55,7 @@
 @Stable
 @JvmDefaultWithCompatibility
 interface FloatState : State<Float> {
+    @AutoboxingStateValueProperty("floatValue")
     override val value: Float
         @Suppress("AutoBoxing") get() = floatValue
 
@@ -79,6 +81,7 @@
 @Stable
 @JvmDefaultWithCompatibility
 interface MutableFloatState : FloatState, MutableState<Float> {
+    @AutoboxingStateValueProperty("floatValue")
     override var value: Float
         @Suppress("AutoBoxing") get() = floatValue
         set(value) { floatValue = value }
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotIntState.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotIntState.kt
index 4520c42..785f9b7 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotIntState.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotIntState.kt
@@ -18,6 +18,7 @@
 @file:JvmMultifileClass
 package androidx.compose.runtime
 
+import androidx.compose.runtime.snapshots.AutoboxingStateValueProperty
 import androidx.compose.runtime.snapshots.Snapshot
 import androidx.compose.runtime.snapshots.SnapshotMutableState
 import androidx.compose.runtime.snapshots.StateObject
@@ -54,6 +55,7 @@
 @Stable
 @JvmDefaultWithCompatibility
 interface IntState : State<Int> {
+    @AutoboxingStateValueProperty("intValue")
     override val value: Int
         @Suppress("AutoBoxing") get() = intValue
 
@@ -79,6 +81,7 @@
 @Stable
 @JvmDefaultWithCompatibility
 interface MutableIntState : IntState, MutableState<Int> {
+    @AutoboxingStateValueProperty("intValue")
     override var value: Int
         @Suppress("AutoBoxing") get() = intValue
         set(value) { intValue = value }
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotLongState.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotLongState.kt
index f1869df..e129f42 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotLongState.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotLongState.kt
@@ -19,6 +19,7 @@
 package androidx.compose.runtime
 
 import androidx.compose.runtime.internal.JvmDefaultWithCompatibility
+import androidx.compose.runtime.snapshots.AutoboxingStateValueProperty
 import androidx.compose.runtime.snapshots.Snapshot
 import androidx.compose.runtime.snapshots.SnapshotMutableState
 import androidx.compose.runtime.snapshots.StateObject
@@ -55,6 +56,7 @@
 @Stable
 @JvmDefaultWithCompatibility
 interface LongState : State<Long> {
+    @AutoboxingStateValueProperty("longValue")
     override val value: Long
         @Suppress("AutoBoxing") get() = longValue
 
@@ -80,6 +82,7 @@
 @Stable
 @JvmDefaultWithCompatibility
 interface MutableLongState : LongState, MutableState<Long> {
+    @AutoboxingStateValueProperty("longValue")
     override var value: Long
         @Suppress("AutoBoxing") get() = longValue
         set(value) { longValue = value }
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/AutoboxingStateValueProperty.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/AutoboxingStateValueProperty.kt
new file mode 100644
index 0000000..3f3a814
--- /dev/null
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/AutoboxingStateValueProperty.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.compose.runtime.snapshots
+
+/**
+ * This annotation designates that a property on a [State] class will autobox when it is read from
+ * or assigned to. This is helpful for state APIs like [IntState], which define an alternative
+ * value property that does not box while maintaining compatibility with the generic
+ * [`State<T>`][State] API.
+ *
+ * Whenever a property that is annotated with `AutoboxingStateValueProperty` is accessed in code,
+ * it will be flagged with a warning and will suggest using an alternative, non-boxing property
+ * instead.
+ */
+@Retention(AnnotationRetention.BINARY)
+@Target(AnnotationTarget.PROPERTY)
+annotation class AutoboxingStateValueProperty(
+    /**
+     * An alternative, non-boxing property that can be used instead of the annotated property.
+     * The property indicated in this property should contain the exact same value as the annotated
+     * property and should be observed in Compose in the same way, meaning that the designated
+     * replacement property can serve as a drop-in replacement to the annotated property.
+     *
+     * This property name will be used for suggesting quick fixes. It must match the suggested
+     * property name exactly, including its case.
+     */
+    @Suppress("unused") // Used by lint
+    val preferredPropertyName: String
+)
diff --git a/compose/ui/ui-graphics/api/api_lint.ignore b/compose/ui/ui-graphics/api/api_lint.ignore
index 6f1ace9..476b5f2 100644
--- a/compose/ui/ui-graphics/api/api_lint.ignore
+++ b/compose/ui/ui-graphics/api/api_lint.ignore
@@ -43,6 +43,10 @@
     Getter should be on the built object, not the builder: method androidx.compose.ui.graphics.vector.PathBuilder.getNodes()
 
 
+GetterSetterNames: androidx.compose.ui.graphics.ImageBitmap#getHasAlpha():
+    Getter for boolean property `hasAlpha` is named `getHasAlpha` but should match the property name. Use `@get:JvmName` to rename.
+
+
 KotlinDefaultParameterOrder: androidx.compose.ui.graphics.Canvas#drawImageRect(androidx.compose.ui.graphics.ImageBitmap, long, long, long, long, androidx.compose.ui.graphics.Paint) parameter #1:
     Parameter `srcOffset` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
 KotlinDefaultParameterOrder: androidx.compose.ui.graphics.Canvas#drawImageRect(androidx.compose.ui.graphics.ImageBitmap, long, long, long, long, androidx.compose.ui.graphics.Paint) parameter #2:
@@ -59,16 +63,12 @@
     androidx.compose.ui.graphics.vector.PathBuilder does not declare a `build()` method, but builder classes are expected to
 
 
-MissingNullability: androidx.compose.ui.graphics.PaintKt#Paint():
-    Missing nullability on method `Paint` return
-
-
 NotCloseable: androidx.compose.ui.graphics.AndroidPath:
-    Classes that release resources (close()) should implement AutoClosable and CloseGuard: class androidx.compose.ui.graphics.AndroidPath
+    Classes that release resources (close()) should implement AutoCloseable and CloseGuard: class androidx.compose.ui.graphics.AndroidPath
 NotCloseable: androidx.compose.ui.graphics.Path:
-    Classes that release resources (close()) should implement AutoClosable and CloseGuard: class androidx.compose.ui.graphics.Path
+    Classes that release resources (close()) should implement AutoCloseable and CloseGuard: class androidx.compose.ui.graphics.Path
 NotCloseable: androidx.compose.ui.graphics.vector.PathBuilder:
-    Classes that release resources (close()) should implement AutoClosable and CloseGuard: class androidx.compose.ui.graphics.vector.PathBuilder
+    Classes that release resources (close()) should implement AutoCloseable and CloseGuard: class androidx.compose.ui.graphics.vector.PathBuilder
 
 
 TopLevelBuilder: androidx.compose.ui.graphics.vector.PathBuilder:
diff --git a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/ImageBitmapTest.kt b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/ImageBitmapTest.kt
index ab73407..e081e68 100644
--- a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/ImageBitmapTest.kt
+++ b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/ImageBitmapTest.kt
@@ -16,13 +16,22 @@
 
 package androidx.compose.ui.graphics
 
+import android.graphics.ColorSpace
+import android.graphics.ColorSpace.Named
+import android.graphics.ColorSpace.Rgb
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.compose.ui.graphics.ImageBitmapTest.ColorSpaceHelper.Companion.colorSpaceTestHelper
 import androidx.compose.ui.graphics.colorspace.ColorSpaces
+import androidx.compose.ui.graphics.colorspace.TransferParameters
+import androidx.compose.ui.graphics.colorspace.WhitePoint
 import androidx.test.filters.SmallTest
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Test
 import org.junit.runner.RunWith
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
@@ -45,4 +54,227 @@
         assertFalse(image.hasAlpha)
         assertEquals(cs, image.colorSpace)
     }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testSrgbColorspace() {
+        colorSpaceTestHelper(
+            ColorSpaces.Srgb, // Compose
+            ColorSpace.get(Named.SRGB) // Framework
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testAcesColorspace() {
+        colorSpaceTestHelper(
+            ColorSpaces.Aces, // Compose
+            ColorSpace.get(Named.ACES) // Framework
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testAcescgColorspace() {
+        colorSpaceTestHelper(
+            ColorSpaces.Acescg, // Compose
+            ColorSpace.get(Named.ACESCG) // Framework
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testAdobeRgbColorspace() {
+        colorSpaceTestHelper(
+            ColorSpaces.AdobeRgb, // Compose
+            ColorSpace.get(Named.ADOBE_RGB) // Framework
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testBt2020Colorspace() {
+        colorSpaceTestHelper(
+            ColorSpaces.Bt2020, // Compose
+            ColorSpace.get(Named.BT2020) // Framework
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testBt709Colorspace() {
+        colorSpaceTestHelper(
+            ColorSpaces.Bt709, // Compose
+            ColorSpace.get(Named.BT709) // Framework
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testCieLabColorspace() {
+        colorSpaceTestHelper(
+            ColorSpaces.CieLab, // Compose
+            ColorSpace.get(Named.CIE_LAB) // Framework
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testCieXyzColorspace() {
+        colorSpaceTestHelper(
+            ColorSpaces.CieXyz, // Compose
+            ColorSpace.get(Named.CIE_XYZ) // Framework
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testDciP3Colorspace() {
+        colorSpaceTestHelper(
+            ColorSpaces.DciP3, // Compose
+            ColorSpace.get(Named.DCI_P3) // Framework
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testDisplayP3Colorspace() {
+        colorSpaceTestHelper(
+            ColorSpaces.DisplayP3, // Compose
+            ColorSpace.get(Named.DISPLAY_P3) // Framework
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testExtendedSrgbColorspace() {
+        colorSpaceTestHelper(
+            ColorSpaces.ExtendedSrgb, // Compose
+            ColorSpace.get(Named.EXTENDED_SRGB) // Framework
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testLinearExtendedSrgbColorspace() {
+        colorSpaceTestHelper(
+            ColorSpaces.LinearExtendedSrgb, // Compose
+            ColorSpace.get(Named.LINEAR_EXTENDED_SRGB) // Framework
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testLinearSrgbColorspace() {
+        colorSpaceTestHelper(
+            ColorSpaces.LinearSrgb, // Compose
+            ColorSpace.get(Named.LINEAR_SRGB) // Framework
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testNtsc1953Colorspace() {
+        colorSpaceTestHelper(
+            ColorSpaces.Ntsc1953, // Compose
+            ColorSpace.get(Named.NTSC_1953) // Framework
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testProPhotoRgbColorspace() {
+        colorSpaceTestHelper(
+            ColorSpaces.ProPhotoRgb, // Compose
+            ColorSpace.get(Named.PRO_PHOTO_RGB) // Framework
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testSmpteCColorspace() {
+        colorSpaceTestHelper(
+            ColorSpaces.SmpteC, // Compose
+            ColorSpace.get(Named.SMPTE_C) // Framework
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testUnknownColorspace3WhitePointValues() {
+        val name = "MyCustomColorSpace"
+        val whitePoint = floatArrayOf(1.0f, 2.0f, 3.0f)
+        val transferParameters = Rgb.TransferParameters(
+            0.1, // a
+            0.2, // b
+            0.3, // c
+            0.4, // d
+            0.5, // e
+            0.6, // f
+            0.7 // g
+        )
+        val primaries = floatArrayOf(1f, 2f, 3f, 4f, 5f, 6f)
+        colorSpaceTestHelper(
+            androidx.compose.ui.graphics.colorspace.Rgb(
+                name = name,
+                primaries = primaries,
+                WhitePoint(1.0f, 2.0f, 3.0f),
+                TransferParameters(0.7, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6)
+            ),
+            Rgb(
+                name,
+                primaries,
+                whitePoint,
+                transferParameters
+            )
+        )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testUnknownColorspace2WhitePointValues() {
+        val name = "MyCustomColorSpace"
+        val whitePoint = floatArrayOf(1.0f, 2.0f)
+        val transferParameters = Rgb.TransferParameters(
+            0.1, // a
+            0.2, // b
+            0.3, // c
+            0.4, // d
+            0.5, // e
+            0.6, // f
+            0.7 // g
+        )
+        val primaries = floatArrayOf(1f, 2f, 3f, 4f, 5f, 6f)
+
+        colorSpaceTestHelper(
+            androidx.compose.ui.graphics.colorspace.Rgb(
+                name = name,
+                primaries = primaries,
+                WhitePoint(1.0f, 2.0f),
+                TransferParameters(0.7, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6)
+            ),
+            Rgb(
+                name,
+                primaries,
+                whitePoint,
+                transferParameters
+            )
+        )
+    }
+
+    // Helper class to avoid NoSuchClassExceptions being thrown when tests are run on an older
+    // API level that does not understand ColorSpace APIs
+    internal class ColorSpaceHelper {
+        companion object {
+            @RequiresApi(Build.VERSION_CODES.O)
+            fun colorSpaceTestHelper(
+                composeColorSpace: androidx.compose.ui.graphics.colorspace.ColorSpace,
+                frameworkColorSpace: ColorSpace
+            ) {
+                with(Api26Bitmap) {
+                    assertEquals(composeColorSpace, frameworkColorSpace.composeColorSpace())
+                }
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/AndroidImageBitmap.android.kt b/compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/AndroidImageBitmap.android.kt
index 3faf08c..2e7700c 100644
--- a/compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/AndroidImageBitmap.android.kt
+++ b/compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/AndroidImageBitmap.android.kt
@@ -17,12 +17,16 @@
 package androidx.compose.ui.graphics
 
 import android.graphics.Bitmap
+import android.graphics.ColorSpace.Named
 import android.os.Build
 import android.util.DisplayMetrics
 import androidx.annotation.DoNotInline
 import androidx.annotation.RequiresApi
 import androidx.compose.ui.graphics.colorspace.ColorSpace
 import androidx.compose.ui.graphics.colorspace.ColorSpaces
+import androidx.compose.ui.graphics.colorspace.Rgb
+import androidx.compose.ui.graphics.colorspace.TransferParameters
+import androidx.compose.ui.graphics.colorspace.WhitePoint
 
 /**
  * Create an [ImageBitmap] from the given [Bitmap]. Note this does
@@ -184,7 +188,7 @@
  * elimination during compilation time
  */
 @RequiresApi(Build.VERSION_CODES.O)
-private object Api26Bitmap {
+internal object Api26Bitmap {
     @DoNotInline
     @JvmStatic
     internal fun createBitmap(
@@ -214,67 +218,86 @@
     @JvmStatic
     internal fun ColorSpace.toFrameworkColorSpace(): android.graphics.ColorSpace {
         val frameworkNamedSpace = when (this) {
-            ColorSpaces.Srgb -> android.graphics.ColorSpace.Named.SRGB
-            ColorSpaces.Aces -> android.graphics.ColorSpace.Named.ACES
-            ColorSpaces.Acescg -> android.graphics.ColorSpace.Named.ACESCG
-            ColorSpaces.AdobeRgb -> android.graphics.ColorSpace.Named.ADOBE_RGB
-            ColorSpaces.Bt2020 -> android.graphics.ColorSpace.Named.BT2020
-            ColorSpaces.Bt709 -> android.graphics.ColorSpace.Named.BT709
-            ColorSpaces.CieLab -> android.graphics.ColorSpace.Named.CIE_LAB
-            ColorSpaces.CieXyz -> android.graphics.ColorSpace.Named.CIE_XYZ
-            ColorSpaces.DciP3 -> android.graphics.ColorSpace.Named.DCI_P3
-            ColorSpaces.DisplayP3 -> android.graphics.ColorSpace.Named.DISPLAY_P3
-            ColorSpaces.ExtendedSrgb -> android.graphics.ColorSpace.Named.EXTENDED_SRGB
+            ColorSpaces.Srgb -> Named.SRGB
+            ColorSpaces.Aces -> Named.ACES
+            ColorSpaces.Acescg -> Named.ACESCG
+            ColorSpaces.AdobeRgb -> Named.ADOBE_RGB
+            ColorSpaces.Bt2020 -> Named.BT2020
+            ColorSpaces.Bt709 -> Named.BT709
+            ColorSpaces.CieLab -> Named.CIE_LAB
+            ColorSpaces.CieXyz -> Named.CIE_XYZ
+            ColorSpaces.DciP3 -> Named.DCI_P3
+            ColorSpaces.DisplayP3 -> Named.DISPLAY_P3
+            ColorSpaces.ExtendedSrgb -> Named.EXTENDED_SRGB
             ColorSpaces.LinearExtendedSrgb ->
-                android.graphics.ColorSpace.Named.LINEAR_EXTENDED_SRGB
-            ColorSpaces.LinearSrgb -> android.graphics.ColorSpace.Named.LINEAR_SRGB
-            ColorSpaces.Ntsc1953 -> android.graphics.ColorSpace.Named.NTSC_1953
-            ColorSpaces.ProPhotoRgb -> android.graphics.ColorSpace.Named.PRO_PHOTO_RGB
-            ColorSpaces.SmpteC -> android.graphics.ColorSpace.Named.SMPTE_C
-            else -> android.graphics.ColorSpace.Named.SRGB
+                Named.LINEAR_EXTENDED_SRGB
+            ColorSpaces.LinearSrgb -> Named.LINEAR_SRGB
+            ColorSpaces.Ntsc1953 -> Named.NTSC_1953
+            ColorSpaces.ProPhotoRgb -> Named.PRO_PHOTO_RGB
+            ColorSpaces.SmpteC -> Named.SMPTE_C
+            else -> Named.SRGB
         }
         return android.graphics.ColorSpace.get(frameworkNamedSpace)
     }
 
     @DoNotInline
     @JvmStatic
-    internal fun android.graphics.ColorSpace.composeColorSpace(): ColorSpace {
-        return when (this) {
-            android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.SRGB) ->
-                ColorSpaces.Srgb
-            android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.ACES) ->
-                ColorSpaces.Aces
-            android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.ACESCG) ->
-                ColorSpaces.Acescg
-            android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.ADOBE_RGB) ->
-                ColorSpaces.AdobeRgb
-            android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.BT2020) ->
-                ColorSpaces.Bt2020
-            android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.BT709) ->
-                ColorSpaces.Bt709
-            android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.CIE_LAB) ->
-                ColorSpaces.CieLab
-            android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.CIE_XYZ) ->
-                ColorSpaces.CieXyz
-            android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.DCI_P3) ->
-                ColorSpaces.DciP3
-            android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.DISPLAY_P3) ->
-                ColorSpaces.DisplayP3
-            android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.EXTENDED_SRGB) ->
-                ColorSpaces.ExtendedSrgb
-            android.graphics.ColorSpace.get(
-                android.graphics.ColorSpace.Named.LINEAR_EXTENDED_SRGB
-            ) ->
-                ColorSpaces.LinearExtendedSrgb
-            android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.LINEAR_SRGB) ->
-                ColorSpaces.LinearSrgb
-            android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.NTSC_1953) ->
-                ColorSpaces.Ntsc1953
-            android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.PRO_PHOTO_RGB) ->
-                ColorSpaces.ProPhotoRgb
-            android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.SMPTE_C) ->
-                ColorSpaces.SmpteC
-            else -> ColorSpaces.Srgb
+    fun android.graphics.ColorSpace.composeColorSpace(): ColorSpace {
+        return when (this.id) {
+            Named.SRGB.ordinal -> ColorSpaces.Srgb
+            Named.ACES.ordinal -> ColorSpaces.Aces
+            Named.ACESCG.ordinal -> ColorSpaces.Acescg
+            Named.ADOBE_RGB.ordinal -> ColorSpaces.AdobeRgb
+            Named.BT2020.ordinal -> ColorSpaces.Bt2020
+            Named.BT709.ordinal -> ColorSpaces.Bt709
+            Named.CIE_LAB.ordinal -> ColorSpaces.CieLab
+            Named.CIE_XYZ.ordinal -> ColorSpaces.CieXyz
+            Named.DCI_P3.ordinal -> ColorSpaces.DciP3
+            Named.DISPLAY_P3.ordinal -> ColorSpaces.DisplayP3
+            Named.EXTENDED_SRGB.ordinal -> ColorSpaces.ExtendedSrgb
+            Named.LINEAR_EXTENDED_SRGB.ordinal -> ColorSpaces.LinearExtendedSrgb
+            Named.LINEAR_SRGB.ordinal -> ColorSpaces.LinearSrgb
+            Named.NTSC_1953.ordinal -> ColorSpaces.Ntsc1953
+            Named.PRO_PHOTO_RGB.ordinal -> ColorSpaces.ProPhotoRgb
+            Named.SMPTE_C.ordinal -> ColorSpaces.SmpteC
+            else -> {
+                if (this is android.graphics.ColorSpace.Rgb) {
+                    val transferParams = this.transferParameters
+                    val whitePoint = if (this.whitePoint.size == 3) {
+                        WhitePoint(this.whitePoint[0], this.whitePoint[1], this.whitePoint[2])
+                    } else {
+                        WhitePoint(this.whitePoint[0], this.whitePoint[1])
+                    }
+
+                    val composeTransferParams = if (transferParams != null) {
+                        TransferParameters(
+                            gamma = transferParams.g,
+                            a = transferParams.a,
+                            b = transferParams.b,
+                            c = transferParams.c,
+                            d = transferParams.d,
+                            e = transferParams.e,
+                            f = transferParams.f
+                        )
+                    } else {
+                        null
+                    }
+                    Rgb(
+                        name = this.name,
+                        primaries = this.primaries,
+                        whitePoint = whitePoint,
+                        transform = this.transform,
+                        oetf = { x -> this.oetf.applyAsDouble(x) },
+                        eotf = { x -> this.eotf.applyAsDouble(x) },
+                        min = this.getMinValue(0),
+                        max = this.getMaxValue(0),
+                        transferParameters = composeTransferParams,
+                        id = this.id
+                    )
+                } else {
+                    ColorSpaces.Srgb
+                }
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/compose/ui/ui-inspection/build.gradle b/compose/ui/ui-inspection/build.gradle
index b8db908..d7db14f 100644
--- a/compose/ui/ui-inspection/build.gradle
+++ b/compose/ui/ui-inspection/build.gradle
@@ -45,6 +45,7 @@
     androidTestImplementation(libs.kotlinStdlib)
     androidTestImplementation(libs.kotlinCoroutinesAndroid)
     androidTestImplementation(libs.testCore)
+    androidTestImplementation(project(":compose:foundation:foundation-layout"))
     androidTestImplementation(project(":compose:ui:ui-tooling"))
     androidTestImplementation(project(":compose:ui:ui-tooling-data"))
     androidTestImplementation(project(":compose:ui:ui"))
diff --git a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTreeTest.kt b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTreeTest.kt
index f78d114..d68d55d 100644
--- a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTreeTest.kt
+++ b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTreeTest.kt
@@ -97,7 +97,6 @@
 import kotlin.math.roundToInt
 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
@@ -165,7 +164,6 @@
         assertThat(DEBUG).isFalse()
     }
 
-    @Ignore // b/273151077
     @Test
     fun buildTree() {
         val slotTableRecord = CompositionDataRecord.create()
@@ -246,7 +244,6 @@
         }
     }
 
-    @Ignore // b/273151077
     @Test
     fun buildTreeWithTransformedText() {
         val slotTableRecord = CompositionDataRecord.create()
@@ -316,16 +313,13 @@
         val nodes = builder.convert(view)
         dumpNodes(nodes, view, builder)
 
-        if (DEBUG) {
-            validate(nodes, builder) {
-                node("Box", children = listOf("ModalDrawer"))
-                node("ModalDrawer", children = listOf("Column", "Text"))
-                node("Column", children = listOf("Text", "Button"))
-                node("Text")
-                node("Button", children = listOf("Text"))
-                node("Text")
-                node("Text")
-            }
+        validate(nodes, builder) {
+            node("ModalDrawer", isRenderNode = true, children = listOf("Column", "Text"))
+            node("Column", inlined = true, children = listOf("Text", "Button"))
+            node("Text", isRenderNode = true)
+            node("Button", isRenderNode = true, children = listOf("Text"))
+            node("Text", isRenderNode = true)
+            node("Text", isRenderNode = true)
         }
         assertThat(nodes.size).isEqualTo(1)
     }
@@ -357,7 +351,6 @@
 
         if (DEBUG) {
             validate(nodes, builder) {
-                node("Box", children = listOf("ModalDrawer"))
                 node("ModalDrawer", children = listOf("WithConstraints"))
                 node("WithConstraints", children = listOf("SubcomposeLayout"))
                 node("SubcomposeLayout", children = listOf("Box"))
@@ -468,7 +461,6 @@
         assertThat(node?.id).isGreaterThan(0)
     }
 
-    @Ignore // b/273151077
     @Test
     fun testSemantics() {
         val slotTableRecord = CompositionDataRecord.create()
@@ -521,7 +513,6 @@
         }
     }
 
-    @Ignore // b/273151077
     @Test
     fun testDialog() {
         val slotTableRecord = CompositionDataRecord.create()
@@ -594,7 +585,6 @@
         }
     }
 
-    @Ignore // b/273151077
     @Test
     fun testPopup() {
         val slotTableRecord = CompositionDataRecord.create()
@@ -826,7 +816,6 @@
     }
     // WARNING: End formatted section
 
-    @Ignore // b/273151077
     @Test
     fun testLineNumbers() {
         // WARNING: The formatting of the lines below here affect test results.
@@ -1038,6 +1027,7 @@
             assertWithMessage("No such node found: $name").that(nodeIterator.hasNext()).isTrue()
             val node = nodeIterator.next()
             assertThat(node.name).isEqualTo(name)
+            assertThat(node.anchorId).isNotEqualTo(UNDEFINED_ID)
             val message = "Node: $name"
             assertWithMessage(message).that(node.children.map { it.name })
                 .containsExactlyElementsIn(children).inOrder()
diff --git a/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/InspectorNode.kt b/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/InspectorNode.kt
index 4819ad7..2dd9d34 100644
--- a/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/InspectorNode.kt
+++ b/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/InspectorNode.kt
@@ -230,7 +230,10 @@
 
     fun shallowCopy(node: InspectorNode): MutableInspectorNode = apply {
         id = node.id
-        viewId = node.viewId
+        key = node.key
+        anchorId = node.anchorId
+        mergedSemantics.addAll(node.mergedSemantics)
+        unmergedSemantics.addAll(node.unmergedSemantics)
         name = node.name
         fileName = node.fileName
         packageHash = node.packageHash
@@ -240,9 +243,8 @@
         box = node.box
         bounds = node.bounds
         inlined = node.inlined
-        mergedSemantics.addAll(node.mergedSemantics)
-        unmergedSemantics.addAll(node.unmergedSemantics)
         parameters.addAll(node.parameters)
+        viewId = node.viewId
         children.addAll(node.children)
     }
 
diff --git a/compose/ui/ui-test-junit4/api/current.txt b/compose/ui/ui-test-junit4/api/current.txt
index 94a0fe4..d860c74 100644
--- a/compose/ui/ui-test-junit4/api/current.txt
+++ b/compose/ui/ui-test-junit4/api/current.txt
@@ -12,8 +12,8 @@
     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 <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();
@@ -45,8 +45,8 @@
     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 <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);
diff --git a/compose/ui/ui-test-junit4/api/public_plus_experimental_current.txt b/compose/ui/ui-test-junit4/api/public_plus_experimental_current.txt
index 53f3965..2dfc3a1 100644
--- a/compose/ui/ui-test-junit4/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-test-junit4/api/public_plus_experimental_current.txt
@@ -10,7 +10,7 @@
     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);
+    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;
   }
@@ -20,8 +20,8 @@
     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 <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();
@@ -68,8 +68,8 @@
     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 <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();
@@ -109,8 +109,8 @@
     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 <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);
diff --git a/compose/ui/ui-test-junit4/api/restricted_current.txt b/compose/ui/ui-test-junit4/api/restricted_current.txt
index 94a0fe4..d860c74 100644
--- a/compose/ui/ui-test-junit4/api/restricted_current.txt
+++ b/compose/ui/ui-test-junit4/api/restricted_current.txt
@@ -12,8 +12,8 @@
     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 <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();
@@ -45,8 +45,8 @@
     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 <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);
diff --git a/compose/ui/ui-test/api/api_lint.ignore b/compose/ui/ui-test/api/api_lint.ignore
index 4eff534..7466e22 100644
--- a/compose/ui/ui-test/api/api_lint.ignore
+++ b/compose/ui/ui-test/api/api_lint.ignore
@@ -1,3 +1,5 @@
 // Baseline format: 1.0
-GetterSetterNames: androidx.compose.ui.test.MainTestClock#getAutoAdvance():
-    Symmetric method for `setAutoAdvance` must be named `isAutoAdvance`; was `getAutoAdvance`
+GetterSetterNames: androidx.compose.ui.test.TestMonotonicFrameClock#getHasAwaiters():
+    Getter for boolean property `hasAwaiters` is named `getHasAwaiters` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field MainTestClock.autoAdvance:
+    Invalid name for boolean property `autoAdvance`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/compose/ui/ui-test/api/current.ignore b/compose/ui/ui-test/api/current.ignore
index 6cf936b..5af1fc7 100644
--- a/compose/ui/ui-test/api/current.ignore
+++ b/compose/ui/ui-test/api/current.ignore
@@ -5,6 +5,10 @@
     Method androidx.compose.ui.test.ActionsKt.performSemanticsAction has changed return type from androidx.compose.ui.test.SemanticsNodeInteraction to void
 
 
+InvalidNullConversion: androidx.compose.ui.test.SemanticsMatcher.Companion#expectValue(androidx.compose.ui.semantics.SemanticsPropertyKey<T>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter expectedValue in androidx.compose.ui.test.SemanticsMatcher.Companion.expectValue(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T expectedValue)
+
+
 RemovedDeprecatedMethod: androidx.compose.ui.test.ActionsKt#performSemanticsActionUnit(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<T>>, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>):
     Removed deprecated method androidx.compose.ui.test.ActionsKt.performSemanticsActionUnit(androidx.compose.ui.test.SemanticsNodeInteraction,androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<T>>,kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>)
 RemovedDeprecatedMethod: androidx.compose.ui.test.ActionsKt#performSemanticsActionUnit(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<? extends java.lang.Boolean>>>):
diff --git a/compose/ui/ui-test/api/current.txt b/compose/ui/ui-test/api/current.txt
index 684e9c8..88c2a89 100644
--- a/compose/ui/ui-test/api/current.txt
+++ b/compose/ui/ui-test/api/current.txt
@@ -305,7 +305,7 @@
   }
 
   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 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);
   }
diff --git a/compose/ui/ui-test/api/public_plus_experimental_current.txt b/compose/ui/ui-test/api/public_plus_experimental_current.txt
index 219da1d..304fcbb 100644
--- a/compose/ui/ui-test/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-test/api/public_plus_experimental_current.txt
@@ -384,7 +384,7 @@
   }
 
   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 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);
   }
@@ -437,7 +437,7 @@
   @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);
+    method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
     property public abstract androidx.compose.ui.test.MainTestClock mainClock;
   }
 
diff --git a/compose/ui/ui-test/api/restricted_current.ignore b/compose/ui/ui-test/api/restricted_current.ignore
index 6cf936b..5af1fc7 100644
--- a/compose/ui/ui-test/api/restricted_current.ignore
+++ b/compose/ui/ui-test/api/restricted_current.ignore
@@ -5,6 +5,10 @@
     Method androidx.compose.ui.test.ActionsKt.performSemanticsAction has changed return type from androidx.compose.ui.test.SemanticsNodeInteraction to void
 
 
+InvalidNullConversion: androidx.compose.ui.test.SemanticsMatcher.Companion#expectValue(androidx.compose.ui.semantics.SemanticsPropertyKey<T>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter expectedValue in androidx.compose.ui.test.SemanticsMatcher.Companion.expectValue(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T expectedValue)
+
+
 RemovedDeprecatedMethod: androidx.compose.ui.test.ActionsKt#performSemanticsActionUnit(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<T>>, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>):
     Removed deprecated method androidx.compose.ui.test.ActionsKt.performSemanticsActionUnit(androidx.compose.ui.test.SemanticsNodeInteraction,androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<T>>,kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>)
 RemovedDeprecatedMethod: androidx.compose.ui.test.ActionsKt#performSemanticsActionUnit(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<? extends java.lang.Boolean>>>):
diff --git a/compose/ui/ui-test/api/restricted_current.txt b/compose/ui/ui-test/api/restricted_current.txt
index 1305308..e62c3ee 100644
--- a/compose/ui/ui-test/api/restricted_current.txt
+++ b/compose/ui/ui-test/api/restricted_current.txt
@@ -306,7 +306,7 @@
   }
 
   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 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);
   }
diff --git a/compose/ui/ui-text-google-fonts/api/api_lint.ignore b/compose/ui/ui-text-google-fonts/api/api_lint.ignore
new file mode 100644
index 0000000..1cf64ad
--- /dev/null
+++ b/compose/ui/ui-text-google-fonts/api/api_lint.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+GetterSetterNames: field GoogleFont.bestEffort:
+    Invalid name for boolean property `bestEffort`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/compose/ui/ui-text/api/api_lint.ignore b/compose/ui/ui-text/api/api_lint.ignore
index 65c788e..734b4f8 100644
--- a/compose/ui/ui-text/api/api_lint.ignore
+++ b/compose/ui/ui-text/api/api_lint.ignore
@@ -25,6 +25,36 @@
     Getter should be on the built object, not the builder: method androidx.compose.ui.text.AnnotatedString.Builder.getLength()
 
 
+GetterSetterNames: androidx.compose.ui.text.MultiParagraphIntrinsics#getHasStaleResolvedFonts():
+    Getter for boolean property `hasStaleResolvedFonts` is named `getHasStaleResolvedFonts` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.text.ParagraphIntrinsics#getHasStaleResolvedFonts():
+    Getter for boolean property `hasStaleResolvedFonts` is named `getHasStaleResolvedFonts` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.text.TextLayoutResult#getHasVisualOverflow():
+    Getter for boolean property `hasVisualOverflow` is named `getHasVisualOverflow` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field FontVariation.Setting.needsDensity:
+    Invalid name for boolean property `needsDensity`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ImeOptions.autoCorrect:
+    Invalid name for boolean property `autoCorrect`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ImeOptions.singleLine:
+    Invalid name for boolean property `singleLine`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field MultiParagraph.didExceedMaxLines:
+    Invalid name for boolean property `didExceedMaxLines`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Paragraph.didExceedMaxLines:
+    Invalid name for boolean property `didExceedMaxLines`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PlatformParagraphStyle.includeFontPadding:
+    Invalid name for boolean property `includeFontPadding`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field TextLayoutInput.softWrap:
+    Invalid name for boolean property `softWrap`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field TextLayoutResult.didOverflowHeight:
+    Invalid name for boolean property `didOverflowHeight`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field TextLayoutResult.didOverflowWidth:
+    Invalid name for boolean property `didOverflowWidth`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field TextRange.collapsed:
+    Invalid name for boolean property `collapsed`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field TextRange.reversed:
+    Invalid name for boolean property `reversed`. Should start with one of `has`, `can`, `should`, `is`.
+
+
 KotlinDefaultParameterOrder: androidx.compose.ui.text.ParagraphIntrinsicsKt#ParagraphIntrinsics(String, androidx.compose.ui.text.TextStyle, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.SpanStyle>>, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>>, androidx.compose.ui.unit.Density, androidx.compose.ui.text.font.FontFamily.Resolver) parameter #2:
     Parameter `spanStyles` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
 KotlinDefaultParameterOrder: androidx.compose.ui.text.ParagraphIntrinsicsKt#ParagraphIntrinsics(String, androidx.compose.ui.text.TextStyle, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.SpanStyle>>, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>>, androidx.compose.ui.unit.Density, androidx.compose.ui.text.font.FontFamily.Resolver) parameter #3:
diff --git a/compose/ui/ui-text/api/current.ignore b/compose/ui/ui-text/api/current.ignore
index ae0c856..7670599 100644
--- a/compose/ui/ui-text/api/current.ignore
+++ b/compose/ui/ui-text/api/current.ignore
@@ -3,5 +3,11 @@
     Method androidx.compose.ui.text.AnnotatedString.Builder.append has changed return type from androidx.compose.ui.text.AnnotatedString.Builder to void
 
 
+InvalidNullConversion: androidx.compose.ui.text.AnnotatedString.Range#Range(T, int, int) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter item in androidx.compose.ui.text.AnnotatedString.Range(T item, int start, int end)
+InvalidNullConversion: androidx.compose.ui.text.AnnotatedString.Range#Range(T, int, int, String) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter item in androidx.compose.ui.text.AnnotatedString.Range(T item, int start, int end, String tag)
+
+
 RemovedDeprecatedMethod: androidx.compose.ui.text.AnnotatedString.Builder#deprecated_append_returning_void(char):
     Removed deprecated method androidx.compose.ui.text.AnnotatedString.Builder.deprecated_append_returning_void(char)
diff --git a/compose/ui/ui-text/api/current.txt b/compose/ui/ui-text/api/current.txt
index 5438f14..f05e380 100644
--- a/compose/ui/ui-text/api/current.txt
+++ b/compose/ui/ui-text/api/current.txt
@@ -52,19 +52,19 @@
   }
 
   @androidx.compose.runtime.Immutable public static final class AnnotatedString.Range<T> {
-    ctor public AnnotatedString.Range(T? item, int start, int end, String tag);
-    ctor public AnnotatedString.Range(T? item, int start, int end);
-    method public T! component1();
+    ctor public AnnotatedString.Range(T item, int start, int end, String tag);
+    ctor public AnnotatedString.Range(T item, int start, int end);
+    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 T getItem();
     method public int getStart();
     method public String getTag();
     property public final int end;
-    property public final T! item;
+    property public final T item;
     property public final int start;
     property public final String tag;
   }
diff --git a/compose/ui/ui-text/api/public_plus_experimental_current.txt b/compose/ui/ui-text/api/public_plus_experimental_current.txt
index 60ccba7..c7477c0 100644
--- a/compose/ui/ui-text/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-text/api/public_plus_experimental_current.txt
@@ -56,19 +56,19 @@
   }
 
   @androidx.compose.runtime.Immutable public static final class AnnotatedString.Range<T> {
-    ctor public AnnotatedString.Range(T? item, int start, int end, String tag);
-    ctor public AnnotatedString.Range(T? item, int start, int end);
-    method public T! component1();
+    ctor public AnnotatedString.Range(T item, int start, int end, String tag);
+    ctor public AnnotatedString.Range(T item, int start, int end);
+    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 T getItem();
     method public int getStart();
     method public String getTag();
     property public final int end;
-    property public final T! item;
+    property public final T item;
     property public final int start;
     property public final String tag;
   }
diff --git a/compose/ui/ui-text/api/restricted_current.ignore b/compose/ui/ui-text/api/restricted_current.ignore
index ae0c856..7670599 100644
--- a/compose/ui/ui-text/api/restricted_current.ignore
+++ b/compose/ui/ui-text/api/restricted_current.ignore
@@ -3,5 +3,11 @@
     Method androidx.compose.ui.text.AnnotatedString.Builder.append has changed return type from androidx.compose.ui.text.AnnotatedString.Builder to void
 
 
+InvalidNullConversion: androidx.compose.ui.text.AnnotatedString.Range#Range(T, int, int) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter item in androidx.compose.ui.text.AnnotatedString.Range(T item, int start, int end)
+InvalidNullConversion: androidx.compose.ui.text.AnnotatedString.Range#Range(T, int, int, String) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter item in androidx.compose.ui.text.AnnotatedString.Range(T item, int start, int end, String tag)
+
+
 RemovedDeprecatedMethod: androidx.compose.ui.text.AnnotatedString.Builder#deprecated_append_returning_void(char):
     Removed deprecated method androidx.compose.ui.text.AnnotatedString.Builder.deprecated_append_returning_void(char)
diff --git a/compose/ui/ui-text/api/restricted_current.txt b/compose/ui/ui-text/api/restricted_current.txt
index 5438f14..f05e380 100644
--- a/compose/ui/ui-text/api/restricted_current.txt
+++ b/compose/ui/ui-text/api/restricted_current.txt
@@ -52,19 +52,19 @@
   }
 
   @androidx.compose.runtime.Immutable public static final class AnnotatedString.Range<T> {
-    ctor public AnnotatedString.Range(T? item, int start, int end, String tag);
-    ctor public AnnotatedString.Range(T? item, int start, int end);
-    method public T! component1();
+    ctor public AnnotatedString.Range(T item, int start, int end, String tag);
+    ctor public AnnotatedString.Range(T item, int start, int end);
+    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 T getItem();
     method public int getStart();
     method public String getTag();
     property public final int end;
-    property public final T! item;
+    property public final T item;
     property public final int start;
     property public final String tag;
   }
diff --git a/compose/ui/ui-tooling-data/api/api_lint.ignore b/compose/ui/ui-tooling-data/api/api_lint.ignore
new file mode 100644
index 0000000..1d26bba
--- /dev/null
+++ b/compose/ui/ui-tooling-data/api/api_lint.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+GetterSetterNames: field ParameterInformation.compared:
+    Invalid name for boolean property `compared`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ParameterInformation.fromDefault:
+    Invalid name for boolean property `fromDefault`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ParameterInformation.stable:
+    Invalid name for boolean property `stable`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ParameterInformation.static:
+    Invalid name for boolean property `static`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/compose/ui/ui-tooling-preview/api/api_lint.ignore b/compose/ui/ui-tooling-preview/api/api_lint.ignore
new file mode 100644
index 0000000..c8656ca
--- /dev/null
+++ b/compose/ui/ui-tooling-preview/api/api_lint.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+GetterSetterNames: field Preview.showBackground:
+    Invalid name for boolean property `showBackground`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Preview.showSystemUi:
+    Invalid name for boolean property `showSystemUi`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/compose/ui/ui-tooling/api/current.ignore b/compose/ui/ui-tooling/api/current.ignore
new file mode 100644
index 0000000..5b8f04a
--- /dev/null
+++ b/compose/ui/ui-tooling/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.ui.tooling.animation.ToolingState#ToolingState(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter default in androidx.compose.ui.tooling.animation.ToolingState(T default)
diff --git a/compose/ui/ui-tooling/api/current.txt b/compose/ui/ui-tooling/api/current.txt
index 94b79be..486b41e 100644
--- a/compose/ui/ui-tooling/api/current.txt
+++ b/compose/ui/ui-tooling/api/current.txt
@@ -10,10 +10,10 @@
 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();
+    ctor public ToolingState(T default);
+    method public T getValue();
     method public void setValue(T!);
-    property public T! value;
+    property public T value;
   }
 
 }
diff --git a/compose/ui/ui-tooling/api/public_plus_experimental_current.txt b/compose/ui/ui-tooling/api/public_plus_experimental_current.txt
index e9656ce..df56c2d 100644
--- a/compose/ui/ui-tooling/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-tooling/api/public_plus_experimental_current.txt
@@ -15,10 +15,10 @@
 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();
+    ctor public ToolingState(T default);
+    method public T getValue();
     method public void setValue(T!);
-    property public T! value;
+    property public T value;
   }
 
 }
diff --git a/compose/ui/ui-tooling/api/restricted_current.ignore b/compose/ui/ui-tooling/api/restricted_current.ignore
new file mode 100644
index 0000000..5b8f04a
--- /dev/null
+++ b/compose/ui/ui-tooling/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.ui.tooling.animation.ToolingState#ToolingState(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter default in androidx.compose.ui.tooling.animation.ToolingState(T default)
diff --git a/compose/ui/ui-tooling/api/restricted_current.txt b/compose/ui/ui-tooling/api/restricted_current.txt
index 94b79be..486b41e 100644
--- a/compose/ui/ui-tooling/api/restricted_current.txt
+++ b/compose/ui/ui-tooling/api/restricted_current.txt
@@ -10,10 +10,10 @@
 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();
+    ctor public ToolingState(T default);
+    method public T getValue();
     method public void setValue(T!);
-    property public T! value;
+    property public T value;
   }
 
 }
diff --git a/compose/ui/ui-unit/api/api_lint.ignore b/compose/ui/ui-unit/api/api_lint.ignore
index c473df8..2865c78 100644
--- a/compose/ui/ui-unit/api/api_lint.ignore
+++ b/compose/ui/ui-unit/api/api_lint.ignore
@@ -1,3 +1,13 @@
 // Baseline format: 1.0
+GetterSetterNames: androidx.compose.ui.unit.Constraints#getHasBoundedHeight():
+    Getter for boolean property `hasBoundedHeight` is named `getHasBoundedHeight` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.unit.Constraints#getHasBoundedWidth():
+    Getter for boolean property `hasBoundedWidth` is named `getHasBoundedWidth` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.unit.Constraints#getHasFixedHeight():
+    Getter for boolean property `hasFixedHeight` is named `getHasFixedHeight` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.unit.Constraints#getHasFixedWidth():
+    Getter for boolean property `hasFixedWidth` is named `getHasFixedWidth` but should match the property name. Use `@get:JvmName` to rename.
+
+
 KotlinOperator: androidx.compose.ui.unit.IntRect#contains(long):
     Note that adding the `operator` keyword would allow calling this method using operator syntax
diff --git a/compose/ui/ui-util/api/current.txt b/compose/ui/ui-util/api/current.txt
index e80820a..5e5e30e 100644
--- a/compose/ui/ui-util/api/current.txt
+++ b/compose/ui/ui-util/api/current.txt
@@ -2,7 +2,7 @@
 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);
+    method public static inline <T> T trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
   }
 
   public final class InlineClassHelperKt {
diff --git a/compose/ui/ui-util/api/public_plus_experimental_current.txt b/compose/ui/ui-util/api/public_plus_experimental_current.txt
index e80820a..5e5e30e 100644
--- a/compose/ui/ui-util/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-util/api/public_plus_experimental_current.txt
@@ -2,7 +2,7 @@
 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);
+    method public static inline <T> T trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
   }
 
   public final class InlineClassHelperKt {
diff --git a/compose/ui/ui-util/api/restricted_current.txt b/compose/ui/ui-util/api/restricted_current.txt
index e80820a..5e5e30e 100644
--- a/compose/ui/ui-util/api/restricted_current.txt
+++ b/compose/ui/ui-util/api/restricted_current.txt
@@ -2,7 +2,7 @@
 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);
+    method public static inline <T> T trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
   }
 
   public final class InlineClassHelperKt {
diff --git a/compose/ui/ui-viewbinding/api/current.txt b/compose/ui/ui-viewbinding/api/current.txt
index 07ba909..00c3178 100644
--- a/compose/ui/ui-viewbinding/api/current.txt
+++ b/compose/ui/ui-viewbinding/api/current.txt
@@ -3,6 +3,7 @@
 
   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-viewbinding/api/public_plus_experimental_current.txt b/compose/ui/ui-viewbinding/api/public_plus_experimental_current.txt
index 07ba909..00c3178 100644
--- a/compose/ui/ui-viewbinding/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-viewbinding/api/public_plus_experimental_current.txt
@@ -3,6 +3,7 @@
 
   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-viewbinding/api/restricted_current.txt b/compose/ui/ui-viewbinding/api/restricted_current.txt
index 07ba909..00c3178 100644
--- a/compose/ui/ui-viewbinding/api/restricted_current.txt
+++ b/compose/ui/ui-viewbinding/api/restricted_current.txt
@@ -3,6 +3,7 @@
 
   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-viewbinding/samples/build.gradle b/compose/ui/ui-viewbinding/samples/build.gradle
index 6510bbb..29fab3b 100644
--- a/compose/ui/ui-viewbinding/samples/build.gradle
+++ b/compose/ui/ui-viewbinding/samples/build.gradle
@@ -40,6 +40,7 @@
     androidTestImplementation(libs.testRunner)
     androidTestImplementation(libs.junit)
     androidTestImplementation(libs.truth)
+    androidTestImplementation(libs.espressoCore)
 }
 
 androidx {
diff --git a/compose/ui/ui-viewbinding/samples/src/androidTest/java/androidx/compose/ui/samples/ReusableAndroidViewBindingTest.kt b/compose/ui/ui-viewbinding/samples/src/androidTest/java/androidx/compose/ui/samples/ReusableAndroidViewBindingTest.kt
new file mode 100644
index 0000000..2561853
--- /dev/null
+++ b/compose/ui/ui-viewbinding/samples/src/androidTest/java/androidx/compose/ui/samples/ReusableAndroidViewBindingTest.kt
@@ -0,0 +1,343 @@
+/*
+ * 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.samples
+
+import android.widget.Button
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.heightIn
+import androidx.compose.foundation.text.BasicText
+import androidx.compose.runtime.ReusableContent
+import androidx.compose.runtime.ReusableContentHost
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.movableContentOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.test.junit4.createAndroidComposeRule
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.viewbinding.samples.R
+import androidx.compose.ui.viewbinding.samples.databinding.SampleButtonLayoutBinding
+import androidx.compose.ui.viewbinding.samples.databinding.TestFragmentLayoutBinding
+import androidx.compose.ui.viewinterop.AndroidViewBinding
+import androidx.test.espresso.Espresso.onView
+import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
+import androidx.test.espresso.assertion.ViewAssertions.matches
+import androidx.test.espresso.matcher.ViewMatchers.Visibility.VISIBLE
+import androidx.test.espresso.matcher.ViewMatchers.withClassName
+import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
+import androidx.test.espresso.matcher.ViewMatchers.withId
+import androidx.test.espresso.matcher.ViewMatchers.withText
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import org.hamcrest.Matchers.`is`
+import org.junit.Assert.assertEquals
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class ReusableAndroidViewBindingTest {
+
+    @get:Rule
+    val rule = createAndroidComposeRule<EmptyFragmentActivity>()
+
+    @Test
+    fun testViewIsReused_whenMovedAndUpdated() {
+        val events = mutableListOf<String>()
+        var slotWithContent by mutableStateOf(0)
+        val movableContext = movableContentOf {
+            AndroidViewBinding(
+                factory = { inflater, parent, attachToParent ->
+                    events += "inflate"
+                    SampleButtonLayoutBinding.inflate(inflater, parent, attachToParent)
+                },
+                modifier = Modifier.heightIn(max = 200.dp),
+                onReset = {
+                    events += "reset"
+                    myButton.text = null
+                },
+                onRelease = { events += "release" },
+                update = {
+                    events += "update"
+                    myButton.text = "Button in slot $slotWithContent"
+                }
+            )
+        }
+
+        rule.setContent {
+            Column {
+                repeat(10) { slot ->
+                    if (slot == slotWithContent) {
+                        ReusableContent(Unit) {
+                            movableContext()
+                        }
+                    } else {
+                        BasicText("Slot $slot")
+                    }
+                }
+            }
+        }
+
+        onView(withClassName(`is`(ButtonFqClassName)))
+            .check(matches(withText("Button in slot 0")))
+            .check(matches(withEffectiveVisibility(VISIBLE)))
+
+        assertEquals(
+            "Binding did not experience the expected event sequence when being " +
+                "initialized in its first position",
+            listOf("inflate", "update"),
+            events
+        )
+
+        events.clear()
+        slotWithContent++
+
+        onView(withClassName(`is`(ButtonFqClassName)))
+            .check(matches(withText("Button in slot 1")))
+            .check(matches(withEffectiveVisibility(VISIBLE)))
+
+        assertEquals(
+            "Binding did not experience expected events when moving to its new position " +
+                "when the moved content is updated via composition",
+            listOf("update"),
+            events
+        )
+    }
+
+    @Test
+    fun testViewIsReusedAndReleased_whenDeactivatedOrRemovedAndUpdated() {
+        val events = mutableListOf<String>()
+        var includeContent by mutableStateOf(true)
+        var enableContent by mutableStateOf(true)
+
+        rule.setContent {
+            if (includeContent) {
+                ReusableContentHost(enableContent) {
+                    AndroidViewBinding(
+                        factory = { inflater, parent, attachToParent ->
+                            events += "inflate"
+                            SampleButtonLayoutBinding.inflate(inflater, parent, attachToParent)
+                        },
+                        modifier = Modifier.heightIn(max = 200.dp),
+                        onReset = {
+                            events += "reset"
+                            myButton.text = null
+                        },
+                        onRelease = { events += "release" },
+                        update = {
+                            events += "update"
+                            myButton.text = "My Button"
+                        }
+                    )
+                }
+            }
+        }
+
+        onView(withClassName(`is`(ButtonFqClassName)))
+            .check(matches(withText("My Button")))
+            .check(matches(withEffectiveVisibility(VISIBLE)))
+
+        assertEquals(
+            "Binding did not experience the expected event sequence when being " +
+                "created for the first time",
+            listOf("inflate", "update"),
+            events
+        )
+
+        events.clear()
+        includeContent = false
+
+        onView(withClassName(`is`(ButtonFqClassName)))
+            .check(doesNotExist())
+
+        assertEquals(
+            "Binding should be released when its containing group is removed from composition",
+            listOf("release"),
+            events
+        )
+
+        events.clear()
+        includeContent = true
+
+        onView(withClassName(`is`(ButtonFqClassName)))
+            .check(matches(withText("My Button")))
+            .check(matches(withEffectiveVisibility(VISIBLE)))
+
+        assertEquals(
+            "Binding should re-experience its creation lifecycle when its previously removed " +
+                "group is re-added to the composition",
+            listOf("inflate", "update"),
+            events
+        )
+
+        events.clear()
+        enableContent = false
+
+        onView(withClassName(`is`(ButtonFqClassName)))
+            .check(doesNotExist())
+
+        assertEquals(
+            "Binding should be reset when its parent ReusableContentHost is deactivated",
+            listOf("reset"),
+            events
+        )
+
+        events.clear()
+        enableContent = true
+
+        onView(withClassName(`is`(ButtonFqClassName)))
+            .check(matches(withText("My Button")))
+            .check(matches(withEffectiveVisibility(VISIBLE)))
+
+        assertEquals(
+            "Binding should be re-awoken when its parent ReusableContentHost becomes active again",
+            listOf("update"),
+            events
+        )
+    }
+
+    @Test
+    fun testFragmentIsReused_whenMoved() {
+        val events = mutableListOf<String>()
+        var slotWithContent by mutableStateOf(0)
+        val movableContext = movableContentOf {
+            AndroidViewBinding(
+                factory = { inflater, parent, attachToParent ->
+                    events += "inflate"
+                    TestFragmentLayoutBinding.inflate(inflater, parent, attachToParent)
+                },
+                modifier = Modifier.heightIn(max = 200.dp),
+                onReset = { events += "reset" },
+                onRelease = { events += "release" },
+                update = { events += "update" }
+            )
+        }
+
+        rule.setContent {
+            Column {
+                repeat(10) { slot ->
+                    if (slot == slotWithContent) {
+                        ReusableContent(Unit) {
+                            movableContext()
+                        }
+                    } else {
+                        BasicText("Slot $slot")
+                    }
+                }
+            }
+        }
+
+        waitForIdleSync()
+
+        assertEquals(
+            "Binding did not experience the expected event sequence when being " +
+                "initialized in its first position",
+            listOf("inflate", "update"),
+            events
+        )
+
+        events.clear()
+        slotWithContent++
+        waitForIdleSync()
+
+        assertEquals(
+            "Binding should not experience any events when moving to its new position",
+            emptyList<String>(),
+            events
+        )
+    }
+
+    @Test
+    fun testFragmentIsReusedAndReleased_whenDeactivatedOrRemoved() {
+        val events = mutableListOf<String>()
+        var includeContent by mutableStateOf(true)
+        var enableContent by mutableStateOf(true)
+
+        rule.setContent {
+            if (includeContent) {
+                ReusableContentHost(enableContent) {
+                    AndroidViewBinding(
+                        factory = { inflater, parent, attachToParent ->
+                            events += "inflate"
+                            TestFragmentLayoutBinding.inflate(inflater, parent, attachToParent)
+                        },
+                        modifier = Modifier.heightIn(max = 200.dp),
+                        onReset = { events += "reset" },
+                        onRelease = { events += "release" },
+                        update = { events += "update" }
+                    )
+                }
+            }
+        }
+
+        onView(withId(R.id.fragment_layout)).check(matches(withEffectiveVisibility(VISIBLE)))
+        assertEquals(
+            "Binding did not experience the expected event sequence when being " +
+                "created for the first time",
+            listOf("inflate", "update"),
+            events
+        )
+
+        events.clear()
+        includeContent = false
+
+        onView(withId(R.id.fragment_layout)).check(doesNotExist())
+        assertEquals(
+            "Binding should be released when its containing group is removed from composition",
+            listOf("release"),
+            events
+        )
+
+        events.clear()
+        includeContent = true
+
+        onView(withId(R.id.fragment_layout)).check(matches(withEffectiveVisibility(VISIBLE)))
+        assertEquals(
+            "Binding should re-experience its creation lifecycle when its previously removed " +
+                "group is re-added to the composition",
+            listOf("inflate", "update"),
+            events
+        )
+
+        events.clear()
+        enableContent = false
+
+        onView(withId(R.id.fragment_layout)).check(doesNotExist())
+        assertEquals(
+            "Binding should be reset when its parent ReusableContentHost is deactivated",
+            listOf("reset"),
+            events
+        )
+
+        events.clear()
+        enableContent = true
+
+        onView(withId(R.id.fragment_layout)).check(matches(withEffectiveVisibility(VISIBLE)))
+        assertEquals(
+            "Binding should be re-awoken when its parent ReusableContentHost becomes active again",
+            listOf("update"),
+            events
+        )
+    }
+
+    private fun waitForIdleSync() = rule.runOnIdle { /* Do nothing. */ }
+
+    companion object {
+        private val ButtonFqClassName = Button::class.qualifiedName!!
+    }
+}
\ No newline at end of file
diff --git a/compose/ui/ui-viewbinding/samples/src/main/java/androidx/compose/ui/samples/AndroidViewBindingSample.kt b/compose/ui/ui-viewbinding/samples/src/main/java/androidx/compose/ui/samples/AndroidViewBindingSample.kt
index 1555523..67baa43 100644
--- a/compose/ui/ui-viewbinding/samples/src/main/java/androidx/compose/ui/samples/AndroidViewBindingSample.kt
+++ b/compose/ui/ui-viewbinding/samples/src/main/java/androidx/compose/ui/samples/AndroidViewBindingSample.kt
@@ -19,6 +19,8 @@
 import android.graphics.Color
 import androidx.annotation.Sampled
 import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.viewbinding.samples.databinding.SampleButtonLayoutBinding
 import androidx.compose.ui.viewbinding.samples.databinding.SampleLayoutBinding
 import androidx.compose.ui.viewinterop.AndroidViewBinding
 
@@ -30,4 +32,28 @@
     AndroidViewBinding(SampleLayoutBinding::inflate) {
         second.setBackgroundColor(Color.GRAY)
     }
+}
+
+@Sampled
+@Composable
+fun AndroidViewBindingReusableSample() {
+    @Composable
+    fun MyButton(
+        label: String,
+        action: () -> Unit,
+        modifier: Modifier = Modifier
+    ) {
+        AndroidViewBinding(
+            SampleButtonLayoutBinding::inflate,
+            modifier = modifier,
+            onReset = {
+                // Null out the OnClickListener to avoid leaking the `action` lambda.
+                myButton.setOnClickListener(null)
+            },
+            update = {
+                myButton.text = label
+                myButton.setOnClickListener { action() }
+            }
+        )
+    }
 }
\ No newline at end of file
diff --git a/compose/ui/ui-viewbinding/samples/src/main/res/layout/sample_button_layout.xml b/compose/ui/ui-viewbinding/samples/src/main/res/layout/sample_button_layout.xml
new file mode 100644
index 0000000..00f137a
--- /dev/null
+++ b/compose/ui/ui-viewbinding/samples/src/main/res/layout/sample_button_layout.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:orientation="vertical"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+    <Button android:id="@+id/my_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        tools:text="My Button" />
+</LinearLayout>
\ No newline at end of file
diff --git a/compose/ui/ui-viewbinding/samples/src/main/res/layout/sample_layout.xml b/compose/ui/ui-viewbinding/samples/src/main/res/layout/sample_layout.xml
index 85ba5ee..5a4a9f9 100644
--- a/compose/ui/ui-viewbinding/samples/src/main/res/layout/sample_layout.xml
+++ b/compose/ui/ui-viewbinding/samples/src/main/res/layout/sample_layout.xml
@@ -16,6 +16,7 @@
   -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/fragment_layout"
     android:orientation="vertical"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content">
diff --git a/compose/ui/ui-viewbinding/src/main/java/androidx/compose/ui/viewinterop/AndroidViewBinding.kt b/compose/ui/ui-viewbinding/src/main/java/androidx/compose/ui/viewinterop/AndroidViewBinding.kt
index 145df82..1424583 100644
--- a/compose/ui/ui-viewbinding/src/main/java/androidx/compose/ui/viewinterop/AndroidViewBinding.kt
+++ b/compose/ui/ui-viewbinding/src/main/java/androidx/compose/ui/viewinterop/AndroidViewBinding.kt
@@ -16,20 +16,17 @@
 
 package androidx.compose.ui.viewinterop
 
-import android.content.Context
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.FrameLayout
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
-import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.ReusableContentHost
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.node.Ref
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.platform.LocalView
-import androidx.compose.ui.util.fastForEach
+import androidx.compose.ui.viewbinding.R
 import androidx.core.view.forEach
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.FragmentActivity
@@ -49,19 +46,115 @@
  * the block will be reexecuted to set the new properties. Note the block will also be ran once
  * right after the [factory] block completes.
  *
+ * This overload of [AndroidViewBinding] does not automatically pool or reuse Views and their
+ * bindings. If placed inside of a reusable container (including inside a
+ * [LazyRow][androidx.compose.foundation.lazy.LazyRow] or
+ * [LazyColumn][androidx.compose.foundation.lazy.LazyColumn]), the View instances and their
+ * bindings will always be discarded and recreated if the composition hierarchy containing the
+ * `AndroidViewBinding` changes, even if its group structure did not change and the `View` and its
+ * binding could have conceivably been reused.
+ *
+ * To opt-in for View reuse, call the overload of [AndroidViewBinding] that accepts an `onReset`
+ * callback, and provide a non-null implementation for this callback. Since it is expensive to
+ * discard and recreate View instances, reusing Views can lead to noticeable performance
+ * improvements — especially when building a scrolling list of [AndroidViews][AndroidView]. It is
+ * highly recommended to opt-in to View reuse when possible.
+ *
+ * There is generally no need to opt-in for reuse when using an `AndroidViewBinding` to host a
+ * Fragment, since Fragments have their own view lifecycles and do not usually appear in contexts
+ * where the reuse offered by `AndroidViewBinding` would lead to measurable performance
+ * improvements.
+ *
  * @sample androidx.compose.ui.samples.AndroidViewBindingSample
  *
  * @param factory The block creating the [ViewBinding] to be composed.
  * @param modifier The modifier to be applied to the layout.
- * @param update The callback to be invoked after the layout is inflated.
+ * @param update The callback to be invoked after the layout is inflated and upon recomposition to
+ * update the information and state of the binding
  */
 @Composable
 fun <T : ViewBinding> AndroidViewBinding(
     factory: (inflater: LayoutInflater, parent: ViewGroup, attachToParent: Boolean) -> T,
     modifier: Modifier = Modifier,
-    update: T.() -> Unit = {}
+    update: T.() -> Unit = { }
 ) {
-    val viewBindingRef = remember { Ref<T>() }
+    AndroidViewBinding(
+        factory = factory,
+        modifier = modifier,
+        onReset = null,
+        update = update
+    )
+}
+
+/**
+ * Composes an Android layout resource in the presence of [ViewBinding]. The binding is obtained
+ * from the [factory] block, which will be called exactly once to obtain the [ViewBinding]
+ * to be composed, and it is also guaranteed to be invoked on the UI thread.
+ * Therefore, in addition to creating the [ViewBinding], the block can also be used
+ * to perform one-off initializations and [View] constant properties' setting.
+ * The [update] block can be run multiple times (on the UI thread as well) due to recomposition,
+ * and it is the right place to set [View] properties depending on state. When state changes,
+ * the block will be reexecuted to set the new properties. Note the block will also be ran once
+ * right after the [factory] block completes.
+ *
+ * This overload includes support for View reuse, which behaves in the same way as it does for
+ * [AndroidView]. Namely, Views and their binding instances are only eligible for reuse if a
+ * non-null [onReset] callback is provided. It is expensive to discard and recreate View instances,
+ * so opting-in to View reuse can lead to noticeable performance improvements — especially when
+ * [AndroidViewBinding] is used in a scrolling list. It is highly recommended to specify an
+ * [onReset] implementation and opt-in to View reuse when possible.
+ *
+ * When [onReset] is specified, [View] instances and their bindings may be reused when hosted
+ * inside of a container that supports reusable elements. Reuse occurs when compatible instances
+ * of [AndroidViewBinding] are inserted and removed during recomposition. Two instances of
+ * `AndroidViewBinding` are considered compatible if they are invoked with the same composable
+ * group structure. The most common scenario where this happens is in lazy layout APIs like
+ * `LazyRow` and `LazyColumn`, which can reuse layout nodes (and, in this case, Views and their
+ * bindings as well) between items when scrolling.
+ *
+ * [onReset] is invoked on the UI thread when the View and its binding will be reused, signaling
+ * that the View and binding should be prepared to appear in a new context in the composition
+ * hierarchy. This callback is invoked before [update] and may be used to reset any transient View
+ * state like animations or user input.
+ *
+ * Note that [onReset] may not be immediately followed by a call to [update]. Compose may
+ * temporarily detach the View from the composition hierarchy if it is deactivated but not released
+ * from composition. This can happen if the View appears in a [ReusableContentHost] that is not
+ * currently active or inside of a [movable content][androidx.compose.runtime.movableContentOf]
+ * block that is being moved. If this happens, the View will be removed from its parent, but
+ * retained by Compose so that it may be reused if its content host becomes active again. If the
+ * View never becomes active again and is instead discarded entirely, the [onReset] callback will
+ * be invoked directly from this deactivated state when Compose releases the View and its binding.
+ *
+ * When the View is removed from the composition permanently, [onRelease] will be invoked (also on
+ * the UI thread). Once this callback returns, Compose will never attempt to reuse the previous
+ * View or binding instance regardless of whether an [onReset] implementation was provided. If the
+ * View is needed again in the future, a new instance will be created, with a fresh lifecycle that
+ * begins by calling the [factory].
+ *
+ * @sample androidx.compose.ui.samples.AndroidViewBindingReusableSample
+ *
+ * @param factory The block creating the [ViewBinding] to be composed.
+ * @param modifier The modifier to be applied to the layout.
+ * @param onReset A callback invoked as a signal that the view is about to be attached to the
+ * composition hierarchy in a different context than its original creation. This callback is invoked
+ * before [update] and should prepare the view for general reuse. If `null` or not specified, the
+ * `AndroidViewBinding` instance will not support reuse, and the View and its binding will always be
+ * discarded whenever the AndroidViewBinding is moved or removed from the composition hierarchy.
+ * @param onRelease A callback invoked as a signal that this view and its binding have exited the
+ * composition hierarchy entirely and will not be reused again. Any additional resources used by the
+ * binding should be freed at this time.
+ * @param update The callback to be invoked after the layout is inflated and upon recomposition to
+ * update the information and state of the binding.
+ */
+@Composable
+fun <T : ViewBinding> AndroidViewBinding(
+    factory: (inflater: LayoutInflater, parent: ViewGroup, attachToParent: Boolean) -> T,
+    modifier: Modifier = Modifier,
+    onReset: (T.() -> Unit)? = null,
+    onRelease: T.() -> Unit = { },
+    update: T.() -> Unit = { }
+) {
     val localView = LocalView.current
     // Find the parent fragment, if one exists. This will let us ensure that
     // fragments inflated via a FragmentContainerView are properly nested
@@ -74,62 +167,62 @@
             null
         }
     }
-    val fragmentContainerViews = remember { mutableStateListOf<FragmentContainerView>() }
-    val viewBlock: (Context) -> View = remember(localView) {
-        { context ->
+
+    val localContext = LocalContext.current
+    AndroidView(
+        factory = { context ->
             // Inflated fragments are automatically nested properly when
             // using the parent fragment's LayoutInflater
             val inflater = parentFragment?.layoutInflater ?: LayoutInflater.from(context)
             val viewBinding = factory(inflater, FrameLayout(context), false)
-            viewBindingRef.value = viewBinding
-            // Find all FragmentContainerView instances in the newly inflated layout
-            fragmentContainerViews.clear()
-            val rootGroup = viewBinding.root as? ViewGroup
-            if (rootGroup != null) {
-                findFragmentContainerViews(rootGroup, fragmentContainerViews)
+            viewBinding.root.apply {
+                setBinding(viewBinding)
             }
-            viewBinding.root
-        }
-    }
-    AndroidView(
-        factory = viewBlock,
+        },
         modifier = modifier,
-        update = { viewBindingRef.value?.update() }
-    )
+        onReset = onReset?.let { reset -> { view -> view.getBinding<T>().reset() } },
+        onRelease = { view ->
+            view.getBinding<T>().onRelease()
 
-    // Set up a DisposableEffect for each FragmentContainerView that will
-    // clean up inflated fragments when the AndroidViewBinding is disposed
-    val localContext = LocalContext.current
-    fragmentContainerViews.fastForEach { container ->
-        DisposableEffect(localContext, container) {
-            // Find the right FragmentManager
-            val fragmentManager = parentFragment?.childFragmentManager
-                ?: (localContext as? FragmentActivity)?.supportFragmentManager
-            // Now find the fragment inflated via the FragmentContainerView
-            val existingFragment = fragmentManager?.findFragmentById(container.id)
-            onDispose {
-                if (existingFragment != null && !fragmentManager.isStateSaved) {
-                    // If the state isn't saved, that means that some state change
-                    // has removed this Composable from the hierarchy
-                    fragmentManager.commit {
-                        remove(existingFragment)
+            (view as? ViewGroup)?.let { rootGroup ->
+                // clean up inflated fragments when the AndroidViewBinding is disposed
+                // Find the right FragmentManager
+                val fragmentManager = parentFragment?.childFragmentManager
+                    ?: (localContext as? FragmentActivity)?.supportFragmentManager
+                forEachFragmentContainerView(rootGroup) { container ->
+                    // Now find the fragment inflated via the FragmentContainerView
+                    val existingFragment = fragmentManager?.findFragmentById(container.id)
+                    if (existingFragment != null && !fragmentManager.isStateSaved) {
+                        // If the state isn't saved, that means that some state change
+                        // has removed this Composable from the hierarchy
+                        fragmentManager.commit {
+                            remove(existingFragment)
+                        }
                     }
                 }
             }
-        }
-    }
+        },
+        update = { view -> view.getBinding<T>().update() }
+    )
 }
 
-private fun findFragmentContainerViews(
+private fun <T : ViewBinding> View.setBinding(binding: T) =
+    setTag(R.id.binding_reference, binding)
+
+@Suppress("UNCHECKED_CAST")
+private fun <T : ViewBinding> View.getBinding(): T =
+    getTag(R.id.binding_reference) as T
+
+private fun forEachFragmentContainerView(
     viewGroup: ViewGroup,
-    list: MutableList<FragmentContainerView>
+    action: (FragmentContainerView) -> Unit
 ) {
     if (viewGroup is FragmentContainerView) {
-        list += viewGroup
+        action(viewGroup)
     } else {
         viewGroup.forEach {
             if (it is ViewGroup) {
-                findFragmentContainerViews(it, list)
+                forEachFragmentContainerView(it, action)
             }
         }
     }
diff --git a/compose/ui/ui-viewbinding/src/main/res/values/ids.xml b/compose/ui/ui-viewbinding/src/main/res/values/ids.xml
new file mode 100644
index 0000000..110ceb1
--- /dev/null
+++ b/compose/ui/ui-viewbinding/src/main/res/values/ids.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.
+  -->
+
+<resources>
+    <id name="binding_reference"/>
+</resources>
\ No newline at end of file
diff --git a/compose/ui/ui/api/api_lint.ignore b/compose/ui/ui/api/api_lint.ignore
index 4be51cd..b334166 100644
--- a/compose/ui/ui/api/api_lint.ignore
+++ b/compose/ui/ui/api/api_lint.ignore
@@ -1,24 +1,58 @@
 // Baseline format: 1.0
+GetterSetterNames: androidx.compose.ui.focus.FocusProperties#getCanFocus():
+    Getter for boolean property `canFocus` is named `getCanFocus` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.focus.FocusState#getHasFocus():
+    Getter for boolean property `hasFocus` is named `getHasFocus` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.layout.BeyondBoundsLayout.BeyondBoundsScope#getHasMoreContent():
+    Getter for boolean property `hasMoreContent` is named `getHasMoreContent` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.platform.AbstractComposeView#getHasComposition():
+    Getter for boolean property `hasComposition` is named `getHasComposition` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.platform.AbstractComposeView#getShouldCreateCompositionOnAttachedToWindow():
+    Getter for boolean property `shouldCreateCompositionOnAttachedToWindow` is named `getShouldCreateCompositionOnAttachedToWindow` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.platform.ComposeView#getShouldCreateCompositionOnAttachedToWindow():
+    Getter for boolean property `shouldCreateCompositionOnAttachedToWindow` is named `getShouldCreateCompositionOnAttachedToWindow` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.platform.ViewRootForTest#getHasPendingMeasureOrLayout():
+    Getter for boolean property `hasPendingMeasureOrLayout` is named `getHasPendingMeasureOrLayout` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field DialogProperties.decorFitsSystemWindows:
+    Invalid name for boolean property `decorFitsSystemWindows`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field DialogProperties.dismissOnBackPress:
+    Invalid name for boolean property `dismissOnBackPress`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field DialogProperties.dismissOnClickOutside:
+    Invalid name for boolean property `dismissOnClickOutside`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field DialogProperties.usePlatformDefaultWidth:
+    Invalid name for boolean property `usePlatformDefaultWidth`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ImageVector.autoMirror:
+    Invalid name for boolean property `autoMirror`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ModifierNodeElement.autoInvalidate:
+    Invalid name for boolean property `autoInvalidate`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PointerInputChange.pressed:
+    Invalid name for boolean property `pressed`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PointerInputChange.previousPressed:
+    Invalid name for boolean property `previousPressed`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PointerInputFilter.interceptOutOfBoundsChildEvents:
+    Invalid name for boolean property `interceptOutOfBoundsChildEvents`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PointerInputFilter.shareWithSiblings:
+    Invalid name for boolean property `shareWithSiblings`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PopupProperties.clippingEnabled:
+    Invalid name for boolean property `clippingEnabled`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PopupProperties.dismissOnBackPress:
+    Invalid name for boolean property `dismissOnBackPress`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PopupProperties.dismissOnClickOutside:
+    Invalid name for boolean property `dismissOnClickOutside`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PopupProperties.excludeFromSystemGesture:
+    Invalid name for boolean property `excludeFromSystemGesture`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PopupProperties.focusable:
+    Invalid name for boolean property `focusable`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PopupProperties.usePlatformDefaultWidth:
+    Invalid name for boolean property `usePlatformDefaultWidth`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ScrollAxisRange.reverseScrolling:
+    Invalid name for boolean property `reverseScrolling`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field SemanticsNode.mergingEnabled:
+    Invalid name for boolean property `mergingEnabled`. Should start with one of `has`, `can`, `should`, `is`.
+
+
 KotlinDefaultParameterOrder: androidx.compose.ui.graphics.vector.ImageVector.Builder#Builder(String, float, float, float, float, long, int, boolean) parameter #0:
     Parameter `name` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #0:
-    Parameter `id` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #1:
-    Parameter `currentTime` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #2:
-    Parameter `currentPosition` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #3:
-    Parameter `currentPressed` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #4:
-    Parameter `pressure` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #5:
-    Parameter `previousTime` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #6:
-    Parameter `previousPosition` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #7:
-    Parameter `previousPressed` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #8:
-    Parameter `type` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
 KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #0:
     Parameter `id` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
 KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #1:
diff --git a/compose/ui/ui/api/current.ignore b/compose/ui/ui/api/current.ignore
index 2001639..adee0b1 100644
--- a/compose/ui/ui/api/current.ignore
+++ b/compose/ui/ui/api/current.ignore
@@ -1,3 +1,31 @@
 // Baseline format: 1.0
+InvalidNullConversion: androidx.compose.ui.CombinedModifier#foldIn(R, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.CombinedModifier.foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.CombinedModifier#foldOut(R, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.CombinedModifier.foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier#foldIn(R, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier#foldOut(R, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier.Companion#foldIn(R, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.Companion.foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier.Companion#foldOut(R, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.Companion.foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier.Element#foldIn(R, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.Element.foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier.Element#foldOut(R, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.Element.foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.graphics.vector.VectorConfig#getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter defaultValue in androidx.compose.ui.graphics.vector.VectorConfig.getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T> property, T defaultValue)
+InvalidNullConversion: androidx.compose.ui.semantics.SemanticsConfiguration#set(androidx.compose.ui.semantics.SemanticsPropertyKey<T>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.ui.semantics.SemanticsConfiguration.set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value)
+InvalidNullConversion: androidx.compose.ui.semantics.SemanticsPropertyKey#merge(T, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter childValue in androidx.compose.ui.semantics.SemanticsPropertyKey.merge(T parentValue, T childValue)
+InvalidNullConversion: androidx.compose.ui.semantics.SemanticsPropertyKey#setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver, kotlin.reflect.KProperty<?>, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.ui.semantics.SemanticsPropertyKey.setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property, T value)
+InvalidNullConversion: androidx.compose.ui.semantics.SemanticsPropertyReceiver#set(androidx.compose.ui.semantics.SemanticsPropertyKey<T>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.ui.semantics.SemanticsPropertyReceiver.set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value)
+
+
 RemovedClass: androidx.compose.ui.platform.AndroidComposeView_androidKt:
     Removed class androidx.compose.ui.platform.AndroidComposeView_androidKt
diff --git a/compose/ui/ui/api/current.txt b/compose/ui/ui/api/current.txt
index 4eb047f..48fd02b 100644
--- a/compose/ui/ui/api/current.txt
+++ b/compose/ui/ui/api/current.txt
@@ -107,8 +107,8 @@
     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);
+    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 {
@@ -120,8 +120,8 @@
   @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 <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;
   }
@@ -129,15 +129,15 @@
   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);
+    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);
+    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 {
@@ -608,7 +608,7 @@
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface VectorConfig {
-    method public default <T> T! getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T> property, T? defaultValue);
+    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 {
@@ -2226,7 +2226,7 @@
   public interface ModifierLocalNode 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);
+    method public default <T> void provide(androidx.compose.ui.modifier.ModifierLocal<T> key, T value);
     property public default androidx.compose.ui.modifier.ModifierLocalMap providedValues;
   }
 
@@ -2240,13 +2240,13 @@
 
   @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();
+    method public T getValue();
     property public abstract androidx.compose.ui.modifier.ProvidableModifierLocal<T> key;
-    property public abstract T! value;
+    property public abstract T value;
   }
 
   public interface ModifierLocalReadScope {
-    method public <T> T! getCurrent(androidx.compose.ui.modifier.ModifierLocal<T>);
+    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> {
@@ -2261,7 +2261,7 @@
   }
 
   public final class CompositionLocalConsumerModifierNodeKt {
-    method public static <T> T! currentValueOf(androidx.compose.ui.node.CompositionLocalConsumerModifierNode, androidx.compose.runtime.CompositionLocal<T> local);
+    method public static <T> T currentValueOf(androidx.compose.ui.node.CompositionLocalConsumerModifierNode, androidx.compose.runtime.CompositionLocal<T> local);
   }
 
   public interface DelegatableNode {
@@ -2885,13 +2885,13 @@
     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 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 <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;
@@ -3092,14 +3092,14 @@
   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);
+    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);
+    method public operator <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
   }
 
 }
diff --git a/compose/ui/ui/api/public_plus_experimental_current.txt b/compose/ui/ui/api/public_plus_experimental_current.txt
index c46de0a..95fddb6 100644
--- a/compose/ui/ui/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui/api/public_plus_experimental_current.txt
@@ -107,8 +107,8 @@
     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);
+    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 {
@@ -130,8 +130,8 @@
   @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 <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;
   }
@@ -139,15 +139,15 @@
   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);
+    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);
+    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 {
@@ -726,7 +726,7 @@
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface VectorConfig {
-    method public default <T> T! getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T> property, T? defaultValue);
+    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 {
@@ -2436,7 +2436,7 @@
   public interface ModifierLocalNode 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);
+    method public default <T> void provide(androidx.compose.ui.modifier.ModifierLocal<T> key, T value);
     property public default androidx.compose.ui.modifier.ModifierLocalMap providedValues;
   }
 
@@ -2450,9 +2450,9 @@
 
   @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();
+    method public T getValue();
     property public abstract androidx.compose.ui.modifier.ProvidableModifierLocal<T> key;
-    property public abstract T! value;
+    property public abstract T value;
   }
 
   public final class ModifierLocalProviderKt {
@@ -2460,7 +2460,7 @@
   }
 
   public interface ModifierLocalReadScope {
-    method public <T> T! getCurrent(androidx.compose.ui.modifier.ModifierLocal<T>);
+    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> {
@@ -2475,7 +2475,7 @@
   }
 
   public final class CompositionLocalConsumerModifierNodeKt {
-    method public static <T> T! currentValueOf(androidx.compose.ui.node.CompositionLocalConsumerModifierNode, androidx.compose.runtime.CompositionLocal<T> local);
+    method public static <T> T currentValueOf(androidx.compose.ui.node.CompositionLocalConsumerModifierNode, androidx.compose.runtime.CompositionLocal<T> local);
   }
 
   public interface DelegatableNode {
@@ -2942,7 +2942,7 @@
 
   @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);
+    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;
   }
 
@@ -3144,13 +3144,13 @@
     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 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 <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;
@@ -3363,14 +3363,14 @@
   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);
+    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);
+    method public operator <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
   }
 
 }
diff --git a/compose/ui/ui/api/restricted_current.ignore b/compose/ui/ui/api/restricted_current.ignore
index 2001639..adee0b1 100644
--- a/compose/ui/ui/api/restricted_current.ignore
+++ b/compose/ui/ui/api/restricted_current.ignore
@@ -1,3 +1,31 @@
 // Baseline format: 1.0
+InvalidNullConversion: androidx.compose.ui.CombinedModifier#foldIn(R, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.CombinedModifier.foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.CombinedModifier#foldOut(R, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.CombinedModifier.foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier#foldIn(R, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier#foldOut(R, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier.Companion#foldIn(R, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.Companion.foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier.Companion#foldOut(R, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.Companion.foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier.Element#foldIn(R, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.Element.foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier.Element#foldOut(R, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.Element.foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.graphics.vector.VectorConfig#getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter defaultValue in androidx.compose.ui.graphics.vector.VectorConfig.getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T> property, T defaultValue)
+InvalidNullConversion: androidx.compose.ui.semantics.SemanticsConfiguration#set(androidx.compose.ui.semantics.SemanticsPropertyKey<T>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.ui.semantics.SemanticsConfiguration.set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value)
+InvalidNullConversion: androidx.compose.ui.semantics.SemanticsPropertyKey#merge(T, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter childValue in androidx.compose.ui.semantics.SemanticsPropertyKey.merge(T parentValue, T childValue)
+InvalidNullConversion: androidx.compose.ui.semantics.SemanticsPropertyKey#setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver, kotlin.reflect.KProperty<?>, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.ui.semantics.SemanticsPropertyKey.setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property, T value)
+InvalidNullConversion: androidx.compose.ui.semantics.SemanticsPropertyReceiver#set(androidx.compose.ui.semantics.SemanticsPropertyKey<T>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.ui.semantics.SemanticsPropertyReceiver.set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value)
+
+
 RemovedClass: androidx.compose.ui.platform.AndroidComposeView_androidKt:
     Removed class androidx.compose.ui.platform.AndroidComposeView_androidKt
diff --git a/compose/ui/ui/api/restricted_current.txt b/compose/ui/ui/api/restricted_current.txt
index 8b45d71..fe0c61d 100644
--- a/compose/ui/ui/api/restricted_current.txt
+++ b/compose/ui/ui/api/restricted_current.txt
@@ -107,8 +107,8 @@
     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);
+    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 {
@@ -120,8 +120,8 @@
   @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 <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;
   }
@@ -129,15 +129,15 @@
   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);
+    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);
+    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 {
@@ -608,7 +608,7 @@
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface VectorConfig {
-    method public default <T> T! getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T> property, T? defaultValue);
+    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 {
@@ -2233,7 +2233,7 @@
   public interface ModifierLocalNode 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);
+    method public default <T> void provide(androidx.compose.ui.modifier.ModifierLocal<T> key, T value);
     property public default androidx.compose.ui.modifier.ModifierLocalMap providedValues;
   }
 
@@ -2247,13 +2247,13 @@
 
   @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();
+    method public T getValue();
     property public abstract androidx.compose.ui.modifier.ProvidableModifierLocal<T> key;
-    property public abstract T! value;
+    property public abstract T value;
   }
 
   public interface ModifierLocalReadScope {
-    method public <T> T! getCurrent(androidx.compose.ui.modifier.ModifierLocal<T>);
+    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> {
@@ -2309,7 +2309,7 @@
   }
 
   public final class CompositionLocalConsumerModifierNodeKt {
-    method public static <T> T! currentValueOf(androidx.compose.ui.node.CompositionLocalConsumerModifierNode, androidx.compose.runtime.CompositionLocal<T> local);
+    method public static <T> T currentValueOf(androidx.compose.ui.node.CompositionLocalConsumerModifierNode, androidx.compose.runtime.CompositionLocal<T> local);
   }
 
   public interface DelegatableNode {
@@ -2934,13 +2934,13 @@
     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 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 <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;
@@ -3141,14 +3141,14 @@
   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);
+    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);
+    method public operator <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
   }
 
 }
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/HitPathTrackerTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/HitPathTrackerTest.kt
index 5595853..a13aa46 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/HitPathTrackerTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/HitPathTrackerTest.kt
@@ -3688,7 +3688,8 @@
     override fun onRequestMeasure(
         layoutNode: LayoutNode,
         affectsLookahead: Boolean,
-        forceRequest: Boolean
+        forceRequest: Boolean,
+        scheduleMeasureAndLayout: Boolean
     ) {
         onRequestMeasureParams += layoutNode
         if (affectsLookahead) {
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessorTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessorTest.kt
index 18faf11..a1603dd 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessorTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessorTest.kt
@@ -3337,7 +3337,8 @@
     override fun onRequestMeasure(
         layoutNode: LayoutNode,
         affectsLookahead: Boolean,
-        forceRequest: Boolean
+        forceRequest: Boolean,
+        scheduleMeasureAndLayout: Boolean
     ) {
         if (affectsLookahead) {
             delegate.requestLookaheadRemeasure(layoutNode)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/Helpers.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/Helpers.kt
index 89ff38b..8e4d1a2 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/Helpers.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/Helpers.kt
@@ -92,7 +92,8 @@
     override fun onRequestMeasure(
         layoutNode: LayoutNode,
         affectsLookahead: Boolean,
-        forceRequest: Boolean
+        forceRequest: Boolean,
+        scheduleMeasureAndLayout: Boolean
     ) {
         if (affectsLookahead) {
             delegate.requestLookaheadRemeasure(layoutNode)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/ResizingComposeViewTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/ResizingComposeViewTest.kt
index 3e4c2be..eaed850 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/ResizingComposeViewTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/ResizingComposeViewTest.kt
@@ -28,6 +28,8 @@
 import androidx.compose.runtime.snapshots.Snapshot
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.drawBehind
+import androidx.compose.ui.node.LayoutModifierNode
+import androidx.compose.ui.node.ModifierNodeElement
 import androidx.compose.ui.platform.ComposeView
 import androidx.compose.ui.test.TestActivity
 import androidx.compose.ui.unit.Constraints
@@ -261,6 +263,60 @@
         awaitDrawAndAssertSizes()
     }
 
+    @Test
+    fun whenForceRemeasureCalledAndSizeChanged() {
+        var childHeight by mutableStateOf(10)
+        val parent = RequestLayoutTrackingFrameLayout(rule.activity)
+        var remeasurement: Remeasurement? = null
+        rule.runOnUiThread {
+            parent.addView(composeView, WrapContentLayoutParams)
+            rule.activity.setContentView(parent, WrapContentLayoutParams)
+            composeView.setContent {
+                ResizingChild(
+                    layoutHeight = { childHeight },
+                    modifier = RemeasurementModifierElement { remeasurement = it }
+                )
+            }
+        }
+
+        awaitDrawAndAssertSizes()
+        rule.runOnUiThread {
+            parent.requestLayoutCalled = false
+            drawLatch = CountDownLatch(1)
+
+            childHeight = 20
+            remeasurement!!.forceRemeasure()
+        }
+
+        awaitDrawAndAssertSizes()
+        assertThat(parent.requestLayoutCalled).isTrue()
+    }
+
+    @Test
+    fun noRequestLayoutWhenForceRemeasureCalled() {
+        val parent = RequestLayoutTrackingFrameLayout(rule.activity)
+        var remeasurement: Remeasurement? = null
+        rule.runOnUiThread {
+            parent.addView(composeView, WrapContentLayoutParams)
+            rule.activity.setContentView(parent, WrapContentLayoutParams)
+            composeView.setContent {
+                ResizingChild(
+                    layoutHeight = { 10 },
+                    modifier = RemeasurementModifierElement { remeasurement = it }
+                )
+            }
+        }
+
+        awaitDrawAndAssertSizes()
+        rule.runOnUiThread {
+            parent.requestLayoutCalled = false
+
+            remeasurement!!.forceRemeasure()
+
+            assertThat(parent.requestLayoutCalled).isFalse()
+        }
+    }
+
     private fun awaitDrawAndAssertSizes() {
         Assert.assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
         // size assertion is done inside Modifier.drawBehind() which calls countDown() on the latch
@@ -270,10 +326,11 @@
     private fun ResizingChild(
         layoutHeight: () -> Int,
         viewHeight: () -> Int = layoutHeight,
+        modifier: Modifier = Modifier
     ) {
         Layout(
             {},
-            Modifier.drawBehind {
+            modifier.drawBehind {
                 val expectedLayoutHeight = Snapshot.withoutReadObservation { layoutHeight() }
                 assertWithMessage("Layout size is wrong")
                     .that(size.height.roundToInt()).isEqualTo(expectedLayoutHeight)
@@ -332,3 +389,28 @@
     ViewGroup.LayoutParams.WRAP_CONTENT,
     ViewGroup.LayoutParams.WRAP_CONTENT
 )
+
+private class RemeasurementModifierElement(
+    private val onRemeasurementAvailable: (Remeasurement) -> Unit
+) : ModifierNodeElement<RemeasurementModifierNode>() {
+    override fun create() = RemeasurementModifierNode().also {
+        onRemeasurementAvailable(it)
+    }
+    override fun update(node: RemeasurementModifierNode) = node.also {
+        onRemeasurementAvailable(it)
+    }
+    override fun hashCode(): Int = 242
+    override fun equals(other: Any?) = other === this
+}
+
+private class RemeasurementModifierNode : Modifier.Node(), LayoutModifierNode {
+    override fun MeasureScope.measure(
+        measurable: Measurable,
+        constraints: Constraints
+    ): MeasureResult {
+        val placeable = measurable.measure(constraints)
+        return layout(placeable.width, placeable.height) {
+            placeable.place(0, 0)
+        }
+    }
+}
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
index 5c19f10..3b68870 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
@@ -841,13 +841,18 @@
     override fun onRequestMeasure(
         layoutNode: LayoutNode,
         affectsLookahead: Boolean,
-        forceRequest: Boolean
+        forceRequest: Boolean,
+        scheduleMeasureAndLayout: Boolean
     ) {
         if (affectsLookahead) {
-            if (measureAndLayoutDelegate.requestLookaheadRemeasure(layoutNode, forceRequest)) {
+            if (measureAndLayoutDelegate.requestLookaheadRemeasure(layoutNode, forceRequest) &&
+                scheduleMeasureAndLayout
+            ) {
                 scheduleMeasureAndLayout(layoutNode)
             }
-        } else if (measureAndLayoutDelegate.requestRemeasure(layoutNode, forceRequest)) {
+        } else if (measureAndLayoutDelegate.requestRemeasure(layoutNode, forceRequest) &&
+            scheduleMeasureAndLayout
+        ) {
             scheduleMeasureAndLayout(layoutNode)
         }
     }
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidView.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidView.android.kt
index 57e248f..e47c66b 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidView.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidView.android.kt
@@ -183,12 +183,12 @@
  * @sample androidx.compose.ui.samples.AndroidViewWithReleaseSample
  *
  * @param factory The block creating the [View] to be composed.
+ * @param modifier The modifier to be applied to the layout.
  * @param onReset A callback invoked as a signal that the view is about to be attached to the
  * composition hierarchy in a different context than its original creation. This callback is invoked
  * before [update] and should prepare the view for general reuse. If `null` or not specified, the
  * `AndroidView` instance will not support reuse, and the View instance will always be discarded
  * whenever the AndroidView is moved or removed from the composition hierarchy.
- * @param modifier The modifier to be applied to the layout.
  * @param onRelease A callback invoked as a signal that this view instance has exited the
  * composition hierarchy entirely and will not be reused again. Any additional resources used by the
  * View should be freed at this time.
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusSearch.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusSearch.kt
index 25e9c36..d3dced6 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusSearch.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusSearch.kt
@@ -186,6 +186,9 @@
     accessibleChildren: MutableVector<FocusTargetModifierNode>
 ) {
     visitChildren(Nodes.FocusTarget) {
+        // TODO(b/278765590): Find the root issue why visitChildren returns unattached nodes.
+        if (!it.isAttached) return@visitChildren
+
         if (it.fetchFocusProperties().canFocus) {
             accessibleChildren.add(it)
         } else {
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 f19d852..aff7b04 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
@@ -949,10 +949,17 @@
     /**
      * Used to request a new measurement + layout pass from the owner.
      */
-    internal fun requestRemeasure(forceRequest: Boolean = false) {
+    internal fun requestRemeasure(
+        forceRequest: Boolean = false,
+        scheduleMeasureAndLayout: Boolean = true
+    ) {
         if (!ignoreRemeasureRequests && !isVirtual) {
             val owner = owner ?: return
-            owner.onRequestMeasure(this, forceRequest = forceRequest)
+            owner.onRequestMeasure(
+                layoutNode = this,
+                forceRequest = forceRequest,
+                scheduleMeasureAndLayout = scheduleMeasureAndLayout
+            )
             measurePassDelegate.invalidateIntrinsicsParent(forceRequest)
         }
     }
@@ -961,14 +968,22 @@
      * Used to request a new lookahead measurement, lookahead layout, and subsequently
      * measure and layout from the owner.
      */
-    internal fun requestLookaheadRemeasure(forceRequest: Boolean = false) {
+    internal fun requestLookaheadRemeasure(
+        forceRequest: Boolean = false,
+        scheduleMeasureAndLayout: Boolean = true
+    ) {
         check(lookaheadRoot != null) {
             "Lookahead measure cannot be requested on a node that is not a part of the" +
                 "LookaheadLayout"
         }
         val owner = owner ?: return
         if (!ignoreRemeasureRequests && !isVirtual) {
-            owner.onRequestMeasure(this, affectsLookahead = true, forceRequest = forceRequest)
+            owner.onRequestMeasure(
+                layoutNode = this,
+                affectsLookahead = true,
+                forceRequest = forceRequest,
+                scheduleMeasureAndLayout = scheduleMeasureAndLayout
+            )
             lookaheadPassDelegate!!.invalidateIntrinsicsParent(forceRequest)
         }
     }
@@ -1156,10 +1171,11 @@
         layoutDelegate.markLookaheadMeasurePending()
 
     override fun forceRemeasure() {
+        // we do not schedule measure and layout as we are going to call it manually right after
         if (lookaheadRoot != null) {
-            requestLookaheadRemeasure()
+            requestLookaheadRemeasure(scheduleMeasureAndLayout = false)
         } else {
-            requestRemeasure()
+            requestRemeasure(scheduleMeasureAndLayout = false)
         }
         val lastConstraints = layoutDelegate.lastConstraints
         if (lastConstraints != null) {
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/Owner.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/Owner.kt
index 41cdde0..426e1f7 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/Owner.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/Owner.kt
@@ -154,7 +154,8 @@
     fun onRequestMeasure(
         layoutNode: LayoutNode,
         affectsLookahead: Boolean = false,
-        forceRequest: Boolean = false
+        forceRequest: Boolean = false,
+        scheduleMeasureAndLayout: Boolean = true
     )
 
     /**
diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt
index e649130..66310c1 100644
--- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt
+++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt
@@ -329,13 +329,18 @@
     override fun onRequestMeasure(
         layoutNode: LayoutNode,
         affectsLookahead: Boolean,
-        forceRequest: Boolean
+        forceRequest: Boolean,
+        scheduleMeasureAndLayout: Boolean
     ) {
         if (affectsLookahead) {
-            if (measureAndLayoutDelegate.requestLookaheadRemeasure(layoutNode, forceRequest)) {
+            if (measureAndLayoutDelegate.requestLookaheadRemeasure(layoutNode, forceRequest) &&
+                scheduleMeasureAndLayout
+            ) {
                 requestLayout()
             }
-        } else if (measureAndLayoutDelegate.requestRemeasure(layoutNode, forceRequest)) {
+        } else if (measureAndLayoutDelegate.requestRemeasure(layoutNode, forceRequest) &&
+            scheduleMeasureAndLayout
+        ) {
             requestLayout()
         }
     }
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt
index 132252b..5c31d51 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt
@@ -2558,7 +2558,8 @@
     override fun onRequestMeasure(
         layoutNode: LayoutNode,
         affectsLookahead: Boolean,
-        forceRequest: Boolean
+        forceRequest: Boolean,
+        scheduleMeasureAndLayout: Boolean
     ) {
         onRequestMeasureParams += layoutNode
         if (affectsLookahead) {
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/ModifierLocalConsumerEntityTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/ModifierLocalConsumerEntityTest.kt
index d2c911d..62a2b15 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/ModifierLocalConsumerEntityTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/ModifierLocalConsumerEntityTest.kt
@@ -317,7 +317,8 @@
         override fun onRequestMeasure(
             layoutNode: LayoutNode,
             affectsLookahead: Boolean,
-            forceRequest: Boolean
+            forceRequest: Boolean,
+            scheduleMeasureAndLayout: Boolean
         ) {
         }
 
diff --git a/constraintlayout/constraintlayout-compose/api/api_lint.ignore b/constraintlayout/constraintlayout-compose/api/api_lint.ignore
index 33c2cfc..71cc70d 100644
--- a/constraintlayout/constraintlayout-compose/api/api_lint.ignore
+++ b/constraintlayout/constraintlayout-compose/api/api_lint.ignore
@@ -5,6 +5,14 @@
     Parameter type is concrete collection (`java.util.HashMap`); must be higher-level interface
 
 
+GetterSetterNames: field DebugFlags.showBounds:
+    Invalid name for boolean property `showBounds`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field DebugFlags.showKeyPositions:
+    Invalid name for boolean property `showKeyPositions`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field DebugFlags.showPaths:
+    Invalid name for boolean property `showPaths`. Should start with one of `has`, `can`, `should`, `is`.
+
+
 KotlinDefaultParameterOrder: androidx.constraintlayout.compose.MotionLayoutKt#MotionLayout(androidx.constraintlayout.compose.ConstraintSet, androidx.constraintlayout.compose.ConstraintSet, androidx.compose.ui.Modifier, androidx.constraintlayout.compose.Transition, float, int, androidx.constraintlayout.compose.LayoutInformationReceiver, int, kotlin.jvm.functions.Function1<? super androidx.constraintlayout.compose.MotionLayoutScope,kotlin.Unit>) parameter #2:
     Parameter `modifier` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
 KotlinDefaultParameterOrder: androidx.constraintlayout.compose.MotionLayoutKt#MotionLayout(androidx.constraintlayout.compose.ConstraintSet, androidx.constraintlayout.compose.ConstraintSet, androidx.compose.ui.Modifier, androidx.constraintlayout.compose.Transition, float, int, androidx.constraintlayout.compose.LayoutInformationReceiver, int, kotlin.jvm.functions.Function1<? super androidx.constraintlayout.compose.MotionLayoutScope,kotlin.Unit>) parameter #3:
diff --git a/constraintlayout/constraintlayout-compose/api/public_plus_experimental_current.txt b/constraintlayout/constraintlayout-compose/api/public_plus_experimental_current.txt
index 92a3feb..49794f2 100644
--- a/constraintlayout/constraintlayout-compose/api/public_plus_experimental_current.txt
+++ b/constraintlayout/constraintlayout-compose/api/public_plus_experimental_current.txt
@@ -23,12 +23,12 @@
   }
 
   @androidx.constraintlayout.compose.ExperimentalMotionApi public abstract class BaseKeyFrameScope {
-    method protected final <E extends androidx.constraintlayout.compose.NamedPropertyOrValue> kotlin.properties.ObservableProperty<E> addNameOnPropertyChange(E? initialValue, optional String? nameOverride);
-    method protected final <T> kotlin.properties.ObservableProperty<T> addOnPropertyChange(T? initialValue, optional String? nameOverride);
+    method protected final <E extends androidx.constraintlayout.compose.NamedPropertyOrValue> kotlin.properties.ObservableProperty<E> addNameOnPropertyChange(E initialValue, optional String? nameOverride);
+    method protected final <T> kotlin.properties.ObservableProperty<T> addOnPropertyChange(T initialValue, optional String? nameOverride);
   }
 
   @androidx.constraintlayout.compose.ExperimentalMotionApi public class BaseKeyFramesScope {
-    method protected final <E extends androidx.constraintlayout.compose.NamedPropertyOrValue> kotlin.properties.ObservableProperty<E> addNameOnPropertyChange(E? initialValue, optional String? nameOverride);
+    method protected final <E extends androidx.constraintlayout.compose.NamedPropertyOrValue> kotlin.properties.ObservableProperty<E> addNameOnPropertyChange(E initialValue, optional String? nameOverride);
     method public final androidx.constraintlayout.compose.Easing getEasing();
     method protected final androidx.constraintlayout.core.parser.CLArray getFramesContainer();
     method public final void setEasing(androidx.constraintlayout.compose.Easing);
diff --git a/constraintlayout/constraintlayout/api/current.txt b/constraintlayout/constraintlayout/api/current.txt
index 6e30c9f..469ddb0 100644
--- a/constraintlayout/constraintlayout/api/current.txt
+++ b/constraintlayout/constraintlayout/api/current.txt
@@ -120,20 +120,6 @@
     field protected float mComputedMinY;
   }
 
-  public class LogJson extends androidx.constraintlayout.widget.ConstraintHelper {
-    ctor public LogJson(android.content.Context);
-    ctor public LogJson(android.content.Context, android.util.AttributeSet?);
-    ctor public LogJson(android.content.Context, android.util.AttributeSet?, int);
-    method public void periodicStart();
-    method public void periodicStop();
-    method public void setDelay(int);
-    method public void writeLog();
-    field public static final int LOG_API = 4; // 0x4
-    field public static final int LOG_DELAYED = 2; // 0x2
-    field public static final int LOG_LAYOUT = 3; // 0x3
-    field public static final int LOG_PERIODIC = 1; // 0x1
-  }
-
   public class MotionEffect extends androidx.constraintlayout.motion.widget.MotionHelper {
     ctor public MotionEffect(android.content.Context!);
     ctor public MotionEffect(android.content.Context!, android.util.AttributeSet!);
diff --git a/constraintlayout/constraintlayout/api/public_plus_experimental_current.txt b/constraintlayout/constraintlayout/api/public_plus_experimental_current.txt
index 6e30c9f..469ddb0 100644
--- a/constraintlayout/constraintlayout/api/public_plus_experimental_current.txt
+++ b/constraintlayout/constraintlayout/api/public_plus_experimental_current.txt
@@ -120,20 +120,6 @@
     field protected float mComputedMinY;
   }
 
-  public class LogJson extends androidx.constraintlayout.widget.ConstraintHelper {
-    ctor public LogJson(android.content.Context);
-    ctor public LogJson(android.content.Context, android.util.AttributeSet?);
-    ctor public LogJson(android.content.Context, android.util.AttributeSet?, int);
-    method public void periodicStart();
-    method public void periodicStop();
-    method public void setDelay(int);
-    method public void writeLog();
-    field public static final int LOG_API = 4; // 0x4
-    field public static final int LOG_DELAYED = 2; // 0x2
-    field public static final int LOG_LAYOUT = 3; // 0x3
-    field public static final int LOG_PERIODIC = 1; // 0x1
-  }
-
   public class MotionEffect extends androidx.constraintlayout.motion.widget.MotionHelper {
     ctor public MotionEffect(android.content.Context!);
     ctor public MotionEffect(android.content.Context!, android.util.AttributeSet!);
diff --git a/constraintlayout/constraintlayout/api/restricted_current.txt b/constraintlayout/constraintlayout/api/restricted_current.txt
index 6e30c9f..469ddb0 100644
--- a/constraintlayout/constraintlayout/api/restricted_current.txt
+++ b/constraintlayout/constraintlayout/api/restricted_current.txt
@@ -120,20 +120,6 @@
     field protected float mComputedMinY;
   }
 
-  public class LogJson extends androidx.constraintlayout.widget.ConstraintHelper {
-    ctor public LogJson(android.content.Context);
-    ctor public LogJson(android.content.Context, android.util.AttributeSet?);
-    ctor public LogJson(android.content.Context, android.util.AttributeSet?, int);
-    method public void periodicStart();
-    method public void periodicStop();
-    method public void setDelay(int);
-    method public void writeLog();
-    field public static final int LOG_API = 4; // 0x4
-    field public static final int LOG_DELAYED = 2; // 0x2
-    field public static final int LOG_LAYOUT = 3; // 0x3
-    field public static final int LOG_PERIODIC = 1; // 0x1
-  }
-
   public class MotionEffect extends androidx.constraintlayout.motion.widget.MotionHelper {
     ctor public MotionEffect(android.content.Context!);
     ctor public MotionEffect(android.content.Context!, android.util.AttributeSet!);
diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/helper/widget/LogJson.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/helper/widget/LogJson.java
deleted file mode 100644
index 6b1c9db..0000000
--- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/helper/widget/LogJson.java
+++ /dev/null
@@ -1,772 +0,0 @@
-/*

- * Copyright (C) 2023 The Android Open Source Project

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-

-package androidx.constraintlayout.helper.widget;

-

-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;

-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;

-

-import static androidx.constraintlayout.widget.ConstraintSet.Layout.UNSET_GONE_MARGIN;

-

-import android.annotation.SuppressLint;

-import android.content.Context;

-import android.content.res.TypedArray;

-import android.os.Environment;

-import android.util.AttributeSet;

-import android.util.Log;

-import android.util.TypedValue;

-import android.view.View;

-import android.view.ViewGroup;

-import android.widget.Button;

-import android.widget.TextView;

-

-import androidx.annotation.RequiresApi;

-import androidx.constraintlayout.motion.widget.Debug;

-import androidx.constraintlayout.widget.ConstraintAttribute;

-import androidx.constraintlayout.widget.ConstraintHelper;

-import androidx.constraintlayout.widget.ConstraintLayout;

-import androidx.constraintlayout.widget.ConstraintSet;

-import androidx.constraintlayout.widget.R;

-

-import java.io.File;

-import java.io.FileOutputStream;

-import java.io.IOException;

-import java.io.StringWriter;

-import java.io.Writer;

-import java.util.HashMap;

-import java.util.concurrent.atomic.AtomicInteger;

-

-/**

- * This is a class is a debugging/logging utility to write out the constraints in JSON

- * This is used for debugging purposes

- * <ul>

- *     <li>logJsonTo - defines the output log console or "fileName"</li>

- *     <li>logJsonMode - mode one of:

- *     <b>periodic</b>, <b>delayed</b>, <b>layout</b> or <b>api</b></li>

- *     <li>logJsonDelay - the duration of the delay or the delay between repeated logs</li>

- * </ul>

- * logJsonTo supports:

- * <ul>

- *     <li>log - logs using log.v("JSON5", ...)</li>

- *     <li>console - logs using System.out.println(...)</li>

- *     <li>[fileName] - will write to /storage/emulated/0/Download/[fileName].json5</li>

- * </ul>

- * logJsonMode modes are:

- * <ul>

- *     <li>periodic - after window is attached will log every delay ms</li>

- *     <li>delayed - log once after delay ms</li>

- *     <li>layout - log every time there is a layout call</li>

- *     <li>api - do not automatically log developer will call writeLog</li>

- * </ul>

- *

- * The defaults are:

- * <ul>

- *     <li>logJsonTo="log"</li>

- *     <li>logJsonMode="delayed"</li>

- *     <li>logJsonDelay="1000"</li>

- * </ul>

- *  Usage:

- *  <p></p>

- *  <pre>

- *  {@code

- *      <androidx.constraintlayout.helper.widget.LogJson

- *         android:layout_width="0dp"

- *         android:layout_height="0dp"

- *         android:visibility="gone"

- *         app:logJsonTo="log"

- *         app:logJsonMode="delayed"

- *         app:logJsonDelay="1000"

- *         />

- *  }

- * </pre>

- * </p>

- */

-public class LogJson extends ConstraintHelper {

-    private static final String TAG = "JSON5";

-    private int mDelay = 1000;

-    private int mMode = LOG_DELAYED;

-    private String mLogToFile = null;

-    private boolean mLogConsole = true;

-

-    public static final int LOG_PERIODIC = 1;

-    public static final int LOG_DELAYED = 2;

-    public static final int LOG_LAYOUT = 3;

-    public static final int LOG_API = 4;

-    private boolean mPeriodic = false;

-

-    public LogJson(@androidx.annotation.NonNull Context context) {

-        super(context);

-    }

-

-    public LogJson(@androidx.annotation.NonNull Context context,

-                   @androidx.annotation.Nullable AttributeSet attrs) {

-        super(context, attrs);

-        initLogJson(attrs);

-

-    }

-

-    public LogJson(@androidx.annotation.NonNull Context context,

-                   @androidx.annotation.Nullable AttributeSet attrs, int defStyleAttr) {

-        super(context, attrs, defStyleAttr);

-        initLogJson(attrs);

-    }

-

-    private void initLogJson(AttributeSet attrs) {

-

-        if (attrs != null) {

-            TypedArray a = getContext().obtainStyledAttributes(attrs,

-                    R.styleable.LogJson);

-            final int count = a.getIndexCount();

-            for (int i = 0; i < count; i++) {

-                int attr = a.getIndex(i);

-                if (attr == R.styleable.LogJson_logJsonDelay) {

-                    mDelay = a.getInt(attr, mDelay);

-                } else if (attr == R.styleable.LogJson_logJsonMode) {

-                    mMode = a.getInt(attr, mMode);

-                } else if (attr == R.styleable.LogJson_logJsonTo) {

-                    TypedValue v = a.peekValue(attr);

-                    if (v.type == TypedValue.TYPE_STRING) {

-                        mLogToFile = a.getString(attr);

-                    } else {

-                        int value = a.getInt(attr, 0);

-                        mLogConsole = value == 2;

-                    }

-                }

-            }

-            a.recycle();

-        }

-        setVisibility(GONE);

-    }

-

-    @Override

-    protected void onAttachedToWindow() {

-        super.onAttachedToWindow();

-        switch (mMode) {

-            case LOG_PERIODIC:

-                mPeriodic = true;

-                this.postDelayed(this::periodic, mDelay);

-                break;

-            case LOG_DELAYED:

-                this.postDelayed(this::writeLog, mDelay);

-                break;

-            case LOG_LAYOUT:

-                ConstraintLayout cl = (ConstraintLayout) getParent();

-                cl.addOnLayoutChangeListener((v, a, b, c, d, e, f, g, h) -> logOnLayout());

-        }

-    }

-

-    private void logOnLayout() {

-        if (mMode == LOG_LAYOUT) {

-            writeLog();

-        }

-    }

-

-    /**

-     * Set the duration of periodic logging of constraints

-     *

-     * @param duration the time in ms between writing files

-     */

-    public void setDelay(int duration) {

-        mDelay = duration;

-    }

-

-    /**

-     * Start periodic sampling

-     */

-    public void periodicStart() {

-        if (mPeriodic) {

-            return;

-        }

-        mPeriodic = true;

-        this.postDelayed(this::periodic, mDelay);

-    }

-

-    /**

-     * Stop periodic sampling

-     */

-    public void periodicStop() {

-        mPeriodic = false;

-    }

-

-    private void periodic() {

-        if (mPeriodic) {

-            writeLog();

-            this.postDelayed(this::periodic, mDelay);

-        }

-    }

-

-    /**

-     * This writes a JSON5 representation of the constraintSet

-     */

-    public void writeLog() {

-        String str = asString((ConstraintLayout) this.getParent());

-        if (mLogToFile == null) {

-            if (mLogConsole) {

-                System.out.println(str);

-            } else {

-                logBigString(str);

-            }

-        } else {

-            String name = toFile(str, mLogToFile);

-            Log.v("JSON", "\"" + name + "\" written!");

-        }

-    }

-

-    /**

-     * This writes the JSON5 description of the constraintLayout to a file named fileName.json5

-     * in the download directory which can be pulled with:

-     * "adb pull "/storage/emulated/0/Download/" ."

-     *

-     * @param str      String to write as a file

-     * @param fileName file name

-     * @return full path name of file

-     */

-    private static String toFile(String str, String fileName) {

-        FileOutputStream outputStream;

-        if (!fileName.endsWith(".json5")) {

-            fileName += ".json5";

-        }

-        try {

-            File down =

-                    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);

-            File file = new File(down, fileName);

-            outputStream = new FileOutputStream(file);

-            outputStream.write(str.getBytes());

-            outputStream.close();

-            return file.getCanonicalPath();

-        } catch (IOException e) {

-            return e.toString();

-        }

-    }

-

-    @SuppressLint("LogConditional")

-    private void logBigString(String str) {

-        int len = str.length();

-        for (int i = 0; i < len; i++) {

-            int k = str.indexOf("\n", i);

-            if (k == -1) {

-                Log.v(TAG, str.substring(i));

-                break;

-            }

-            Log.v(TAG, str.substring(i, k));

-            i = k;

-        }

-    }

-

-    /**

-     * Get a JSON5 String that represents the Constraints in a running ConstraintLayout

-     *

-     * @param constraintLayout its constraints are converted to a string

-     * @return JSON5 string

-     */

-    private static String asString(ConstraintLayout constraintLayout) {

-        JsonWriter c = new JsonWriter();

-        return c.constraintLayoutToJson(constraintLayout);

-    }

-

-    // ================================== JSON writer==============================================

-

-    private static class JsonWriter {

-        public static final int UNSET = ConstraintLayout.LayoutParams.UNSET;

-        ConstraintSet mSet;

-        Writer mWriter;

-        Context mContext;

-        int mUnknownCount = 0;

-        final String mLEFT = "left";

-        final String mRIGHT = "right";

-        final String mBASELINE = "baseline";

-        final String mBOTTOM = "bottom";

-        final String mTOP = "top";

-        final String mSTART = "start";

-        final String mEND = "end";

-        private static final String INDENT = "    ";

-        private static final String SMALL_INDENT = "  ";

-        HashMap<Integer, String> mIdMap = new HashMap<>();

-        private static final String LOG_JSON = LogJson.class.getSimpleName();

-        private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);

-        HashMap<Integer, String> mNames = new HashMap<>();

-

-        private static int generateViewId() {

-            final int max_id = 0x00FFFFFF;

-            for (;;) {

-                final int result = sNextGeneratedId.get();

-                int newValue = result + 1;

-                if (newValue > max_id) {

-                    newValue = 1;

-                }

-                if (sNextGeneratedId.compareAndSet(result, newValue)) {

-                    return result;

-                }

-            }

-        }

-

-        @RequiresApi(17)

-        private static class JellyBean {

-            static int generateViewId() {

-                return View.generateViewId();

-            }

-        }

-

-        String constraintLayoutToJson(ConstraintLayout constraintLayout) {

-            StringWriter writer = new StringWriter();

-

-            int count = constraintLayout.getChildCount();

-            for (int i = 0; i < count; i++) {

-                View v = constraintLayout.getChildAt(i);

-                String name = v.getClass().getSimpleName();

-                int id = v.getId();

-                if (id == -1) {

-                    if (android.os.Build.VERSION.SDK_INT

-                            >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {

-                        id = JellyBean.generateViewId();

-                    } else {

-                        id = generateViewId();

-                    }

-                    v.setId(id);

-                    if (!LOG_JSON.equals(name)) {

-                        name = "noid_" + name;

-                    }

-                    mNames.put(id, name);

-                } else if (LOG_JSON.equals(name)) {

-                    mNames.put(id, name);

-                }

-            }

-            writer.append("{\n");

-

-            writeWidgets(writer, constraintLayout);

-            writer.append("  ConstraintSet:{\n");

-            ConstraintSet set = new ConstraintSet();

-            set.clone(constraintLayout);

-            String name =

-                    (constraintLayout.getId() == -1) ? "cset" : Debug.getName(constraintLayout);

-            try {

-                writer.append(name + ":");

-                setup(writer, set, constraintLayout);

-                writeLayout();

-                writer.append("\n");

-            } catch (IOException e) {

-                throw new RuntimeException(e);

-            }

-            writer.append("  }\n");

-            writer.append("}\n");

-            return writer.toString();

-        }

-

-        private void writeWidgets(StringWriter writer, ConstraintLayout constraintLayout) {

-            writer.append("Widgets:{\n");

-            int count = constraintLayout.getChildCount();

-

-            for (int i = -1; i < count; i++) {

-                View v = (i == -1) ? constraintLayout : constraintLayout.getChildAt(i);

-                int id = v.getId();

-                if (LOG_JSON.equals(v.getClass().getSimpleName())) {

-                    continue;

-                }

-                String name = mNames.containsKey(id) ? mNames.get(id)

-                        : ((i == -1) ? "parent" : Debug.getName(v));

-                String cname = v.getClass().getSimpleName();

-                String bounds = ", bounds: [" + v.getLeft() + ", " + v.getTop()

-                        + ", " + v.getRight() + ", " + v.getBottom() + "]},\n";

-                writer.append("  " + name + ": { ");

-                if (i == -1) {

-                    writer.append("type: '" + v.getClass().getSimpleName() + "' , ");

-

-                    try {

-                        ViewGroup.LayoutParams p = (ViewGroup.LayoutParams) v.getLayoutParams();

-                        String wrap = "'WRAP_CONTENT'";

-                        String match = "'MATCH_PARENT'";

-                        String w = p.width == MATCH_PARENT ? match :

-                                (p.width == WRAP_CONTENT) ? wrap : p.width + "";

-                        writer.append("width: " + w + ", ");

-                        String h = p.height == MATCH_PARENT ? match :

-                                (p.height == WRAP_CONTENT) ? wrap : p.height + "";

-                        writer.append("height: ").append(h);

-                    } catch (Exception e) {

-                    }

-                } else if (cname.contains("Text")) {

-                    if (v instanceof TextView) {

-                        writer.append("type: 'Text', label: '"

-                                + escape(((TextView) v).getText().toString()) + "'");

-                    } else {

-                        writer.append("type: 'Text' },\n");

-                    }

-                } else if (cname.contains("Button")) {

-                    if (v instanceof Button) {

-                        writer.append("type: 'Button', label: '" + ((Button) v).getText() + "'");

-                    } else

-                        writer.append("type: 'Button'");

-                } else if (cname.contains("Image")) {

-                    writer.append("type: 'Image'");

-                } else if (cname.contains("View")) {

-                    writer.append("type: 'Box'");

-                } else {

-                    writer.append("type: '" + v.getClass().getSimpleName() + "'");

-                }

-                writer.append(bounds);

-            }

-            writer.append("},\n");

-        }

-

-        private static String escape(String str) {

-            return str.replaceAll("'", "\\'");

-        }

-

-        JsonWriter() {

-        }

-

-        void setup(Writer writer,

-                   ConstraintSet set,

-                   ConstraintLayout layout) throws IOException {

-            this.mWriter = writer;

-            this.mContext = layout.getContext();

-            this.mSet = set;

-            set.getConstraint(2);

-        }

-

-        private int[] getIDs() {

-            return mSet.getKnownIds();

-        }

-

-        private ConstraintSet.Constraint getConstraint(int id) {

-            return mSet.getConstraint(id);

-        }

-

-        private void writeLayout() throws IOException {

-            mWriter.write("{\n");

-            for (Integer id : getIDs()) {

-                ConstraintSet.Constraint c = getConstraint(id);

-                String idName = getSimpleName(id);

-                if (LOG_JSON.equals(idName)) { // skip LogJson it is for used to log

-                    continue;

-                }

-                mWriter.write(SMALL_INDENT + idName + ":{\n");

-                ConstraintSet.Layout l = c.layout;

-                if (l.mReferenceIds != null) {

-                    StringBuilder ref =

-                            new StringBuilder("type: '_" + idName + "_' , contains: [");

-                    for (int r = 0; r < l.mReferenceIds.length; r++) {

-                        int rid = l.mReferenceIds[r];

-                        ref.append((r == 0) ? "" : ", ").append(getName(rid));

-                    }

-                    mWriter.write(ref + "]\n");

-                }

-                if (l.mReferenceIdString != null) {

-                    StringBuilder ref =

-                            new StringBuilder(SMALL_INDENT + "type: '???' , contains: [");

-                    String[] rids = l.mReferenceIdString.split(",");

-                    for (int r = 0; r < rids.length; r++) {

-                        String rid = rids[r];

-                        ref.append((r == 0) ? "" : ", ").append("`").append(rid).append("`");

-                    }

-                    mWriter.write(ref + "]\n");

-                }

-                writeDimension("height", l.mHeight, l.heightDefault, l.heightPercent,

-                        l.heightMin, l.heightMax, l.constrainedHeight);

-                writeDimension("width", l.mWidth, l.widthDefault, l.widthPercent,

-                        l.widthMin, l.widthMax, l.constrainedWidth);

-

-                writeConstraint(mLEFT, l.leftToLeft, mLEFT, l.leftMargin, l.goneLeftMargin);

-                writeConstraint(mLEFT, l.leftToRight, mRIGHT, l.leftMargin, l.goneLeftMargin);

-                writeConstraint(mRIGHT, l.rightToLeft, mLEFT, l.rightMargin, l.goneRightMargin);

-                writeConstraint(mRIGHT, l.rightToRight, mRIGHT, l.rightMargin, l.goneRightMargin);

-                writeConstraint(mBASELINE, l.baselineToBaseline, mBASELINE, UNSET,

-                        l.goneBaselineMargin);

-                writeConstraint(mBASELINE, l.baselineToTop, mTOP, UNSET, l.goneBaselineMargin);

-                writeConstraint(mBASELINE, l.baselineToBottom,

-                        mBOTTOM, UNSET, l.goneBaselineMargin);

-

-                writeConstraint(mTOP, l.topToBottom, mBOTTOM, l.topMargin, l.goneTopMargin);

-                writeConstraint(mTOP, l.topToTop, mTOP, l.topMargin, l.goneTopMargin);

-                writeConstraint(mBOTTOM, l.bottomToBottom, mBOTTOM, l.bottomMargin,

-                        l.goneBottomMargin);

-                writeConstraint(mBOTTOM, l.bottomToTop, mTOP, l.bottomMargin, l.goneBottomMargin);

-                writeConstraint(mSTART, l.startToStart, mSTART, l.startMargin, l.goneStartMargin);

-                writeConstraint(mSTART, l.startToEnd, mEND, l.startMargin, l.goneStartMargin);

-                writeConstraint(mEND, l.endToStart, mSTART, l.endMargin, l.goneEndMargin);

-                writeConstraint(mEND, l.endToEnd, mEND, l.endMargin, l.goneEndMargin);

-

-                writeVariable("horizontalBias", l.horizontalBias, 0.5f);

-                writeVariable("verticalBias", l.verticalBias, 0.5f);

-

-                writeCircle(l.circleConstraint, l.circleAngle, l.circleRadius);

-

-                writeGuideline(l.orientation, l.guideBegin, l.guideEnd, l.guidePercent);

-                writeVariable("dimensionRatio", l.dimensionRatio);

-                writeVariable("barrierMargin", l.mBarrierMargin);

-                writeVariable("type", l.mHelperType);

-                writeVariable("ReferenceId", l.mReferenceIdString);

-                writeVariable("mBarrierAllowsGoneWidgets",

-                        l.mBarrierAllowsGoneWidgets, true);

-                writeVariable("WrapBehavior", l.mWrapBehavior);

-

-                writeVariable("verticalWeight", l.verticalWeight);

-                writeVariable("horizontalWeight", l.horizontalWeight);

-                writeVariable("horizontalChainStyle", l.horizontalChainStyle);

-                writeVariable("verticalChainStyle", l.verticalChainStyle);

-                writeVariable("barrierDirection", l.mBarrierDirection);

-                if (l.mReferenceIds != null) {

-                    writeVariable("ReferenceIds", l.mReferenceIds);

-                }

-                writeTransform(c.transform);

-                writeCustom(c.mCustomConstraints);

-

-                mWriter.write("  },\n");

-            }

-            mWriter.write("},\n");

-        }

-

-        private void writeTransform(ConstraintSet.Transform transform) throws IOException {

-            if (transform.applyElevation) {

-                writeVariable("elevation", transform.elevation);

-            }

-            writeVariable("rotationX", transform.rotationX, 0);

-            writeVariable("rotationY", transform.rotationY, 0);

-            writeVariable("rotationZ", transform.rotation, 0);

-            writeVariable("scaleX", transform.scaleX, 1);

-            writeVariable("scaleY", transform.scaleY, 1);

-            writeVariable("translationX", transform.translationX, 0);

-            writeVariable("translationY", transform.translationY, 0);

-            writeVariable("translationZ", transform.translationZ, 0);

-        }

-

-        private void writeCustom(HashMap<String, ConstraintAttribute> cset) throws IOException {

-            if (cset != null && cset.size() > 0) {

-                mWriter.write(INDENT + "custom: {\n");

-                for (String s : cset.keySet()) {

-                    ConstraintAttribute attr = cset.get(s);

-                    if (attr == null) {

-                        continue;

-                    }

-                    String custom = INDENT + SMALL_INDENT + attr.getName() + ": ";

-                    switch (attr.getType()) {

-                        case INT_TYPE:

-                            custom += attr.getIntegerValue();

-                            break;

-                        case COLOR_TYPE:

-                            custom += colorString(attr.getColorValue());

-                            break;

-                        case FLOAT_TYPE:

-                            custom += attr.getFloatValue();

-                            break;

-                        case STRING_TYPE:

-                            custom += "'" + attr.getStringValue() + "'";

-                            break;

-                        case DIMENSION_TYPE:

-                            custom = custom + attr.getFloatValue();

-                            break;

-                        case REFERENCE_TYPE:

-                        case COLOR_DRAWABLE_TYPE:

-                        case BOOLEAN_TYPE:

-                            custom = null;

-                    }

-                    if (custom != null) {

-                        mWriter.write(custom + ",\n");

-                    }

-                }

-                mWriter.write(SMALL_INDENT + "   } \n");

-            }

-        }

-

-        private static String colorString(int v) {

-            String str = "00000000" + Integer.toHexString(v);

-            return "#" + str.substring(str.length() - 8);

-        }

-

-        private void writeGuideline(int orientation,

-                                    int guideBegin,

-                                    int guideEnd,

-                                    float guidePercent) throws IOException {

-            writeVariable("orientation", orientation);

-            writeVariable("guideBegin", guideBegin);

-            writeVariable("guideEnd", guideEnd);

-            writeVariable("guidePercent", guidePercent);

-        }

-

-        private void writeDimension(String dimString,

-                                    int dim,

-                                    int dimDefault,

-                                    float dimPercent,

-                                    int dimMin,

-                                    int dimMax,

-                                    boolean unusedConstrainedDim) throws IOException {

-            if (dim == 0) {

-                if (dimMax != UNSET || dimMin != UNSET) {

-                    String s = "-----";

-                    switch (dimDefault) {

-                        case 0: // spread

-                            s = INDENT + dimString + ": {value:'spread'";

-                            break;

-                        case 1: //  wrap

-                            s = INDENT + dimString + ": {value:'wrap'";

-                            break;

-                        case 2: // percent

-                            s = INDENT + dimString + ": {value: '" + dimPercent + "%'";

-                            break;

-                    }

-                    if (dimMax != UNSET) {

-                        s += ", max: " + dimMax;

-                    }

-                    if (dimMax != UNSET) {

-                        s += ", min: " + dimMin;

-                    }

-                    s += "},\n";

-                    mWriter.write(s);

-                    return;

-                }

-

-                switch (dimDefault) {

-                    case 0: // spread is the default

-                        break;

-                    case 1: //  wrap

-                        mWriter.write(INDENT + dimString + ": '???????????',\n");

-                        return;

-                    case 2: // percent

-                        mWriter.write(INDENT + dimString + ": '" + dimPercent + "%',\n");

-                }

-

-            } else if (dim == -2) {

-                mWriter.write(INDENT + dimString + ": 'wrap',\n");

-            } else if (dim == -1) {

-                mWriter.write(INDENT + dimString + ": 'parent',\n");

-            } else {

-                mWriter.write(INDENT + dimString + ": " + dim + ",\n");

-            }

-        }

-

-        private String getSimpleName(int id) {

-            if (mIdMap.containsKey(id)) {

-                return "" + mIdMap.get(id);

-            }

-            if (id == 0) {

-                return "parent";

-            }

-            String name = lookup(id);

-            mIdMap.put(id, name);

-            return "" + name + "";

-        }

-

-        private String getName(int id) {

-            return "'" + getSimpleName(id) + "'";

-        }

-

-        private String lookup(int id) {

-            try {

-                if (mNames.containsKey(id)) {

-                    return mNames.get(id);

-                }

-                if (id != -1) {

-                    return mContext.getResources().getResourceEntryName(id);

-                } else {

-                    return "unknown" + ++mUnknownCount;

-                }

-            } catch (Exception ex) {

-                return "unknown" + ++mUnknownCount;

-            }

-        }

-

-        private void writeConstraint(String my,

-                                     int constraint,

-                                     String other,

-                                     int margin,

-                                     int goneMargin) throws IOException {

-            if (constraint == UNSET) {

-                return;

-            }

-            mWriter.write(INDENT + my);

-            mWriter.write(":[");

-            mWriter.write(getName(constraint));

-            mWriter.write(", ");

-            mWriter.write("'" + other + "'");

-            if (margin != 0 || goneMargin != UNSET_GONE_MARGIN) {

-                mWriter.write(", " + margin);

-                if (goneMargin != UNSET_GONE_MARGIN) {

-                    mWriter.write(", " + goneMargin);

-                }

-            }

-            mWriter.write("],\n");

-        }

-

-        private void writeCircle(int circleConstraint,

-                                 float circleAngle,

-                                 int circleRadius) throws IOException {

-            if (circleConstraint == UNSET) {

-                return;

-            }

-            mWriter.write(INDENT + "circle");

-            mWriter.write(":[");

-            mWriter.write(getName(circleConstraint));

-            mWriter.write(", " + circleAngle);

-            mWriter.write(circleRadius + "],\n");

-        }

-

-        private void writeVariable(String name, int value) throws IOException {

-            if (value == 0 || value == -1) {

-                return;

-            }

-            mWriter.write(INDENT + name);

-            mWriter.write(": " + value);

-            mWriter.write(",\n");

-        }

-

-        private void writeVariable(String name, float value) throws IOException {

-            if (value == UNSET) {

-                return;

-            }

-            mWriter.write(INDENT + name);

-            mWriter.write(": " + value);

-            mWriter.write(",\n");

-        }

-

-        private void writeVariable(String name, float value, float def) throws IOException {

-            if (value == def) {

-                return;

-            }

-            mWriter.write(INDENT + name);

-            mWriter.write(": " + value);

-            mWriter.write(",\n");

-        }

-

-        private void writeVariable(String name, boolean value, boolean def) throws IOException {

-            if (value == def) {

-                return;

-            }

-            mWriter.write(INDENT + name);

-            mWriter.write(": " + value);

-            mWriter.write(",\n");

-        }

-

-        private void writeVariable(String name, int[] value) throws IOException {

-            if (value == null) {

-                return;

-            }

-            mWriter.write(INDENT + name);

-            mWriter.write(": ");

-            for (int i = 0; i < value.length; i++) {

-                mWriter.write(((i == 0) ? "[" : ", ") + getName(value[i]));

-            }

-            mWriter.write("],\n");

-        }

-

-        private void writeVariable(String name, String value) throws IOException {

-            if (value == null) {

-                return;

-            }

-            mWriter.write(INDENT + name);

-            mWriter.write(": '" + value);

-            mWriter.write("',\n");

-        }

-    }

-}

diff --git a/constraintlayout/constraintlayout/src/main/res/values/attrs.xml b/constraintlayout/constraintlayout/src/main/res/values/attrs.xml
index aba4fb6..d9029b17 100644
--- a/constraintlayout/constraintlayout/src/main/res/values/attrs.xml
+++ b/constraintlayout/constraintlayout/src/main/res/values/attrs.xml
@@ -816,21 +816,6 @@
 
     </declare-styleable>
 
-    <!--    This is the api for logging constraints in JSON5 format -->
-    <declare-styleable name="LogJson">
-        <attr name="logJsonTo" format="enum|string">
-            <enum name="log" value="1" />
-            <enum name="console" value="2" />
-        </attr>
-        <attr name="logJsonMode" format="enum">
-            <enum name="periodic" value="1" />
-            <enum name="delayed" value="2" />
-            <enum name="layout" value="3" />
-            <enum name="api" value="4" />
-        </attr>
-        <attr name="logJsonDelay" format="integer" />
-    </declare-styleable>
-
     <declare-styleable name="Constraint">
         <attr name="android:orientation" />
         <attr name="android:id" />
diff --git a/core/core-ktx/api/current.ignore b/core/core-ktx/api/current.ignore
new file mode 100644
index 0000000..6557477
--- /dev/null
+++ b/core/core-ktx/api/current.ignore
@@ -0,0 +1,17 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.core.util.LongSparseArrayKt#containsValue(android.util.LongSparseArray<T>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.LongSparseArrayKt.containsValue(android.util.LongSparseArray<T> arg1, T value)
+InvalidNullConversion: androidx.core.util.LongSparseArrayKt#getOrDefault(android.util.LongSparseArray<T>, long, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter defaultValue in androidx.core.util.LongSparseArrayKt.getOrDefault(android.util.LongSparseArray<T> arg1, long key, T defaultValue)
+InvalidNullConversion: androidx.core.util.LongSparseArrayKt#remove(android.util.LongSparseArray<T>, long, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.LongSparseArrayKt.remove(android.util.LongSparseArray<T> arg1, long key, T value)
+InvalidNullConversion: androidx.core.util.LongSparseArrayKt#set(android.util.LongSparseArray<T>, long, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.LongSparseArrayKt.set(android.util.LongSparseArray<T> arg1, long key, T value)
+InvalidNullConversion: androidx.core.util.SparseArrayKt#containsValue(android.util.SparseArray<T>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.SparseArrayKt.containsValue(android.util.SparseArray<T> arg1, T value)
+InvalidNullConversion: androidx.core.util.SparseArrayKt#getOrDefault(android.util.SparseArray<T>, int, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter defaultValue in androidx.core.util.SparseArrayKt.getOrDefault(android.util.SparseArray<T> arg1, int key, T defaultValue)
+InvalidNullConversion: androidx.core.util.SparseArrayKt#remove(android.util.SparseArray<T>, int, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.SparseArrayKt.remove(android.util.SparseArray<T> arg1, int key, T value)
+InvalidNullConversion: androidx.core.util.SparseArrayKt#set(android.util.SparseArray<T>, int, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.SparseArrayKt.set(android.util.SparseArray<T> arg1, int key, T value)
diff --git a/core/core-ktx/api/current.txt b/core/core-ktx/api/current.txt
index d3bbf86..89ab047 100644
--- a/core/core-ktx/api/current.txt
+++ b/core/core-ktx/api/current.txt
@@ -50,7 +50,7 @@
     method public static String getStringOrThrow(android.content.res.TypedArray, @StyleableRes int index);
     method public static CharSequence![] getTextArrayOrThrow(android.content.res.TypedArray, @StyleableRes int index);
     method public static CharSequence getTextOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static inline <R> R! use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
+    method public static inline <R> R use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
   }
 
 }
@@ -72,7 +72,7 @@
 package androidx.core.database.sqlite {
 
   public final class SQLiteDatabaseKt {
-    method public static inline <T> T! transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
+    method public static inline <T> T transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
   }
 
 }
@@ -333,7 +333,7 @@
   }
 
   public final class TraceKt {
-    method @Deprecated public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+    method @Deprecated public static inline <T> T trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
   }
 
 }
@@ -428,18 +428,18 @@
   public final class LongSparseArrayKt {
     method @RequiresApi(16) public static inline operator <T> boolean contains(android.util.LongSparseArray<T>, long key);
     method @RequiresApi(16) public static inline <T> boolean containsKey(android.util.LongSparseArray<T>, long key);
-    method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T? value);
+    method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T value);
     method @RequiresApi(16) public static inline <T> void forEach(android.util.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
-    method @RequiresApi(16) public static inline <T> T! getOrDefault(android.util.LongSparseArray<T>, long key, T? defaultValue);
-    method @RequiresApi(16) public static inline <T> T! getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method @RequiresApi(16) public static inline <T> T getOrDefault(android.util.LongSparseArray<T>, long key, T defaultValue);
+    method @RequiresApi(16) public static inline <T> T getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method @RequiresApi(16) public static inline <T> int getSize(android.util.LongSparseArray<T>);
     method @RequiresApi(16) public static inline <T> boolean isEmpty(android.util.LongSparseArray<T>);
     method @RequiresApi(16) public static inline <T> boolean isNotEmpty(android.util.LongSparseArray<T>);
     method @RequiresApi(16) public static <T> kotlin.collections.LongIterator keyIterator(android.util.LongSparseArray<T>);
     method @RequiresApi(16) public static operator <T> android.util.LongSparseArray<T> plus(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
     method @RequiresApi(16) public static <T> void putAll(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
-    method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T? value);
-    method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T? value);
+    method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T value);
+    method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T value);
     method @RequiresApi(16) public static <T> java.util.Iterator<T> valueIterator(android.util.LongSparseArray<T>);
   }
 
@@ -448,10 +448,10 @@
   }
 
   public final class PairKt {
-    method public static inline operator <F, S> F! component1(androidx.core.util.Pair<F,S>);
-    method public static inline operator <F, S> F! component1(android.util.Pair<F,S>);
-    method public static inline operator <F, S> S! component2(androidx.core.util.Pair<F,S>);
-    method public static inline operator <F, S> S! component2(android.util.Pair<F,S>);
+    method public static inline operator <F, S> F component1(androidx.core.util.Pair<F,S>);
+    method public static inline operator <F, S> F component1(android.util.Pair<F,S>);
+    method public static inline operator <F, S> S component2(androidx.core.util.Pair<F,S>);
+    method public static inline operator <F, S> S component2(android.util.Pair<F,S>);
     method public static inline <F, S> android.util.Pair<F,S> toAndroidPair(kotlin.Pair<? extends F,? extends S>);
     method public static inline <F, S> androidx.core.util.Pair<F,S> toAndroidXPair(kotlin.Pair<? extends F,? extends S>);
     method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(androidx.core.util.Pair<F,S>);
@@ -483,18 +483,18 @@
   public final class SparseArrayKt {
     method public static inline operator <T> boolean contains(android.util.SparseArray<T>, int key);
     method public static inline <T> boolean containsKey(android.util.SparseArray<T>, int key);
-    method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T? value);
+    method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T value);
     method public static inline <T> void forEach(android.util.SparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
-    method public static inline <T> T! getOrDefault(android.util.SparseArray<T>, int key, T? defaultValue);
-    method public static inline <T> T! getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public static inline <T> T getOrDefault(android.util.SparseArray<T>, int key, T defaultValue);
+    method public static inline <T> T getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public static inline <T> int getSize(android.util.SparseArray<T>);
     method public static inline <T> boolean isEmpty(android.util.SparseArray<T>);
     method public static inline <T> boolean isNotEmpty(android.util.SparseArray<T>);
     method public static <T> kotlin.collections.IntIterator keyIterator(android.util.SparseArray<T>);
     method public static operator <T> android.util.SparseArray<T> plus(android.util.SparseArray<T>, android.util.SparseArray<T> other);
     method public static <T> void putAll(android.util.SparseArray<T>, android.util.SparseArray<T> other);
-    method public static <T> boolean remove(android.util.SparseArray<T>, int key, T? value);
-    method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T? value);
+    method public static <T> boolean remove(android.util.SparseArray<T>, int key, T value);
+    method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T value);
     method public static <T> java.util.Iterator<T> valueIterator(android.util.SparseArray<T>);
   }
 
diff --git a/core/core-ktx/api/public_plus_experimental_current.txt b/core/core-ktx/api/public_plus_experimental_current.txt
index d3bbf86..89ab047 100644
--- a/core/core-ktx/api/public_plus_experimental_current.txt
+++ b/core/core-ktx/api/public_plus_experimental_current.txt
@@ -50,7 +50,7 @@
     method public static String getStringOrThrow(android.content.res.TypedArray, @StyleableRes int index);
     method public static CharSequence![] getTextArrayOrThrow(android.content.res.TypedArray, @StyleableRes int index);
     method public static CharSequence getTextOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static inline <R> R! use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
+    method public static inline <R> R use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
   }
 
 }
@@ -72,7 +72,7 @@
 package androidx.core.database.sqlite {
 
   public final class SQLiteDatabaseKt {
-    method public static inline <T> T! transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
+    method public static inline <T> T transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
   }
 
 }
@@ -333,7 +333,7 @@
   }
 
   public final class TraceKt {
-    method @Deprecated public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+    method @Deprecated public static inline <T> T trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
   }
 
 }
@@ -428,18 +428,18 @@
   public final class LongSparseArrayKt {
     method @RequiresApi(16) public static inline operator <T> boolean contains(android.util.LongSparseArray<T>, long key);
     method @RequiresApi(16) public static inline <T> boolean containsKey(android.util.LongSparseArray<T>, long key);
-    method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T? value);
+    method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T value);
     method @RequiresApi(16) public static inline <T> void forEach(android.util.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
-    method @RequiresApi(16) public static inline <T> T! getOrDefault(android.util.LongSparseArray<T>, long key, T? defaultValue);
-    method @RequiresApi(16) public static inline <T> T! getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method @RequiresApi(16) public static inline <T> T getOrDefault(android.util.LongSparseArray<T>, long key, T defaultValue);
+    method @RequiresApi(16) public static inline <T> T getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method @RequiresApi(16) public static inline <T> int getSize(android.util.LongSparseArray<T>);
     method @RequiresApi(16) public static inline <T> boolean isEmpty(android.util.LongSparseArray<T>);
     method @RequiresApi(16) public static inline <T> boolean isNotEmpty(android.util.LongSparseArray<T>);
     method @RequiresApi(16) public static <T> kotlin.collections.LongIterator keyIterator(android.util.LongSparseArray<T>);
     method @RequiresApi(16) public static operator <T> android.util.LongSparseArray<T> plus(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
     method @RequiresApi(16) public static <T> void putAll(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
-    method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T? value);
-    method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T? value);
+    method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T value);
+    method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T value);
     method @RequiresApi(16) public static <T> java.util.Iterator<T> valueIterator(android.util.LongSparseArray<T>);
   }
 
@@ -448,10 +448,10 @@
   }
 
   public final class PairKt {
-    method public static inline operator <F, S> F! component1(androidx.core.util.Pair<F,S>);
-    method public static inline operator <F, S> F! component1(android.util.Pair<F,S>);
-    method public static inline operator <F, S> S! component2(androidx.core.util.Pair<F,S>);
-    method public static inline operator <F, S> S! component2(android.util.Pair<F,S>);
+    method public static inline operator <F, S> F component1(androidx.core.util.Pair<F,S>);
+    method public static inline operator <F, S> F component1(android.util.Pair<F,S>);
+    method public static inline operator <F, S> S component2(androidx.core.util.Pair<F,S>);
+    method public static inline operator <F, S> S component2(android.util.Pair<F,S>);
     method public static inline <F, S> android.util.Pair<F,S> toAndroidPair(kotlin.Pair<? extends F,? extends S>);
     method public static inline <F, S> androidx.core.util.Pair<F,S> toAndroidXPair(kotlin.Pair<? extends F,? extends S>);
     method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(androidx.core.util.Pair<F,S>);
@@ -483,18 +483,18 @@
   public final class SparseArrayKt {
     method public static inline operator <T> boolean contains(android.util.SparseArray<T>, int key);
     method public static inline <T> boolean containsKey(android.util.SparseArray<T>, int key);
-    method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T? value);
+    method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T value);
     method public static inline <T> void forEach(android.util.SparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
-    method public static inline <T> T! getOrDefault(android.util.SparseArray<T>, int key, T? defaultValue);
-    method public static inline <T> T! getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public static inline <T> T getOrDefault(android.util.SparseArray<T>, int key, T defaultValue);
+    method public static inline <T> T getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public static inline <T> int getSize(android.util.SparseArray<T>);
     method public static inline <T> boolean isEmpty(android.util.SparseArray<T>);
     method public static inline <T> boolean isNotEmpty(android.util.SparseArray<T>);
     method public static <T> kotlin.collections.IntIterator keyIterator(android.util.SparseArray<T>);
     method public static operator <T> android.util.SparseArray<T> plus(android.util.SparseArray<T>, android.util.SparseArray<T> other);
     method public static <T> void putAll(android.util.SparseArray<T>, android.util.SparseArray<T> other);
-    method public static <T> boolean remove(android.util.SparseArray<T>, int key, T? value);
-    method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T? value);
+    method public static <T> boolean remove(android.util.SparseArray<T>, int key, T value);
+    method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T value);
     method public static <T> java.util.Iterator<T> valueIterator(android.util.SparseArray<T>);
   }
 
diff --git a/core/core-ktx/api/restricted_current.ignore b/core/core-ktx/api/restricted_current.ignore
new file mode 100644
index 0000000..6557477
--- /dev/null
+++ b/core/core-ktx/api/restricted_current.ignore
@@ -0,0 +1,17 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.core.util.LongSparseArrayKt#containsValue(android.util.LongSparseArray<T>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.LongSparseArrayKt.containsValue(android.util.LongSparseArray<T> arg1, T value)
+InvalidNullConversion: androidx.core.util.LongSparseArrayKt#getOrDefault(android.util.LongSparseArray<T>, long, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter defaultValue in androidx.core.util.LongSparseArrayKt.getOrDefault(android.util.LongSparseArray<T> arg1, long key, T defaultValue)
+InvalidNullConversion: androidx.core.util.LongSparseArrayKt#remove(android.util.LongSparseArray<T>, long, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.LongSparseArrayKt.remove(android.util.LongSparseArray<T> arg1, long key, T value)
+InvalidNullConversion: androidx.core.util.LongSparseArrayKt#set(android.util.LongSparseArray<T>, long, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.LongSparseArrayKt.set(android.util.LongSparseArray<T> arg1, long key, T value)
+InvalidNullConversion: androidx.core.util.SparseArrayKt#containsValue(android.util.SparseArray<T>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.SparseArrayKt.containsValue(android.util.SparseArray<T> arg1, T value)
+InvalidNullConversion: androidx.core.util.SparseArrayKt#getOrDefault(android.util.SparseArray<T>, int, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter defaultValue in androidx.core.util.SparseArrayKt.getOrDefault(android.util.SparseArray<T> arg1, int key, T defaultValue)
+InvalidNullConversion: androidx.core.util.SparseArrayKt#remove(android.util.SparseArray<T>, int, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.SparseArrayKt.remove(android.util.SparseArray<T> arg1, int key, T value)
+InvalidNullConversion: androidx.core.util.SparseArrayKt#set(android.util.SparseArray<T>, int, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.SparseArrayKt.set(android.util.SparseArray<T> arg1, int key, T value)
diff --git a/core/core-ktx/api/restricted_current.txt b/core/core-ktx/api/restricted_current.txt
index d3bbf86..89ab047 100644
--- a/core/core-ktx/api/restricted_current.txt
+++ b/core/core-ktx/api/restricted_current.txt
@@ -50,7 +50,7 @@
     method public static String getStringOrThrow(android.content.res.TypedArray, @StyleableRes int index);
     method public static CharSequence![] getTextArrayOrThrow(android.content.res.TypedArray, @StyleableRes int index);
     method public static CharSequence getTextOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static inline <R> R! use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
+    method public static inline <R> R use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
   }
 
 }
@@ -72,7 +72,7 @@
 package androidx.core.database.sqlite {
 
   public final class SQLiteDatabaseKt {
-    method public static inline <T> T! transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
+    method public static inline <T> T transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
   }
 
 }
@@ -333,7 +333,7 @@
   }
 
   public final class TraceKt {
-    method @Deprecated public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+    method @Deprecated public static inline <T> T trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
   }
 
 }
@@ -428,18 +428,18 @@
   public final class LongSparseArrayKt {
     method @RequiresApi(16) public static inline operator <T> boolean contains(android.util.LongSparseArray<T>, long key);
     method @RequiresApi(16) public static inline <T> boolean containsKey(android.util.LongSparseArray<T>, long key);
-    method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T? value);
+    method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T value);
     method @RequiresApi(16) public static inline <T> void forEach(android.util.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
-    method @RequiresApi(16) public static inline <T> T! getOrDefault(android.util.LongSparseArray<T>, long key, T? defaultValue);
-    method @RequiresApi(16) public static inline <T> T! getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method @RequiresApi(16) public static inline <T> T getOrDefault(android.util.LongSparseArray<T>, long key, T defaultValue);
+    method @RequiresApi(16) public static inline <T> T getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method @RequiresApi(16) public static inline <T> int getSize(android.util.LongSparseArray<T>);
     method @RequiresApi(16) public static inline <T> boolean isEmpty(android.util.LongSparseArray<T>);
     method @RequiresApi(16) public static inline <T> boolean isNotEmpty(android.util.LongSparseArray<T>);
     method @RequiresApi(16) public static <T> kotlin.collections.LongIterator keyIterator(android.util.LongSparseArray<T>);
     method @RequiresApi(16) public static operator <T> android.util.LongSparseArray<T> plus(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
     method @RequiresApi(16) public static <T> void putAll(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
-    method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T? value);
-    method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T? value);
+    method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T value);
+    method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T value);
     method @RequiresApi(16) public static <T> java.util.Iterator<T> valueIterator(android.util.LongSparseArray<T>);
   }
 
@@ -448,10 +448,10 @@
   }
 
   public final class PairKt {
-    method public static inline operator <F, S> F! component1(androidx.core.util.Pair<F,S>);
-    method public static inline operator <F, S> F! component1(android.util.Pair<F,S>);
-    method public static inline operator <F, S> S! component2(androidx.core.util.Pair<F,S>);
-    method public static inline operator <F, S> S! component2(android.util.Pair<F,S>);
+    method public static inline operator <F, S> F component1(androidx.core.util.Pair<F,S>);
+    method public static inline operator <F, S> F component1(android.util.Pair<F,S>);
+    method public static inline operator <F, S> S component2(androidx.core.util.Pair<F,S>);
+    method public static inline operator <F, S> S component2(android.util.Pair<F,S>);
     method public static inline <F, S> android.util.Pair<F,S> toAndroidPair(kotlin.Pair<? extends F,? extends S>);
     method public static inline <F, S> androidx.core.util.Pair<F,S> toAndroidXPair(kotlin.Pair<? extends F,? extends S>);
     method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(androidx.core.util.Pair<F,S>);
@@ -483,18 +483,18 @@
   public final class SparseArrayKt {
     method public static inline operator <T> boolean contains(android.util.SparseArray<T>, int key);
     method public static inline <T> boolean containsKey(android.util.SparseArray<T>, int key);
-    method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T? value);
+    method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T value);
     method public static inline <T> void forEach(android.util.SparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
-    method public static inline <T> T! getOrDefault(android.util.SparseArray<T>, int key, T? defaultValue);
-    method public static inline <T> T! getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public static inline <T> T getOrDefault(android.util.SparseArray<T>, int key, T defaultValue);
+    method public static inline <T> T getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public static inline <T> int getSize(android.util.SparseArray<T>);
     method public static inline <T> boolean isEmpty(android.util.SparseArray<T>);
     method public static inline <T> boolean isNotEmpty(android.util.SparseArray<T>);
     method public static <T> kotlin.collections.IntIterator keyIterator(android.util.SparseArray<T>);
     method public static operator <T> android.util.SparseArray<T> plus(android.util.SparseArray<T>, android.util.SparseArray<T> other);
     method public static <T> void putAll(android.util.SparseArray<T>, android.util.SparseArray<T> other);
-    method public static <T> boolean remove(android.util.SparseArray<T>, int key, T? value);
-    method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T? value);
+    method public static <T> boolean remove(android.util.SparseArray<T>, int key, T value);
+    method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T value);
     method public static <T> java.util.Iterator<T> valueIterator(android.util.SparseArray<T>);
   }
 
diff --git a/core/core-testing/api/current.txt b/core/core-testing/api/current.txt
index bca6bb8..40c6d07 100644
--- a/core/core-testing/api/current.txt
+++ b/core/core-testing/api/current.txt
@@ -3,7 +3,7 @@
 
   public final class TestConsumer<T> implements androidx.core.util.Consumer<T> {
     ctor public TestConsumer();
-    method public void accept(T? t);
+    method public void accept(T t);
     method public void assertValues(java.util.List<? extends T> values);
   }
 
diff --git a/core/core-testing/api/public_plus_experimental_current.txt b/core/core-testing/api/public_plus_experimental_current.txt
index bca6bb8..40c6d07 100644
--- a/core/core-testing/api/public_plus_experimental_current.txt
+++ b/core/core-testing/api/public_plus_experimental_current.txt
@@ -3,7 +3,7 @@
 
   public final class TestConsumer<T> implements androidx.core.util.Consumer<T> {
     ctor public TestConsumer();
-    method public void accept(T? t);
+    method public void accept(T t);
     method public void assertValues(java.util.List<? extends T> values);
   }
 
diff --git a/core/core-testing/api/restricted_current.txt b/core/core-testing/api/restricted_current.txt
index bca6bb8..40c6d07 100644
--- a/core/core-testing/api/restricted_current.txt
+++ b/core/core-testing/api/restricted_current.txt
@@ -3,7 +3,7 @@
 
   public final class TestConsumer<T> implements androidx.core.util.Consumer<T> {
     ctor public TestConsumer();
-    method public void accept(T? t);
+    method public void accept(T t);
     method public void assertValues(java.util.List<? extends T> values);
   }
 
diff --git a/core/core/api/current.txt b/core/core/api/current.txt
index 2c3c0b8..7ce3b2f 100644
--- a/core/core/api/current.txt
+++ b/core/core/api/current.txt
@@ -2172,6 +2172,14 @@
 
 }
 
+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 {
diff --git a/core/core/api/public_plus_experimental_current.txt b/core/core/api/public_plus_experimental_current.txt
index 2be0c06..77a0578 100644
--- a/core/core/api/public_plus_experimental_current.txt
+++ b/core/core/api/public_plus_experimental_current.txt
@@ -2179,6 +2179,14 @@
 
 }
 
+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 {
diff --git a/core/core/api/restricted_current.txt b/core/core/api/restricted_current.txt
index c860f39..5b50848 100644
--- a/core/core/api/restricted_current.txt
+++ b/core/core/api/restricted_current.txt
@@ -2547,6 +2547,14 @@
 
 }
 
+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 {
diff --git a/core/core/src/androidTest/java/androidx/core/text/method/LinkMovementMethodCompatTest.java b/core/core/src/androidTest/java/androidx/core/text/method/LinkMovementMethodCompatTest.java
new file mode 100644
index 0000000..7eb6b39
--- /dev/null
+++ b/core/core/src/androidTest/java/androidx/core/text/method/LinkMovementMethodCompatTest.java
@@ -0,0 +1,230 @@
+/*
+ * 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.core.text.method;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.os.SystemClock;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.Spanned;
+import android.text.style.ClickableSpan;
+import android.util.TypedValue;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.core.app.TestActivity;
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.rule.ActivityTestRule;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Test for {@link LinkMovementMethodCompat}.
+ *
+ * @see android.text.method.cts.LinkMovementMethodTest
+ */
+public class LinkMovementMethodCompatTest {
+    private static final String CONTENT = "clickable\nunclickable\nclickable";
+
+    private TestActivity mActivity;
+    private LinkMovementMethodCompat mMethod;
+    private TextView mView;
+    private Spannable mSpannable;
+    private ClickableSpan mClickable0;
+    private ClickableSpan mClickable1;
+
+    @Rule
+    public ActivityTestRule<TestActivity> mActivityRule =
+            new ActivityTestRule<>(TestActivity.class);
+
+    @Before
+    public void setup() throws Throwable {
+        mActivity = mActivityRule.getActivity();
+        mMethod = LinkMovementMethodCompat.getInstance();
+
+        // Set the content view with a text view which contains 3 lines,
+        mActivityRule.runOnUiThread(() -> mView = new TextViewNoIme(mActivity));
+        mView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
+        mView.setText(CONTENT, TextView.BufferType.SPANNABLE);
+
+        mActivityRule.runOnUiThread(() -> mActivity.setContentView(mView));
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+        mSpannable = (Spannable) mView.getText();
+        // make first line clickable
+        mClickable0 = markClickable(0, CONTENT.indexOf('\n'));
+        // make last line clickable
+        mClickable1 = markClickable(CONTENT.lastIndexOf('\n'), CONTENT.length());
+    }
+
+    @UiThreadTest
+    @Test
+    public void testOnTouchEvent() {
+        assertSelection(mSpannable, -1);
+
+        // press on first line (Clickable)
+        assertTrue(pressOnLine(0));
+        assertSelectClickableLeftToRight(mSpannable, mClickable0);
+
+        // release on first line
+        verify(mClickable0, never()).onClick(any());
+        assertTrue(releaseOnLine(0));
+        verify(mClickable0, times(1)).onClick(any());
+
+        // press on second line (unclickable)
+        assertSelectClickableLeftToRight(mSpannable, mClickable0);
+        // just clear selection
+        pressOnLine(1);
+        assertSelection(mSpannable, -1);
+
+        // press on last line  (Clickable)
+        assertTrue(pressOnLine(2));
+        assertSelectClickableLeftToRight(mSpannable, mClickable1);
+
+        // release on last line
+        verify(mClickable1, never()).onClick(any());
+        assertTrue(releaseOnLine(2));
+        verify(mClickable1, times(1)).onClick(any());
+
+        // release on second line (unclickable)
+        assertSelectClickableLeftToRight(mSpannable, mClickable1);
+        // just clear selection
+        releaseOnLine(1);
+        assertSelection(mSpannable, -1);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testOnTouchEvent_outsideLineBounds() {
+        assertSelection(mSpannable, -1);
+
+        // press on first line (clickable)
+        assertTrue(pressOnLine(0));
+        assertSelectClickableLeftToRight(mSpannable, mClickable0);
+
+        // release above first line
+        float x = (mView.getLayout().getLineLeft(0) + mView.getLayout().getLineRight(0)) / 2f;
+        float y = -1f;
+        assertFalse(performMotionAtPoint(x, y, MotionEvent.ACTION_UP));
+        verify(mClickable0, never()).onClick(any());
+
+        // press on first line (clickable)
+        assertTrue(pressOnLine(0));
+        assertSelectClickableLeftToRight(mSpannable, mClickable0);
+
+        // release to left of first line
+        x = mView.getLayout().getLineLeft(0) - 1f;
+        y = (mView.getLayout().getLineTop(0) + mView.getLayout().getLineBottom(0)) / 2f;
+        assertFalse(performMotionAtPoint(x, y, MotionEvent.ACTION_UP));
+        verify(mClickable0, never()).onClick(any());
+
+        // press on first line (clickable)
+        assertTrue(pressOnLine(0));
+        assertSelectClickableLeftToRight(mSpannable, mClickable0);
+
+        // release to right of first line
+        x = mView.getLayout().getLineRight(0) + 1f;
+        y = (mView.getLayout().getLineTop(0) + mView.getLayout().getLineBottom(0)) / 2f;
+        assertFalse(performMotionAtPoint(x, y, MotionEvent.ACTION_UP));
+        verify(mClickable0, never()).onClick(any());
+
+        // press on last line (clickable)
+        assertTrue(pressOnLine(2));
+        assertSelectClickableLeftToRight(mSpannable, mClickable1);
+
+        // release below last line
+        x = (mView.getLayout().getLineLeft(0) + mView.getLayout().getLineRight(0)) / 2f;
+        y = mView.getLayout().getHeight() + 1f;
+        assertFalse(performMotionAtPoint(x, y, MotionEvent.ACTION_UP));
+        verify(mClickable1, never()).onClick(any());
+    }
+
+    private ClickableSpan markClickable(final int start, final int end) throws Throwable {
+        final ClickableSpan clickableSpan = spy(new MockClickableSpan());
+        mActivityRule.runOnUiThread(() -> mSpannable.setSpan(clickableSpan, start, end,
+                Spanned.SPAN_MARK_MARK));
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+        return clickableSpan;
+    }
+
+    private boolean performMotionAtPoint(float x, float y, int action) {
+        long now = SystemClock.uptimeMillis();
+        return mMethod.onTouchEvent(mView, mSpannable,
+                MotionEvent.obtain(now, now, action, x, y, 0));
+    }
+
+    private boolean performMotionOnLine(int line, int action) {
+        float x = (mView.getLayout().getLineLeft(line) + mView.getLayout().getLineRight(line)) / 2f;
+        float y = (mView.getLayout().getLineTop(line) + mView.getLayout().getLineBottom(line)) / 2f;
+        return performMotionAtPoint(x, y, action);
+    }
+
+    private boolean pressOnLine(int line) {
+        return performMotionOnLine(line, MotionEvent.ACTION_DOWN);
+    }
+
+    private boolean releaseOnLine(int line) {
+        return performMotionOnLine(line, MotionEvent.ACTION_UP);
+    }
+
+    private void assertSelection(Spannable spannable, int start, int end) {
+        assertEquals(start, Selection.getSelectionStart(spannable));
+        assertEquals(end, Selection.getSelectionEnd(spannable));
+    }
+
+    private void assertSelection(Spannable spannable, int position) {
+        assertSelection(spannable, position, position);
+    }
+
+    private void assertSelectClickableLeftToRight(Spannable spannable,
+            ClickableSpan clickableSpan) {
+        assertSelection(spannable, spannable.getSpanStart(clickableSpan),
+                spannable.getSpanEnd(clickableSpan));
+    }
+
+    public static class TextViewNoIme extends TextView {
+        public TextViewNoIme(@NonNull Context context) {
+            super(context);
+        }
+
+        @Override
+        public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+            return null;
+        }
+    }
+
+    public static class MockClickableSpan extends ClickableSpan {
+        @Override
+        public void onClick(View widget) {}
+    }
+}
diff --git a/core/core/src/main/java/androidx/core/text/method/LinkMovementMethodCompat.java b/core/core/src/main/java/androidx/core/text/method/LinkMovementMethodCompat.java
new file mode 100644
index 0000000..f783934
--- /dev/null
+++ b/core/core/src/main/java/androidx/core/text/method/LinkMovementMethodCompat.java
@@ -0,0 +1,94 @@
+/*
+ * 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.core.text.method;
+
+import android.text.Layout;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.method.LinkMovementMethod;
+import android.text.method.Touch;
+import android.view.MotionEvent;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.OptIn;
+import androidx.core.os.BuildCompat;
+
+/**
+ * Backwards compatible version of {@link LinkMovementMethod} which fixes the issue that links can
+ * be triggered for touches outside of line bounds before Android V.
+ */
+public class LinkMovementMethodCompat extends LinkMovementMethod {
+    private static LinkMovementMethodCompat sInstance;
+
+    private LinkMovementMethodCompat() {}
+
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @Override
+    public boolean onTouchEvent(@Nullable TextView widget, @Nullable Spannable buffer,
+            @Nullable MotionEvent event) {
+        if (!BuildCompat.isAtLeastV()) {
+            int action = event.getAction();
+
+            if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
+                int x = (int) event.getX();
+                int y = (int) event.getY();
+
+                x -= widget.getTotalPaddingLeft();
+                y -= widget.getTotalPaddingTop();
+
+                x += widget.getScrollX();
+                y += widget.getScrollY();
+
+                Layout layout = widget.getLayout();
+                boolean isOutOfLineBounds;
+                if (y < 0 || y > layout.getHeight()) {
+                    isOutOfLineBounds = true;
+                } else {
+                    int line = layout.getLineForVertical(y);
+                    isOutOfLineBounds = x < layout.getLineLeft(line)
+                            || x > layout.getLineRight(line);
+                }
+
+                if (isOutOfLineBounds) {
+                    Selection.removeSelection(buffer);
+
+                    // The same as super.onTouchEvent() in LinkMovementMethod.onTouchEvent(), i.e.
+                    // ScrollingMovementMethod.onTouchEvent().
+                    return Touch.onTouchEvent(widget, buffer, event);
+                }
+            }
+        }
+
+        return super.onTouchEvent(widget, buffer, event);
+    }
+
+    /**
+     * Retrieves the singleton instance of {@link LinkMovementMethodCompat}.
+     *
+     * @return the singleton instance of {@link LinkMovementMethodCompat}
+     */
+    @NonNull
+    public static LinkMovementMethodCompat getInstance() {
+        if (sInstance == null) {
+            sInstance = new LinkMovementMethodCompat();
+        }
+
+        return sInstance;
+    }
+}
diff --git a/credentials/credentials/api/api_lint.ignore b/credentials/credentials/api/api_lint.ignore
index 1b0526a3..be1a990 100644
--- a/credentials/credentials/api/api_lint.ignore
+++ b/credentials/credentials/api/api_lint.ignore
@@ -1,4 +1,5 @@
 // Baseline format: 1.0
-GenericCallbacks: androidx.credentials.CredentialManagerCallback:
-    CredentialManagerCallback can be replaced with OutcomeReceiver<R,E> (platform) or suspend fun / ListenableFuture (AndroidX).
-Unnecessary safe call on a non-null receiver of type Bundle
+GetterSetterNames: field CreatePublicKeyCredentialRequest.preferImmediatelyAvailableCredentials:
+    Invalid name for boolean property `preferImmediatelyAvailableCredentials`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field GetPublicKeyCredentialOption.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 0ccc2b2..d15ea9a 100644
--- a/credentials/credentials/api/current.txt
+++ b/credentials/credentials/api/current.txt
@@ -98,7 +98,7 @@
 
   public interface CredentialManagerCallback<R, E> {
     method public void onError(E e);
-    method public void onResult(R? result);
+    method public void onResult(R result);
   }
 
   public abstract class CredentialOption {
diff --git a/credentials/credentials/api/public_plus_experimental_current.txt b/credentials/credentials/api/public_plus_experimental_current.txt
index 0ccc2b2..d15ea9a 100644
--- a/credentials/credentials/api/public_plus_experimental_current.txt
+++ b/credentials/credentials/api/public_plus_experimental_current.txt
@@ -98,7 +98,7 @@
 
   public interface CredentialManagerCallback<R, E> {
     method public void onError(E e);
-    method public void onResult(R? result);
+    method public void onResult(R result);
   }
 
   public abstract class CredentialOption {
diff --git a/credentials/credentials/api/restricted_current.txt b/credentials/credentials/api/restricted_current.txt
index 0ccc2b2..d15ea9a 100644
--- a/credentials/credentials/api/restricted_current.txt
+++ b/credentials/credentials/api/restricted_current.txt
@@ -98,7 +98,7 @@
 
   public interface CredentialManagerCallback<R, E> {
     method public void onError(E e);
-    method public void onResult(R? result);
+    method public void onResult(R result);
   }
 
   public abstract class CredentialOption {
diff --git a/datastore/datastore-core/api/current.ignore b/datastore/datastore-core/api/current.ignore
index c6d6684..9d477c1 100644
--- a/datastore/datastore-core/api/current.ignore
+++ b/datastore/datastore-core/api/current.ignore
@@ -1,4 +1,12 @@
 // Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.core.DataMigration#migrate(T, kotlin.coroutines.Continuation<? super T>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.core.DataMigration.migrate(T currentData, kotlin.coroutines.Continuation<? super T> arg2)
+InvalidNullConversion: androidx.datastore.core.DataMigration#shouldMigrate(T, kotlin.coroutines.Continuation<? super java.lang.Boolean>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.core.DataMigration.shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean> arg2)
+InvalidNullConversion: androidx.datastore.core.Serializer#writeTo(T, java.io.OutputStream, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter t in androidx.datastore.core.Serializer.writeTo(T t, java.io.OutputStream output, kotlin.coroutines.Continuation<? super kotlin.Unit> arg3)
+
+
 ParameterNameChange: androidx.datastore.core.DataMigration#cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
     Attempted to remove parameter name from parameter arg1 in androidx.datastore.core.DataMigration.cleanUp
 ParameterNameChange: androidx.datastore.core.DataMigration#migrate(T, kotlin.coroutines.Continuation<? super T>) parameter #1:
diff --git a/datastore/datastore-core/api/current.txt b/datastore/datastore-core/api/current.txt
index 64fe57a..64db9d6 100644
--- a/datastore/datastore-core/api/current.txt
+++ b/datastore/datastore-core/api/current.txt
@@ -6,7 +6,7 @@
   }
 
   public final class CloseableKt {
-    method public static inline <T extends androidx.datastore.core.Closeable, R> R! use(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+    method public static inline <T extends androidx.datastore.core.Closeable, R> R use(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
   }
 
   public final class CorruptionException extends java.io.IOException {
@@ -15,8 +15,8 @@
 
   public interface DataMigration<T> {
     method public suspend Object? cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public suspend Object? migrate(T? currentData, kotlin.coroutines.Continuation<? super T>);
-    method public suspend Object? shouldMigrate(T? currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public suspend Object? migrate(T currentData, kotlin.coroutines.Continuation<? super T>);
+    method public suspend Object? shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
   }
 
   public interface DataStore<T> {
@@ -60,10 +60,10 @@
   }
 
   public interface Serializer<T> {
-    method public T! getDefaultValue();
+    method public T getDefaultValue();
     method public suspend Object? readFrom(java.io.InputStream input, kotlin.coroutines.Continuation<? super T>);
-    method public suspend Object? writeTo(T? t, java.io.OutputStream output, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public abstract T! defaultValue;
+    method public suspend Object? writeTo(T t, java.io.OutputStream output, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public abstract T defaultValue;
   }
 
   public interface Storage<T> {
@@ -79,11 +79,11 @@
 
   public final class StorageConnectionKt {
     method public static suspend <T> Object? readData(androidx.datastore.core.StorageConnection<T>, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? writeData(androidx.datastore.core.StorageConnection<T>, T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend <T> Object? writeData(androidx.datastore.core.StorageConnection<T>, T value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
   }
 
   public interface WriteScope<T> extends androidx.datastore.core.ReadScope<T> {
-    method public suspend Object? writeData(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? writeData(T value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
   }
 
 }
diff --git a/datastore/datastore-core/api/public_plus_experimental_current.txt b/datastore/datastore-core/api/public_plus_experimental_current.txt
index 3ef2791..0518771 100644
--- a/datastore/datastore-core/api/public_plus_experimental_current.txt
+++ b/datastore/datastore-core/api/public_plus_experimental_current.txt
@@ -6,7 +6,7 @@
   }
 
   public final class CloseableKt {
-    method public static inline <T extends androidx.datastore.core.Closeable, R> R! use(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+    method public static inline <T extends androidx.datastore.core.Closeable, R> R use(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
   }
 
   public final class CorruptionException extends java.io.IOException {
@@ -15,8 +15,8 @@
 
   public interface DataMigration<T> {
     method public suspend Object? cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public suspend Object? migrate(T? currentData, kotlin.coroutines.Continuation<? super T>);
-    method public suspend Object? shouldMigrate(T? currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public suspend Object? migrate(T currentData, kotlin.coroutines.Continuation<? super T>);
+    method public suspend Object? shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
   }
 
   public interface DataStore<T> {
@@ -71,10 +71,10 @@
   }
 
   public interface Serializer<T> {
-    method public T! getDefaultValue();
+    method public T getDefaultValue();
     method public suspend Object? readFrom(java.io.InputStream input, kotlin.coroutines.Continuation<? super T>);
-    method public suspend Object? writeTo(T? t, java.io.OutputStream output, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public abstract T! defaultValue;
+    method public suspend Object? writeTo(T t, java.io.OutputStream output, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public abstract T defaultValue;
   }
 
   public interface Storage<T> {
@@ -90,11 +90,11 @@
 
   public final class StorageConnectionKt {
     method public static suspend <T> Object? readData(androidx.datastore.core.StorageConnection<T>, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? writeData(androidx.datastore.core.StorageConnection<T>, T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend <T> Object? writeData(androidx.datastore.core.StorageConnection<T>, T value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
   }
 
   public interface WriteScope<T> extends androidx.datastore.core.ReadScope<T> {
-    method public suspend Object? writeData(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? writeData(T value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
   }
 
 }
diff --git a/datastore/datastore-core/api/restricted_current.ignore b/datastore/datastore-core/api/restricted_current.ignore
index c6d6684..9d477c1 100644
--- a/datastore/datastore-core/api/restricted_current.ignore
+++ b/datastore/datastore-core/api/restricted_current.ignore
@@ -1,4 +1,12 @@
 // Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.core.DataMigration#migrate(T, kotlin.coroutines.Continuation<? super T>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.core.DataMigration.migrate(T currentData, kotlin.coroutines.Continuation<? super T> arg2)
+InvalidNullConversion: androidx.datastore.core.DataMigration#shouldMigrate(T, kotlin.coroutines.Continuation<? super java.lang.Boolean>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.core.DataMigration.shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean> arg2)
+InvalidNullConversion: androidx.datastore.core.Serializer#writeTo(T, java.io.OutputStream, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter t in androidx.datastore.core.Serializer.writeTo(T t, java.io.OutputStream output, kotlin.coroutines.Continuation<? super kotlin.Unit> arg3)
+
+
 ParameterNameChange: androidx.datastore.core.DataMigration#cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
     Attempted to remove parameter name from parameter arg1 in androidx.datastore.core.DataMigration.cleanUp
 ParameterNameChange: androidx.datastore.core.DataMigration#migrate(T, kotlin.coroutines.Continuation<? super T>) parameter #1:
diff --git a/datastore/datastore-core/api/restricted_current.txt b/datastore/datastore-core/api/restricted_current.txt
index 64fe57a..64db9d6 100644
--- a/datastore/datastore-core/api/restricted_current.txt
+++ b/datastore/datastore-core/api/restricted_current.txt
@@ -6,7 +6,7 @@
   }
 
   public final class CloseableKt {
-    method public static inline <T extends androidx.datastore.core.Closeable, R> R! use(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+    method public static inline <T extends androidx.datastore.core.Closeable, R> R use(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
   }
 
   public final class CorruptionException extends java.io.IOException {
@@ -15,8 +15,8 @@
 
   public interface DataMigration<T> {
     method public suspend Object? cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public suspend Object? migrate(T? currentData, kotlin.coroutines.Continuation<? super T>);
-    method public suspend Object? shouldMigrate(T? currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public suspend Object? migrate(T currentData, kotlin.coroutines.Continuation<? super T>);
+    method public suspend Object? shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
   }
 
   public interface DataStore<T> {
@@ -60,10 +60,10 @@
   }
 
   public interface Serializer<T> {
-    method public T! getDefaultValue();
+    method public T getDefaultValue();
     method public suspend Object? readFrom(java.io.InputStream input, kotlin.coroutines.Continuation<? super T>);
-    method public suspend Object? writeTo(T? t, java.io.OutputStream output, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public abstract T! defaultValue;
+    method public suspend Object? writeTo(T t, java.io.OutputStream output, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public abstract T defaultValue;
   }
 
   public interface Storage<T> {
@@ -79,11 +79,11 @@
 
   public final class StorageConnectionKt {
     method public static suspend <T> Object? readData(androidx.datastore.core.StorageConnection<T>, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? writeData(androidx.datastore.core.StorageConnection<T>, T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend <T> Object? writeData(androidx.datastore.core.StorageConnection<T>, T value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
   }
 
   public interface WriteScope<T> extends androidx.datastore.core.ReadScope<T> {
-    method public suspend Object? writeData(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? writeData(T value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
   }
 
 }
diff --git a/datastore/datastore-preferences-core/api/current.ignore b/datastore/datastore-preferences-core/api/current.ignore
index 92ab16a..dcd14f6 100644
--- a/datastore/datastore-preferences-core/api/current.ignore
+++ b/datastore/datastore-preferences-core/api/current.ignore
@@ -1,3 +1,9 @@
 // Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.preferences.core.MutablePreferences#set(androidx.datastore.preferences.core.Preferences.Key<T>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.datastore.preferences.core.MutablePreferences.set(androidx.datastore.preferences.core.Preferences.Key<T> key, T value)
+InvalidNullConversion: androidx.datastore.preferences.core.Preferences.Key#to(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.datastore.preferences.core.Preferences.Key.to(T value)
+
+
 ParameterNameChange: androidx.datastore.preferences.core.PreferencesKt#edit(androidx.datastore.core.DataStore<androidx.datastore.preferences.core.Preferences>, kotlin.jvm.functions.Function2<? super androidx.datastore.preferences.core.MutablePreferences,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>, kotlin.coroutines.Continuation<? super androidx.datastore.preferences.core.Preferences>) parameter #2:
     Attempted to remove parameter name from parameter arg3 in androidx.datastore.preferences.core.PreferencesKt.edit
diff --git a/datastore/datastore-preferences-core/api/current.txt b/datastore/datastore-preferences-core/api/current.txt
index cdc92af..d3e249b 100644
--- a/datastore/datastore-preferences-core/api/current.txt
+++ b/datastore/datastore-preferences-core/api/current.txt
@@ -10,8 +10,8 @@
     method public operator void plusAssign(androidx.datastore.preferences.core.Preferences prefs);
     method public operator void plusAssign(androidx.datastore.preferences.core.Preferences.Pair<?> pair);
     method public void putAll(androidx.datastore.preferences.core.Preferences.Pair<?>... pairs);
-    method public <T> T! remove(androidx.datastore.preferences.core.Preferences.Key<T> key);
-    method public operator <T> void set(androidx.datastore.preferences.core.Preferences.Key<T> key, T? value);
+    method public <T> T remove(androidx.datastore.preferences.core.Preferences.Key<T> key);
+    method public operator <T> void set(androidx.datastore.preferences.core.Preferences.Key<T> key, T value);
   }
 
   public final class PreferenceDataStoreFactory {
@@ -34,7 +34,7 @@
 
   public static final class Preferences.Key<T> {
     method public String getName();
-    method public infix androidx.datastore.preferences.core.Preferences.Pair<T> to(T? value);
+    method public infix androidx.datastore.preferences.core.Preferences.Pair<T> to(T value);
     property public final String name;
   }
 
diff --git a/datastore/datastore-preferences-core/api/public_plus_experimental_current.txt b/datastore/datastore-preferences-core/api/public_plus_experimental_current.txt
index cdc92af..d3e249b 100644
--- a/datastore/datastore-preferences-core/api/public_plus_experimental_current.txt
+++ b/datastore/datastore-preferences-core/api/public_plus_experimental_current.txt
@@ -10,8 +10,8 @@
     method public operator void plusAssign(androidx.datastore.preferences.core.Preferences prefs);
     method public operator void plusAssign(androidx.datastore.preferences.core.Preferences.Pair<?> pair);
     method public void putAll(androidx.datastore.preferences.core.Preferences.Pair<?>... pairs);
-    method public <T> T! remove(androidx.datastore.preferences.core.Preferences.Key<T> key);
-    method public operator <T> void set(androidx.datastore.preferences.core.Preferences.Key<T> key, T? value);
+    method public <T> T remove(androidx.datastore.preferences.core.Preferences.Key<T> key);
+    method public operator <T> void set(androidx.datastore.preferences.core.Preferences.Key<T> key, T value);
   }
 
   public final class PreferenceDataStoreFactory {
@@ -34,7 +34,7 @@
 
   public static final class Preferences.Key<T> {
     method public String getName();
-    method public infix androidx.datastore.preferences.core.Preferences.Pair<T> to(T? value);
+    method public infix androidx.datastore.preferences.core.Preferences.Pair<T> to(T value);
     property public final String name;
   }
 
diff --git a/datastore/datastore-preferences-core/api/restricted_current.ignore b/datastore/datastore-preferences-core/api/restricted_current.ignore
index 92ab16a..dcd14f6 100644
--- a/datastore/datastore-preferences-core/api/restricted_current.ignore
+++ b/datastore/datastore-preferences-core/api/restricted_current.ignore
@@ -1,3 +1,9 @@
 // Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.preferences.core.MutablePreferences#set(androidx.datastore.preferences.core.Preferences.Key<T>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.datastore.preferences.core.MutablePreferences.set(androidx.datastore.preferences.core.Preferences.Key<T> key, T value)
+InvalidNullConversion: androidx.datastore.preferences.core.Preferences.Key#to(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.datastore.preferences.core.Preferences.Key.to(T value)
+
+
 ParameterNameChange: androidx.datastore.preferences.core.PreferencesKt#edit(androidx.datastore.core.DataStore<androidx.datastore.preferences.core.Preferences>, kotlin.jvm.functions.Function2<? super androidx.datastore.preferences.core.MutablePreferences,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>, kotlin.coroutines.Continuation<? super androidx.datastore.preferences.core.Preferences>) parameter #2:
     Attempted to remove parameter name from parameter arg3 in androidx.datastore.preferences.core.PreferencesKt.edit
diff --git a/datastore/datastore-preferences-core/api/restricted_current.txt b/datastore/datastore-preferences-core/api/restricted_current.txt
index cdc92af..d3e249b 100644
--- a/datastore/datastore-preferences-core/api/restricted_current.txt
+++ b/datastore/datastore-preferences-core/api/restricted_current.txt
@@ -10,8 +10,8 @@
     method public operator void plusAssign(androidx.datastore.preferences.core.Preferences prefs);
     method public operator void plusAssign(androidx.datastore.preferences.core.Preferences.Pair<?> pair);
     method public void putAll(androidx.datastore.preferences.core.Preferences.Pair<?>... pairs);
-    method public <T> T! remove(androidx.datastore.preferences.core.Preferences.Key<T> key);
-    method public operator <T> void set(androidx.datastore.preferences.core.Preferences.Key<T> key, T? value);
+    method public <T> T remove(androidx.datastore.preferences.core.Preferences.Key<T> key);
+    method public operator <T> void set(androidx.datastore.preferences.core.Preferences.Key<T> key, T value);
   }
 
   public final class PreferenceDataStoreFactory {
@@ -34,7 +34,7 @@
 
   public static final class Preferences.Key<T> {
     method public String getName();
-    method public infix androidx.datastore.preferences.core.Preferences.Pair<T> to(T? value);
+    method public infix androidx.datastore.preferences.core.Preferences.Pair<T> to(T value);
     property public final String name;
   }
 
diff --git a/datastore/datastore-rxjava2/api/current.ignore b/datastore/datastore-rxjava2/api/current.ignore
new file mode 100644
index 0000000..2b1768d
--- /dev/null
+++ b/datastore/datastore-rxjava2/api/current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.rxjava2.RxSharedPreferencesMigration#migrate(androidx.datastore.migrations.SharedPreferencesView, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.rxjava2.RxSharedPreferencesMigration.migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData)
+InvalidNullConversion: androidx.datastore.rxjava2.RxSharedPreferencesMigration#shouldMigrate(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.rxjava2.RxSharedPreferencesMigration.shouldMigrate(T currentData)
diff --git a/datastore/datastore-rxjava2/api/current.txt b/datastore/datastore-rxjava2/api/current.txt
index dc394de..0f8fead 100644
--- a/datastore/datastore-rxjava2/api/current.txt
+++ b/datastore/datastore-rxjava2/api/current.txt
@@ -28,8 +28,8 @@
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface RxSharedPreferencesMigration<T> {
-    method public io.reactivex.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T? currentData);
-    method public default io.reactivex.Single<java.lang.Boolean> shouldMigrate(T? currentData);
+    method public io.reactivex.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData);
+    method public default io.reactivex.Single<java.lang.Boolean> shouldMigrate(T currentData);
   }
 
   public final class RxSharedPreferencesMigrationBuilder<T> {
diff --git a/datastore/datastore-rxjava2/api/public_plus_experimental_current.txt b/datastore/datastore-rxjava2/api/public_plus_experimental_current.txt
index fb412f3..50486f6 100644
--- a/datastore/datastore-rxjava2/api/public_plus_experimental_current.txt
+++ b/datastore/datastore-rxjava2/api/public_plus_experimental_current.txt
@@ -30,8 +30,8 @@
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface RxSharedPreferencesMigration<T> {
-    method public io.reactivex.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T? currentData);
-    method public default io.reactivex.Single<java.lang.Boolean> shouldMigrate(T? currentData);
+    method public io.reactivex.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData);
+    method public default io.reactivex.Single<java.lang.Boolean> shouldMigrate(T currentData);
   }
 
   public final class RxSharedPreferencesMigrationBuilder<T> {
diff --git a/datastore/datastore-rxjava2/api/restricted_current.ignore b/datastore/datastore-rxjava2/api/restricted_current.ignore
new file mode 100644
index 0000000..2b1768d
--- /dev/null
+++ b/datastore/datastore-rxjava2/api/restricted_current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.rxjava2.RxSharedPreferencesMigration#migrate(androidx.datastore.migrations.SharedPreferencesView, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.rxjava2.RxSharedPreferencesMigration.migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData)
+InvalidNullConversion: androidx.datastore.rxjava2.RxSharedPreferencesMigration#shouldMigrate(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.rxjava2.RxSharedPreferencesMigration.shouldMigrate(T currentData)
diff --git a/datastore/datastore-rxjava2/api/restricted_current.txt b/datastore/datastore-rxjava2/api/restricted_current.txt
index dc394de..0f8fead 100644
--- a/datastore/datastore-rxjava2/api/restricted_current.txt
+++ b/datastore/datastore-rxjava2/api/restricted_current.txt
@@ -28,8 +28,8 @@
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface RxSharedPreferencesMigration<T> {
-    method public io.reactivex.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T? currentData);
-    method public default io.reactivex.Single<java.lang.Boolean> shouldMigrate(T? currentData);
+    method public io.reactivex.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData);
+    method public default io.reactivex.Single<java.lang.Boolean> shouldMigrate(T currentData);
   }
 
   public final class RxSharedPreferencesMigrationBuilder<T> {
diff --git a/datastore/datastore-rxjava3/api/current.ignore b/datastore/datastore-rxjava3/api/current.ignore
new file mode 100644
index 0000000..624856f
--- /dev/null
+++ b/datastore/datastore-rxjava3/api/current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.rxjava3.RxSharedPreferencesMigration#migrate(androidx.datastore.migrations.SharedPreferencesView, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.rxjava3.RxSharedPreferencesMigration.migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData)
+InvalidNullConversion: androidx.datastore.rxjava3.RxSharedPreferencesMigration#shouldMigrate(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.rxjava3.RxSharedPreferencesMigration.shouldMigrate(T currentData)
diff --git a/datastore/datastore-rxjava3/api/current.txt b/datastore/datastore-rxjava3/api/current.txt
index 218d1e9..ae8528e 100644
--- a/datastore/datastore-rxjava3/api/current.txt
+++ b/datastore/datastore-rxjava3/api/current.txt
@@ -28,8 +28,8 @@
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface RxSharedPreferencesMigration<T> {
-    method public io.reactivex.rxjava3.core.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T? currentData);
-    method public default io.reactivex.rxjava3.core.Single<java.lang.Boolean> shouldMigrate(T? currentData);
+    method public io.reactivex.rxjava3.core.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData);
+    method public default io.reactivex.rxjava3.core.Single<java.lang.Boolean> shouldMigrate(T currentData);
   }
 
   public final class RxSharedPreferencesMigrationBuilder<T> {
diff --git a/datastore/datastore-rxjava3/api/public_plus_experimental_current.txt b/datastore/datastore-rxjava3/api/public_plus_experimental_current.txt
index 025e898..c451a45 100644
--- a/datastore/datastore-rxjava3/api/public_plus_experimental_current.txt
+++ b/datastore/datastore-rxjava3/api/public_plus_experimental_current.txt
@@ -30,8 +30,8 @@
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface RxSharedPreferencesMigration<T> {
-    method public io.reactivex.rxjava3.core.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T? currentData);
-    method public default io.reactivex.rxjava3.core.Single<java.lang.Boolean> shouldMigrate(T? currentData);
+    method public io.reactivex.rxjava3.core.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData);
+    method public default io.reactivex.rxjava3.core.Single<java.lang.Boolean> shouldMigrate(T currentData);
   }
 
   public final class RxSharedPreferencesMigrationBuilder<T> {
diff --git a/datastore/datastore-rxjava3/api/restricted_current.ignore b/datastore/datastore-rxjava3/api/restricted_current.ignore
new file mode 100644
index 0000000..624856f
--- /dev/null
+++ b/datastore/datastore-rxjava3/api/restricted_current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.rxjava3.RxSharedPreferencesMigration#migrate(androidx.datastore.migrations.SharedPreferencesView, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.rxjava3.RxSharedPreferencesMigration.migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData)
+InvalidNullConversion: androidx.datastore.rxjava3.RxSharedPreferencesMigration#shouldMigrate(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.rxjava3.RxSharedPreferencesMigration.shouldMigrate(T currentData)
diff --git a/datastore/datastore-rxjava3/api/restricted_current.txt b/datastore/datastore-rxjava3/api/restricted_current.txt
index 218d1e9..ae8528e 100644
--- a/datastore/datastore-rxjava3/api/restricted_current.txt
+++ b/datastore/datastore-rxjava3/api/restricted_current.txt
@@ -28,8 +28,8 @@
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface RxSharedPreferencesMigration<T> {
-    method public io.reactivex.rxjava3.core.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T? currentData);
-    method public default io.reactivex.rxjava3.core.Single<java.lang.Boolean> shouldMigrate(T? currentData);
+    method public io.reactivex.rxjava3.core.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData);
+    method public default io.reactivex.rxjava3.core.Single<java.lang.Boolean> shouldMigrate(T currentData);
   }
 
   public final class RxSharedPreferencesMigrationBuilder<T> {
diff --git a/datastore/datastore/api/current.ignore b/datastore/datastore/api/current.ignore
index 7141632..a3186a11 100644
--- a/datastore/datastore/api/current.ignore
+++ b/datastore/datastore/api/current.ignore
@@ -1,4 +1,10 @@
 // Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.migrations.SharedPreferencesMigration#migrate(T, kotlin.coroutines.Continuation<? super T>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.migrations.SharedPreferencesMigration.migrate(T currentData, kotlin.coroutines.Continuation<? super T> arg2)
+InvalidNullConversion: androidx.datastore.migrations.SharedPreferencesMigration#shouldMigrate(T, kotlin.coroutines.Continuation<? super java.lang.Boolean>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.migrations.SharedPreferencesMigration.shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean> arg2)
+
+
 ParameterNameChange: androidx.datastore.migrations.SharedPreferencesMigration#cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
     Attempted to remove parameter name from parameter arg1 in androidx.datastore.migrations.SharedPreferencesMigration.cleanUp
 ParameterNameChange: androidx.datastore.migrations.SharedPreferencesMigration#migrate(T, kotlin.coroutines.Continuation<? super T>) parameter #1:
diff --git a/datastore/datastore/api/current.txt b/datastore/datastore/api/current.txt
index c4a6933..91d9597 100644
--- a/datastore/datastore/api/current.txt
+++ b/datastore/datastore/api/current.txt
@@ -21,8 +21,8 @@
     ctor public SharedPreferencesMigration(android.content.Context context, String sharedPreferencesName, optional java.util.Set<java.lang.String> keysToMigrate, kotlin.jvm.functions.Function3<? super androidx.datastore.migrations.SharedPreferencesView,? super T,? super kotlin.coroutines.Continuation<? super T>,?> migrate);
     ctor public SharedPreferencesMigration(android.content.Context context, String sharedPreferencesName, kotlin.jvm.functions.Function3<? super androidx.datastore.migrations.SharedPreferencesView,? super T,? super kotlin.coroutines.Continuation<? super T>,?> migrate);
     method @kotlin.jvm.Throws(exceptionClasses=IOException::class) public suspend Object? cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>) throws java.io.IOException;
-    method public suspend Object? migrate(T? currentData, kotlin.coroutines.Continuation<? super T>);
-    method public suspend Object? shouldMigrate(T? currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public suspend Object? migrate(T currentData, kotlin.coroutines.Continuation<? super T>);
+    method public suspend Object? shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
   }
 
   public final class SharedPreferencesView {
diff --git a/datastore/datastore/api/public_plus_experimental_current.txt b/datastore/datastore/api/public_plus_experimental_current.txt
index c4a6933..91d9597 100644
--- a/datastore/datastore/api/public_plus_experimental_current.txt
+++ b/datastore/datastore/api/public_plus_experimental_current.txt
@@ -21,8 +21,8 @@
     ctor public SharedPreferencesMigration(android.content.Context context, String sharedPreferencesName, optional java.util.Set<java.lang.String> keysToMigrate, kotlin.jvm.functions.Function3<? super androidx.datastore.migrations.SharedPreferencesView,? super T,? super kotlin.coroutines.Continuation<? super T>,?> migrate);
     ctor public SharedPreferencesMigration(android.content.Context context, String sharedPreferencesName, kotlin.jvm.functions.Function3<? super androidx.datastore.migrations.SharedPreferencesView,? super T,? super kotlin.coroutines.Continuation<? super T>,?> migrate);
     method @kotlin.jvm.Throws(exceptionClasses=IOException::class) public suspend Object? cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>) throws java.io.IOException;
-    method public suspend Object? migrate(T? currentData, kotlin.coroutines.Continuation<? super T>);
-    method public suspend Object? shouldMigrate(T? currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public suspend Object? migrate(T currentData, kotlin.coroutines.Continuation<? super T>);
+    method public suspend Object? shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
   }
 
   public final class SharedPreferencesView {
diff --git a/datastore/datastore/api/restricted_current.ignore b/datastore/datastore/api/restricted_current.ignore
index 7141632..a3186a11 100644
--- a/datastore/datastore/api/restricted_current.ignore
+++ b/datastore/datastore/api/restricted_current.ignore
@@ -1,4 +1,10 @@
 // Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.migrations.SharedPreferencesMigration#migrate(T, kotlin.coroutines.Continuation<? super T>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.migrations.SharedPreferencesMigration.migrate(T currentData, kotlin.coroutines.Continuation<? super T> arg2)
+InvalidNullConversion: androidx.datastore.migrations.SharedPreferencesMigration#shouldMigrate(T, kotlin.coroutines.Continuation<? super java.lang.Boolean>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.migrations.SharedPreferencesMigration.shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean> arg2)
+
+
 ParameterNameChange: androidx.datastore.migrations.SharedPreferencesMigration#cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
     Attempted to remove parameter name from parameter arg1 in androidx.datastore.migrations.SharedPreferencesMigration.cleanUp
 ParameterNameChange: androidx.datastore.migrations.SharedPreferencesMigration#migrate(T, kotlin.coroutines.Continuation<? super T>) parameter #1:
diff --git a/datastore/datastore/api/restricted_current.txt b/datastore/datastore/api/restricted_current.txt
index c4a6933..91d9597 100644
--- a/datastore/datastore/api/restricted_current.txt
+++ b/datastore/datastore/api/restricted_current.txt
@@ -21,8 +21,8 @@
     ctor public SharedPreferencesMigration(android.content.Context context, String sharedPreferencesName, optional java.util.Set<java.lang.String> keysToMigrate, kotlin.jvm.functions.Function3<? super androidx.datastore.migrations.SharedPreferencesView,? super T,? super kotlin.coroutines.Continuation<? super T>,?> migrate);
     ctor public SharedPreferencesMigration(android.content.Context context, String sharedPreferencesName, kotlin.jvm.functions.Function3<? super androidx.datastore.migrations.SharedPreferencesView,? super T,? super kotlin.coroutines.Continuation<? super T>,?> migrate);
     method @kotlin.jvm.Throws(exceptionClasses=IOException::class) public suspend Object? cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>) throws java.io.IOException;
-    method public suspend Object? migrate(T? currentData, kotlin.coroutines.Continuation<? super T>);
-    method public suspend Object? shouldMigrate(T? currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public suspend Object? migrate(T currentData, kotlin.coroutines.Continuation<? super T>);
+    method public suspend Object? shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
   }
 
   public final class SharedPreferencesView {
diff --git a/development/update-verification-metadata.sh b/development/update-verification-metadata.sh
index 90720f2..4820585 100755
--- a/development/update-verification-metadata.sh
+++ b/development/update-verification-metadata.sh
@@ -17,15 +17,17 @@
   echo "regenerating verification metadata and keyring"
   # regenerate metadata
   # Need to run a clean build, https://github.com/gradle/gradle/issues/19228
-  runGradle --stacktrace --write-verification-metadata pgp,sha256 --export-keys --dry-run --clean bOS :docs-kmp:zipCombinedKmpDocs
+  runGradle --stacktrace --write-verification-metadata pgp,sha256 --export-keys --dry-run --clean -Pandroidx.update.signatures=true bOS :docs-kmp:zipCombinedKmpDocs
 
   # update verification metadata file
   # also remove 'version=' lines, https://github.com/gradle/gradle/issues/20192
   cat gradle/verification-metadata.dryrun.xml | sed 's/ \(trusted-key.*\)version="[^"]*"/\1/' > gradle/verification-metadata.xml
 
+  # rename keyring
+  mv gradle/verification-keyring-dryrun.keys gradle/verification-keyring.keys
+
   # remove temporary files
   rm -f gradle/verification-keyring-dryrun.gpg
-  rm -f gradle/verification-keyring-dryrun.keys
   rm -f gradle/verification-metadata.dryrun.xml
 }
 regenerateVerificationMetadata
diff --git a/docs-public/build.gradle b/docs-public/build.gradle
index fbe7d81..54c5515 100644
--- a/docs-public/build.gradle
+++ b/docs-public/build.gradle
@@ -402,7 +402,7 @@
     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-beta01")
-    docs("androidx.window.extensions.core:core:1.0.0-beta02")
+    docs("androidx.window.extensions.core:core:1.0.0-rc01")
     docs("androidx.window:window:1.1.0-beta02")
     stubs(fileTree(dir: "../window/stubs/", include: ["window-sidecar-release-0.1.0-alpha01.aar"]))
     docs("androidx.window:window-core:1.1.0-beta02")
diff --git a/docs-tip-of-tree/build.gradle b/docs-tip-of-tree/build.gradle
index 1b401fe..20df0bf 100644
--- a/docs-tip-of-tree/build.gradle
+++ b/docs-tip-of-tree/build.gradle
@@ -171,6 +171,7 @@
     docs(project(":fragment:fragment-testing"))
     docs(project(":glance:glance"))
     docs(project(":glance:glance-appwidget"))
+    samples(project(":glance:glance-appwidget:glance-appwidget-samples"))
     docs(project(":glance:glance-wear-tiles"))
     docs(project(":graphics:filters:filters"))
     docs(project(":graphics:graphics-core"))
@@ -367,7 +368,7 @@
     docs(project(":window:window-rxjava2"))
     docs(project(":window:window-rxjava3"))
     stubs(project(":window:sidecar:sidecar"))
-    samples(project(":window:window-samples:"))
+    samples(project(":window:window-samples"))
     stubs(project(":window:extensions:extensions"))
     stubs(project(":window:extensions:core:core"))
     docs(project(":window:window-testing"))
diff --git a/enterprise/enterprise-feedback-testing/build.gradle b/enterprise/enterprise-feedback-testing/build.gradle
index 643fe67..184a4d1 100644
--- a/enterprise/enterprise-feedback-testing/build.gradle
+++ b/enterprise/enterprise-feedback-testing/build.gradle
@@ -21,7 +21,7 @@
     id("com.android.library")
 }
 dependencies {
-    api(project(":enterprise:enterprise-feedback:"))
+    api(project(":enterprise:enterprise-feedback"))
     testImplementation(libs.truth)
 }
 android {
diff --git a/fragment/fragment/api/1.6.0-beta01.txt b/fragment/fragment/api/1.6.0-beta01.txt
index 2f167cf..4d44df2 100644
--- a/fragment/fragment/api/1.6.0-beta01.txt
+++ b/fragment/fragment/api/1.6.0-beta01.txt
@@ -196,7 +196,7 @@
     ctor public FragmentContainerView(android.content.Context context);
     ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs, optional int defStyleAttr);
     ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs);
-    method public <F extends androidx.fragment.app.Fragment> F! getFragment();
+    method public <F extends androidx.fragment.app.Fragment> F getFragment();
   }
 
   public class FragmentController {
diff --git a/fragment/fragment/api/current.txt b/fragment/fragment/api/current.txt
index 2f167cf..4d44df2 100644
--- a/fragment/fragment/api/current.txt
+++ b/fragment/fragment/api/current.txt
@@ -196,7 +196,7 @@
     ctor public FragmentContainerView(android.content.Context context);
     ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs, optional int defStyleAttr);
     ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs);
-    method public <F extends androidx.fragment.app.Fragment> F! getFragment();
+    method public <F extends androidx.fragment.app.Fragment> F getFragment();
   }
 
   public class FragmentController {
diff --git a/fragment/fragment/api/public_plus_experimental_1.6.0-beta01.txt b/fragment/fragment/api/public_plus_experimental_1.6.0-beta01.txt
index 2f167cf..4d44df2 100644
--- a/fragment/fragment/api/public_plus_experimental_1.6.0-beta01.txt
+++ b/fragment/fragment/api/public_plus_experimental_1.6.0-beta01.txt
@@ -196,7 +196,7 @@
     ctor public FragmentContainerView(android.content.Context context);
     ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs, optional int defStyleAttr);
     ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs);
-    method public <F extends androidx.fragment.app.Fragment> F! getFragment();
+    method public <F extends androidx.fragment.app.Fragment> F getFragment();
   }
 
   public class FragmentController {
diff --git a/fragment/fragment/api/public_plus_experimental_current.txt b/fragment/fragment/api/public_plus_experimental_current.txt
index 2f167cf..4d44df2 100644
--- a/fragment/fragment/api/public_plus_experimental_current.txt
+++ b/fragment/fragment/api/public_plus_experimental_current.txt
@@ -196,7 +196,7 @@
     ctor public FragmentContainerView(android.content.Context context);
     ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs, optional int defStyleAttr);
     ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs);
-    method public <F extends androidx.fragment.app.Fragment> F! getFragment();
+    method public <F extends androidx.fragment.app.Fragment> F getFragment();
   }
 
   public class FragmentController {
diff --git a/fragment/fragment/api/restricted_1.6.0-beta01.txt b/fragment/fragment/api/restricted_1.6.0-beta01.txt
index 83801ad..369fe63 100644
--- a/fragment/fragment/api/restricted_1.6.0-beta01.txt
+++ b/fragment/fragment/api/restricted_1.6.0-beta01.txt
@@ -200,7 +200,7 @@
     ctor public FragmentContainerView(android.content.Context context);
     ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs, optional int defStyleAttr);
     ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs);
-    method public <F extends androidx.fragment.app.Fragment> F! getFragment();
+    method public <F extends androidx.fragment.app.Fragment> F getFragment();
   }
 
   public class FragmentController {
diff --git a/fragment/fragment/api/restricted_current.txt b/fragment/fragment/api/restricted_current.txt
index 83801ad..369fe63 100644
--- a/fragment/fragment/api/restricted_current.txt
+++ b/fragment/fragment/api/restricted_current.txt
@@ -200,7 +200,7 @@
     ctor public FragmentContainerView(android.content.Context context);
     ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs, optional int defStyleAttr);
     ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs);
-    method public <F extends androidx.fragment.app.Fragment> F! getFragment();
+    method public <F extends androidx.fragment.app.Fragment> F getFragment();
   }
 
   public class FragmentController {
diff --git a/glance/glance-appwidget/api/current.txt b/glance/glance-appwidget/api/current.txt
index ca32bb4..72717d0 100644
--- a/glance/glance-appwidget/api/current.txt
+++ b/glance/glance-appwidget/api/current.txt
@@ -24,9 +24,13 @@
   public final class CheckBoxKt {
     method @androidx.compose.runtime.Composable public static void CheckBox(boolean checked, androidx.glance.action.Action? onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines);
     method @androidx.compose.runtime.Composable public static void CheckBox(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors(long checkedColor, long uncheckedColor);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors();
+  }
+
+  public final class CheckboxDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors(long checkedColor, long uncheckedColor);
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors();
+    field public static final androidx.glance.appwidget.CheckboxDefaults INSTANCE;
   }
 
   public final class CircularProgressIndicatorKt {
@@ -45,11 +49,10 @@
 
   public abstract class GlanceAppWidget {
     ctor public GlanceAppWidget(optional @LayoutRes int errorUiLayout);
-    method @Deprecated @androidx.compose.runtime.Composable @androidx.glance.GlanceComposable public void Content();
     method public androidx.glance.appwidget.SizeMode getSizeMode();
     method public androidx.glance.state.GlanceStateDefinition<?>? getStateDefinition();
     method public suspend Object? onDelete(android.content.Context context, androidx.glance.GlanceId glanceId, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public abstract suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public final suspend Object? update(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     property public androidx.glance.appwidget.SizeMode sizeMode;
     property public androidx.glance.state.GlanceStateDefinition<?>? stateDefinition;
@@ -102,12 +105,16 @@
   public final class RadioButtonColors {
   }
 
+  public final class RadioButtonDefaults {
+    method public androidx.glance.appwidget.RadioButtonColors colors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
+    method public androidx.glance.appwidget.RadioButtonColors colors(long checkedColor, long uncheckedColor);
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.RadioButtonColors colors();
+    field public static final androidx.glance.appwidget.RadioButtonDefaults INSTANCE;
+  }
+
   public final class RadioButtonKt {
     method @androidx.compose.runtime.Composable public static void RadioButton(boolean checked, androidx.glance.action.Action? onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines);
     method @androidx.compose.runtime.Composable public static void RadioButton(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines);
-    method public static androidx.glance.appwidget.RadioButtonColors radioButtonColors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
-    method public static androidx.glance.appwidget.RadioButtonColors radioButtonColors(long checkedColor, long uncheckedColor);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.RadioButtonColors radioButtonColors();
     method public static androidx.glance.GlanceModifier selectableGroup(androidx.glance.GlanceModifier);
   }
 
@@ -131,11 +138,15 @@
   public abstract sealed class SwitchColors {
   }
 
+  public final class SwitchDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.SwitchColors colors(androidx.glance.unit.ColorProvider checkedThumbColor, androidx.glance.unit.ColorProvider uncheckedThumbColor, androidx.glance.unit.ColorProvider checkedTrackColor, androidx.glance.unit.ColorProvider uncheckedTrackColor);
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.SwitchColors colors();
+    field public static final androidx.glance.appwidget.SwitchDefaults INSTANCE;
+  }
+
   public final class SwitchKt {
     method @androidx.compose.runtime.Composable public static void Switch(boolean checked, androidx.glance.action.Action? onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines);
     method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.SwitchColors switchColors(androidx.glance.unit.ColorProvider checkedThumbColor, androidx.glance.unit.ColorProvider uncheckedThumbColor, androidx.glance.unit.ColorProvider checkedTrackColor, androidx.glance.unit.ColorProvider uncheckedTrackColor);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.SwitchColors switchColors();
   }
 
 }
diff --git a/glance/glance-appwidget/api/public_plus_experimental_current.txt b/glance/glance-appwidget/api/public_plus_experimental_current.txt
index 7143945..4ac3223 100644
--- a/glance/glance-appwidget/api/public_plus_experimental_current.txt
+++ b/glance/glance-appwidget/api/public_plus_experimental_current.txt
@@ -24,9 +24,13 @@
   public final class CheckBoxKt {
     method @androidx.compose.runtime.Composable public static void CheckBox(boolean checked, androidx.glance.action.Action? onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines);
     method @androidx.compose.runtime.Composable public static void CheckBox(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors(long checkedColor, long uncheckedColor);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors();
+  }
+
+  public final class CheckboxDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors(long checkedColor, long uncheckedColor);
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors();
+    field public static final androidx.glance.appwidget.CheckboxDefaults INSTANCE;
   }
 
   public final class CircularProgressIndicatorKt {
@@ -48,11 +52,10 @@
 
   public abstract class GlanceAppWidget {
     ctor public GlanceAppWidget(optional @LayoutRes int errorUiLayout);
-    method @Deprecated @androidx.compose.runtime.Composable @androidx.glance.GlanceComposable public void Content();
     method public androidx.glance.appwidget.SizeMode getSizeMode();
     method public androidx.glance.state.GlanceStateDefinition<?>? getStateDefinition();
     method public suspend Object? onDelete(android.content.Context context, androidx.glance.GlanceId glanceId, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public abstract suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public final suspend Object? update(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     property public androidx.glance.appwidget.SizeMode sizeMode;
     property public androidx.glance.state.GlanceStateDefinition<?>? stateDefinition;
@@ -110,12 +113,16 @@
   public final class RadioButtonColors {
   }
 
+  public final class RadioButtonDefaults {
+    method public androidx.glance.appwidget.RadioButtonColors colors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
+    method public androidx.glance.appwidget.RadioButtonColors colors(long checkedColor, long uncheckedColor);
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.RadioButtonColors colors();
+    field public static final androidx.glance.appwidget.RadioButtonDefaults INSTANCE;
+  }
+
   public final class RadioButtonKt {
     method @androidx.compose.runtime.Composable public static void RadioButton(boolean checked, androidx.glance.action.Action? onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines);
     method @androidx.compose.runtime.Composable public static void RadioButton(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines);
-    method public static androidx.glance.appwidget.RadioButtonColors radioButtonColors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
-    method public static androidx.glance.appwidget.RadioButtonColors radioButtonColors(long checkedColor, long uncheckedColor);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.RadioButtonColors radioButtonColors();
     method public static androidx.glance.GlanceModifier selectableGroup(androidx.glance.GlanceModifier);
   }
 
@@ -145,11 +152,15 @@
   public abstract sealed class SwitchColors {
   }
 
+  public final class SwitchDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.SwitchColors colors(androidx.glance.unit.ColorProvider checkedThumbColor, androidx.glance.unit.ColorProvider uncheckedThumbColor, androidx.glance.unit.ColorProvider checkedTrackColor, androidx.glance.unit.ColorProvider uncheckedTrackColor);
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.SwitchColors colors();
+    field public static final androidx.glance.appwidget.SwitchDefaults INSTANCE;
+  }
+
   public final class SwitchKt {
     method @androidx.compose.runtime.Composable public static void Switch(boolean checked, androidx.glance.action.Action? onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines);
     method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.SwitchColors switchColors(androidx.glance.unit.ColorProvider checkedThumbColor, androidx.glance.unit.ColorProvider uncheckedThumbColor, androidx.glance.unit.ColorProvider checkedTrackColor, androidx.glance.unit.ColorProvider uncheckedTrackColor);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.SwitchColors switchColors();
   }
 
 }
diff --git a/glance/glance-appwidget/api/restricted_current.txt b/glance/glance-appwidget/api/restricted_current.txt
index ca32bb4..72717d0 100644
--- a/glance/glance-appwidget/api/restricted_current.txt
+++ b/glance/glance-appwidget/api/restricted_current.txt
@@ -24,9 +24,13 @@
   public final class CheckBoxKt {
     method @androidx.compose.runtime.Composable public static void CheckBox(boolean checked, androidx.glance.action.Action? onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines);
     method @androidx.compose.runtime.Composable public static void CheckBox(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors(long checkedColor, long uncheckedColor);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors();
+  }
+
+  public final class CheckboxDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors(long checkedColor, long uncheckedColor);
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors();
+    field public static final androidx.glance.appwidget.CheckboxDefaults INSTANCE;
   }
 
   public final class CircularProgressIndicatorKt {
@@ -45,11 +49,10 @@
 
   public abstract class GlanceAppWidget {
     ctor public GlanceAppWidget(optional @LayoutRes int errorUiLayout);
-    method @Deprecated @androidx.compose.runtime.Composable @androidx.glance.GlanceComposable public void Content();
     method public androidx.glance.appwidget.SizeMode getSizeMode();
     method public androidx.glance.state.GlanceStateDefinition<?>? getStateDefinition();
     method public suspend Object? onDelete(android.content.Context context, androidx.glance.GlanceId glanceId, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public abstract suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public final suspend Object? update(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     property public androidx.glance.appwidget.SizeMode sizeMode;
     property public androidx.glance.state.GlanceStateDefinition<?>? stateDefinition;
@@ -102,12 +105,16 @@
   public final class RadioButtonColors {
   }
 
+  public final class RadioButtonDefaults {
+    method public androidx.glance.appwidget.RadioButtonColors colors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
+    method public androidx.glance.appwidget.RadioButtonColors colors(long checkedColor, long uncheckedColor);
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.RadioButtonColors colors();
+    field public static final androidx.glance.appwidget.RadioButtonDefaults INSTANCE;
+  }
+
   public final class RadioButtonKt {
     method @androidx.compose.runtime.Composable public static void RadioButton(boolean checked, androidx.glance.action.Action? onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines);
     method @androidx.compose.runtime.Composable public static void RadioButton(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines);
-    method public static androidx.glance.appwidget.RadioButtonColors radioButtonColors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
-    method public static androidx.glance.appwidget.RadioButtonColors radioButtonColors(long checkedColor, long uncheckedColor);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.RadioButtonColors radioButtonColors();
     method public static androidx.glance.GlanceModifier selectableGroup(androidx.glance.GlanceModifier);
   }
 
@@ -131,11 +138,15 @@
   public abstract sealed class SwitchColors {
   }
 
+  public final class SwitchDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.SwitchColors colors(androidx.glance.unit.ColorProvider checkedThumbColor, androidx.glance.unit.ColorProvider uncheckedThumbColor, androidx.glance.unit.ColorProvider checkedTrackColor, androidx.glance.unit.ColorProvider uncheckedTrackColor);
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.SwitchColors colors();
+    field public static final androidx.glance.appwidget.SwitchDefaults INSTANCE;
+  }
+
   public final class SwitchKt {
     method @androidx.compose.runtime.Composable public static void Switch(boolean checked, androidx.glance.action.Action? onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines);
     method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.SwitchColors switchColors(androidx.glance.unit.ColorProvider checkedThumbColor, androidx.glance.unit.ColorProvider uncheckedThumbColor, androidx.glance.unit.ColorProvider checkedTrackColor, androidx.glance.unit.ColorProvider uncheckedTrackColor);
-    method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.SwitchColors switchColors();
   }
 
 }
diff --git a/glance/glance-appwidget/build.gradle b/glance/glance-appwidget/build.gradle
index b098ddc..3eaf94a 100644
--- a/glance/glance-appwidget/build.gradle
+++ b/glance/glance-appwidget/build.gradle
@@ -86,6 +86,8 @@
     androidTestImplementation(libs.testRunner)
     androidTestImplementation(libs.truth)
     androidTestImplementation(libs.kotlinReflect)
+
+    samples(projectOrArtifact(":glance:glance-appwidget:glance-appwidget-samples"))
 }
 
 android {
diff --git a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/CompoundButtonAppWidget.kt b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/CompoundButtonAppWidget.kt
index e6fbcbf..597ba89 100644
--- a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/CompoundButtonAppWidget.kt
+++ b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/CompoundButtonAppWidget.kt
@@ -27,18 +27,18 @@
 import androidx.glance.GlanceId
 import androidx.glance.GlanceModifier
 import androidx.glance.appwidget.CheckBox
+import androidx.glance.appwidget.CheckboxDefaults
 import androidx.glance.appwidget.GlanceAppWidget
 import androidx.glance.appwidget.GlanceAppWidgetReceiver
 import androidx.glance.appwidget.RadioButton
+import androidx.glance.appwidget.RadioButtonDefaults
 import androidx.glance.appwidget.SizeMode
 import androidx.glance.appwidget.Switch
+import androidx.glance.appwidget.SwitchDefaults
 import androidx.glance.appwidget.appWidgetBackground
-import androidx.glance.appwidget.checkBoxColors
 import androidx.glance.appwidget.cornerRadius
-import androidx.glance.appwidget.radioButtonColors
 import androidx.glance.appwidget.selectableGroup
 import androidx.glance.appwidget.provideContent
-import androidx.glance.appwidget.switchColors
 import androidx.glance.background
 import androidx.glance.color.ColorProvider
 import androidx.glance.layout.Alignment
@@ -94,7 +94,7 @@
                 text = "Checkbox 2",
                 style = textStyle,
                 modifier = fillModifier,
-                colors = checkBoxColors(
+                colors = CheckboxDefaults.colors(
                     checkedColor = ColorProvider(day = Color.Red, night = Color.Cyan),
                     uncheckedColor = ColorProvider(day = Color.Green, night = Color.Magenta)
                 )
@@ -108,7 +108,7 @@
                 checked = switch1Checked,
                 onCheckedChange = { switch1Checked = !switch1Checked },
                 text = "Switch 1",
-                colors = switchColors(
+                colors = SwitchDefaults.colors(
                     checkedThumbColor = ColorProvider(day = Color.Red, night = Color.Cyan),
                     uncheckedThumbColor = ColorProvider(day = Color.Green, night = Color.Magenta),
                     checkedTrackColor = ColorProvider(day = Color.Blue, night = Color.Yellow),
@@ -127,7 +127,7 @@
                     checked = radioChecked == 0,
                     onClick = { radioChecked = 0 },
                     text = "Radio 1",
-                    colors = radioButtonColors(
+                    colors = RadioButtonDefaults.colors(
                         checkedColor = ColorProvider(day = Color.Red, night = Color.Cyan),
                         uncheckedColor = ColorProvider(day = Color.Green, night = Color.Magenta)
                     ),
@@ -136,7 +136,7 @@
                     checked = radioChecked == 1,
                     onClick = { radioChecked = 1 },
                     text = "Radio 2",
-                    colors = radioButtonColors(
+                    colors = RadioButtonDefaults.colors(
                         checkedColor = ColorProvider(day = Color.Cyan, night = Color.Yellow),
                         uncheckedColor = ColorProvider(day = Color.Red, night = Color.Blue)
                     ),
diff --git a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/DefaultStateAppWidget.kt b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/DefaultStateAppWidget.kt
index fe9dbc3..c4cdd7a 100644
--- a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/DefaultStateAppWidget.kt
+++ b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/DefaultStateAppWidget.kt
@@ -1,7 +1,6 @@
 package androidx.glance.appwidget.demos
 
 import android.content.Context
-import androidx.compose.runtime.Composable
 import androidx.compose.ui.unit.dp
 import androidx.datastore.preferences.core.intPreferencesKey
 import androidx.glance.Button
@@ -14,6 +13,7 @@
 import androidx.glance.appwidget.action.ActionCallback
 import androidx.glance.appwidget.action.actionRunCallback
 import androidx.glance.appwidget.appWidgetBackground
+import androidx.glance.appwidget.provideContent
 import androidx.glance.appwidget.state.updateAppWidgetState
 import androidx.glance.background
 import androidx.glance.currentState
@@ -35,9 +35,7 @@
 // the +/- clicks values.
 class DefaultStateAppWidget : GlanceAppWidget() {
 
-    @Composable
-    @Deprecated("")
-    override fun Content() {
+    override suspend fun provideGlance(context: Context, id: GlanceId) = provideContent {
         // Get the current stored value for the given Key.
         val count = currentState(CountClicksKey) ?: 0
 
diff --git a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ResponsiveAppWidget.kt b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ResponsiveAppWidget.kt
index cdea0ef..aaf9c38 100644
--- a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ResponsiveAppWidget.kt
+++ b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ResponsiveAppWidget.kt
@@ -24,7 +24,7 @@
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
 import androidx.glance.Button
-import androidx.glance.ButtonColors
+import androidx.glance.ButtonDefaults
 import androidx.glance.GlanceId
 import androidx.glance.GlanceModifier
 import androidx.glance.LocalContext
@@ -157,7 +157,7 @@
         Button(
             text = text,
             modifier = GlanceModifier.fillMaxSize().padding(8.dp).background(color),
-            colors = ButtonColors(
+            colors = ButtonDefaults.buttonColors(
                 backgroundColor = ColorProvider(color),
                 contentColor = ColorProvider(Color.White)
             ),
diff --git a/glance/glance-appwidget/samples/build.gradle b/glance/glance-appwidget/samples/build.gradle
new file mode 100644
index 0000000..e5279ee
--- /dev/null
+++ b/glance/glance-appwidget/samples/build.gradle
@@ -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.
+ */
+
+import androidx.build.LibraryType
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+    id("AndroidXComposePlugin")
+    id("org.jetbrains.kotlin.android")
+}
+
+dependencies {
+
+    implementation(libs.kotlinStdlib)
+    implementation("androidx.core:core:1.5.0")
+
+    compileOnly(project(":annotation:annotation-sampled"))
+
+    implementation(project(":glance:glance"))
+    implementation(project(":glance:glance-appwidget"))
+}
+
+androidx {
+    name = "Glance AppWidget Classes Samples"
+    type = LibraryType.SAMPLES
+    inceptionYear = "2023"
+    description = "Contains the sample code for the Glance AppWidget Classes Samples"
+}
+
+android {
+    namespace "androidx.glance.appwidget.samples"
+}
diff --git a/glance/glance-appwidget/samples/src/main/java/androidx/glance/appwidget/samples/GlanceAppWidgetSamples.kt b/glance/glance-appwidget/samples/src/main/java/androidx/glance/appwidget/samples/GlanceAppWidgetSamples.kt
new file mode 100644
index 0000000..43fec19
--- /dev/null
+++ b/glance/glance-appwidget/samples/src/main/java/androidx/glance/appwidget/samples/GlanceAppWidgetSamples.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.glance.appwidget.samples
+
+import android.content.Context
+import androidx.annotation.Sampled
+import androidx.glance.GlanceId
+import androidx.glance.appwidget.GlanceAppWidget
+import androidx.glance.appwidget.provideContent
+import androidx.glance.text.Text
+
+@Sampled
+suspend fun GlanceAppWidget.provideGlanceSample(
+    @Suppress("UNUSED_PARAMETER") context: Context,
+    @Suppress("UNUSED_PARAMETER") id: GlanceId,
+) {
+    // Load data needed to render the AppWidget.
+    provideContent {
+        // create your AppWidget here
+        Text("Hello World")
+    }
+}
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverScreenshotTest.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverScreenshotTest.kt
index b0897e3..3fcfbdd 100644
--- a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverScreenshotTest.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverScreenshotTest.kt
@@ -24,7 +24,7 @@
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 import androidx.glance.Button
-import androidx.glance.ButtonColors
+import androidx.glance.ButtonDefaults
 import androidx.glance.GlanceModifier
 import androidx.glance.Image
 import androidx.glance.ImageProvider
@@ -252,7 +252,7 @@
                         "Start",
                         onClick = actionStartActivity<Activity>(),
                         modifier = GlanceModifier.defaultWeight().fillMaxHeight(),
-                        colors = ButtonColors(
+                        colors = ButtonDefaults.buttonColors(
                             backgroundColor = ColorProvider(Color.Transparent),
                             contentColor = ColorProvider(Color.DarkGray)
                         ),
@@ -262,7 +262,7 @@
                         "End",
                         onClick = actionStartActivity<Activity>(),
                         modifier = GlanceModifier.defaultWeight().fillMaxHeight(),
-                        colors = ButtonColors(
+                        colors = ButtonDefaults.buttonColors(
                             backgroundColor = ColorProvider(Color.Transparent),
                             contentColor = ColorProvider(Color.DarkGray)
                         ),
@@ -656,7 +656,7 @@
         Button(
             "Button with textAlign = Start",
             onClick = actionStartActivity<Activity>(),
-            colors = ButtonColors(
+            colors = ButtonDefaults.buttonColors(
                 backgroundColor = ColorProvider(day = buttonBgColors[0], night = buttonBgColors[1]),
                 contentColor = ColorProvider(day = buttonTextColors[0], night = buttonTextColors[1])
             ),
@@ -667,7 +667,7 @@
             "Button with textAlign = Center and padding (30dp, 30dp)",
             onClick = actionStartActivity<Activity>(),
             modifier = GlanceModifier.padding(horizontal = 30.dp, vertical = 30.dp),
-            colors = ButtonColors(
+            colors = ButtonDefaults.buttonColors(
                 backgroundColor = ColorProvider(day = buttonBgColors[0], night = buttonBgColors[1]),
                 contentColor = ColorProvider(day = buttonTextColors[0], night = buttonTextColors[1])
             ),
@@ -677,7 +677,7 @@
         Button(
             "Button with textAlign = End",
             onClick = actionStartActivity<Activity>(),
-            colors = ButtonColors(
+            colors = ButtonDefaults.buttonColors(
                 backgroundColor = ColorProvider(day = buttonBgColors[0], night = buttonBgColors[1]),
                 contentColor = ColorProvider(day = buttonTextColors[0], night = buttonTextColors[1])
             ),
@@ -699,7 +699,7 @@
                 fontWeight = FontWeight.Bold,
                 fontStyle = FontStyle.Normal,
             ),
-            colors = checkBoxColors(
+            colors = CheckboxDefaults.colors(
                 checkedColor = ColorProvider(day = Color.Magenta, night = Color.Yellow),
                 uncheckedColor = ColorProvider(day = Color.Black, night = Color.Gray)
             )
@@ -715,7 +715,7 @@
                 fontWeight = FontWeight.Medium,
                 fontStyle = FontStyle.Italic,
             ),
-            colors = checkBoxColors(checkedColor = Color.Red, uncheckedColor = Color.Green)
+            colors = CheckboxDefaults.colors(checkedColor = Color.Red, uncheckedColor = Color.Green)
         )
     }
 }
@@ -732,7 +732,7 @@
                 fontWeight = FontWeight.Bold,
                 fontStyle = FontStyle.Normal,
             ),
-            colors = switchColors(
+            colors = SwitchDefaults.colors(
                 checkedThumbColor = ColorProvider(day = Color.Blue, night = Color.Red),
                 uncheckedThumbColor = ColorProvider(Color.Magenta),
                 checkedTrackColor = ColorProvider(day = Color.Green, night = Color.Yellow),
@@ -750,7 +750,7 @@
                 fontWeight = FontWeight.Medium,
                 fontStyle = FontStyle.Italic,
             ),
-            colors = switchColors(
+            colors = SwitchDefaults.colors(
                 checkedThumbColor = ColorProvider(Color.Blue),
                 uncheckedThumbColor = ColorProvider(day = Color.Magenta, night = Color.Cyan),
                 checkedTrackColor = ColorProvider(Color.Blue),
@@ -775,7 +775,7 @@
                 fontWeight = FontWeight.Bold,
                 fontStyle = FontStyle.Normal,
             ),
-            colors = radioButtonColors(
+            colors = RadioButtonDefaults.colors(
                 checkedColor = ColorProvider(day = Color.Magenta, night = Color.Yellow),
                 uncheckedColor = ColorProvider(day = Color.Yellow, night = Color.Magenta)
             )
@@ -791,7 +791,10 @@
                 fontWeight = FontWeight.Medium,
                 fontStyle = FontStyle.Italic,
             ),
-            colors = radioButtonColors(checkedColor = Color.Red, uncheckedColor = Color.Green)
+            colors = RadioButtonDefaults.colors(
+                checkedColor = Color.Red,
+                uncheckedColor = Color.Green
+            )
         )
     }
 }
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt
index 448dbf1..7ba78d1 100644
--- a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt
@@ -51,7 +51,7 @@
 import androidx.datastore.preferences.core.booleanPreferencesKey
 import androidx.datastore.preferences.core.intPreferencesKey
 import androidx.glance.Button
-import androidx.glance.ButtonColors
+import androidx.glance.ButtonDefaults
 import androidx.glance.GlanceId
 import androidx.glance.GlanceModifier
 import androidx.glance.Image
@@ -443,7 +443,7 @@
             Button(
                 text = "Button",
                 onClick = actionStartActivity<Activity>(),
-                colors = ButtonColors(
+                colors = ButtonDefaults.buttonColors(
                     backgroundColor = ColorProvider(Color.Transparent),
                     contentColor = ColorProvider(Color.DarkGray)
                 ),
@@ -470,7 +470,7 @@
             Button(
                 text = "Button",
                 onClick = actionStartActivity<Activity>(),
-                colors = ButtonColors(
+                colors = ButtonDefaults.buttonColors(
                     backgroundColor = ColorProvider(Color.Transparent),
                     contentColor = ColorProvider(Color.DarkGray)
                 ),
@@ -887,7 +887,7 @@
                     fontWeight = FontWeight.Bold,
                     fontStyle = FontStyle.Normal,
                 ),
-                colors = switchColors(
+                colors = SwitchDefaults.colors(
                     checkedThumbColor = ColorProvider(
                         day = Color.Blue,
                         night = Color.Red
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/CheckBox.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/CheckBox.kt
index bc88b30..3b4719e 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/CheckBox.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/CheckBox.kt
@@ -44,59 +44,6 @@
 ) : CheckBoxColors()
 
 /**
- * [checkBoxColors] that uses [checkedColor] or [uncheckedColor] depending ons the checked state of the
- * CheckBox.
- *
- * @param checkedColor the [Color] to use when the CheckBox is checked
- * @param uncheckedColor the [Color] to use when the CheckBox is not checked
- */
-@Composable
-fun checkBoxColors(checkedColor: Color, uncheckedColor: Color): CheckBoxColors =
-    checkBoxColors(FixedColorProvider(checkedColor), FixedColorProvider(uncheckedColor))
-
-/**
- * [checkBoxColors] that uses [checkedColor] or [uncheckedColor] depending on the checked state of
- * the CheckBox.
- *
- * None of the [ColorProvider] parameters to this function can be created from resource ids. To use
- * resources to tint the check box color, use `CheckBoxColors(Int)` instead.
- *
- * @param checkedColor the [ColorProvider] to use when the check box is checked, or null to use the
- * default tint
- * @param uncheckedColor the [ColorProvider] to use when the check box is not checked, or null to
- * use the default tint
- */
-@Composable
-fun checkBoxColors(
-    checkedColor: ColorProvider,
-    uncheckedColor: ColorProvider
-): CheckBoxColors =
-    CheckBoxColorsImpl(
-        createCheckableColorProvider(
-            source = "CheckBoxColors",
-            checked = checkedColor,
-            unchecked = uncheckedColor,
-        )
-    )
-
-@Composable
-fun checkBoxColors(): CheckBoxColors {
-    val colorProvider = if (GlanceTheme.colors == DynamicThemeColorProviders) {
-        // If using the m3 dynamic color theme, we need to create a color provider from xml
-        // because resource backed ColorStateLists cannot be created programmatically
-        ResourceCheckableColorProvider(R.color.glance_default_check_box)
-    } else {
-        createCheckableColorProvider(
-            source = "CheckBoxColors",
-            checked = GlanceTheme.colors.primary,
-            unchecked = GlanceTheme.colors.onSurface
-        )
-    }
-
-    return CheckBoxColorsImpl(colorProvider)
-}
-
-/**
  * Adds a check box view to the glance view.
  *
  * @param checked whether the check box is checked
@@ -118,7 +65,7 @@
     modifier: GlanceModifier = GlanceModifier,
     text: String = "",
     style: TextStyle? = null,
-    colors: CheckBoxColors = checkBoxColors(),
+    colors: CheckBoxColors = CheckboxDefaults.colors(),
     maxLines: Int = Int.MAX_VALUE,
 ) = CheckBoxElement(checked, onCheckedChange, modifier, text, style, colors, maxLines)
 
@@ -141,7 +88,7 @@
     modifier: GlanceModifier = GlanceModifier,
     text: String = "",
     style: TextStyle? = null,
-    colors: CheckBoxColors = checkBoxColors(),
+    colors: CheckBoxColors = CheckboxDefaults.colors(),
     maxLines: Int = Int.MAX_VALUE,
 ) = CheckBoxElement(
     checked,
@@ -160,7 +107,7 @@
     modifier: GlanceModifier = GlanceModifier,
     text: String = "",
     style: TextStyle? = null,
-    colors: CheckBoxColors = checkBoxColors(),
+    colors: CheckBoxColors = CheckboxDefaults.colors(),
     maxLines: Int = Int.MAX_VALUE,
 ) {
     val finalModifier = if (onCheckedChange != null) {
@@ -181,6 +128,67 @@
     )
 }
 
+/**
+ * Contains the default values used by [CheckBox].
+ */
+object CheckboxDefaults {
+
+    /**
+     * @param checkedColor the [ColorProvider] to use when the check box is checked.
+     * @param uncheckedColor the [ColorProvider] to use when the check box is not checked.
+     * @return [CheckBoxColors] that uses [checkedColor] or [uncheckedColor] depending on the
+     * checked state of the CheckBox.
+     */
+    @Composable
+    fun colors(
+        checkedColor: ColorProvider,
+        uncheckedColor: ColorProvider
+    ): CheckBoxColors =
+        CheckBoxColorsImpl(
+            createCheckableColorProvider(
+                source = "CheckBoxColors",
+                checked = checkedColor,
+                unchecked = uncheckedColor,
+            )
+        )
+
+    /**
+     * @param checkedColor the [Color] to use when the check box is checked.
+     * @param uncheckedColor the [Color] to use when the check box is not checked.
+     * @return [CheckBoxColors] that uses [checkedColor] or [uncheckedColor] depending on the
+     * checked state of the CheckBox.
+     */
+    @Composable
+    fun colors(
+        checkedColor: Color,
+        uncheckedColor: Color
+    ): CheckBoxColors = CheckboxDefaults.colors(
+        checkedColor = FixedColorProvider(checkedColor),
+        uncheckedColor = FixedColorProvider(uncheckedColor)
+    )
+
+    /**
+     * Creates a default [CheckBoxColors].
+     * @return default [CheckBoxColors].
+     */
+    @Composable
+    fun colors(): CheckBoxColors {
+        val colorProvider = if (GlanceTheme.colors == DynamicThemeColorProviders) {
+            // If using the m3 dynamic color theme, we need to create a color provider from xml
+            // because resource backed ColorStateLists cannot be created programmatically
+            ResourceCheckableColorProvider(R.color.glance_default_check_box)
+        } else {
+            createCheckableColorProvider(
+                source = "CheckBoxColors",
+                checked = GlanceTheme.colors.primary,
+                unchecked = GlanceTheme.colors.onSurface
+            )
+        }
+
+        return CheckBoxColorsImpl(colorProvider)
+    }
+}
+
 internal class EmittableCheckBox(
     var colors: CheckBoxColors
 ) : Emittable {
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceAppWidget.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceAppWidget.kt
index 8fafe34..2638da4 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceAppWidget.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceAppWidget.kt
@@ -50,35 +50,19 @@
     internal val errorUiLayout: Int = R.layout.glance_error_layout,
 ) {
     private val sessionManager: SessionManager = GlanceSessionManager
+
     /**
      * Override this function to provide the Glance Composable.
      *
      * This is a good place to load any data needed to render the Composable. Use
-     * [provideContent] to provide the Composable once it is ready.
+     * [provideContent] to provide the Composable once the data is ready.
+     *
+     * @sample androidx.glance.appwidget.samples.provideGlanceSample
      */
-    open suspend fun provideGlance(
+    abstract suspend fun provideGlance(
         context: Context,
         id: GlanceId,
-    ) {
-        provideContent { @Suppress("DEPRECATION") Content() }
-    }
-
-    /**
-     * Provide the Glance Composable.
-     */
-    @Composable
-    @GlanceComposable
-    @Deprecated(
-        message = "Override provideGlance to provide the Composable.",
-        replaceWith = ReplaceWith(
-            "override suspend fun provideGlance(context: Context, id: GlanceId) {" +
-            "    provideContent { /** Composable content **/ }" +
-            "}",
-            "androidx.glance.appwidget.provideContent",
-        ),
-        level = DeprecationLevel.WARNING,
     )
-    open fun Content() {}
 
     /**
      * Defines the handling of sizes.
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RadioButton.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RadioButton.kt
index 48bafbc..4db3e21 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RadioButton.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RadioButton.kt
@@ -36,55 +36,6 @@
 /** Set of colors to apply to a RadioButton depending on the checked state. */
 class RadioButtonColors internal constructor(internal val radio: CheckableColorProvider)
 
-/**
- * RadioButtonColors to tint the drawable of the [RadioButton] according to the checked state.
- *
- * None of the [ColorProvider] parameters to this function can be created from resource ids. To use
- * resources to tint the switch color, use `RadioButtonColors(Int, Int)` instead.
- *
- * @param checkedColor the tint to apply to the radio button when it is checked, or null
- * to use the default tint.
- * @param uncheckedColor the tint to apply to the radio button when it is not checked,
- * or null to use the default tint.
- */
-fun radioButtonColors(
-    checkedColor: ColorProvider,
-    uncheckedColor: ColorProvider,
-): RadioButtonColors {
-    return RadioButtonColors(
-        radio = createCheckableColorProvider(
-            source = "RadioButtonColors", checked = checkedColor, unchecked = uncheckedColor
-        )
-    )
-}
-
-/**
- * [radioButtonColors] that uses [checkedColor] or [uncheckedColor] depending on the checked state
- * of the RadioButton.
- *
- * @param checkedColor the [Color] to use when the RadioButton is checked
- * @param uncheckedColor the [Color] to use when the RadioButton is not checked
- */
-fun radioButtonColors(checkedColor: Color, uncheckedColor: Color): RadioButtonColors =
-    radioButtonColors(FixedColorProvider(checkedColor), FixedColorProvider(uncheckedColor))
-
-@Composable
-fun radioButtonColors(): RadioButtonColors {
-    val colorProvider = if (GlanceTheme.colors == DynamicThemeColorProviders) {
-        // If using the m3 dynamic color theme, we need to create a color provider from xml
-        // because resource backed ColorStateLists cannot be created programmatically
-        ResourceCheckableColorProvider(R.color.glance_default_radio_button)
-    } else {
-        createCheckableColorProvider(
-            source = "CheckBoxColors",
-            checked = GlanceTheme.colors.primary,
-            unchecked = GlanceTheme.colors.onSurfaceVariant
-        )
-    }
-
-    return RadioButtonColors(colorProvider)
-}
-
 internal class EmittableRadioButton(
     var colors: RadioButtonColors
 ) : Emittable {
@@ -141,7 +92,7 @@
     enabled: Boolean = true,
     text: String = "",
     style: TextStyle? = null,
-    colors: RadioButtonColors = radioButtonColors(),
+    colors: RadioButtonColors = RadioButtonDefaults.colors(),
     maxLines: Int = Int.MAX_VALUE,
 ) = RadioButtonElement(checked, onClick, modifier, enabled, text, style, colors, maxLines)
 
@@ -170,7 +121,7 @@
     enabled: Boolean = true,
     text: String = "",
     style: TextStyle? = null,
-    colors: RadioButtonColors = radioButtonColors(),
+    colors: RadioButtonColors = RadioButtonDefaults.colors(),
     maxLines: Int = Int.MAX_VALUE,
 ) = RadioButtonElement(
     checked,
@@ -183,6 +134,65 @@
     maxLines
 )
 
+/**
+ * Contains the default values used by [RadioButton].
+ */
+object RadioButtonDefaults {
+    /**
+     * Creates a [RadioButtonColors] using [ColorProvider]s.
+     * @param checkedColor the tint to apply to the radio button when it is checked.
+     * @param uncheckedColor the tint to apply to the radio button when it is not checked.
+     * @return [RadioButtonColors] to tint the drawable of the [RadioButton] according to
+     * the checked state.
+     */
+    fun colors(
+        checkedColor: ColorProvider,
+        uncheckedColor: ColorProvider,
+    ): RadioButtonColors {
+        return RadioButtonColors(
+            radio = createCheckableColorProvider(
+                source = "RadioButtonColors", checked = checkedColor, unchecked = uncheckedColor
+            )
+        )
+    }
+
+    /**
+     * Creates a [RadioButtonColors] using [FixedColorProvider]s for the given colors.
+     * @param checkedColor the [Color] to use when the RadioButton is checked
+     * @param uncheckedColor the [Color] to use when the RadioButton is not checked
+     * @return [RadioButtonColors] to tint the drawable of the [RadioButton] according to
+     * the checked state.
+     */
+    fun colors(
+        checkedColor: Color,
+        uncheckedColor: Color
+    ): RadioButtonColors = colors(
+        checkedColor = FixedColorProvider(checkedColor),
+        uncheckedColor = FixedColorProvider(uncheckedColor)
+    )
+
+    /**
+     * Creates a default [RadioButtonColors]
+     * @return default [RadioButtonColors].
+     */
+    @Composable
+    fun colors(): RadioButtonColors {
+        val colorProvider = if (GlanceTheme.colors == DynamicThemeColorProviders) {
+            // If using the m3 dynamic color theme, we need to create a color provider from xml
+            // because resource backed ColorStateLists cannot be created programmatically
+            ResourceCheckableColorProvider(R.color.glance_default_radio_button)
+        } else {
+            createCheckableColorProvider(
+                source = "CheckBoxColors",
+                checked = GlanceTheme.colors.primary,
+                unchecked = GlanceTheme.colors.onSurfaceVariant
+            )
+        }
+
+        return RadioButtonColors(colorProvider)
+    }
+}
+
 @Composable
 private fun RadioButtonElement(
     checked: Boolean,
@@ -191,7 +201,7 @@
     enabled: Boolean = true,
     text: String = "",
     style: TextStyle? = null,
-    colors: RadioButtonColors = radioButtonColors(),
+    colors: RadioButtonColors = RadioButtonDefaults.colors(),
     maxLines: Int = Int.MAX_VALUE,
 ) {
     val finalModifier = if (enabled && onClick != null) modifier.clickable(onClick) else modifier
@@ -205,6 +215,7 @@
         this.set(maxLines) { this.maxLines = it }
     })
 }
+
 /**
  * Use this modifier to group a list of RadioButtons together for accessibility purposes.
  *
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/Switch.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/Switch.kt
index 4097244..06a9168 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/Switch.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/Switch.kt
@@ -44,57 +44,6 @@
 ) : SwitchColors()
 
 /**
- * SwitchColors to tint the thumb and track of the [Switch] according to the checked state.
- *
- * None of the [ColorProvider] parameters to this function can be created from resource ids.
- *
- * @param checkedThumbColor the tint to apply to the thumb of the switch when it is checked
- * @param uncheckedThumbColor the tint to apply to the thumb of the switch when it is not checked
- * @param checkedTrackColor the tint to apply to the track of the switch when it is checked
- * @param uncheckedTrackColor the tint to apply to the track of the switch when it is not checked
- */
-@Composable
-fun switchColors(
-    checkedThumbColor: ColorProvider,
-    uncheckedThumbColor: ColorProvider,
-    checkedTrackColor: ColorProvider,
-    uncheckedTrackColor: ColorProvider,
-): SwitchColors {
-    return SwitchColorsImpl(
-        thumb = createCheckableColorProvider(
-            source = "SwitchColors",
-            checked = checkedThumbColor,
-            unchecked = uncheckedThumbColor,
-        ),
-        track = createCheckableColorProvider(
-            source = "SwitchColors",
-            checked = checkedTrackColor,
-            unchecked = uncheckedTrackColor,
-        )
-    )
-}
-
-/**
- * Create a default set of SwitchColors.
- */
-@Composable
-fun switchColors(): SwitchColors {
-    return if (GlanceTheme.colors == DynamicThemeColorProviders) {
-        SwitchColorsImpl(
-            thumb = ResourceCheckableColorProvider(R.color.glance_default_switch_thumb),
-            track = ResourceCheckableColorProvider(R.color.glance_default_switch_track)
-        )
-    } else {
-        switchColors(
-            checkedThumbColor = GlanceTheme.colors.onPrimary,
-            uncheckedThumbColor = GlanceTheme.colors.outline,
-            checkedTrackColor = GlanceTheme.colors.primary,
-            uncheckedTrackColor = GlanceTheme.colors.surfaceVariant,
-        )
-    }
-}
-
-/**
  * Adds a switch view to the glance view.
  *
  * @param checked whether the switch is checked
@@ -116,7 +65,7 @@
     modifier: GlanceModifier = GlanceModifier,
     text: String = "",
     style: TextStyle? = null,
-    colors: SwitchColors = switchColors(),
+    colors: SwitchColors = SwitchDefaults.colors(),
     maxLines: Int = Int.MAX_VALUE,
 ) = SwitchElement(checked, onCheckedChange, modifier, text, style, colors, maxLines)
 
@@ -139,7 +88,7 @@
     modifier: GlanceModifier = GlanceModifier,
     text: String = "",
     style: TextStyle? = null,
-    colors: SwitchColors = switchColors(),
+    colors: SwitchColors = SwitchDefaults.colors(),
     maxLines: Int = Int.MAX_VALUE,
 ) = SwitchElement(
     checked,
@@ -151,6 +100,65 @@
     maxLines
 )
 
+/**
+ * Contains the default values used by [Switch].
+ */
+object SwitchDefaults {
+
+    /**
+     * SwitchColors to tint the thumb and track of the [Switch] according to the checked state.
+     *
+     * @param checkedThumbColor the tint to apply to the thumb of the switch when it is checked
+     * @param uncheckedThumbColor the tint to apply to the thumb of the switch when it is not
+     * checked
+     * @param checkedTrackColor the tint to apply to the track of the switch when it is checked
+     * @param uncheckedTrackColor the tint to apply to the track of the switch when it is not
+     * checked
+     */
+    @Composable
+    fun colors(
+        checkedThumbColor: ColorProvider,
+        uncheckedThumbColor: ColorProvider,
+        checkedTrackColor: ColorProvider,
+        uncheckedTrackColor: ColorProvider,
+    ): SwitchColors {
+        return SwitchColorsImpl(
+            thumb = createCheckableColorProvider(
+                source = "SwitchColors",
+                checked = checkedThumbColor,
+                unchecked = uncheckedThumbColor,
+            ),
+            track = createCheckableColorProvider(
+                source = "SwitchColors",
+                checked = checkedTrackColor,
+                unchecked = uncheckedTrackColor,
+            )
+        )
+    }
+
+    /**
+     *
+     * SwitchColors to tint the thumb and track of the [Switch] according to the checked state.
+     * @return a default set of [SwitchColors].
+     */
+    @Composable
+    fun colors(): SwitchColors {
+        return if (GlanceTheme.colors == DynamicThemeColorProviders) {
+            SwitchColorsImpl(
+                thumb = ResourceCheckableColorProvider(R.color.glance_default_switch_thumb),
+                track = ResourceCheckableColorProvider(R.color.glance_default_switch_track)
+            )
+        } else {
+            colors(
+                checkedThumbColor = GlanceTheme.colors.onPrimary,
+                uncheckedThumbColor = GlanceTheme.colors.outline,
+                checkedTrackColor = GlanceTheme.colors.primary,
+                uncheckedTrackColor = GlanceTheme.colors.surfaceVariant,
+            )
+        }
+    }
+}
+
 @Composable
 private fun SwitchElement(
     checked: Boolean,
@@ -158,7 +166,7 @@
     modifier: GlanceModifier = GlanceModifier,
     text: String = "",
     style: TextStyle? = null,
-    colors: SwitchColors = switchColors(),
+    colors: SwitchColors = SwitchDefaults.colors(),
     maxLines: Int = Int.MAX_VALUE,
 ) {
     val finalModifier = if (onCheckedChange != null) {
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/CheckBoxBackportTranslatorTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/CheckBoxBackportTranslatorTest.kt
index 1923a54..eb4b190 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/CheckBoxBackportTranslatorTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/CheckBoxBackportTranslatorTest.kt
@@ -23,7 +23,7 @@
 import androidx.compose.ui.graphics.Color
 import androidx.glance.GlanceModifier
 import androidx.glance.appwidget.CheckBox
-import androidx.glance.appwidget.checkBoxColors
+import androidx.glance.appwidget.CheckboxDefaults
 import androidx.glance.appwidget.ImageViewSubject.Companion.assertThat
 import androidx.glance.appwidget.action.ActionCallback
 import androidx.glance.appwidget.action.actionRunCallback
@@ -69,7 +69,10 @@
                 checked = false,
                 onCheckedChange = null,
                 text = "Check",
-                colors = checkBoxColors(checkedColor = Color.Red, uncheckedColor = Color.Blue)
+                colors = CheckboxDefaults.colors(
+                    checkedColor = Color.Red,
+                    uncheckedColor = Color.Blue
+                )
             )
         }
 
@@ -85,7 +88,10 @@
                 checked = true,
                 onCheckedChange = null,
                 text = "Check",
-                colors = checkBoxColors(checkedColor = Color.Red, uncheckedColor = Color.Blue)
+                colors = CheckboxDefaults.colors(
+                    checkedColor = Color.Red,
+                    uncheckedColor = Color.Blue
+                )
             )
         }
 
@@ -101,7 +107,7 @@
                 checked = false,
                 onCheckedChange = null,
                 text = "Check",
-                colors = checkBoxColors(
+                colors = CheckboxDefaults.colors(
                     checkedColor = ColorProvider(day = Color.Red, night = Color.Blue),
                     uncheckedColor = ColorProvider(day = Color.Yellow, night = Color.Green)
                 )
@@ -120,7 +126,7 @@
                 checked = false,
                 onCheckedChange = null,
                 text = "Check",
-                colors = checkBoxColors(
+                colors = CheckboxDefaults.colors(
                     checkedColor = ColorProvider(day = Color.Red, night = Color.Blue),
                     uncheckedColor = ColorProvider(day = Color.Yellow, night = Color.Green)
                 )
@@ -139,7 +145,7 @@
                 checked = true,
                 onCheckedChange = null,
                 text = "Check",
-                colors = checkBoxColors(
+                colors = CheckboxDefaults.colors(
                     checkedColor = ColorProvider(day = Color.Red, night = Color.Blue),
                     uncheckedColor = ColorProvider(day = Color.Yellow, night = Color.Green)
                 )
@@ -158,7 +164,7 @@
                 checked = true,
                 onCheckedChange = null,
                 text = "Check",
-                colors = checkBoxColors(
+                colors = CheckboxDefaults.colors(
                     checkedColor = ColorProvider(day = Color.Red, night = Color.Blue),
                     uncheckedColor = ColorProvider(day = Color.Yellow, night = Color.Green)
                 )
@@ -177,7 +183,7 @@
                 checked = true,
                 onCheckedChange = null,
                 text = "Check",
-                colors = checkBoxColors(
+                colors = CheckboxDefaults.colors(
                     checkedColor = FixedColorProvider(Color.Red),
                     uncheckedColor = FixedColorProvider(Color.Blue)
                 )
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/RadioButtonBackportTranslatorTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/RadioButtonBackportTranslatorTest.kt
index a0a6683..cddb9bd 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/RadioButtonBackportTranslatorTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/RadioButtonBackportTranslatorTest.kt
@@ -25,7 +25,7 @@
 import androidx.glance.GlanceModifier
 import androidx.glance.appwidget.ImageViewSubject.Companion.assertThat
 import androidx.glance.appwidget.RadioButton
-import androidx.glance.appwidget.radioButtonColors
+import androidx.glance.appwidget.RadioButtonDefaults
 import androidx.glance.appwidget.action.ActionCallback
 import androidx.glance.appwidget.action.actionRunCallback
 import androidx.glance.appwidget.applyRemoteViews
@@ -72,7 +72,7 @@
                 checked = false,
                 onClick = null,
                 text = "RadioButton",
-                colors = radioButtonColors(
+                colors = RadioButtonDefaults.colors(
                     checkedColor = ColorProvider(Color.Blue),
                     uncheckedColor = ColorProvider(Color.Red),
                 )
@@ -90,7 +90,7 @@
                 checked = true,
                 onClick = null,
                 text = "RadioButton",
-                colors = radioButtonColors(
+                colors = RadioButtonDefaults.colors(
                     checkedColor = ColorProvider(Color.Blue),
                     uncheckedColor = ColorProvider(Color.Red),
                 )
@@ -108,7 +108,7 @@
                 checked = false,
                 onClick = null,
                 text = "RadioButton",
-                colors = radioButtonColors(
+                colors = RadioButtonDefaults.colors(
                     checkedColor = ColorProvider(day = Color.Blue, night = Color.Red),
                     uncheckedColor = ColorProvider(day = Color.Green, night = Color.Yellow),
                 )
@@ -126,7 +126,7 @@
                 checked = false,
                 onClick = null,
                 text = "RadioButton",
-                colors = radioButtonColors(
+                colors = RadioButtonDefaults.colors(
                     checkedColor = ColorProvider(day = Color.Blue, night = Color.Red),
                     uncheckedColor = ColorProvider(day = Color.Green, night = Color.Yellow),
                 )
@@ -144,7 +144,7 @@
                 checked = true,
                 onClick = null,
                 text = "RadioButton",
-                colors = radioButtonColors(
+                colors = RadioButtonDefaults.colors(
                     checkedColor = ColorProvider(day = Color.Blue, night = Color.Red),
                     uncheckedColor = ColorProvider(day = Color.Green, night = Color.Yellow),
                 )
@@ -162,7 +162,7 @@
                 checked = true,
                 onClick = null,
                 text = "RadioButton",
-                colors = radioButtonColors(
+                colors = RadioButtonDefaults.colors(
                     checkedColor = ColorProvider(day = Color.Blue, night = Color.Red),
                     uncheckedColor = ColorProvider(day = Color.Green, night = Color.Yellow),
                 )
@@ -180,7 +180,7 @@
                 checked = false,
                 onClick = null,
                 text = "RadioButton",
-                colors = radioButtonColors(
+                colors = RadioButtonDefaults.colors(
                     checkedColor = ColorProvider(day = Color.Blue, night = Color.Red),
                     uncheckedColor = ColorProvider(day = Color.Green, night = Color.Yellow),
                 )
@@ -198,7 +198,7 @@
                 checked = true,
                 onClick = null,
                 text = "RadioButton",
-                colors = radioButtonColors(
+                colors = RadioButtonDefaults.colors(
                     checkedColor = ColorProvider(day = Color.Blue, night = Color.Red),
                     uncheckedColor = ColorProvider(day = Color.Green, night = Color.Yellow),
                 )
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/SwitchBackportTranslatorTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/SwitchBackportTranslatorTest.kt
index d4ba832..ec11aab 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/SwitchBackportTranslatorTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/SwitchBackportTranslatorTest.kt
@@ -30,7 +30,7 @@
 import androidx.glance.appwidget.configurationContext
 import androidx.glance.appwidget.findView
 import androidx.glance.appwidget.runAndTranslate
-import androidx.glance.appwidget.switchColors
+import androidx.glance.appwidget.SwitchDefaults
 import androidx.glance.color.ColorProvider
 import androidx.glance.semantics.contentDescription
 import androidx.glance.semantics.semantics
@@ -70,7 +70,7 @@
                 checked = false,
                 onCheckedChange = null,
                 text = "Switch",
-                colors = switchColors(
+                colors = SwitchDefaults.colors(
                     checkedThumbColor = ColorProvider(Color.Blue),
                     uncheckedThumbColor = ColorProvider(Color.Red),
                     checkedTrackColor = ColorProvider(Color.Green),
@@ -91,7 +91,7 @@
                 checked = true,
                 onCheckedChange = null,
                 text = "Switch",
-                colors = switchColors(
+                colors = SwitchDefaults.colors(
                     checkedThumbColor = ColorProvider(Color.Blue),
                     uncheckedThumbColor = ColorProvider(Color.Red),
                     checkedTrackColor = ColorProvider(Color.Green),
@@ -116,7 +116,7 @@
                 checked = false,
                 onCheckedChange = null,
                 text = "Switch",
-                colors = switchColors(
+                colors = SwitchDefaults.colors(
                     checkedThumbColor = ColorProvider(otherColor),
                     uncheckedThumbColor = ColorProvider(day = thumbColor, night = otherColor),
                     checkedTrackColor = ColorProvider(otherColor),
@@ -141,7 +141,7 @@
                 checked = false,
                 onCheckedChange = null,
                 text = "Switch",
-                colors = switchColors(
+                colors = SwitchDefaults.colors(
                     checkedThumbColor = ColorProvider(otherColor),
                     uncheckedThumbColor = ColorProvider(day = otherColor, night = thumbColor),
                     checkedTrackColor = ColorProvider(otherColor),
@@ -166,7 +166,7 @@
                 checked = true,
                 onCheckedChange = null,
                 text = "Switch",
-                colors = switchColors(
+                colors = SwitchDefaults.colors(
                     checkedThumbColor = ColorProvider(day = thumbColor, night = otherColor),
                     uncheckedThumbColor = ColorProvider(day = otherColor, night = otherColor),
                     checkedTrackColor = ColorProvider(day = trackColor, night = otherColor),
@@ -191,7 +191,7 @@
                 checked = true,
                 onCheckedChange = null,
                 text = "Switch",
-                colors = switchColors(
+                colors = SwitchDefaults.colors(
                     checkedThumbColor = ColorProvider(day = otherColor, night = thumbColor),
                     uncheckedThumbColor = ColorProvider(otherColor),
                     checkedTrackColor = ColorProvider(day = otherColor, night = trackColor),
@@ -212,7 +212,7 @@
                 checked = false,
                 onCheckedChange = null,
                 text = "Switch",
-                colors = switchColors(
+                colors = SwitchDefaults.colors(
                     checkedThumbColor = ColorProvider(Color.Magenta),
                     uncheckedThumbColor = ColorProvider(Color.Red),
                     checkedTrackColor = ColorProvider(Color.Magenta),
@@ -233,7 +233,7 @@
                 checked = true,
                 onCheckedChange = null,
                 text = "Switch",
-                colors = switchColors(
+                colors = SwitchDefaults.colors(
                     checkedThumbColor = ColorProvider(Color.Red),
                     uncheckedThumbColor = ColorProvider(Color.Magenta),
                     checkedTrackColor = ColorProvider(Color.Blue),
diff --git a/glance/glance-wear-tiles/api/current.txt b/glance/glance-wear-tiles/api/current.txt
index c693cbc..fe52a64 100644
--- a/glance/glance-wear-tiles/api/current.txt
+++ b/glance/glance-wear-tiles/api/current.txt
@@ -87,8 +87,8 @@
     ctor public CombinedGlanceCurvedModifier(androidx.glance.wear.tiles.curved.GlanceCurvedModifier outer, androidx.glance.wear.tiles.curved.GlanceCurvedModifier inner);
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
   }
 
   @androidx.glance.wear.tiles.curved.CurvedScopeMarker public interface CurvedChildScope {
@@ -123,8 +123,8 @@
   @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface GlanceCurvedModifier {
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
     method public default infix androidx.glance.wear.tiles.curved.GlanceCurvedModifier then(androidx.glance.wear.tiles.curved.GlanceCurvedModifier other);
     field public static final androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Companion Companion;
   }
@@ -132,15 +132,15 @@
   public static final class GlanceCurvedModifier.Companion implements androidx.glance.wear.tiles.curved.GlanceCurvedModifier {
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public static interface GlanceCurvedModifier.Element extends androidx.glance.wear.tiles.curved.GlanceCurvedModifier {
     method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
     method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
-    method public default <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
-    method public default <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+    method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+    method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
   }
 
   public final class GlanceCurvedModifierKt {
diff --git a/glance/glance-wear-tiles/api/public_plus_experimental_current.txt b/glance/glance-wear-tiles/api/public_plus_experimental_current.txt
index ecc93bf..c7e2370 100644
--- a/glance/glance-wear-tiles/api/public_plus_experimental_current.txt
+++ b/glance/glance-wear-tiles/api/public_plus_experimental_current.txt
@@ -102,8 +102,8 @@
     ctor public CombinedGlanceCurvedModifier(androidx.glance.wear.tiles.curved.GlanceCurvedModifier outer, androidx.glance.wear.tiles.curved.GlanceCurvedModifier inner);
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
   }
 
   @androidx.glance.wear.tiles.curved.CurvedScopeMarker public interface CurvedChildScope {
@@ -138,8 +138,8 @@
   @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface GlanceCurvedModifier {
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
     method public default infix androidx.glance.wear.tiles.curved.GlanceCurvedModifier then(androidx.glance.wear.tiles.curved.GlanceCurvedModifier other);
     field public static final androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Companion Companion;
   }
@@ -147,15 +147,15 @@
   public static final class GlanceCurvedModifier.Companion implements androidx.glance.wear.tiles.curved.GlanceCurvedModifier {
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public static interface GlanceCurvedModifier.Element extends androidx.glance.wear.tiles.curved.GlanceCurvedModifier {
     method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
     method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
-    method public default <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
-    method public default <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+    method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+    method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
   }
 
   public final class GlanceCurvedModifierKt {
diff --git a/glance/glance-wear-tiles/api/restricted_current.txt b/glance/glance-wear-tiles/api/restricted_current.txt
index c693cbc..fe52a64 100644
--- a/glance/glance-wear-tiles/api/restricted_current.txt
+++ b/glance/glance-wear-tiles/api/restricted_current.txt
@@ -87,8 +87,8 @@
     ctor public CombinedGlanceCurvedModifier(androidx.glance.wear.tiles.curved.GlanceCurvedModifier outer, androidx.glance.wear.tiles.curved.GlanceCurvedModifier inner);
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
   }
 
   @androidx.glance.wear.tiles.curved.CurvedScopeMarker public interface CurvedChildScope {
@@ -123,8 +123,8 @@
   @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface GlanceCurvedModifier {
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
     method public default infix androidx.glance.wear.tiles.curved.GlanceCurvedModifier then(androidx.glance.wear.tiles.curved.GlanceCurvedModifier other);
     field public static final androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Companion Companion;
   }
@@ -132,15 +132,15 @@
   public static final class GlanceCurvedModifier.Companion implements androidx.glance.wear.tiles.curved.GlanceCurvedModifier {
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public static interface GlanceCurvedModifier.Element extends androidx.glance.wear.tiles.curved.GlanceCurvedModifier {
     method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
     method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
-    method public default <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
-    method public default <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+    method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+    method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
   }
 
   public final class GlanceCurvedModifierKt {
diff --git a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/WearCompositionTranslatorTest.kt b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/WearCompositionTranslatorTest.kt
index 68be983..b167405 100644
--- a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/WearCompositionTranslatorTest.kt
+++ b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/WearCompositionTranslatorTest.kt
@@ -26,7 +26,7 @@
 import androidx.compose.ui.unit.sp
 import androidx.core.graphics.drawable.toBitmap
 import androidx.glance.Button
-import androidx.glance.ButtonColors
+import androidx.glance.ButtonDefaults
 import androidx.glance.ColorFilter
 import androidx.glance.GlanceId
 import androidx.glance.GlanceModifier
@@ -723,7 +723,7 @@
                 "Hello World",
                 onClick = actionStartActivity(TestActivity::class.java),
                 modifier = GlanceModifier.padding(1.dp),
-                colors = ButtonColors(
+                colors = ButtonDefaults.buttonColors(
                     backgroundColor = ColorProvider(Color.Black),
                     contentColor = ColorProvider(Color.Magenta)
                 ),
diff --git a/glance/glance/api/current.txt b/glance/glance/api/current.txt
index a0498de..47d790f 100644
--- a/glance/glance/api/current.txt
+++ b/glance/glance/api/current.txt
@@ -9,13 +9,17 @@
   }
 
   public final class ButtonColors {
-    ctor public ButtonColors(androidx.glance.unit.ColorProvider backgroundColor, androidx.glance.unit.ColorProvider contentColor);
     method public androidx.glance.unit.ColorProvider getBackgroundColor();
     method public androidx.glance.unit.ColorProvider getContentColor();
     property public final androidx.glance.unit.ColorProvider backgroundColor;
     property public final androidx.glance.unit.ColorProvider contentColor;
   }
 
+  public final class ButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.ButtonColors buttonColors(optional androidx.glance.unit.ColorProvider backgroundColor, optional androidx.glance.unit.ColorProvider contentColor);
+    field public static final androidx.glance.ButtonDefaults INSTANCE;
+  }
+
   public final class ButtonKt {
     method @androidx.compose.runtime.Composable public static void Button(String text, androidx.glance.action.Action onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines);
     method @androidx.compose.runtime.Composable public static void Button(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines);
@@ -33,12 +37,12 @@
     ctor public CombinedGlanceModifier(androidx.glance.GlanceModifier outer, androidx.glance.GlanceModifier inner);
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
   }
 
   public final class CompositionLocalsKt {
-    method @androidx.compose.runtime.Composable public static inline <reified T> T? currentState();
+    method @androidx.compose.runtime.Composable public static inline <reified T> T currentState();
     method @androidx.compose.runtime.Composable public static inline <reified T> T? currentState(androidx.datastore.preferences.core.Preferences.Key<T> key);
     method public static androidx.compose.runtime.ProvidableCompositionLocal<android.content.Context> getLocalContext();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.glance.GlanceId> getLocalGlanceId();
@@ -59,8 +63,8 @@
   @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface GlanceModifier {
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
     method public default infix androidx.glance.GlanceModifier then(androidx.glance.GlanceModifier other);
     field public static final androidx.glance.GlanceModifier.Companion Companion;
   }
@@ -68,15 +72,15 @@
   public static final class GlanceModifier.Companion implements androidx.glance.GlanceModifier {
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public static interface GlanceModifier.Element extends androidx.glance.GlanceModifier {
     method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
     method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
-    method public default <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
-    method public default <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+    method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
   }
 
   public final class GlanceTheme {
@@ -381,10 +385,10 @@
 
   public final class SemanticsConfiguration implements androidx.glance.semantics.SemanticsPropertyReceiver {
     ctor public SemanticsConfiguration();
-    method public operator <T> T! get(androidx.glance.semantics.SemanticsPropertyKey<T> key);
+    method public operator <T> T get(androidx.glance.semantics.SemanticsPropertyKey<T> key);
     method public <T> T? getOrElseNullable(androidx.glance.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public <T> T? getOrNull(androidx.glance.semantics.SemanticsPropertyKey<T> key);
-    method public <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T? value);
+    method public <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T value);
   }
 
   public final class SemanticsModifierKt {
@@ -405,12 +409,12 @@
   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 T? merge(T? parentValue, T? childValue);
+    method public T? merge(T? parentValue, T childValue);
     property public final String name;
   }
 
   public interface SemanticsPropertyReceiver {
-    method public operator <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T? value);
+    method public operator <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T value);
   }
 
 }
@@ -519,9 +523,10 @@
   }
 
   public final class TextDefaults {
-    method public androidx.glance.text.TextStyle defaultTextStyle();
     method public androidx.glance.unit.ColorProvider getDefaultTextColor();
+    method public androidx.glance.text.TextStyle getDefaultTextStyle();
     property public final androidx.glance.unit.ColorProvider defaultTextColor;
+    property public final androidx.glance.text.TextStyle defaultTextStyle;
     field public static final androidx.glance.text.TextDefaults INSTANCE;
   }
 
diff --git a/glance/glance/api/public_plus_experimental_current.txt b/glance/glance/api/public_plus_experimental_current.txt
index a0498de..47d790f 100644
--- a/glance/glance/api/public_plus_experimental_current.txt
+++ b/glance/glance/api/public_plus_experimental_current.txt
@@ -9,13 +9,17 @@
   }
 
   public final class ButtonColors {
-    ctor public ButtonColors(androidx.glance.unit.ColorProvider backgroundColor, androidx.glance.unit.ColorProvider contentColor);
     method public androidx.glance.unit.ColorProvider getBackgroundColor();
     method public androidx.glance.unit.ColorProvider getContentColor();
     property public final androidx.glance.unit.ColorProvider backgroundColor;
     property public final androidx.glance.unit.ColorProvider contentColor;
   }
 
+  public final class ButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.ButtonColors buttonColors(optional androidx.glance.unit.ColorProvider backgroundColor, optional androidx.glance.unit.ColorProvider contentColor);
+    field public static final androidx.glance.ButtonDefaults INSTANCE;
+  }
+
   public final class ButtonKt {
     method @androidx.compose.runtime.Composable public static void Button(String text, androidx.glance.action.Action onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines);
     method @androidx.compose.runtime.Composable public static void Button(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines);
@@ -33,12 +37,12 @@
     ctor public CombinedGlanceModifier(androidx.glance.GlanceModifier outer, androidx.glance.GlanceModifier inner);
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
   }
 
   public final class CompositionLocalsKt {
-    method @androidx.compose.runtime.Composable public static inline <reified T> T? currentState();
+    method @androidx.compose.runtime.Composable public static inline <reified T> T currentState();
     method @androidx.compose.runtime.Composable public static inline <reified T> T? currentState(androidx.datastore.preferences.core.Preferences.Key<T> key);
     method public static androidx.compose.runtime.ProvidableCompositionLocal<android.content.Context> getLocalContext();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.glance.GlanceId> getLocalGlanceId();
@@ -59,8 +63,8 @@
   @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface GlanceModifier {
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
     method public default infix androidx.glance.GlanceModifier then(androidx.glance.GlanceModifier other);
     field public static final androidx.glance.GlanceModifier.Companion Companion;
   }
@@ -68,15 +72,15 @@
   public static final class GlanceModifier.Companion implements androidx.glance.GlanceModifier {
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public static interface GlanceModifier.Element extends androidx.glance.GlanceModifier {
     method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
     method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
-    method public default <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
-    method public default <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+    method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
   }
 
   public final class GlanceTheme {
@@ -381,10 +385,10 @@
 
   public final class SemanticsConfiguration implements androidx.glance.semantics.SemanticsPropertyReceiver {
     ctor public SemanticsConfiguration();
-    method public operator <T> T! get(androidx.glance.semantics.SemanticsPropertyKey<T> key);
+    method public operator <T> T get(androidx.glance.semantics.SemanticsPropertyKey<T> key);
     method public <T> T? getOrElseNullable(androidx.glance.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public <T> T? getOrNull(androidx.glance.semantics.SemanticsPropertyKey<T> key);
-    method public <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T? value);
+    method public <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T value);
   }
 
   public final class SemanticsModifierKt {
@@ -405,12 +409,12 @@
   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 T? merge(T? parentValue, T? childValue);
+    method public T? merge(T? parentValue, T childValue);
     property public final String name;
   }
 
   public interface SemanticsPropertyReceiver {
-    method public operator <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T? value);
+    method public operator <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T value);
   }
 
 }
@@ -519,9 +523,10 @@
   }
 
   public final class TextDefaults {
-    method public androidx.glance.text.TextStyle defaultTextStyle();
     method public androidx.glance.unit.ColorProvider getDefaultTextColor();
+    method public androidx.glance.text.TextStyle getDefaultTextStyle();
     property public final androidx.glance.unit.ColorProvider defaultTextColor;
+    property public final androidx.glance.text.TextStyle defaultTextStyle;
     field public static final androidx.glance.text.TextDefaults INSTANCE;
   }
 
diff --git a/glance/glance/api/restricted_current.txt b/glance/glance/api/restricted_current.txt
index a0498de..47d790f 100644
--- a/glance/glance/api/restricted_current.txt
+++ b/glance/glance/api/restricted_current.txt
@@ -9,13 +9,17 @@
   }
 
   public final class ButtonColors {
-    ctor public ButtonColors(androidx.glance.unit.ColorProvider backgroundColor, androidx.glance.unit.ColorProvider contentColor);
     method public androidx.glance.unit.ColorProvider getBackgroundColor();
     method public androidx.glance.unit.ColorProvider getContentColor();
     property public final androidx.glance.unit.ColorProvider backgroundColor;
     property public final androidx.glance.unit.ColorProvider contentColor;
   }
 
+  public final class ButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.ButtonColors buttonColors(optional androidx.glance.unit.ColorProvider backgroundColor, optional androidx.glance.unit.ColorProvider contentColor);
+    field public static final androidx.glance.ButtonDefaults INSTANCE;
+  }
+
   public final class ButtonKt {
     method @androidx.compose.runtime.Composable public static void Button(String text, androidx.glance.action.Action onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines);
     method @androidx.compose.runtime.Composable public static void Button(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines);
@@ -33,12 +37,12 @@
     ctor public CombinedGlanceModifier(androidx.glance.GlanceModifier outer, androidx.glance.GlanceModifier inner);
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
   }
 
   public final class CompositionLocalsKt {
-    method @androidx.compose.runtime.Composable public static inline <reified T> T? currentState();
+    method @androidx.compose.runtime.Composable public static inline <reified T> T currentState();
     method @androidx.compose.runtime.Composable public static inline <reified T> T? currentState(androidx.datastore.preferences.core.Preferences.Key<T> key);
     method public static androidx.compose.runtime.ProvidableCompositionLocal<android.content.Context> getLocalContext();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.glance.GlanceId> getLocalGlanceId();
@@ -59,8 +63,8 @@
   @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface GlanceModifier {
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
     method public default infix androidx.glance.GlanceModifier then(androidx.glance.GlanceModifier other);
     field public static final androidx.glance.GlanceModifier.Companion Companion;
   }
@@ -68,15 +72,15 @@
   public static final class GlanceModifier.Companion implements androidx.glance.GlanceModifier {
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
-    method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
-    method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public static interface GlanceModifier.Element extends androidx.glance.GlanceModifier {
     method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
     method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
-    method public default <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
-    method public default <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+    method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
   }
 
   public final class GlanceTheme {
@@ -381,10 +385,10 @@
 
   public final class SemanticsConfiguration implements androidx.glance.semantics.SemanticsPropertyReceiver {
     ctor public SemanticsConfiguration();
-    method public operator <T> T! get(androidx.glance.semantics.SemanticsPropertyKey<T> key);
+    method public operator <T> T get(androidx.glance.semantics.SemanticsPropertyKey<T> key);
     method public <T> T? getOrElseNullable(androidx.glance.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public <T> T? getOrNull(androidx.glance.semantics.SemanticsPropertyKey<T> key);
-    method public <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T? value);
+    method public <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T value);
   }
 
   public final class SemanticsModifierKt {
@@ -405,12 +409,12 @@
   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 T? merge(T? parentValue, T? childValue);
+    method public T? merge(T? parentValue, T childValue);
     property public final String name;
   }
 
   public interface SemanticsPropertyReceiver {
-    method public operator <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T? value);
+    method public operator <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T value);
   }
 
 }
@@ -519,9 +523,10 @@
   }
 
   public final class TextDefaults {
-    method public androidx.glance.text.TextStyle defaultTextStyle();
     method public androidx.glance.unit.ColorProvider getDefaultTextColor();
+    method public androidx.glance.text.TextStyle getDefaultTextStyle();
     property public final androidx.glance.unit.ColorProvider defaultTextColor;
+    property public final androidx.glance.text.TextStyle defaultTextStyle;
     field public static final androidx.glance.text.TextDefaults INSTANCE;
   }
 
diff --git a/glance/glance/build.gradle b/glance/glance/build.gradle
index bb05696..b8fb797 100644
--- a/glance/glance/build.gradle
+++ b/glance/glance/build.gradle
@@ -63,6 +63,21 @@
     testImplementation("androidx.room:room-runtime:2.4.3")
     testImplementation("androidx.work:work-testing:2.7.1")
     testImplementation("com.google.android.material:material:1.6.0")
+
+    androidTestImplementation('androidx.test:monitor:1.5.0')
+    androidTestImplementation('androidx.core:core-ktx:1.7.0')
+    androidTestImplementation("androidx.work:work-testing:2.7.1")
+    androidTestImplementation("androidx.test.uiautomator:uiautomator:2.2.0")
+    androidTestImplementation(libs.kotlinCoroutinesTest)
+    androidTestImplementation(libs.kotlinTest)
+    androidTestImplementation(libs.testCore)
+    androidTestImplementation(libs.testExtJunit)
+    androidTestImplementation(libs.testExtJunitKtx)
+    androidTestImplementation(libs.testRules)
+    androidTestImplementation(libs.testRunner)
+    androidTestImplementation(libs.truth)
+    androidTestImplementation("androidx.lifecycle:lifecycle-livedata:2.5.1")
+    androidTestImplementation("androidx.lifecycle:lifecycle-livedata-ktx:2.5.1")
 }
 
 android {
diff --git a/glance/glance/src/androidAndroidTest/AndroidManifest.xml b/glance/glance/src/androidAndroidTest/AndroidManifest.xml
new file mode 100644
index 0000000..b4af9e2
--- /dev/null
+++ b/glance/glance/src/androidAndroidTest/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  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.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+</manifest>
diff --git a/glance/glance/src/androidAndroidTest/kotlin/androidx/glance/session/GlanceSessionManagerTest.kt b/glance/glance/src/androidAndroidTest/kotlin/androidx/glance/session/GlanceSessionManagerTest.kt
new file mode 100644
index 0000000..9db9374
--- /dev/null
+++ b/glance/glance/src/androidAndroidTest/kotlin/androidx/glance/session/GlanceSessionManagerTest.kt
@@ -0,0 +1,236 @@
+/*
+ * 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.glance.session
+
+import android.content.Context
+import android.util.Log
+import androidx.compose.runtime.Composable
+import androidx.glance.EmittableWithChildren
+import androidx.glance.GlanceModifier
+import androidx.glance.session.SessionWorker.Companion.TimeoutExitReason
+import androidx.glance.text.EmittableText
+import androidx.glance.text.Text
+import androidx.lifecycle.asFlow
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.work.Configuration
+import androidx.work.ListenableWorker
+import androidx.work.WorkInfo
+import androidx.work.WorkInfo.State
+import androidx.work.WorkManager
+import androidx.work.WorkerFactory
+import androidx.work.WorkerParameters
+import androidx.work.testing.SynchronousExecutor
+import androidx.work.testing.WorkManagerTestInitHelper
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
+import kotlin.test.assertNotNull
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.ExperimentalTime
+import kotlin.time.measureTime
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.currentTime
+import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.test.testTimeSource
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+
+@OptIn(ExperimentalStdlibApi::class, ExperimentalTime::class, ExperimentalCoroutinesApi::class)
+class GlanceSessionManagerTest {
+    private val context = InstrumentationRegistry.getInstrumentation().targetContext!!
+
+    private val testScope = TestScope()
+    private val testSession = TestSession()
+
+    private lateinit var workerState: StateFlow<List<WorkInfo>>
+    private val workerStateScope = CoroutineScope(Job())
+
+    private val additionalTime = 200.milliseconds
+    private val idleTimeout = 200.milliseconds
+    private val initialTimeout = 500.milliseconds
+    private val timeouts = TimeoutOptions(
+        additionalTime = additionalTime,
+        idleTimeout = idleTimeout,
+        initialTimeout = initialTimeout,
+        timeSource = { testScope.currentTime },
+    )
+
+    @Before
+    fun before() = runBlocking {
+        val config = Configuration.Builder()
+            .setMinimumLoggingLevel(Log.DEBUG)
+            .setExecutor(SynchronousExecutor())
+            .setWorkerFactory(object : WorkerFactory() {
+                    override fun createWorker(
+                    appContext: Context,
+                    workerClassName: String,
+                    workerParameters: WorkerParameters
+                ): ListenableWorker {
+                    assertThat(workerClassName).isEqualTo(SessionWorker::class.qualifiedName)
+                    return SessionWorker(
+                        appContext,
+                        workerParameters,
+                        GlanceSessionManager,
+                        timeouts,
+                        testScope.coroutineContext[CoroutineDispatcher]!!,
+                    )
+                }
+            })
+            .build()
+        WorkManagerTestInitHelper.initializeTestWorkManager(context, config)
+        workerState = WorkManager.getInstance(context)
+            .getWorkInfosForUniqueWorkLiveData(testSession.key)
+            .asFlow()
+            .stateIn(workerStateScope)
+    }
+
+    @After
+    fun after() {
+        testScope.cancel()
+        workerStateScope.cancel()
+        WorkManager.getInstance(context).cancelAllWork()
+    }
+
+    @Test
+    fun startingSessionRunsComposition() = testScope.runTest {
+        startSession()
+
+        val text = assertIs<EmittableText>(testSession.uiTree.receive().children.single())
+        assertThat(text.text).isEqualTo("Hello World")
+
+        assertNotNull(GlanceSessionManager.getSession(testSession.key)).close()
+        waitForWorkerSuccess()
+    }
+
+    @Test
+    fun sessionInitialTimeout() = testScope.runTest {
+        startSession()
+
+        // Timeout starts after first successful composition
+        testSession.uiTree.receive()
+        val timeout = testTimeSource.measureTime {
+            waitForWorkerTimeout()
+        }
+        assertThat(timeout).isEqualTo(initialTimeout)
+    }
+
+    @Test
+    fun sessionDoesNotTimeoutBeforeFirstComposition() = testScope.runTest {
+        startSession()
+
+        // The session is not subject to a timeout before the composition has been processed
+        // successfully for the first time.
+        delay(initialTimeout * 5)
+        assertThat(GlanceSessionManager.isSessionRunning(context, testSession.key)).isTrue()
+
+        testSession.uiTree.receive()
+        val timeout = testTimeSource.measureTime {
+            waitForWorkerTimeout()
+        }
+        assertThat(timeout).isEqualTo(initialTimeout)
+    }
+
+    @Test
+    fun sessionAddsTimeOnExternalEvents() = testScope.runTest {
+        startSession()
+
+        // Timeout starts after first successful composition, and is incremented every time an event
+        // is received.
+        testSession.uiTree.receive()
+        val timeout = testTimeSource.measureTime {
+            delay(initialTimeout - 1.milliseconds)
+            testSession.sendEvent()
+            waitForWorkerTimeout()
+        }
+        assertThat(timeout).isEqualTo(initialTimeout + additionalTime)
+    }
+
+    @Test
+    fun sessionDoesNotAddTimeOnExternalEventsIfThereIsEnoughTimeLeft() = testScope.runTest {
+        startSession()
+
+        // Timeout starts after first successful composition. There is still enough time when events
+        // arrive, so the deadline will not be extended.
+        testSession.uiTree.receive()
+        val timeout = testTimeSource.measureTime {
+            repeat(5) { testSession.sendEvent() }
+            waitForWorkerTimeout()
+        }
+        assertThat(timeout).isEqualTo(initialTimeout)
+    }
+
+    private suspend fun startSession() {
+        GlanceSessionManager.startSession(context, testSession)
+        waitForWorkerStart()
+        assertThat(GlanceSessionManager.isSessionRunning(context, testSession.key)).isTrue()
+    }
+
+    private suspend fun waitForWorkerState(vararg state: State) = workerState.first {
+        it.singleOrNull()?.state in state
+    }.single()
+
+    private suspend fun waitForWorkerStart() = waitForWorkerState(State.RUNNING)
+    private suspend fun waitForWorkerSuccess() = waitForWorkerState(State.SUCCEEDED)
+    private suspend fun waitForWorkerTimeout() = waitForWorkerSuccess().also {
+        assertThat(it.outputData.getBoolean(TimeoutExitReason, false)).isTrue()
+    }
+}
+
+class TestSession : Session("session-123") {
+    val uiTree = Channel<EmittableWithChildren>(capacity = Channel.RENDEZVOUS)
+
+    suspend fun sendEvent() = sendEvent(Any())
+
+    override fun createRootEmittable(): EmittableWithChildren = RootEmittable()
+
+    override fun provideGlance(context: Context) = @Composable {
+        Text("Hello World")
+    }
+
+    override suspend fun processEmittableTree(
+        context: Context,
+        root: EmittableWithChildren
+    ): Boolean {
+        uiTree.send(root)
+        return true
+    }
+
+    override suspend fun processEvent(context: Context, event: Any) {
+    }
+
+    private class RootEmittable(
+        override var modifier: GlanceModifier = GlanceModifier
+    ) : EmittableWithChildren() {
+        override fun copy() = RootEmittable(modifier).also {
+            it.children.addAll(children)
+        }
+    }
+}
+
+private suspend fun <T> Flow<T?>.firstNotNull() = first { it != null }!!
\ No newline at end of file
diff --git a/glance/glance/src/androidMain/kotlin/androidx/glance/Button.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/Button.kt
index 19116de..ddfb772 100644
--- a/glance/glance/src/androidMain/kotlin/androidx/glance/Button.kt
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/Button.kt
@@ -44,7 +44,7 @@
     modifier: GlanceModifier = GlanceModifier,
     enabled: Boolean = true,
     style: TextStyle? = null,
-    colors: ButtonColors = defaultButtonColors(),
+    colors: ButtonColors = ButtonDefaults.buttonColors(),
     maxLines: Int = Int.MAX_VALUE,
 ) = ButtonElement(text, onClick, modifier, enabled, style, colors, maxLines)
 
@@ -67,7 +67,7 @@
     modifier: GlanceModifier = GlanceModifier,
     enabled: Boolean = true,
     style: TextStyle? = null,
-    colors: ButtonColors = defaultButtonColors(),
+    colors: ButtonColors = ButtonDefaults.buttonColors(),
     maxLines: Int = Int.MAX_VALUE,
 ) = ButtonElement(text, action(block = onClick), modifier, enabled, style, colors, maxLines)
 
@@ -78,7 +78,7 @@
     modifier: GlanceModifier = GlanceModifier,
     enabled: Boolean = true,
     style: TextStyle? = null,
-    colors: ButtonColors = defaultButtonColors(),
+    colors: ButtonColors = ButtonDefaults.buttonColors(),
     maxLines: Int = Int.MAX_VALUE,
 ) {
     var finalModifier = if (enabled) modifier.clickable(onClick) else modifier
@@ -132,7 +132,10 @@
 }
 
 /** Represents the colors used to style a button, prefer this to using the modifier. */
-class ButtonColors(val backgroundColor: ColorProvider, val contentColor: ColorProvider) {
+class ButtonColors internal constructor(
+    val backgroundColor: ColorProvider,
+    val contentColor: ColorProvider
+) {
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
         if (javaClass != other?.javaClass) return false
@@ -152,8 +155,23 @@
     }
 }
 
-@Composable
-internal fun defaultButtonColors() = ButtonColors(
-    GlanceTheme.colors.primary,
-    GlanceTheme.colors.onPrimary
-)
+/**
+ * Contains the default values used by [Button].
+ */
+object ButtonDefaults {
+    @Composable
+    /**
+    * Creates a [ButtonColors] that represents the default background and content colors used in
+    * a [Button].
+    *
+    * @param backgroundColor the background color of this [Button]
+    * @param contentColor the content color of this [Button]
+    */
+    fun buttonColors(
+        backgroundColor: ColorProvider = GlanceTheme.colors.primary,
+        contentColor: ColorProvider = GlanceTheme.colors.onPrimary
+    ) = ButtonColors(
+        backgroundColor = backgroundColor,
+        contentColor = contentColor
+    )
+}
\ No newline at end of file
diff --git a/glance/glance/src/androidMain/kotlin/androidx/glance/session/IdleEventBroadcastReceiver.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/session/IdleEventBroadcastReceiver.kt
new file mode 100644
index 0000000..372f57c
--- /dev/null
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/session/IdleEventBroadcastReceiver.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.glance.session
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.os.Build
+import android.os.PowerManager
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
+
+internal class IdleEventBroadcastReceiver(val onIdle: () -> Unit) : BroadcastReceiver() {
+    companion object {
+        val events = listOf(
+            PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED,
+            PowerManager.ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED,
+            PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED
+        )
+        val filter = IntentFilter().apply {
+            events.forEach { addAction(it) }
+        }
+    }
+
+    override fun onReceive(context: Context, intent: Intent) {
+        if (intent.action in events)
+            checkIdleStatus(context)
+    }
+
+    internal fun checkIdleStatus(context: Context) {
+        // Idle status is not available before Android M
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return
+
+        val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
+        var isIdle = Api23Impl.isIdle(pm)
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+            isIdle = isIdle || Api33Impl.isLightIdleOrLowPowerStandby(pm)
+        }
+        if (isIdle) onIdle()
+    }
+}
+
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+private object Api33Impl {
+    @DoNotInline
+    fun isLightIdleOrLowPowerStandby(pm: PowerManager): Boolean {
+        return pm.isLowPowerStandbyEnabled || pm.isDeviceLightIdleMode
+    }
+}
+
+@RequiresApi(Build.VERSION_CODES.M)
+private object Api23Impl {
+    @DoNotInline
+    fun isIdle(pm: PowerManager): Boolean {
+        return pm.isDeviceIdleMode
+    }
+}
+
+/**
+ * Observe idle events while running [block]. If the device enters idle mode, run [onIdle].
+ */
+internal suspend fun <T> observeIdleEvents(
+    context: Context,
+    onIdle: suspend () -> Unit,
+    block: suspend () -> T,
+): T = coroutineScope {
+    val idleReceiver = IdleEventBroadcastReceiver { launch { onIdle() } }
+    context.registerReceiver(idleReceiver, IdleEventBroadcastReceiver.filter)
+    try {
+        idleReceiver.checkIdleStatus(context)
+        return@coroutineScope block()
+    } finally {
+        context.unregisterReceiver(idleReceiver)
+    }
+}
\ No newline at end of file
diff --git a/glance/glance/src/androidMain/kotlin/androidx/glance/session/SessionWorker.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/session/SessionWorker.kt
index b09f015..e3cb1fa 100644
--- a/glance/glance/src/androidMain/kotlin/androidx/glance/session/SessionWorker.kt
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/session/SessionWorker.kt
@@ -18,20 +18,38 @@
 
 import android.content.Context
 import android.util.Log
-import androidx.annotation.VisibleForTesting
 import androidx.compose.runtime.Composition
 import androidx.compose.runtime.Recomposer
 import androidx.glance.Applier
 import androidx.glance.EmittableWithChildren
 import androidx.work.CoroutineWorker
+import androidx.work.Data
 import androidx.work.WorkerParameters
+import kotlin.time.Duration
 import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.launch
-import kotlinx.coroutines.withTimeoutOrNull
+
+/**
+ * Options to configure [SessionWorker] timeouts.
+ * @property initialTimeout How long to wait after the first successful composition before timing
+ * out.
+ * @property additionalTime If an external event is received and there is less than [additionalTime]
+ * remaining, add [additionalTime] so that there is enough time to respond to the event.
+ * @property idleTimeout Timeout within [idleTimeout] if the system is in idle/light idle/low power
+ * standby mode.
+ * @property timeSource The time source for measuring progress towards timeouts.
+ */
+internal data class TimeoutOptions(
+    val initialTimeout: Duration = 45.seconds,
+    val additionalTime: Duration = 5.seconds,
+    val idleTimeout: Duration = 5.seconds,
+    val timeSource: TimeSource = TimeSource.Monotonic,
+)
 
 /**
  * [SessionWorker] handles composition for a particular Glanceable.
@@ -44,25 +62,44 @@
 internal class SessionWorker(
     appContext: Context,
     params: WorkerParameters,
+    private val sessionManager: SessionManager = GlanceSessionManager,
+    private val timeouts: TimeoutOptions = TimeoutOptions(),
+    @Deprecated("Deprecated by super class, replacement in progress, see b/245353737")
+    override val coroutineContext: CoroutineDispatcher = Dispatchers.Main
 ) : CoroutineWorker(appContext, params) {
-    @VisibleForTesting
-    internal var sessionManager: SessionManager = GlanceSessionManager
+    // This constructor is required by WorkManager's default WorkerFactory.
+    constructor(appContext: Context, params: WorkerParameters) : this(
+        appContext,
+        params,
+        GlanceSessionManager,
+    )
 
     companion object {
         private const val TAG = "GlanceSessionWorker"
         private const val DEBUG = false
-        @VisibleForTesting
-        internal val defaultTimeout = 45.seconds
+        internal const val TimeoutExitReason = "TIMEOUT_EXIT_REASON"
     }
 
     private val key = inputData.getString(sessionManager.keyParam)
-            ?: error("SessionWorker must be started with a key")
+        ?: error("SessionWorker must be started with a key")
 
-    @Deprecated("Deprecated by super class, replacement in progress, see b/245353737")
-    override val coroutineContext = Dispatchers.Main
+    override suspend fun doWork() =
+        withTimerOrNull(timeouts.timeSource) {
+            observeIdleEvents(
+                applicationContext,
+                onIdle = {
+                    startTimer(timeouts.idleTimeout)
+                    if (DEBUG) Log.d(TAG, "Received idle event, session timeout $timeLeft")
+                }
+            ) {
+                work()
+            }
+        } ?: Result.success(Data.Builder().putBoolean(TimeoutExitReason, true).build())
 
-    override suspend fun doWork(): Result = withTimeoutOrNull(defaultTimeout) {
-        val session = sessionManager.getSession(key) ?: error("No session available for key $key")
+    private suspend fun TimerScope.work(): Result {
+        val session = sessionManager.getSession(key)
+            ?: error("No session available for key $key")
+
         if (DEBUG) Log.d(TAG, "Setting up composition for ${session.key}")
         val frameClock = InteractiveFrameClock(this)
         val snapshotMonitor = launch { globalSnapshotMonitor() }
@@ -83,15 +120,21 @@
                 when (state) {
                     Recomposer.State.Idle -> {
                         // Only update the session when a change has actually occurred. The
-                        // Recomposer may sometimes wake up due to changes in other compositions.
-                        // Also update the session if we have not sent an initial tree yet.
+                        // Recomposer may sometimes wake up due to changes in other
+                        // compositions. Also update the session if we have not sent an initial
+                        // tree yet.
                         if (recomposer.changeCount > lastRecomposeCount || !uiReady.value) {
                             if (DEBUG) Log.d(TAG, "UI tree updated (${session.key})")
                             val processed = session.processEmittableTree(
                                 applicationContext,
                                 root.copy() as EmittableWithChildren
                             )
-                            if (!uiReady.value && processed) uiReady.emit(true)
+                            // If the UI has been processed for the first time, set uiReady to true
+                            // and start the timeout.
+                            if (!uiReady.value && processed) {
+                                uiReady.emit(true)
+                                startTimer(timeouts.initialTimeout)
+                            }
                         }
                         lastRecomposeCount = recomposer.changeCount
                     }
@@ -100,11 +143,13 @@
                 }
             }
         }
-
         // Wait until the Emittable tree has been processed at least once before receiving events.
         uiReady.first { it }
         session.receiveEvents(applicationContext) {
-            if (DEBUG) Log.d(TAG, "processing event for ${session.key}")
+            // If time is running low, add time to make sure that we have time to respond to this
+            // event.
+            if (timeLeft < timeouts.additionalTime) addTime(timeouts.additionalTime)
+            if (DEBUG) Log.d(TAG, "processing event for ${session.key}; $timeLeft left")
             launch { frameClock.startInteractive() }
         }
 
@@ -113,6 +158,6 @@
         snapshotMonitor.cancel()
         recomposer.close()
         recomposer.join()
-        return@withTimeoutOrNull Result.success()
-    } ?: Result.success()
+        return Result.success()
+    }
 }
diff --git a/glance/glance/src/androidMain/kotlin/androidx/glance/session/TimerScope.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/session/TimerScope.kt
new file mode 100644
index 0000000..fd3b317
--- /dev/null
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/session/TimerScope.kt
@@ -0,0 +1,152 @@
+/*
+ * 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.glance.session
+
+import java.util.concurrent.atomic.AtomicReference
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+internal class TimeoutCancellationException(
+    override val message: String,
+    internal val block: Int,
+) : CancellationException(message) {
+    override fun toString() = "TimeoutCancellationException($message, $block)"
+    override fun fillInStackTrace() = this
+}
+
+/**
+ * This interface is similar to [kotlin.time.TimeSource], which is still marked experimental.
+ */
+internal fun interface TimeSource {
+    /**
+     * Current time in milliseconds.
+     */
+    fun markNow(): Long
+
+    companion object {
+        val Monotonic = TimeSource { System.currentTimeMillis() }
+    }
+}
+
+/**
+ * TimerScope is a CoroutineScope that allows setting an adjustable timeout for all of the
+ * coroutines in the scope.
+ */
+internal interface TimerScope : CoroutineScope {
+    /**
+     * Amount of time left before this timer cancels the scope. This is not valid before
+     * [startTimer] is called.
+     */
+    val timeLeft: Duration
+
+    /**
+     * Start the timer with an [initialTimeout].
+     *
+     * Once the [initialTimeout] has passed, the scope is cancelled. If [startTimer] is called again
+     * while the timer is running, it will reset the timer if [initialTimeout] is less than
+     * [timeLeft]. If [initialTimeout] is larger than [timeLeft], the current timer is kept.
+     *
+     * In order to extend the deadline, call [addTime].
+     */
+    fun startTimer(initialTimeout: Duration)
+
+    /**
+     *  Shift the deadline for this timer forward by [time].
+     */
+    fun addTime(time: Duration)
+}
+
+internal suspend fun <T> withTimer(
+    timeSource: TimeSource = TimeSource.Monotonic,
+    block: suspend TimerScope.() -> T,
+): T = coroutineScope {
+    val timerScope = this
+    val timerJob: AtomicReference<Job?> = AtomicReference(null)
+    coroutineScope {
+        val blockScope = object : TimerScope, CoroutineScope by this {
+            override val timeLeft: Duration
+                get() = (deadline.get()?.minus(timeSource.markNow()))?.milliseconds
+                    ?: Duration.INFINITE
+            private val deadline: AtomicReference<Long?> = AtomicReference(null)
+
+            override fun addTime(time: Duration) {
+                deadline.update {
+                    checkNotNull(it) { "Start the timer with startTimer before calling addTime" }
+                    require(time.isPositive()) { "Cannot call addTime with a negative duration" }
+                    it + time.inWholeMilliseconds
+                }
+            }
+
+            override fun startTimer(initialTimeout: Duration) {
+                if (initialTimeout.inWholeMilliseconds <= 0) {
+                    timerScope.cancel(
+                        TimeoutCancellationException("Timed out immediately", block.hashCode())
+                    )
+                    return
+                }
+                if (timeLeft < initialTimeout) return
+
+                deadline.set(timeSource.markNow() + initialTimeout.inWholeMilliseconds)
+                // Loop until the deadline is reached.
+                timerJob.getAndSet(
+                    timerScope.launch {
+                        while (deadline.get()!! > timeSource.markNow()) {
+                            delay(timeLeft)
+                        }
+                        timerScope.cancel(
+                            TimeoutCancellationException(
+                                "Timed out of executing block.",
+                                block.hashCode()
+                            )
+                        )
+                    }
+                )?.cancel()
+            }
+        }
+        blockScope.block()
+    }.also {
+        timerJob.get()?.cancel()
+    }
+}
+
+internal suspend fun <T> withTimerOrNull(
+    timeSource: TimeSource = TimeSource.Monotonic,
+    block: suspend TimerScope.() -> T,
+): T? = try {
+    withTimer(timeSource, block)
+} catch (e: TimeoutCancellationException) {
+    // Return null if it's our exception, else propagate it upstream in case there are nested
+    // withTimers
+    if (e.block == block.hashCode()) null else throw e
+}
+
+// Update the value of the AtomicReference using the given updater function. Will throw an error
+// if unable to successfully set the value.
+private fun <T> AtomicReference<T>.update(updater: (T) -> T) {
+    while (true) {
+        get().let {
+            if (compareAndSet(it, updater(it))) return
+        }
+    }
+}
diff --git a/glance/glance/src/androidMain/kotlin/androidx/glance/text/Text.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/text/Text.kt
index b079d59..ace0cfb 100644
--- a/glance/glance/src/androidMain/kotlin/androidx/glance/text/Text.kt
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/text/Text.kt
@@ -39,7 +39,7 @@
 fun Text(
     text: String,
     modifier: GlanceModifier = GlanceModifier,
-    style: TextStyle = defaultTextStyle(),
+    style: TextStyle = defaultTextStyle,
     maxLines: Int = Int.MAX_VALUE,
 ) {
     GlanceNode(
@@ -55,7 +55,7 @@
 
 object TextDefaults {
     val defaultTextColor = ColorProvider(Color.Black)
-    fun defaultTextStyle(): TextStyle = TextStyle(color = defaultTextColor)
+    val defaultTextStyle: TextStyle = TextStyle(color = defaultTextColor)
 }
 
 /** @suppress */
diff --git a/glance/glance/src/test/kotlin/androidx/glance/session/IdleEventBroadcastReceiverTest.kt b/glance/glance/src/test/kotlin/androidx/glance/session/IdleEventBroadcastReceiverTest.kt
new file mode 100644
index 0000000..5d20c8f
--- /dev/null
+++ b/glance/glance/src/test/kotlin/androidx/glance/session/IdleEventBroadcastReceiverTest.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.glance.session
+
+import android.content.Context
+import android.content.Intent
+import android.os.Build
+import android.os.PowerManager
+import androidx.test.core.app.ApplicationProvider
+import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.atomic.AtomicInteger
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+import org.robolectric.Shadows
+import org.robolectric.annotation.Config
+
+@RunWith(RobolectricTestRunner::class)
+class IdleEventBroadcastReceiverTest() {
+    private val receiver = IdleEventBroadcastReceiver { onIdleCalled.incrementAndGet() }
+    private val onIdleCalled = AtomicInteger(0)
+    private val context = ApplicationProvider.getApplicationContext<Context>()
+
+    @Test
+    @Config(minSdk = Build.VERSION_CODES.M)
+    fun onReceive_idleModeChanged() {
+        val pm = Shadows.shadowOf(context.getSystemService(PowerManager::class.java))
+
+        pm.setIsDeviceIdleMode(false)
+        receiver.onReceive(context, Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED))
+        assertThat(onIdleCalled.get()).isEqualTo(0)
+
+        pm.setIsDeviceIdleMode(true)
+        receiver.onReceive(context, Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED))
+        assertThat(onIdleCalled.get()).isEqualTo(1)
+    }
+
+    @Test
+    @Config(minSdk = Build.VERSION_CODES.TIRAMISU)
+    fun onReceive_lightIdleModeChanged() {
+        val pm = Shadows.shadowOf(context.getSystemService(PowerManager::class.java))
+
+        pm.setIsDeviceLightIdleMode(false)
+        receiver.onReceive(context, Intent(PowerManager.ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED))
+        assertThat(onIdleCalled.get()).isEqualTo(0)
+
+        pm.setIsDeviceLightIdleMode(true)
+        receiver.onReceive(context, Intent(PowerManager.ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED))
+        assertThat(onIdleCalled.get()).isEqualTo(1)
+    }
+}
\ No newline at end of file
diff --git a/glance/glance/src/test/kotlin/androidx/glance/session/SessionWorkerTest.kt b/glance/glance/src/test/kotlin/androidx/glance/session/SessionWorkerTest.kt
index ea5ebc6..43a1916 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/session/SessionWorkerTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/session/SessionWorkerTest.kt
@@ -29,6 +29,8 @@
 import androidx.test.core.app.ApplicationProvider
 import androidx.work.Data
 import androidx.work.ListenableWorker.Result
+import androidx.work.WorkerFactory
+import androidx.work.WorkerParameters
 import androidx.work.testing.TestListenableWorkerBuilder
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.assertIs
@@ -36,7 +38,6 @@
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.launch
-import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -55,10 +56,14 @@
         context = ApplicationProvider.getApplicationContext()
         worker = TestListenableWorkerBuilder<SessionWorker>(context)
             .setInputData(Data(mapOf(sessionManager.keyParam to SESSION_KEY)))
+            .setWorkerFactory(object : WorkerFactory() {
+                override fun createWorker(
+                    appContext: Context,
+                    workerClassName: String,
+                    workerParameters: WorkerParameters
+                ) = SessionWorker(appContext, workerParameters, sessionManager)
+            })
             .build()
-            .also {
-                it.sessionManager = sessionManager
-            }
     }
 
     @Test
@@ -150,16 +155,6 @@
         }
         sessionManager.closeSession()
     }
-
-    @Test
-    fun sessionWorkerTimeout() = runTest {
-        launch {
-            val result = worker.doWork()
-            assertThat(result).isEqualTo(Result.success())
-        }
-        sessionManager.startSession(context)
-        advanceTimeBy(SessionWorker.defaultTimeout.inWholeMilliseconds + 1)
-    }
 }
 
 private const val SESSION_KEY = "123"
diff --git a/glance/glance/src/test/kotlin/androidx/glance/session/WithTimerTest.kt b/glance/glance/src/test/kotlin/androidx/glance/session/WithTimerTest.kt
new file mode 100644
index 0000000..8bafe94
--- /dev/null
+++ b/glance/glance/src/test/kotlin/androidx/glance/session/WithTimerTest.kt
@@ -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.glance.session
+
+import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.atomic.AtomicBoolean
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.days
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.async
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.currentTime
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(RobolectricTestRunner::class)
+class WithTimerTest {
+    private val TestScope.timeSource
+        get() = TimeSource { currentTime }
+
+    @Test
+    fun completingNormallyThrowsNoException() = runTest {
+        val result = async {
+            withTimerOrNull(timeSource) {
+                startTimer(200.milliseconds)
+                delay(100.milliseconds)
+                Any()
+            }
+        }
+        assertThat(result.await()).isNotNull()
+    }
+
+    @Test
+    fun completingNormallyDoesNotCancelParentJob() = runTest {
+        val timerSuccess = Job()
+        val parentJob = launch {
+            withTimer(timeSource) {
+                startTimer(200.milliseconds)
+                delay(100.milliseconds)
+            }
+            timerSuccess.complete()
+            delay(Duration.INFINITE)
+        }
+        timerSuccess.join()
+        assertThat(timerSuccess.isCompleted).isTrue()
+        assertThat(parentJob.isActive).isTrue()
+        parentJob.cancel()
+    }
+
+    @Test
+    fun timeoutThrowsTimeoutCancellationException() = runTest {
+        var expected: TimeoutCancellationException? = null
+        try {
+            withTimer(timeSource) {
+                startTimer(200.milliseconds)
+                delay(1.seconds)
+            }
+        } catch (e: TimeoutCancellationException) {
+            expected = e
+        } finally {
+            assertThat(expected).isNotNull()
+        }
+    }
+
+    @Test
+    fun doesNotTimeoutBeforeStartTimer() = runTest {
+        var unexpected: TimeoutCancellationException? = null
+        try {
+            withTimer(timeSource) {
+                delay(30.days)
+                startTimer(200.milliseconds)
+                delay(100.milliseconds)
+            }
+        } catch (e: TimeoutCancellationException) {
+            unexpected = e
+        } finally {
+            assertThat(unexpected).isNull()
+        }
+    }
+
+    @Test
+    fun addTime() = runTest {
+        var unexpected: TimeoutCancellationException? = null
+        try {
+            withTimer(timeSource) {
+                startTimer(200.milliseconds)
+                delay(100)
+                assertThat(timeLeft).isEqualTo(100.milliseconds)
+                addTime(100.milliseconds)
+                assertThat(timeLeft).isEqualTo(200.milliseconds)
+                delay(199.milliseconds)
+            }
+        } catch (e: TimeoutCancellationException) {
+            unexpected = e
+        } finally {
+            assertThat(unexpected).isNull()
+        }
+    }
+
+    @Test
+    fun addTimeBeforeStartTimer() = runTest {
+        var expected: IllegalStateException? = null
+        try {
+            withTimer(timeSource) {
+                addTime(100.milliseconds)
+            }
+        } catch (e: IllegalStateException) {
+            expected = e
+        } finally {
+            assertThat(expected).isNotNull()
+        }
+    }
+
+    @Test
+    fun addNegativeDuration() = runTest {
+        var expected: IllegalArgumentException? = null
+        try {
+            withTimer(timeSource) {
+                startTimer(100.milliseconds)
+                addTime(-100.milliseconds)
+            }
+        } catch (e: IllegalArgumentException) {
+            expected = e
+        } finally {
+            assertThat(expected).isNotNull()
+        }
+    }
+
+    @Test
+    fun nestedWithTimerOrNull() = runTest {
+        val checkpoint1 = AtomicBoolean(false)
+        val checkpoint2 = AtomicBoolean(false)
+        // The remaining two checkpoints should never be hit
+        val checkpoint3 = AtomicBoolean(false)
+        val checkpoint4 = AtomicBoolean(false)
+
+        val result = withTimerOrNull(timeSource) {
+            // The outer timer should trigger during the delay(), and nothing after that should run.
+            startTimer(200.milliseconds)
+            checkpoint1.set(true)
+            withTimerOrNull(timeSource) {
+                startTimer(1.seconds)
+                checkpoint2.set(true)
+                delay(201.milliseconds)
+                checkpoint3.set(true)
+            }
+            checkpoint4.set(true)
+        }
+
+        assertThat(result).isNull()
+        assertThat(checkpoint1.get()).isTrue()
+        assertThat(checkpoint2.get()).isTrue()
+        assertThat(checkpoint3.get()).isFalse()
+        assertThat(checkpoint4.get()).isFalse()
+    }
+}
diff --git a/graphics/graphics-core/api/current.txt b/graphics/graphics-core/api/current.txt
index e10c65e..69d2dd9 100644
--- a/graphics/graphics-core/api/current.txt
+++ b/graphics/graphics-core/api/current.txt
@@ -17,12 +17,12 @@
     method public boolean isValid();
     method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseComplete);
     method public void release(boolean cancelPending);
-    method public void renderFrontBufferedLayer(T? param);
+    method public void renderFrontBufferedLayer(T param);
     method public void renderMultiBufferedLayer(java.util.Collection<? extends T> params);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public static interface CanvasFrontBufferedRenderer.Callback<T> {
-    method @WorkerThread public void onDrawFrontBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, T? param);
+    method @WorkerThread public void onDrawFrontBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, T param);
     method @WorkerThread public void onDrawMultiBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, java.util.Collection<? extends T> params);
     method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
     method @WorkerThread public default void onMultiBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
@@ -46,12 +46,12 @@
     method public boolean isValid();
     method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseComplete);
     method public void release(boolean cancelPending);
-    method public void renderFrontBufferedLayer(T? param);
+    method public void renderFrontBufferedLayer(T param);
     method public void renderMultiBufferedLayer(java.util.Collection<? extends T> params);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public static interface GLFrontBufferedRenderer.Callback<T> {
-    method @WorkerThread public void onDrawFrontBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, T? param);
+    method @WorkerThread public void onDrawFrontBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, T param);
     method @WorkerThread public void onDrawMultiBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, java.util.Collection<? extends T> params);
     method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
     method @WorkerThread public default void onMultiBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
diff --git a/graphics/graphics-core/api/public_plus_experimental_current.txt b/graphics/graphics-core/api/public_plus_experimental_current.txt
index e10c65e..69d2dd9 100644
--- a/graphics/graphics-core/api/public_plus_experimental_current.txt
+++ b/graphics/graphics-core/api/public_plus_experimental_current.txt
@@ -17,12 +17,12 @@
     method public boolean isValid();
     method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseComplete);
     method public void release(boolean cancelPending);
-    method public void renderFrontBufferedLayer(T? param);
+    method public void renderFrontBufferedLayer(T param);
     method public void renderMultiBufferedLayer(java.util.Collection<? extends T> params);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public static interface CanvasFrontBufferedRenderer.Callback<T> {
-    method @WorkerThread public void onDrawFrontBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, T? param);
+    method @WorkerThread public void onDrawFrontBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, T param);
     method @WorkerThread public void onDrawMultiBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, java.util.Collection<? extends T> params);
     method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
     method @WorkerThread public default void onMultiBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
@@ -46,12 +46,12 @@
     method public boolean isValid();
     method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseComplete);
     method public void release(boolean cancelPending);
-    method public void renderFrontBufferedLayer(T? param);
+    method public void renderFrontBufferedLayer(T param);
     method public void renderMultiBufferedLayer(java.util.Collection<? extends T> params);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public static interface GLFrontBufferedRenderer.Callback<T> {
-    method @WorkerThread public void onDrawFrontBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, T? param);
+    method @WorkerThread public void onDrawFrontBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, T param);
     method @WorkerThread public void onDrawMultiBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, java.util.Collection<? extends T> params);
     method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
     method @WorkerThread public default void onMultiBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
diff --git a/graphics/graphics-core/api/restricted_current.txt b/graphics/graphics-core/api/restricted_current.txt
index bf4aa7c..0b087b8 100644
--- a/graphics/graphics-core/api/restricted_current.txt
+++ b/graphics/graphics-core/api/restricted_current.txt
@@ -17,12 +17,12 @@
     method public boolean isValid();
     method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseComplete);
     method public void release(boolean cancelPending);
-    method public void renderFrontBufferedLayer(T? param);
+    method public void renderFrontBufferedLayer(T param);
     method public void renderMultiBufferedLayer(java.util.Collection<? extends T> params);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public static interface CanvasFrontBufferedRenderer.Callback<T> {
-    method @WorkerThread public void onDrawFrontBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, T? param);
+    method @WorkerThread public void onDrawFrontBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, T param);
     method @WorkerThread public void onDrawMultiBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, java.util.Collection<? extends T> params);
     method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
     method @WorkerThread public default void onMultiBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
@@ -46,12 +46,12 @@
     method public boolean isValid();
     method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseComplete);
     method public void release(boolean cancelPending);
-    method public void renderFrontBufferedLayer(T? param);
+    method public void renderFrontBufferedLayer(T param);
     method public void renderMultiBufferedLayer(java.util.Collection<? extends T> params);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public static interface GLFrontBufferedRenderer.Callback<T> {
-    method @WorkerThread public void onDrawFrontBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, T? param);
+    method @WorkerThread public void onDrawFrontBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, T param);
     method @WorkerThread public void onDrawMultiBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, java.util.Collection<? extends T> params);
     method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
     method @WorkerThread public default void onMultiBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
diff --git a/health/connect/connect-client/api/api_lint.ignore b/health/connect/connect-client/api/api_lint.ignore
index e2d1805..218a3d6 100644
--- a/health/connect/connect-client/api/api_lint.ignore
+++ b/health/connect/connect-client/api/api_lint.ignore
@@ -1,3 +1,7 @@
 // Baseline format: 1.0
+GetterSetterNames: field ChangesResponse.changesTokenExpired:
+    Invalid name for boolean property `changesTokenExpired`. Should start with one of `has`, `can`, `should`, `is`.
+
+
 MissingJvmstatic: androidx.health.connect.client.HealthConnectClient#ACTION_HEALTH_CONNECT_SETTINGS:
     Companion object constants like ACTION_HEALTH_CONNECT_SETTINGS should be using @JvmField, not @JvmStatic; see https://developer.android.com/kotlin/interop#companion_constants
diff --git a/health/health-services-client/api/api_lint.ignore b/health/health-services-client/api/api_lint.ignore
index 844c583..7bcf2c0 100644
--- a/health/health-services-client/api/api_lint.ignore
+++ b/health/health-services-client/api/api_lint.ignore
@@ -1,12 +1,12 @@
 // Baseline format: 1.0
-DocumentExceptions: androidx.health.services.client.ExerciseClient#updateExerciseTypeConfigAsync(androidx.health.services.client.data.ExerciseTypeConfig):
-    Method ExerciseClient.updateExerciseTypeConfigAsync appears to be throwing kotlin.NotImplementedError; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
-
-
 ExecutorRegistration: androidx.health.services.client.ExerciseClient#clearUpdateCallbackAsync(androidx.health.services.client.ExerciseUpdateCallback):
     Registration methods should have overload that accepts delivery Executor: `clearUpdateCallbackAsync`
 
 
+GetterSetterNames: field ExerciseTypeCapabilities.supportsAutoPauseAndResume:
+    Invalid name for boolean property `supportsAutoPauseAndResume`. Should start with one of `has`, `can`, `should`, `is`.
+
+
 InvalidNullabilityOverride: androidx.health.services.client.PassiveListenerService#onBind(android.content.Intent):
     Invalid nullability on method `onBind` return. Overrides of unannotated super method cannot be Nullable.
 InvalidNullabilityOverride: androidx.health.services.client.PassiveListenerService#onBind(android.content.Intent) parameter #0:
diff --git a/javascriptengine/javascriptengine/build.gradle b/javascriptengine/javascriptengine/build.gradle
index d6f3824..4e8c63b 100644
--- a/javascriptengine/javascriptengine/build.gradle
+++ b/javascriptengine/javascriptengine/build.gradle
@@ -26,7 +26,8 @@
     api("androidx.annotation:annotation:1.3.0")
     api("androidx.concurrent:concurrent-futures:1.0.0")
     api("androidx.core:core:1.1.0")
-    implementation(libs.guavaAndroid)
+    api(libs.guavaAndroid)
+
     androidTestImplementation 'junit:junit:4.12'
     annotationProcessor(libs.nullaway)
     androidTestImplementation(libs.testExtJunit)
diff --git a/libraryversions.toml b/libraryversions.toml
index 65322bc..77cd29b 100644
--- a/libraryversions.toml
+++ b/libraryversions.toml
@@ -149,9 +149,9 @@
 WEAR_TILES = "1.2.0-alpha04"
 WEAR_WATCHFACE = "1.2.0-alpha08"
 WEBKIT = "1.8.0-alpha01"
-WINDOW = "1.1.0-beta03"
-WINDOW_EXTENSIONS = "1.1.0-beta02"
-WINDOW_EXTENSIONS_CORE = "1.0.0-beta03"
+WINDOW = "1.1.0-rc01"
+WINDOW_EXTENSIONS = "1.1.0-rc01"
+WINDOW_EXTENSIONS_CORE = "1.0.0-rc01"
 WINDOW_SIDECAR = "1.0.0-rc01"
 WORK = "2.9.0-alpha01"
 
diff --git a/lifecycle/lifecycle-livedata-core/api/current.ignore b/lifecycle/lifecycle-livedata-core/api/current.ignore
new file mode 100644
index 0000000..723ad63
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-core/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.Observer#onChanged(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.lifecycle.Observer.onChanged(T value)
diff --git a/lifecycle/lifecycle-livedata-core/api/current.txt b/lifecycle/lifecycle-livedata-core/api/current.txt
index f528b4e..eed1a51 100644
--- a/lifecycle/lifecycle-livedata-core/api/current.txt
+++ b/lifecycle/lifecycle-livedata-core/api/current.txt
@@ -26,7 +26,7 @@
   }
 
   public fun interface Observer<T> {
-    method public void onChanged(T? value);
+    method public void onChanged(T value);
   }
 
 }
diff --git a/lifecycle/lifecycle-livedata-core/api/public_plus_experimental_current.txt b/lifecycle/lifecycle-livedata-core/api/public_plus_experimental_current.txt
index f528b4e..eed1a51 100644
--- a/lifecycle/lifecycle-livedata-core/api/public_plus_experimental_current.txt
+++ b/lifecycle/lifecycle-livedata-core/api/public_plus_experimental_current.txt
@@ -26,7 +26,7 @@
   }
 
   public fun interface Observer<T> {
-    method public void onChanged(T? value);
+    method public void onChanged(T value);
   }
 
 }
diff --git a/lifecycle/lifecycle-livedata-core/api/restricted_current.ignore b/lifecycle/lifecycle-livedata-core/api/restricted_current.ignore
new file mode 100644
index 0000000..723ad63
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-core/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.Observer#onChanged(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.lifecycle.Observer.onChanged(T value)
diff --git a/lifecycle/lifecycle-livedata-core/api/restricted_current.txt b/lifecycle/lifecycle-livedata-core/api/restricted_current.txt
index f528b4e..eed1a51 100644
--- a/lifecycle/lifecycle-livedata-core/api/restricted_current.txt
+++ b/lifecycle/lifecycle-livedata-core/api/restricted_current.txt
@@ -26,7 +26,7 @@
   }
 
   public fun interface Observer<T> {
-    method public void onChanged(T? value);
+    method public void onChanged(T value);
   }
 
 }
diff --git a/lifecycle/lifecycle-livedata-ktx/api/current.ignore b/lifecycle/lifecycle-livedata-ktx/api/current.ignore
new file mode 100644
index 0000000..d7e55f2
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.LiveDataScope#emit(T, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.lifecycle.LiveDataScope.emit(T value, kotlin.coroutines.Continuation<? super kotlin.Unit> arg2)
diff --git a/lifecycle/lifecycle-livedata-ktx/api/current.txt b/lifecycle/lifecycle-livedata-ktx/api/current.txt
index bae0928..57284ff 100644
--- a/lifecycle/lifecycle-livedata-ktx/api/current.txt
+++ b/lifecycle/lifecycle-livedata-ktx/api/current.txt
@@ -15,7 +15,7 @@
   }
 
   public interface LiveDataScope<T> {
-    method public suspend Object? emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    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_current.txt b/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_current.txt
index bae0928..57284ff 100644
--- a/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_current.txt
+++ b/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_current.txt
@@ -15,7 +15,7 @@
   }
 
   public interface LiveDataScope<T> {
-    method public suspend Object? emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    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/restricted_current.ignore b/lifecycle/lifecycle-livedata-ktx/api/restricted_current.ignore
new file mode 100644
index 0000000..d7e55f2
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.LiveDataScope#emit(T, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.lifecycle.LiveDataScope.emit(T value, kotlin.coroutines.Continuation<? super kotlin.Unit> arg2)
diff --git a/lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt b/lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt
index bae0928..57284ff 100644
--- a/lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt
+++ b/lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt
@@ -15,7 +15,7 @@
   }
 
   public interface LiveDataScope<T> {
-    method public suspend Object? emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    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/restricted_current.txt b/lifecycle/lifecycle-livedata/api/restricted_current.txt
index bb61b39..6ffd1d9 100644
--- a/lifecycle/lifecycle-livedata/api/restricted_current.txt
+++ b/lifecycle/lifecycle-livedata/api/restricted_current.txt
@@ -4,7 +4,7 @@
   @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 @WorkerThread protected abstract T compute();
     method public androidx.lifecycle.LiveData<T> getLiveData();
     method public void invalidate();
     property public androidx.lifecycle.LiveData<T> liveData;
diff --git a/lifecycle/lifecycle-runtime-compose/api/current.ignore b/lifecycle/lifecycle-runtime-compose/api/current.ignore
new file mode 100644
index 0000000..bfd5f84
--- /dev/null
+++ b/lifecycle/lifecycle-runtime-compose/api/current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.compose.FlowExtKt#collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T, androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State, kotlin.coroutines.CoroutineContext) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.lifecycle.compose.FlowExtKt.collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T> arg1, T initialValue, androidx.lifecycle.Lifecycle lifecycle, androidx.lifecycle.Lifecycle.State minActiveState, kotlin.coroutines.CoroutineContext context)
+InvalidNullConversion: androidx.lifecycle.compose.FlowExtKt#collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T, androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State, kotlin.coroutines.CoroutineContext) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.lifecycle.compose.FlowExtKt.collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T> arg1, T initialValue, androidx.lifecycle.LifecycleOwner lifecycleOwner, androidx.lifecycle.Lifecycle.State minActiveState, kotlin.coroutines.CoroutineContext context)
diff --git a/lifecycle/lifecycle-runtime-compose/api/current.txt b/lifecycle/lifecycle-runtime-compose/api/current.txt
index 95c6977..0686666 100644
--- a/lifecycle/lifecycle-runtime-compose/api/current.txt
+++ b/lifecycle/lifecycle-runtime-compose/api/current.txt
@@ -4,8 +4,8 @@
   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);
+    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);
   }
 
   public final class LifecycleExtKt {
diff --git a/lifecycle/lifecycle-runtime-compose/api/public_plus_experimental_current.txt b/lifecycle/lifecycle-runtime-compose/api/public_plus_experimental_current.txt
index 95c6977..0686666 100644
--- a/lifecycle/lifecycle-runtime-compose/api/public_plus_experimental_current.txt
+++ b/lifecycle/lifecycle-runtime-compose/api/public_plus_experimental_current.txt
@@ -4,8 +4,8 @@
   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);
+    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);
   }
 
   public final class LifecycleExtKt {
diff --git a/lifecycle/lifecycle-runtime-compose/api/restricted_current.ignore b/lifecycle/lifecycle-runtime-compose/api/restricted_current.ignore
new file mode 100644
index 0000000..bfd5f84
--- /dev/null
+++ b/lifecycle/lifecycle-runtime-compose/api/restricted_current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.compose.FlowExtKt#collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T, androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State, kotlin.coroutines.CoroutineContext) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.lifecycle.compose.FlowExtKt.collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T> arg1, T initialValue, androidx.lifecycle.Lifecycle lifecycle, androidx.lifecycle.Lifecycle.State minActiveState, kotlin.coroutines.CoroutineContext context)
+InvalidNullConversion: androidx.lifecycle.compose.FlowExtKt#collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T, androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State, kotlin.coroutines.CoroutineContext) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.lifecycle.compose.FlowExtKt.collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T> arg1, T initialValue, androidx.lifecycle.LifecycleOwner lifecycleOwner, androidx.lifecycle.Lifecycle.State minActiveState, kotlin.coroutines.CoroutineContext context)
diff --git a/lifecycle/lifecycle-runtime-compose/api/restricted_current.txt b/lifecycle/lifecycle-runtime-compose/api/restricted_current.txt
index 95c6977..0686666 100644
--- a/lifecycle/lifecycle-runtime-compose/api/restricted_current.txt
+++ b/lifecycle/lifecycle-runtime-compose/api/restricted_current.txt
@@ -4,8 +4,8 @@
   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);
+    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);
   }
 
   public final class LifecycleExtKt {
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/api/current.ignore b/lifecycle/lifecycle-viewmodel-savedstate/api/current.ignore
new file mode 100644
index 0000000..41a6e11
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-savedstate/api/current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.SavedStateHandle#getLiveData(String, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.lifecycle.SavedStateHandle.getLiveData(String key, T initialValue)
+InvalidNullConversion: androidx.lifecycle.SavedStateHandle#getStateFlow(String, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.lifecycle.SavedStateHandle.getStateFlow(String key, T initialValue)
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/api/current.txt b/lifecycle/lifecycle-viewmodel-savedstate/api/current.txt
index c030c8a..18f47c7 100644
--- a/lifecycle/lifecycle-viewmodel-savedstate/api/current.txt
+++ b/lifecycle/lifecycle-viewmodel-savedstate/api/current.txt
@@ -14,8 +14,8 @@
     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 <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);
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/api/public_plus_experimental_current.txt b/lifecycle/lifecycle-viewmodel-savedstate/api/public_plus_experimental_current.txt
index c030c8a..18f47c7 100644
--- a/lifecycle/lifecycle-viewmodel-savedstate/api/public_plus_experimental_current.txt
+++ b/lifecycle/lifecycle-viewmodel-savedstate/api/public_plus_experimental_current.txt
@@ -14,8 +14,8 @@
     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 <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);
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_current.ignore b/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_current.ignore
new file mode 100644
index 0000000..41a6e11
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.SavedStateHandle#getLiveData(String, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.lifecycle.SavedStateHandle.getLiveData(String key, T initialValue)
+InvalidNullConversion: androidx.lifecycle.SavedStateHandle#getStateFlow(String, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.lifecycle.SavedStateHandle.getStateFlow(String key, T initialValue)
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_current.txt b/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_current.txt
index c030c8a..18f47c7 100644
--- a/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_current.txt
+++ b/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_current.txt
@@ -14,8 +14,8 @@
     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 <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);
diff --git a/lifecycle/lifecycle-viewmodel/api/current.ignore b/lifecycle/lifecycle-viewmodel/api/current.ignore
new file mode 100644
index 0000000..68d0b3a
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.viewmodel.MutableCreationExtras#set(androidx.lifecycle.viewmodel.CreationExtras.Key<T>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter t in androidx.lifecycle.viewmodel.MutableCreationExtras.set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T t)
diff --git a/lifecycle/lifecycle-viewmodel/api/current.txt b/lifecycle/lifecycle-viewmodel/api/current.txt
index f8457f6..f6e96bc 100644
--- a/lifecycle/lifecycle-viewmodel/api/current.txt
+++ b/lifecycle/lifecycle-viewmodel/api/current.txt
@@ -122,7 +122,7 @@
   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);
+    method public operator <T> void set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T t);
   }
 
   @kotlin.DslMarker public @interface ViewModelFactoryDsl {
diff --git a/lifecycle/lifecycle-viewmodel/api/public_plus_experimental_current.txt b/lifecycle/lifecycle-viewmodel/api/public_plus_experimental_current.txt
index f8457f6..f6e96bc 100644
--- a/lifecycle/lifecycle-viewmodel/api/public_plus_experimental_current.txt
+++ b/lifecycle/lifecycle-viewmodel/api/public_plus_experimental_current.txt
@@ -122,7 +122,7 @@
   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);
+    method public operator <T> void set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T t);
   }
 
   @kotlin.DslMarker public @interface ViewModelFactoryDsl {
diff --git a/lifecycle/lifecycle-viewmodel/api/restricted_current.ignore b/lifecycle/lifecycle-viewmodel/api/restricted_current.ignore
new file mode 100644
index 0000000..68d0b3a
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.viewmodel.MutableCreationExtras#set(androidx.lifecycle.viewmodel.CreationExtras.Key<T>, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter t in androidx.lifecycle.viewmodel.MutableCreationExtras.set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T t)
diff --git a/lifecycle/lifecycle-viewmodel/api/restricted_current.txt b/lifecycle/lifecycle-viewmodel/api/restricted_current.txt
index f8457f6..f6e96bc 100644
--- a/lifecycle/lifecycle-viewmodel/api/restricted_current.txt
+++ b/lifecycle/lifecycle-viewmodel/api/restricted_current.txt
@@ -122,7 +122,7 @@
   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);
+    method public operator <T> void set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T t);
   }
 
   @kotlin.DslMarker public @interface ViewModelFactoryDsl {
diff --git a/lint-checks/src/main/java/androidx/build/lint/AndroidXIssueRegistry.kt b/lint-checks/src/main/java/androidx/build/lint/AndroidXIssueRegistry.kt
index b9cbe32..9bf1025 100644
--- a/lint-checks/src/main/java/androidx/build/lint/AndroidXIssueRegistry.kt
+++ b/lint-checks/src/main/java/androidx/build/lint/AndroidXIssueRegistry.kt
@@ -70,7 +70,8 @@
                 NullabilityAnnotationsDetector.ISSUE,
                 IgnoreClassLevelDetector.ISSUE,
                 ExperimentalPropertyAnnotationDetector.ISSUE,
-                UnstableAidlAnnotationDetector.ISSUE,
+                // Temporarily disable AIDL lint check due to b/278871118.
+                // UnstableAidlAnnotationDetector.ISSUE,
                 // MissingJvmDefaultWithCompatibilityDetector is intentionally left out of the
                 // registry, see comments on the class for more details.
             )
diff --git a/navigation/navigation-common/api/2.6.0-beta01.txt b/navigation/navigation-common/api/2.6.0-beta01.txt
index de2b551..e6d0229 100644
--- a/navigation/navigation-common/api/2.6.0-beta01.txt
+++ b/navigation/navigation-common/api/2.6.0-beta01.txt
@@ -398,10 +398,10 @@
     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);
+    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;
@@ -438,8 +438,8 @@
   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);
+    method public D parseValue(String value);
+    method public void put(android.os.Bundle bundle, String key, D value);
     property public String name;
   }
 
diff --git a/navigation/navigation-common/api/api_lint.ignore b/navigation/navigation-common/api/api_lint.ignore
index 6ada04b..ef9b41b 100644
--- a/navigation/navigation-common/api/api_lint.ignore
+++ b/navigation/navigation-common/api/api_lint.ignore
@@ -89,12 +89,12 @@
     Getter should be on the built object, not the builder: method androidx.navigation.PopUpToBuilder.getInclusive()
 
 
-GetterSetterNames: androidx.navigation.NavArgumentBuilder#getNullable():
-    Symmetric method for `setNullable` must be named `isNullable`; was `getNullable`
-GetterSetterNames: androidx.navigation.NavOptionsBuilder#getLaunchSingleTop():
-    Symmetric method for `setLaunchSingleTop` must be named `isLaunchSingleTop`; was `getLaunchSingleTop`
-GetterSetterNames: androidx.navigation.PopUpToBuilder#getInclusive():
-    Symmetric method for `setInclusive` must be named `isInclusive`; was `getInclusive`
+GetterSetterNames: field NavArgumentBuilder.nullable:
+    Invalid name for boolean property `nullable`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field NavOptionsBuilder.launchSingleTop:
+    Invalid name for boolean property `launchSingleTop`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PopUpToBuilder.inclusive:
+    Invalid name for boolean property `inclusive`. Should start with one of `has`, `can`, `should`, `is`.
 
 
 MissingBuildMethod: androidx.navigation.AnimBuilder:
diff --git a/navigation/navigation-common/api/current.ignore b/navigation/navigation-common/api/current.ignore
index a8fe9ea..8eebd5d 100644
--- a/navigation/navigation-common/api/current.ignore
+++ b/navigation/navigation-common/api/current.ignore
@@ -1,3 +1,9 @@
 // Baseline format: 1.0
+InvalidNullConversion: androidx.navigation.NavType#put(android.os.Bundle, String, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.navigation.NavType.put(android.os.Bundle bundle, String key, T value)
+InvalidNullConversion: androidx.navigation.NavType.ParcelableType#put(android.os.Bundle, String, D) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.navigation.NavType.ParcelableType.put(android.os.Bundle bundle, String key, D value)
+
+
 RemovedClass: androidx.navigation.NavArgsLazyKt:
     Removed class androidx.navigation.NavArgsLazyKt
diff --git a/navigation/navigation-common/api/current.txt b/navigation/navigation-common/api/current.txt
index de2b551..e6d0229 100644
--- a/navigation/navigation-common/api/current.txt
+++ b/navigation/navigation-common/api/current.txt
@@ -398,10 +398,10 @@
     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);
+    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;
@@ -438,8 +438,8 @@
   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);
+    method public D parseValue(String value);
+    method public void put(android.os.Bundle bundle, String key, D value);
     property public String name;
   }
 
diff --git a/navigation/navigation-common/api/public_plus_experimental_2.6.0-beta01.txt b/navigation/navigation-common/api/public_plus_experimental_2.6.0-beta01.txt
index de2b551..e6d0229 100644
--- a/navigation/navigation-common/api/public_plus_experimental_2.6.0-beta01.txt
+++ b/navigation/navigation-common/api/public_plus_experimental_2.6.0-beta01.txt
@@ -398,10 +398,10 @@
     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);
+    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;
@@ -438,8 +438,8 @@
   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);
+    method public D parseValue(String value);
+    method public void put(android.os.Bundle bundle, String key, D value);
     property public String name;
   }
 
diff --git a/navigation/navigation-common/api/public_plus_experimental_current.txt b/navigation/navigation-common/api/public_plus_experimental_current.txt
index de2b551..e6d0229 100644
--- a/navigation/navigation-common/api/public_plus_experimental_current.txt
+++ b/navigation/navigation-common/api/public_plus_experimental_current.txt
@@ -398,10 +398,10 @@
     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);
+    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;
@@ -438,8 +438,8 @@
   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);
+    method public D parseValue(String value);
+    method public void put(android.os.Bundle bundle, String key, D value);
     property public String name;
   }
 
diff --git a/navigation/navigation-common/api/restricted_2.6.0-beta01.txt b/navigation/navigation-common/api/restricted_2.6.0-beta01.txt
index de2b551..e6d0229 100644
--- a/navigation/navigation-common/api/restricted_2.6.0-beta01.txt
+++ b/navigation/navigation-common/api/restricted_2.6.0-beta01.txt
@@ -398,10 +398,10 @@
     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);
+    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;
@@ -438,8 +438,8 @@
   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);
+    method public D parseValue(String value);
+    method public void put(android.os.Bundle bundle, String key, D value);
     property public String name;
   }
 
diff --git a/navigation/navigation-common/api/restricted_current.ignore b/navigation/navigation-common/api/restricted_current.ignore
index a8fe9ea..8eebd5d 100644
--- a/navigation/navigation-common/api/restricted_current.ignore
+++ b/navigation/navigation-common/api/restricted_current.ignore
@@ -1,3 +1,9 @@
 // Baseline format: 1.0
+InvalidNullConversion: androidx.navigation.NavType#put(android.os.Bundle, String, T) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.navigation.NavType.put(android.os.Bundle bundle, String key, T value)
+InvalidNullConversion: androidx.navigation.NavType.ParcelableType#put(android.os.Bundle, String, D) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.navigation.NavType.ParcelableType.put(android.os.Bundle bundle, String key, D value)
+
+
 RemovedClass: androidx.navigation.NavArgsLazyKt:
     Removed class androidx.navigation.NavArgsLazyKt
diff --git a/navigation/navigation-common/api/restricted_current.txt b/navigation/navigation-common/api/restricted_current.txt
index de2b551..e6d0229 100644
--- a/navigation/navigation-common/api/restricted_current.txt
+++ b/navigation/navigation-common/api/restricted_current.txt
@@ -398,10 +398,10 @@
     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);
+    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;
@@ -438,8 +438,8 @@
   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);
+    method public D parseValue(String value);
+    method public void put(android.os.Bundle bundle, String key, D value);
     property public String name;
   }
 
diff --git a/paging/OWNERS b/paging/OWNERS
index dadce6e..5bb78a1 100644
--- a/paging/OWNERS
+++ b/paging/OWNERS
@@ -1,4 +1,4 @@
-# Bug component: 413106
+# Bug component: 461228
 clarafok@google.com
 ilake@google.com
 jbwoods@google.com
diff --git a/paging/paging-common/api/api_lint.ignore b/paging/paging-common/api/api_lint.ignore
index dfe3f6e..3748215 100644
--- a/paging/paging-common/api/api_lint.ignore
+++ b/paging/paging-common/api/api_lint.ignore
@@ -11,6 +11,20 @@
     Registration methods should have overload that accepts delivery Executor: `addWeakCallback`
 
 
+GetterSetterNames: field LoadState.endOfPaginationReached:
+    Invalid name for boolean property `endOfPaginationReached`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PagingSource.LoadParams.placeholdersEnabled:
+    Invalid name for boolean property `placeholdersEnabled`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PagingSource.invalid:
+    Invalid name for boolean property `invalid`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PagingSource.jumpingSupported:
+    Invalid name for boolean property `jumpingSupported`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PagingSource.keyReuseSupported:
+    Invalid name for boolean property `keyReuseSupported`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field RemoteMediator.MediatorResult.Success.endOfPaginationReached:
+    Invalid name for boolean property `endOfPaginationReached`. Should start with one of `has`, `can`, `should`, `is`.
+
+
 KotlinDefaultParameterOrder: androidx.paging.Pager#Pager(androidx.paging.PagingConfig, Key, androidx.paging.RemoteMediator<Key,Value>, kotlin.jvm.functions.Function0<? extends androidx.paging.PagingSource<Key,Value>>) parameter #1:
     Parameter `initialKey` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
 KotlinDefaultParameterOrder: androidx.paging.PagingDataTransforms#insertFooterItem(androidx.paging.PagingData<T>, androidx.paging.TerminalSeparatorType, T) parameter #1:
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/LegacyPagingSource.kt b/paging/paging-common/src/main/kotlin/androidx/paging/LegacyPagingSource.kt
index 4702943..b3625ac1 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/LegacyPagingSource.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/LegacyPagingSource.kt
@@ -25,7 +25,7 @@
 import androidx.paging.LoadType.PREPEND
 import androidx.paging.LoadType.REFRESH
 import androidx.paging.internal.BUGANIZER_URL
-import kotlinx.coroutines.CoroutineDispatcher
+import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.DelicateCoroutinesApi
 import kotlinx.coroutines.withContext
 
@@ -36,7 +36,7 @@
 @OptIn(DelicateCoroutinesApi::class)
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class LegacyPagingSource<Key : Any, Value : Any>(
-    private val fetchDispatcher: CoroutineDispatcher,
+    private val fetchContext: CoroutineContext,
     internal val dataSource: DataSource<Key, Value>
 ) : PagingSource<Key, Value>() {
     private var pageSize: Int = PAGE_SIZE_NOT_SET
@@ -106,7 +106,7 @@
             pageSize
         )
 
-        return withContext(fetchDispatcher) {
+        return withContext(fetchContext) {
             dataSource.load(dataSourceParams).run {
                 LoadResult.Page(
                     data,
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/PagedList.kt b/paging/paging-common/src/main/kotlin/androidx/paging/PagedList.kt
index 35ca80a..ac60b3d 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/PagedList.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/PagedList.kt
@@ -502,7 +502,7 @@
             val fetchDispatcher = fetchDispatcher ?: Dispatchers.IO
             val pagingSource = pagingSource ?: dataSource?.let { dataSource ->
                 LegacyPagingSource(
-                    fetchDispatcher = fetchDispatcher,
+                    fetchContext = fetchDispatcher,
                     dataSource = dataSource
                 )
             }
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/LegacyPagingSourceTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/LegacyPagingSourceTest.kt
index 8091620..ceb1e7f 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/LegacyPagingSourceTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/LegacyPagingSourceTest.kt
@@ -17,9 +17,9 @@
 package androidx.paging
 
 import androidx.paging.PagingSource.LoadResult.Page
-import androidx.testutils.DirectDispatcher
 import androidx.testutils.TestDispatcher
 import com.google.common.truth.Truth.assertThat
+import kotlin.coroutines.EmptyCoroutineContext
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.asCoroutineDispatcher
 import kotlinx.coroutines.flow.collectLatest
@@ -56,7 +56,7 @@
 
     @Test
     fun init_invalidDataSource() {
-        val testDispatcher = DirectDispatcher
+        val testContext = EmptyCoroutineContext
         val dataSource = object : DataSource<Int, Int>(KeyType.ITEM_KEYED) {
             var isInvalidCalls = 0
 
@@ -74,7 +74,7 @@
         }
 
         val pagingSource = LegacyPagingSource(
-            fetchDispatcher = testDispatcher,
+            fetchContext = testContext,
             dataSource = dataSource,
         )
 
@@ -111,7 +111,7 @@
             override fun getKey(item: String) = item.hashCode()
         }
         val pagingSource = LegacyPagingSource(
-            fetchDispatcher = Dispatchers.Unconfined,
+            fetchContext = Dispatchers.Unconfined,
             dataSource
         )
 
@@ -157,7 +157,7 @@
             }
         }
         val pagingSource = LegacyPagingSource(
-            fetchDispatcher = Dispatchers.Unconfined,
+            fetchContext = Dispatchers.Unconfined,
             dataSource = dataSource
         )
 
@@ -180,7 +180,7 @@
     @Test
     fun positional() {
         val pagingSource = LegacyPagingSource(
-            fetchDispatcher = Dispatchers.Unconfined,
+            fetchContext = Dispatchers.Unconfined,
             dataSource = createTestPositionalDataSource()
         )
 
@@ -233,7 +233,7 @@
     @Test
     fun invalidateFromPagingSource() {
         val pagingSource = LegacyPagingSource(
-            fetchDispatcher = Dispatchers.Unconfined,
+            fetchContext = Dispatchers.Unconfined,
             dataSource = createTestPositionalDataSource()
         )
         val dataSource = pagingSource.dataSource
@@ -259,7 +259,7 @@
     @Test
     fun invalidateFromDataSource() {
         val pagingSource = LegacyPagingSource(
-            fetchDispatcher = Dispatchers.Unconfined,
+            fetchContext = Dispatchers.Unconfined,
             dataSource = createTestPositionalDataSource()
         )
         val dataSource = pagingSource.dataSource
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PageEventTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PageEventTest.kt
index 47fe02e4..20a1116 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PageEventTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PageEventTest.kt
@@ -19,7 +19,7 @@
 import androidx.paging.LoadType.PREPEND
 import androidx.paging.LoadType.REFRESH
 import androidx.paging.PageEvent.Drop
-import androidx.testutils.DirectDispatcher
+import kotlin.coroutines.EmptyCoroutineContext
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
@@ -290,7 +290,7 @@
             )
         }
 
-        private val differ = TestPagingDataDiffer<String>(DirectDispatcher)
+        private val differ = TestPagingDataDiffer<String>(EmptyCoroutineContext)
         private lateinit var pagingData: PagingData<String>
 
         @Before
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PagingDataDifferTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PagingDataDifferTest.kt
index fdd21d7..9253657 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PagingDataDifferTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PagingDataDifferTest.kt
@@ -21,7 +21,6 @@
 import androidx.paging.LoadType.PREPEND
 import androidx.paging.PageEvent.Drop
 import androidx.paging.PagingSource.LoadResult
-import androidx.testutils.DirectDispatcher
 import androidx.testutils.MainDispatcherRule
 import androidx.testutils.TestDispatcher
 import com.google.common.truth.Truth.assertThat
@@ -2039,11 +2038,6 @@
     }
 
     private fun runTest(
-        scope: CoroutineScope = CoroutineScope(DirectDispatcher),
-        differ: SimpleDiffer = SimpleDiffer(
-            differCallback = dummyDifferCallback,
-            coroutineScope = scope,
-        ),
         loadDispatcher: TestDispatcher = TestDispatcher(),
         initialKey: Int? = null,
         pagingSources: MutableList<TestPagingSource> = mutableListOf(),
@@ -2065,11 +2059,15 @@
             uiReceivers: List<TrackableUiReceiverWrapper>,
             hintReceivers: List<TrackableHintReceiverWrapper>
         ) -> Unit
-    ) {
+    ) = testScope.runTest {
+        val differ = SimpleDiffer(
+            differCallback = dummyDifferCallback,
+            coroutineScope = this,
+        )
         val uiReceivers = mutableListOf<TrackableUiReceiverWrapper>()
         val hintReceivers = mutableListOf<TrackableHintReceiverWrapper>()
 
-        val collection = scope.launch {
+        val collection = launch {
             pager.flow
             .map { pagingData ->
                 PagingData(
diff --git a/playground-common/playground.properties b/playground-common/playground.properties
index 476ad28..599b0b2 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=9912543
-androidx.playground.metalavaBuildId=9883460
+androidx.playground.snapshotBuildId=9971607
+androidx.playground.metalavaBuildId=9975079
 androidx.studio.type=playground
diff --git a/privacysandbox/OWNERS b/privacysandbox/OWNERS
index 3d0f6bf..fcd4bae 100644
--- a/privacysandbox/OWNERS
+++ b/privacysandbox/OWNERS
@@ -1,4 +1,4 @@
-# Bug component: 1314839
+# Bug component: 1248632
 abz@google.com
 ltenorio@google.com
 nicoroulet@google.com
diff --git a/privacysandbox/ads/OWNERS b/privacysandbox/ads/OWNERS
index 213fd78..dc742a8 100644
--- a/privacysandbox/ads/OWNERS
+++ b/privacysandbox/ads/OWNERS
@@ -1,3 +1,4 @@
+# Bug component: 1248632
 # adservices.measurement OWNERS
 arpanah@google.com # Measurement Primary PoC
 lmohanan@google.com
diff --git a/privacysandbox/ads/ads-adservices/api/api_lint.ignore b/privacysandbox/ads/ads-adservices/api/api_lint.ignore
new file mode 100644
index 0000000..135b6f0
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices/api/api_lint.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+GetterSetterNames: field WebSourceParams.debugKeyAllowed:
+    Invalid name for boolean property `debugKeyAllowed`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field WebTriggerParams.debugKeyAllowed:
+    Invalid name for boolean property `debugKeyAllowed`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/privacysandbox/sdkruntime/OWNERS b/privacysandbox/sdkruntime/OWNERS
index 1ee0dca..5f61b4f 100644
--- a/privacysandbox/sdkruntime/OWNERS
+++ b/privacysandbox/sdkruntime/OWNERS
@@ -1 +1,2 @@
+# Bug component: 1347351
 akulakov@google.com
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyInterfaceStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyInterfaceStubDelegate.kt
index 41dbd62..0f0d2f7 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyInterfaceStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyInterfaceStubDelegate.kt
@@ -5,19 +5,19 @@
 import com.mysdk.PrivacySandboxThrowableParcelConverter.toThrowableParcel
 import kotlin.Int
 import kotlin.Unit
-import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
 
 public class MyInterfaceStubDelegate internal constructor(
   public val `delegate`: MyInterface,
   public val context: Context,
 ) : IMyInterface.Stub() {
+  private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
   public override fun doSomething(request: ParcelableRequest,
       transactionCallback: IResponseTransactionCallback): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.doSomething(RequestConverter(context).fromParcelable(request))
         transactionCallback.onSuccess(ResponseConverter(context).toParcelable(result))
@@ -32,8 +32,7 @@
 
   public override fun getMyInterface(input: IMyInterface,
       transactionCallback: IMyInterfaceTransactionCallback): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.getMyInterface((input as MyInterfaceStubDelegate).delegate)
         transactionCallback.onSuccess(MyInterfaceStubDelegate(result, context))
@@ -48,8 +47,7 @@
 
   public override fun getMySecondInterface(input: IMySecondInterface,
       transactionCallback: IMySecondInterfaceTransactionCallback): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.getMySecondInterface((input as
             MySecondInterfaceStubDelegate).delegate)
@@ -64,6 +62,8 @@
   }
 
   public override fun doMoreStuff(x: Int): Unit {
-    delegate.doMoreStuff(x)
+    coroutineScope.launch {
+      delegate.doMoreStuff(x)
+    }
   }
 }
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySdkStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySdkStubDelegate.kt
index 4419c33..6dbf1b5f 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySdkStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySdkStubDelegate.kt
@@ -7,22 +7,22 @@
 import kotlin.Int
 import kotlin.IntArray
 import kotlin.Unit
-import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
 
 public class MySdkStubDelegate internal constructor(
   public val `delegate`: MySdk,
   public val context: Context,
 ) : IMySdk.Stub() {
+  private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
   public override fun doStuff(
     x: Int,
     y: Int,
     transactionCallback: IStringTransactionCallback,
   ): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.doStuff(x, y)
         transactionCallback.onSuccess(result)
@@ -37,8 +37,7 @@
 
   public override fun handleRequest(request: ParcelableRequest,
       transactionCallback: IResponseTransactionCallback): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.handleRequest(RequestConverter(context).fromParcelable(request))
         transactionCallback.onSuccess(ResponseConverter(context).toParcelable(result))
@@ -53,8 +52,7 @@
 
   public override fun logRequest(request: ParcelableRequest,
       transactionCallback: IUnitTransactionCallback): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         delegate.logRequest(RequestConverter(context).fromParcelable(request))
         transactionCallback.onSuccess()
@@ -68,17 +66,20 @@
   }
 
   public override fun setListener(listener: IMyCallback): Unit {
-    delegate.setListener(MyCallbackClientProxy(listener, context))
+    coroutineScope.launch {
+      delegate.setListener(MyCallbackClientProxy(listener, context))
+    }
   }
 
   public override fun doMoreStuff(): Unit {
-    delegate.doMoreStuff()
+    coroutineScope.launch {
+      delegate.doMoreStuff()
+    }
   }
 
   public override fun getMyInterface(input: IMyInterface,
       transactionCallback: IMyInterfaceTransactionCallback): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.getMyInterface((input as MyInterfaceStubDelegate).delegate)
         transactionCallback.onSuccess(MyInterfaceStubDelegate(result, context))
@@ -92,7 +93,9 @@
   }
 
   public override fun mutateMySecondInterface(input: IMySecondInterface): Unit {
-    delegate.mutateMySecondInterface((input as MySecondInterfaceStubDelegate).delegate)
+    coroutineScope.launch {
+      delegate.mutateMySecondInterface((input as MySecondInterfaceStubDelegate).delegate)
+    }
   }
 
   public override fun handleNullablePrimitives(
@@ -100,8 +103,7 @@
     y: IntArray,
     transactionCallback: IListStringTransactionCallback,
   ): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.handleNullablePrimitives(x.firstOrNull(), y.firstOrNull())
         transactionCallback.onSuccess(if (result == null) arrayOf() else arrayOf(result))
@@ -116,8 +118,7 @@
 
   public override fun handleNullableValues(maybeRequest: ParcelableRequest?,
       transactionCallback: IResponseTransactionCallback): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.handleNullableValues(maybeRequest?.let { notNullValue ->
             RequestConverter(context).fromParcelable(notNullValue) })
@@ -134,8 +135,7 @@
 
   public override fun handleNullableInterfaces(maybeCallback: IMyCallback?,
       transactionCallback: IMyInterfaceTransactionCallback): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.handleNullableInterfaces(maybeCallback?.let { notNullValue ->
             MyCallbackClientProxy(notNullValue, context) })
@@ -152,8 +152,7 @@
 
   public override fun returnUiInterface(transactionCallback: IMyUiInterfaceTransactionCallback):
       Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.returnUiInterface()
         transactionCallback.onSuccess(IMyUiInterfaceCoreLibInfoAndBinderWrapperConverter.toParcelable(result.toCoreLibInfo(context),
@@ -168,6 +167,8 @@
   }
 
   public override fun acceptUiInterfaceParam(input: IMyUiInterface): Unit {
-    delegate.acceptUiInterfaceParam((input as MyUiInterfaceStubDelegate).delegate)
+    coroutineScope.launch {
+      delegate.acceptUiInterfaceParam((input as MyUiInterfaceStubDelegate).delegate)
+    }
   }
 }
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySecondInterfaceStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySecondInterfaceStubDelegate.kt
index 0f6d47f..817f83a 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySecondInterfaceStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySecondInterfaceStubDelegate.kt
@@ -12,19 +12,19 @@
 import kotlin.LongArray
 import kotlin.String
 import kotlin.Unit
-import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
 
 public class MySecondInterfaceStubDelegate internal constructor(
   public val `delegate`: MySecondInterface,
   public val context: Context,
 ) : IMySecondInterface.Stub() {
+  private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
   public override fun doIntStuff(x: IntArray, transactionCallback: IListIntTransactionCallback):
       Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.doIntStuff(x.toList())
         transactionCallback.onSuccess(result.toIntArray())
@@ -39,8 +39,7 @@
 
   public override fun doCharStuff(x: CharArray, transactionCallback: IListCharTransactionCallback):
       Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.doCharStuff(x.toList())
         transactionCallback.onSuccess(result.toCharArray())
@@ -55,8 +54,7 @@
 
   public override fun doFloatStuff(x: FloatArray,
       transactionCallback: IListFloatTransactionCallback): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.doFloatStuff(x.toList())
         transactionCallback.onSuccess(result.toFloatArray())
@@ -71,8 +69,7 @@
 
   public override fun doLongStuff(x: LongArray, transactionCallback: IListLongTransactionCallback):
       Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.doLongStuff(x.toList())
         transactionCallback.onSuccess(result.toLongArray())
@@ -87,8 +84,7 @@
 
   public override fun doDoubleStuff(x: DoubleArray,
       transactionCallback: IListDoubleTransactionCallback): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.doDoubleStuff(x.toList())
         transactionCallback.onSuccess(result.toDoubleArray())
@@ -103,8 +99,7 @@
 
   public override fun doBooleanStuff(x: BooleanArray,
       transactionCallback: IListBooleanTransactionCallback): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.doBooleanStuff(x.toList())
         transactionCallback.onSuccess(result.toBooleanArray())
@@ -119,8 +114,7 @@
 
   public override fun doShortStuff(x: IntArray, transactionCallback: IListShortTransactionCallback):
       Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.doShortStuff(x.map { it.toShort() }.toList())
         transactionCallback.onSuccess(result.map { it.toInt() }.toIntArray())
@@ -135,8 +129,7 @@
 
   public override fun doStringStuff(x: Array<String>,
       transactionCallback: IListStringTransactionCallback): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.doStringStuff(x.toList())
         transactionCallback.onSuccess(result.toTypedArray())
@@ -151,8 +144,7 @@
 
   public override fun doValueStuff(x: Array<ParcelableRequest>,
       transactionCallback: IListResponseTransactionCallback): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.doValueStuff(x.map { RequestConverter(context).fromParcelable(it)
             }.toList())
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyUiInterfaceStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyUiInterfaceStubDelegate.kt
index d25a92d..b234751 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyUiInterfaceStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyUiInterfaceStubDelegate.kt
@@ -3,12 +3,19 @@
 import android.content.Context
 import kotlin.Int
 import kotlin.Unit
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
 
 public class MyUiInterfaceStubDelegate internal constructor(
   public val `delegate`: MyUiInterface,
   public val context: Context,
 ) : IMyUiInterface.Stub() {
+  private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
   public override fun doSomethingForUi(x: Int, y: Int): Unit {
-    delegate.doSomethingForUi(x, y)
+    coroutineScope.launch {
+      delegate.doSomethingForUi(x, y)
+    }
   }
 }
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/myotherpackage/MyOtherPackageInterfaceStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/myotherpackage/MyOtherPackageInterfaceStubDelegate.kt
index 4b68dab..594b8e3 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/myotherpackage/MyOtherPackageInterfaceStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/myotherpackage/MyOtherPackageInterfaceStubDelegate.kt
@@ -6,23 +6,25 @@
 import com.mysdk.TransportCancellationCallback
 import kotlin.Int
 import kotlin.Unit
-import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
 
 public class MyOtherPackageInterfaceStubDelegate internal constructor(
   public val `delegate`: MyOtherPackageInterface,
   public val context: Context,
 ) : IMyOtherPackageInterface.Stub() {
+  private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
   public override fun doStuff(x: Int): Unit {
-    delegate.doStuff(x)
+    coroutineScope.launch {
+      delegate.doStuff(x)
+    }
   }
 
   public override fun useDataClass(x: ParcelableMyOtherPackageDataClass,
       transactionCallback: IUnitTransactionCallback): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         delegate.useDataClass(MyOtherPackageDataClassConverter(context).fromParcelable(x))
         transactionCallback.onSuccess()
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MyMainPackageInterfaceStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MyMainPackageInterfaceStubDelegate.kt
index d4fcb8f..661bf8c 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MyMainPackageInterfaceStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MyMainPackageInterfaceStubDelegate.kt
@@ -7,19 +7,19 @@
 import com.mysdk.PrivacySandboxThrowableParcelConverter.toThrowableParcel
 import kotlin.IntArray
 import kotlin.Unit
-import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
 
 public class MyMainPackageInterfaceStubDelegate internal constructor(
   public val `delegate`: MyMainPackageInterface,
   public val context: Context,
 ) : IMyMainPackageInterface.Stub() {
+  private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
   public override fun doIntStuff(x: IntArray, transactionCallback: IListIntTransactionCallback):
       Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.doIntStuff(x.toList())
         transactionCallback.onSuccess(result.toIntArray())
@@ -34,8 +34,7 @@
 
   public override fun useDataClass(x: ParcelableMyOtherPackageDataClass,
       transactionCallback: IMyOtherPackageDataClassTransactionCallback): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result =
             delegate.useDataClass(MyOtherPackageDataClassConverter(context).fromParcelable(x))
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MySdkStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MySdkStubDelegate.kt
index 1a2beff..b9c2fb5 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MySdkStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MySdkStubDelegate.kt
@@ -6,22 +6,22 @@
 import com.mysdk.PrivacySandboxThrowableParcelConverter.toThrowableParcel
 import kotlin.Int
 import kotlin.Unit
-import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
 
 public class MySdkStubDelegate internal constructor(
   public val `delegate`: MySdk,
   public val context: Context,
 ) : IMySdk.Stub() {
+  private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
   public override fun doStuff(
     x: Int,
     y: Int,
     transactionCallback: IStringTransactionCallback,
   ): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.doStuff(x, y)
         transactionCallback.onSuccess(result)
@@ -36,8 +36,7 @@
 
   public override
       fun getMyInterface(transactionCallback: IMyMainPackageInterfaceTransactionCallback): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.getMyInterface()
         transactionCallback.onSuccess(MyMainPackageInterfaceStubDelegate(result, context))
@@ -53,8 +52,7 @@
   public override
       fun getMyOtherPackageInterface(transactionCallback: IMyOtherPackageInterfaceTransactionCallback):
       Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.getMyOtherPackageInterface()
         transactionCallback.onSuccess(MyOtherPackageInterfaceStubDelegate(result, context))
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/withoutruntimelibrarysdk/output/com/mysdk/WithoutRuntimeLibrarySdkStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/withoutruntimelibrarysdk/output/com/mysdk/WithoutRuntimeLibrarySdkStubDelegate.kt
index e20ab2c..c46719e 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/withoutruntimelibrarysdk/output/com/mysdk/WithoutRuntimeLibrarySdkStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/withoutruntimelibrarysdk/output/com/mysdk/WithoutRuntimeLibrarySdkStubDelegate.kt
@@ -4,22 +4,22 @@
 import com.mysdk.PrivacySandboxThrowableParcelConverter.toThrowableParcel
 import kotlin.Int
 import kotlin.Unit
-import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
 
 public class WithoutRuntimeLibrarySdkStubDelegate internal constructor(
   public val `delegate`: WithoutRuntimeLibrarySdk,
   public val context: Context,
 ) : IWithoutRuntimeLibrarySdk.Stub() {
+  private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
   public override fun doStuff(
     x: Int,
     y: Int,
     transactionCallback: IStringTransactionCallback,
   ): Unit {
-    @OptIn(DelicateCoroutinesApi::class)
-    val job = GlobalScope.launch(Dispatchers.Main) {
+    val job = coroutineScope.launch {
       try {
         val result = delegate.doStuff(x, y)
         transactionCallback.onSuccess(result)
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkCallbackStubDelegate.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkCallbackStubDelegate.kt
index f4043ef..d103c41 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkCallbackStubDelegate.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkCallbackStubDelegate.kt
@@ -3,23 +3,36 @@
 import com.sdkwithcallbacks.ResponseConverter.fromParcelable
 import kotlin.Int
 import kotlin.Unit
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
 
 public class SdkCallbackStubDelegate internal constructor(
   public val `delegate`: SdkCallback,
 ) : ISdkCallback.Stub() {
+  private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
   public override fun onCompleteInterface(myInterface: IMyInterface): Unit {
-    delegate.onCompleteInterface(MyInterfaceClientProxy(myInterface))
+    coroutineScope.launch {
+      delegate.onCompleteInterface(MyInterfaceClientProxy(myInterface))
+    }
   }
 
   public override fun onEmptyEvent(): Unit {
-    delegate.onEmptyEvent()
+    coroutineScope.launch {
+      delegate.onEmptyEvent()
+    }
   }
 
   public override fun onPrimitivesReceived(x: Int, y: Int): Unit {
-    delegate.onPrimitivesReceived(x, y)
+    coroutineScope.launch {
+      delegate.onPrimitivesReceived(x, y)
+    }
   }
 
   public override fun onValueReceived(response: ParcelableResponse): Unit {
-    delegate.onValueReceived(fromParcelable(response))
+    coroutineScope.launch {
+      delegate.onValueReceived(fromParcelable(response))
+    }
   }
 }
diff --git a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/KotlinPoetSpecs.kt b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/KotlinPoetSpecs.kt
index a15104c..39efaca 100644
--- a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/KotlinPoetSpecs.kt
+++ b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/KotlinPoetSpecs.kt
@@ -145,21 +145,28 @@
 }
 
 object SpecNames {
-    val contextPropertyName = "context"
+    const val contextPropertyName = "context"
 
-    val dispatchersMainClass = ClassName("kotlinx.coroutines", "Dispatchers", "Main")
-    val delicateCoroutinesApiClass = ClassName("kotlinx.coroutines", "DelicateCoroutinesApi")
-    val globalScopeClass = ClassName("kotlinx.coroutines", "GlobalScope")
-    val suspendCancellableCoroutineMethod =
-        MemberName("kotlinx.coroutines", "suspendCancellableCoroutine", isExtension = true)
+    // Kotlin coroutines
     val resumeWithExceptionMethod =
         MemberName("kotlin.coroutines", "resumeWithException", isExtension = true)
-    val launchMethod = MemberName("kotlinx.coroutines", "launch", isExtension = true)
 
+    // KotlinX coroutines
+    val coroutineScopeClass = ClassName("kotlinx.coroutines", "CoroutineScope")
+    val dispatchersMainClass = ClassName("kotlinx.coroutines", "Dispatchers", "Main")
+    val launchMethod = MemberName("kotlinx.coroutines", "launch", isExtension = true)
+    val suspendCancellableCoroutineMethod =
+        MemberName("kotlinx.coroutines", "suspendCancellableCoroutine", isExtension = true)
+
+    // Java
     val stackTraceElementClass = ClassName("java.lang", "StackTraceElement")
+
+    // Android
     val iBinderClass = ClassName("android.os", "IBinder")
     val bundleClass = ClassName("android.os", "Bundle")
     val contextClass = ClassName("android.content", "Context")
     val viewClass = ClassName("android.view", "View")
+
+    // Privacy Sandbox UI
     val toCoreLibInfoMethod = MemberName("androidx.privacysandbox.ui.provider", "toCoreLibInfo")
 }
\ No newline at end of file
diff --git a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/StubDelegatesGenerator.kt b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/StubDelegatesGenerator.kt
index fc18f64..85f2dfa 100644
--- a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/StubDelegatesGenerator.kt
+++ b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/StubDelegatesGenerator.kt
@@ -19,7 +19,9 @@
 import androidx.privacysandbox.tools.core.generator.GenerationTarget.SERVER
 import androidx.privacysandbox.tools.core.generator.SpecNames.contextClass
 import androidx.privacysandbox.tools.core.generator.SpecNames.contextPropertyName
-import androidx.privacysandbox.tools.core.generator.SpecNames.delicateCoroutinesApiClass
+import androidx.privacysandbox.tools.core.generator.SpecNames.coroutineScopeClass
+import androidx.privacysandbox.tools.core.generator.SpecNames.dispatchersMainClass
+import androidx.privacysandbox.tools.core.generator.SpecNames.launchMethod
 import androidx.privacysandbox.tools.core.model.AnnotatedInterface
 import androidx.privacysandbox.tools.core.model.Method
 import androidx.privacysandbox.tools.core.model.Types
@@ -42,6 +44,8 @@
             ClassName(packageName, TransportCancellationGenerator.className)
     }
 
+    private val coroutineScopePropertyName = "coroutineScope"
+
     /**
      * Generates a StubDelegate for this interface.
      *
@@ -77,6 +81,12 @@
                 KModifier.INTERNAL,
             )
 
+            val coroutineProperty =
+                PropertySpec.builder(coroutineScopePropertyName, coroutineScopeClass)
+                    .addModifiers(KModifier.PRIVATE)
+                    .initializer(CodeBlock.of("%T(%T)", coroutineScopeClass, dispatchersMainClass))
+                    .build()
+            addProperty(coroutineProperty)
             addFunctions(annotatedInterface.methods.map(::toFunSpec))
         }
 
@@ -95,12 +105,8 @@
             addModifiers(KModifier.OVERRIDE)
             addParameters(getParameters(method))
             addCode {
-                addStatement("@OptIn(%T::class)", delicateCoroutinesApiClass)
                 addControlFlow(
-                    "val job = %T.%M(%T)",
-                    SpecNames.globalScopeClass,
-                    SpecNames.launchMethod,
-                    SpecNames.dispatchersMainClass
+                    "val job = %L.%M", coroutineScopePropertyName, launchMethod
                 ) {
                     addControlFlow("try") {
                         addStatement {
@@ -141,7 +147,11 @@
     private fun toNonSuspendFunSpec(method: Method) = FunSpec.builder(method.name).build {
         addModifiers(KModifier.OVERRIDE)
         addParameters(getParameters(method))
-        addStatement { add(getDelegateCallBlock(method)) }
+        addCode(CodeBlock.builder().build {
+            addControlFlow("%L.%M", coroutineScopePropertyName, launchMethod) {
+                addStatement { add(getDelegateCallBlock(method)) }
+            }
+        })
     }
 
     private fun getParameters(method: Method) = buildList {
diff --git a/profileinstaller/integration-tests/profile-verification/build.gradle b/profileinstaller/integration-tests/profile-verification/build.gradle
index aa13d76..adb81bb 100644
--- a/profileinstaller/integration-tests/profile-verification/build.gradle
+++ b/profileinstaller/integration-tests/profile-verification/build.gradle
@@ -1,3 +1,9 @@
+import com.google.common.io.Files
+import org.apache.commons.compress.utils.IOUtils
+
+import java.util.zip.ZipEntry
+import java.util.zip.ZipFile
+
 /*
  * Copyright (C) 2022 The Android Open Source Project
  *
@@ -20,23 +26,58 @@
 }
 
 // This task copies the apks provided by the `apkAssets` configuration and places them in the
-// assets folder. This allows a build time generation of the sample apps.
-def copyApkTaskProvider = tasks.register("copyApkAssets", Copy) {
-    description = "Copies the asset apks provided by profile-verification-sample projects"
-    dependsOn(configurations.getByName("apkAssets"))
-    from(configurations.getByName("apkAssets").incoming.artifactView {}.files)
-    into(layout.buildDirectory.dir("intermediates/apkAssets"))
+// assets folder. It also extracts the profiles to make them available to the test app.
+// This allows a build time generation of the sample apps.
+abstract class PrepareAssetsTask extends DefaultTask {
 
-    // Note that the artifact directory included contain multiple output-metadata.json files built
-    // with the apks. Since we're not interested in those we can simply exclude duplicates.
-    duplicatesStrategy(DuplicatesStrategy.EXCLUDE)
+    @InputFiles
+    @PathSensitive(PathSensitivity.NONE)
+    abstract ConfigurableFileCollection getApkAssetsFolders()
+
+    @OutputDirectory
+    abstract DirectoryProperty getOutputDir()
+
+    @TaskAction
+    void exec() {
+        for (File folder : apkAssetsFolders.files) {
+            for (File file : folder.listFiles()) {
+
+                // Consider only apk files (skip json metadata)
+                if (!file.name.endsWith(".apk")) {
+                    continue
+                }
+
+                // Copies the apk in the output dir
+                Files.copy(file, outputDir.file(file.name).get().asFile)
+
+                // Extract the profile in the apk and places it in the assets
+                ZipFile zipFile = new ZipFile(file)
+                extractZipEntry(zipFile, "assets/dexopt/baseline.prof", "${file.name}_baseline.prof")
+                extractZipEntry(zipFile, "assets/dexopt/baseline.profm", "${file.name}_baseline.profm")
+            }
+        }
+    }
+
+    private void extractZipEntry(ZipFile zipFile, String zipEntryName, String outputFileName) {
+        ZipEntry entry = zipFile.entries().find { it.name == zipEntryName }
+        File outputFile = outputDir.file(outputFileName).get().asFile
+        try (FileOutputStream os = new FileOutputStream(outputFile)) {
+            IOUtils.copy(zipFile.getInputStream(entry), os)
+        }
+    }
+}
+
+def prepareAssetsTaskProvider = tasks.register("prepareAssets", PrepareAssetsTask) {
+    description = "Copies the apks and profiles provided by profile-verification-sample projects into the assets."
+    apkAssetsFolders.from(configurations.getByName("apkAssets").incoming.artifactView {}.files)
+    outputDir.set(layout.buildDirectory.dir("intermediates/profile-verification-assets"))
 }
 
 android {
     defaultConfig {
         minSdkVersion 23
     }
-    sourceSets.androidTest.assets.srcDir(copyApkTaskProvider)
+    sourceSets.androidTest.assets.srcDir(prepareAssetsTaskProvider.map { it.outputDir })
     namespace "androidx.profileinstaller.integration.profileverification"
 }
 
@@ -71,5 +112,5 @@
 
 // It makes sure that the apks are generated before the assets are packed.
 afterEvaluate {
-    tasks.named("generateDebugAndroidTestAssets").configure { it.dependsOn(copyApkTaskProvider) }
+    tasks.named("generateDebugAndroidTestAssets").configure { it.dependsOn(prepareAssetsTaskProvider) }
 }
diff --git a/profileinstaller/integration-tests/profile-verification/src/androidTest/assets/baseline.prof b/profileinstaller/integration-tests/profile-verification/src/androidTest/assets/baseline.prof
deleted file mode 100644
index dafbbbb..0000000
--- a/profileinstaller/integration-tests/profile-verification/src/androidTest/assets/baseline.prof
+++ /dev/null
Binary files differ
diff --git a/profileinstaller/integration-tests/profile-verification/src/androidTest/assets/baseline.profm b/profileinstaller/integration-tests/profile-verification/src/androidTest/assets/baseline.profm
deleted file mode 100644
index d72fd91..0000000
--- a/profileinstaller/integration-tests/profile-verification/src/androidTest/assets/baseline.profm
+++ /dev/null
Binary files differ
diff --git a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationOnGeneratedProfiles.kt b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationOnGeneratedProfiles.kt
index 0516ad7..fcef429 100644
--- a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationOnGeneratedProfiles.kt
+++ b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationOnGeneratedProfiles.kt
@@ -54,9 +54,6 @@
 
     @Before
     fun setUp() {
-        // TODO: to re-enable for api 34 (b/276970167)
-        Assume.assumeTrue(!isApi34)
-
         // Note that this test fails on emulator api 30 (b/251540646)
         Assume.assumeTrue(!isApi30)
         withPackageName(packageName) { uninstall() }
@@ -68,8 +65,7 @@
     }
 
     @Test
-    fun generatedBaselineProfile() =
-        withPackageName(packageName) {
+    fun profileInstallerInstallation() = withPackageName(packageName) {
 
             // Installs the apk
             install(apkName = apk, withProfile = false)
@@ -94,4 +90,17 @@
                 hasCurrentProfile(false)
             }
         }
+
+    @Test
+    fun packageManagerInstallation() = withPackageName(packageName) {
+
+        // Install with reference profile.
+        install(apkName = apk, withProfile = true)
+        start(ACTIVITY_NAME)
+        evaluateUI {
+            hasReferenceProfile(true)
+            hasCurrentProfile(true)
+            profileInstalled(RESULT_CODE_COMPILED_WITH_PROFILE)
+        }
+    }
 }
diff --git a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationOnUnsupportedApiVersions.kt b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationOnUnsupportedApiVersions.kt
index 34cc956..6e3fae7 100644
--- a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationOnUnsupportedApiVersions.kt
+++ b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationOnUnsupportedApiVersions.kt
@@ -29,9 +29,6 @@
 
     @Before
     fun setUp() {
-        // TODO: to re-enable for api 34 (b/276970167)
-        Assume.assumeTrue(!isApi34)
-
         // This test runs only on selected api version currently unsupported by profile verifier
         Assume.assumeTrue(
             Build.VERSION.SDK_INT < Build.VERSION_CODES.P ||
diff --git a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationTestWithProfileInstallerInitializer.kt b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationTestWithProfileInstallerInitializer.kt
index fe47284..6cbc48f 100644
--- a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationTestWithProfileInstallerInitializer.kt
+++ b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationTestWithProfileInstallerInitializer.kt
@@ -17,6 +17,7 @@
 package androidx.profileinstaller.integration.profileverification
 
 import androidx.profileinstaller.ProfileVerifier.CompilationStatus.RESULT_CODE_COMPILED_WITH_PROFILE
+import androidx.profileinstaller.ProfileVerifier.CompilationStatus.RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING
 import androidx.profileinstaller.ProfileVerifier.CompilationStatus.RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION
 import androidx.profileinstaller.ProfileVersion
 import androidx.test.filters.LargeTest
@@ -47,9 +48,6 @@
 
     @Before
     fun setUp() = withPackageName(PACKAGE_NAME_WITH_INITIALIZER) {
-        // TODO: to re-enable for api 34 (b/276970167)
-        assumeTrue(!isApi34)
-
         // Note that this test fails on emulator api 30 (b/251540646)
         assumeTrue(!isApi30)
         uninstall()
@@ -171,7 +169,14 @@
             install(apkName = APK_WITH_INITIALIZER_V3, withProfile = true)
             start(ACTIVITY_NAME)
             evaluateUI {
-                profileInstalled(RESULT_CODE_COMPILED_WITH_PROFILE)
+
+                // Taimen Api 28 and Cuttlefish Api 29 behave differently.
+                if ((isApi29 && isCuttlefish) || (isApi28 && !isCuttlefish)) {
+                    profileInstalled(RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING)
+                } else {
+                    profileInstalled(RESULT_CODE_COMPILED_WITH_PROFILE)
+                }
+
                 hasReferenceProfile(true)
                 hasCurrentProfile(true)
             }
@@ -226,7 +231,13 @@
             install(apkName = APK_WITH_INITIALIZER_V3, withProfile = true)
             start(ACTIVITY_NAME)
             evaluateUI {
-                profileInstalled(RESULT_CODE_COMPILED_WITH_PROFILE)
+
+                // Taimen Api 28 and Cuttlefish Api 29 behave differently.
+                if ((isApi29 && isCuttlefish) || (isApi28 && !isCuttlefish)) {
+                    profileInstalled(RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING)
+                } else {
+                    profileInstalled(RESULT_CODE_COMPILED_WITH_PROFILE)
+                }
                 hasReferenceProfile(true)
                 hasCurrentProfile(true)
             }
diff --git a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationTestWithoutProfileInstallerInitializer.kt b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationTestWithoutProfileInstallerInitializer.kt
index 63401b6..cca5f12 100644
--- a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationTestWithoutProfileInstallerInitializer.kt
+++ b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationTestWithoutProfileInstallerInitializer.kt
@@ -50,9 +50,6 @@
 
     @Before
     fun setUp() = withPackageName(PACKAGE_NAME_WITHOUT_INITIALIZER) {
-        // TODO: to re-enable for api 34 (b/276970167)
-        assumeTrue(!isApi34)
-
         // Note that this test fails on emulator api 30 (b/251540646)
         assumeTrue(!isApi30)
         uninstall()
diff --git a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/TestManager.kt b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/TestManager.kt
index 91647ac..3e27464 100644
--- a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/TestManager.kt
+++ b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/TestManager.kt
@@ -21,7 +21,6 @@
 import android.os.ParcelFileDescriptor
 import android.util.Log
 import androidx.concurrent.futures.DirectExecutor
-import androidx.core.os.BuildCompat
 import androidx.profileinstaller.DeviceProfileWriter
 import androidx.profileinstaller.ProfileInstaller
 import androidx.test.platform.app.InstrumentationRegistry
@@ -74,24 +73,6 @@
 
         try {
 
-            // First writes in a temp file the apk from the assets
-            val tmpApkFile = File(dirUsableByAppAndShell, "tmp_$apkName").also { file ->
-                file.delete()
-                file.createNewFile()
-                file.deleteOnExit()
-                file.outputStream().use { instrumentation.context.assets.open(apkName).copyTo(it) }
-            }
-            cleanUpBlocks.add { tmpApkFile.delete() }
-
-            // Then moves it to a destination that can be used to install it
-            val destApkPath = "$TEMP_DIR/$apkName"
-            assertThat(executeCommand("mv ${tmpApkFile.absolutePath} $destApkPath")).isEmpty()
-            cleanUpBlocks.add { executeCommand("rm $destApkPath") }
-
-            // This mimes the behaviour of `adb install-multiple` using an install session.
-            // For reference:
-            // https://source.corp.google.com/android-internal/packages/modules/adb/client/adb_install.cpp
-
             // Creates an install session
             val installCreateOutput = executeCommand("pm install-create -t").first().trim()
             val sessionId = REGEX_SESSION_ID
@@ -102,9 +83,32 @@
                 .value
                 .toLong()
 
+            // Creates tmp dir for this session
+            val baseTmpFolder = "$TEMP_DIR/$sessionId"
+            assertThat(executeCommand("mkdir -p $baseTmpFolder")).isEmpty()
+            cleanUpBlocks.add { executeCommand("rm -Rf $baseTmpFolder") }
+
+            // First writes in a temp file the apk from the assets
+            val tmpApkFile = File(dirUsableByAppAndShell, "tmp_$apkName").also { file ->
+                file.delete()
+                file.createNewFile()
+                file.deleteOnExit()
+                file.outputStream().use { instrumentation.context.assets.open(apkName).copyTo(it) }
+            }
+            cleanUpBlocks.add { tmpApkFile.delete() }
+
+            // Then moves it to a destination that can be used to install it
+            val destApkPath = "$baseTmpFolder/base.apk"
+            assertThat(executeCommand("mv ${tmpApkFile.absolutePath} $destApkPath")).isEmpty()
+            cleanUpBlocks.add { executeCommand("rm $destApkPath") }
+
+            // This mimes the behaviour of `adb install-multiple` using an install session.
+            // For reference:
+            // https://source.corp.google.com/android-internal/packages/modules/adb/client/adb_install.cpp
+
             // Adds the base apk to the install session
             val successBaseApk =
-                executeCommand("pm install-write $sessionId base.apk $TEMP_DIR/$apkName")
+                executeCommand("pm install-write $sessionId base.apk $destApkPath")
                     .first()
                     .trim()
                     .startsWith("Success")
@@ -129,8 +133,8 @@
                     DirectExecutor.INSTANCE,
                     EMPTY_DIAGNOSTICS,
                     apkName,
-                    BASELINE_PROF,
-                    BASELINE_PROFM,
+                    "${apkName}_$BASELINE_PROF",
+                    "${apkName}_$BASELINE_PROFM",
                     tmpProfileProfFile
                 )
                 if (!deviceProfileWriter.deviceAllowsProfileInstallerAotWrites()) {
@@ -165,7 +169,7 @@
                 cleanUpBlocks.add { tmpDmFile.delete() }
 
                 // Then moves it to a destination that can be used to install it
-                val dmFilePath = "$TEMP_DIR/$DM_FILE_NAME"
+                val dmFilePath = "$baseTmpFolder/$DM_FILE_NAME"
                 executeCommand("mv ${tmpDmFile.absolutePath} $dmFilePath")
                 cleanUpBlocks.add { executeCommand("rm $dmFilePath") }
 
@@ -196,7 +200,7 @@
 
             // Runs all the clean up blocks. This will clean up also partial operations in case
             // there is an issue during install
-            cleanUpBlocks.forEach { it() }
+            cleanUpBlocks.reversed().forEach { it() }
         }
     }
 
@@ -260,7 +264,7 @@
 
     companion object {
         private const val TAG = "TestManager"
-        private const val TEMP_DIR = "/data/local/tmp/"
+        private const val TEMP_DIR = "/data/local/tmp"
         private const val UI_TIMEOUT = 20000L
         private const val BASELINE_PROF = "baseline.prof"
         private const val BASELINE_PROFM = "baseline.profm"
@@ -284,6 +288,10 @@
                 .that(lines[2].toBoolean())
                 .isEqualTo(value)
     }
+
+    val isCuttlefish by lazy {
+        executeCommand("getprop ro.product.product.model").any { "cuttlefish" in it.lowercase() }
+    }
 }
 
 private val EMPTY_DIAGNOSTICS: ProfileInstaller.DiagnosticsCallback =
@@ -301,7 +309,8 @@
 private fun <T> T?.throwIfNull(message: String): T = this ?: throw Exception(message)
 
 val isApi30 by lazy { Build.VERSION.SDK_INT == Build.VERSION_CODES.R }
-val isApi34 by lazy { BuildCompat.isAtLeastU() }
+val isApi28 by lazy { Build.VERSION.SDK_INT == Build.VERSION_CODES.P }
+val isApi29 by lazy { Build.VERSION.SDK_INT == Build.VERSION_CODES.Q }
 
 const val PACKAGE_NAME_WITH_INITIALIZER =
     "androidx.profileinstaller.integration.profileverification.target"
diff --git a/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/DeviceProfileWriter.java b/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/DeviceProfileWriter.java
index 4fbbfbb..2669001 100644
--- a/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/DeviceProfileWriter.java
+++ b/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/DeviceProfileWriter.java
@@ -130,7 +130,10 @@
             }
         } else {
             try {
-                mCurProfile.createNewFile();
+                if (!mCurProfile.createNewFile()) {
+                    result(ProfileInstaller.RESULT_NOT_WRITABLE, null);
+                    return false;
+                }
             } catch (IOException e) {
                 // If the file cannot be created it's the same of the profile file not being
                 // writeable
@@ -139,7 +142,6 @@
             }
         }
 
-
         mDeviceSupportsAotProfile = true;
         return true;
     }
diff --git a/room/room-common/api/api_lint.ignore b/room/room-common/api/api_lint.ignore
index a783aef..065bd1a 100644
--- a/room/room-common/api/api_lint.ignore
+++ b/room/room-common/api/api_lint.ignore
@@ -3,6 +3,20 @@
     Acronyms should not be capitalized in class names: was `SQLiteTypeAffinity`, should this be `SqLiteTypeAffinity`?
 
 
+GetterSetterNames: field ColumnInfo.index:
+    Invalid name for boolean property `index`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Database.exportSchema:
+    Invalid name for boolean property `exportSchema`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Entity.inheritSuperIndices:
+    Invalid name for boolean property `inheritSuperIndices`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ForeignKey.deferred:
+    Invalid name for boolean property `deferred`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Index.unique:
+    Invalid name for boolean property `unique`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PrimaryKey.autoGenerate:
+    Invalid name for boolean property `autoGenerate`. Should start with one of `has`, `can`, `should`, `is`.
+
+
 PublicTypedef: androidx.room.ColumnInfo.Collate:
     Don't expose @IntDef: Collate must be hidden.
 PublicTypedef: androidx.room.ColumnInfo.SQLiteTypeAffinity:
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/DefaultKspType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/DefaultKspType.kt
index c6f3ec1..77606d3 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/DefaultKspType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/DefaultKspType.kt
@@ -25,8 +25,8 @@
 internal class DefaultKspType(
     env: KspProcessingEnv,
     ksType: KSType,
-    jvmTypeResolver: KspJvmTypeResolver?
-) : KspType(env, ksType, jvmTypeResolver) {
+    scope: KSTypeVarianceResolverScope?
+) : KspType(env, ksType, scope) {
 
     override fun resolveJTypeName(): JTypeName {
         // always box these. For primitives, typeName might return the primitive type but if we
@@ -46,15 +46,15 @@
         return DefaultKspType(
             env = env,
             ksType = ksType.withNullability(nullability),
-            jvmTypeResolver = jvmTypeResolver
+            scope = scope
         )
     }
 
-    override fun copyWithJvmTypeResolver(jvmTypeResolver: KspJvmTypeResolver): KspType {
+    override fun copyWithScope(scope: KSTypeVarianceResolverScope): KspType {
         return DefaultKspType(
             env = env,
             ksType = ksType,
-            jvmTypeResolver = jvmTypeResolver
+            scope = scope
         )
     }
 }
\ No newline at end of file
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
index aa157d0..470c9af 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
@@ -18,6 +18,7 @@
 
 import androidx.room.compiler.processing.XNullability
 import com.google.devtools.ksp.symbol.KSAnnotated
+import com.google.devtools.ksp.symbol.KSAnnotation
 import com.google.devtools.ksp.symbol.KSDeclaration
 import com.google.devtools.ksp.symbol.KSNode
 import com.google.devtools.ksp.symbol.KSType
@@ -57,19 +58,30 @@
     else -> throw IllegalArgumentException("Cannot set KSType nullability to platform")
 }
 
-private fun KSAnnotated.hasAnnotation(
-     qName: String
- ) = annotations.any {
-     it.annotationType.resolve().declaration.qualifiedName?.asString() == qName
- }
+private fun KSAnnotated.hasAnnotation(qName: String) =
+    annotations.any { it.hasQualifiedName(qName) }
 
- internal fun KSAnnotated.hasJvmWildcardAnnotation() = hasAnnotation(
-     JvmWildcard::class.java.canonicalName!!
- )
+private fun KSAnnotation.hasQualifiedName(qName: String): Boolean {
+    return annotationType.resolve().hasQualifiedName(qName)
+}
 
- internal fun KSAnnotated.hasSuppressJvmWildcardAnnotation() = hasAnnotation(
-     JvmSuppressWildcards::class.java.canonicalName!!
- )
+private fun KSType.hasQualifiedName(qName: String): Boolean {
+    return declaration.qualifiedName?.asString() == qName
+}
+
+internal fun KSAnnotated.hasJvmWildcardAnnotation() =
+    hasAnnotation(JvmWildcard::class.java.canonicalName!!)
+
+internal fun KSAnnotated.hasSuppressJvmWildcardAnnotation() =
+    hasAnnotation(JvmSuppressWildcards::class.java.canonicalName!!)
+
+private fun KSType.hasAnnotation(qName: String) = annotations.any { it.hasQualifiedName(qName) }
+
+internal fun KSType.hasJvmWildcardAnnotation() =
+    hasAnnotation(JvmWildcard::class.java.canonicalName!!)
+
+internal fun KSType.hasSuppressJvmWildcardAnnotation() =
+    hasAnnotation(JvmSuppressWildcards::class.java.canonicalName!!)
 
  internal fun KSNode.hasSuppressWildcardsAnnotationInHierarchy(): Boolean {
      (this as? KSAnnotated)?.let {
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 fa385e6..abada70 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
@@ -16,12 +16,13 @@
 
 package androidx.room.compiler.processing.ksp
 
-import androidx.room.compiler.processing.ksp.KspArrayType.Companion.KOTLIN_ARRAY_Q_NAME
+import com.google.devtools.ksp.KspExperimental
 import com.google.devtools.ksp.isOpen
 import com.google.devtools.ksp.processing.Resolver
 import com.google.devtools.ksp.symbol.ClassKind
 import com.google.devtools.ksp.symbol.KSClassDeclaration
 import com.google.devtools.ksp.symbol.KSType
+import com.google.devtools.ksp.symbol.KSTypeAlias
 import com.google.devtools.ksp.symbol.KSTypeArgument
 import com.google.devtools.ksp.symbol.KSTypeParameter
 import com.google.devtools.ksp.symbol.Modifier
@@ -43,166 +44,323 @@
  * Until then, the logic here is mostly reverse engineered from KAPT source code +
  * KspTypeNamesGoldenTest ¯\_(ツ)_/¯
  */
-internal class KSTypeVarianceResolver(
-    private val resolver: Resolver
-) {
+internal class KSTypeVarianceResolver(private val resolver: Resolver) {
     /**
-     * @param ksType The Kotlin type on which the variance will be applied
-     * @param wildcardMode `wildcardMode` defines the default behavior of whether to inherit
-     *        variance or not. This depends on the existence of `SuppressWildcard` annotations or
-     *        the type's location (e.g. whether it is a method parameter or return type)
-     * @param declarationType If a type is resolved via inheritance where it is not explicitly
-     *        declared in its container, this value should have its original type from the
-     *        declaration site. e.g. if you have `val BaseClass.x : T`, and the ksType is the
-     *        type of `x` from `SubClass: BaseClass<String>`, `declarationType` would be `T` whereas
-     *        the `ksType` is `String`. If the `ksType` is from the original declaration, this value
-     *        should be `null`.
+     * @param type The Kotlin type declared by the user on which the variance will be applied.
+     * @param scope The [KSTypeVarianceResolverScope] associated with the given type.
      */
-    fun applyTypeVariance(
-        ksType: KSType,
-        wildcardMode: WildcardMode,
-        declarationType: KSType?
-    ): KSType = ksType.inheritVariance(declarationType, wildcardMode, ReferenceStack())
+    @OptIn(KspExperimental::class)
+    fun applyTypeVariance(type: KSType, scope: KSTypeVarianceResolverScope): KSType {
+        if (type.isError ||
+            type.arguments.isEmpty() ||
+            resolver.isJavaRawType(type) ||
+            !scope.needsWildcardResolution) {
+            // There's nothing to resolve in this case, so just return the original type.
+            return type
+        }
 
-    /**
-     * Update the variance of the arguments of this type based on the types declaration.
-     *
-     * For instance, in List<Foo>, it actually inherits the `out` variance from `List`.
-     */
-    private fun KSType.inheritVariance(
-        declarationType: KSType?,
-        wildcardMode: WildcardMode,
-        referenceStack: ReferenceStack
+        val resolvedType = if (hasTypeVariables(scope.declarationType())) {
+            // If the associated declared type contains type variables that were resolved, e.g.
+            // using "asMemberOf", then it has special rules about how to resolve the types.
+            getJavaWildcardWithTypeVariables(
+                type = type,
+                declarationType = getJavaWildcard(scope.declarationType(), scope),
+                scope = scope,
+            )
+        } else {
+            getJavaWildcard(type, scope)
+        }
+
+        // As a final pass, we apply variance from any @JvmSuppressWildcards or @JvmWildcard
+        // annotations on the resolved type.
+        return applyJvmWildcardAnnotations(resolvedType)
+    }
+
+    private fun hasTypeVariables(
+        type: KSType?,
+        stack: ReferenceStack = ReferenceStack()
+    ): Boolean {
+        if (type == null || type.isError || stack.queue.contains(type)) {
+            return false
+        }
+        return stack.withReference(type) {
+            type.isTypeParameter() ||
+                type.arguments.any { hasTypeVariables(it.type?.resolve(), stack) }
+        }
+    }
+
+    private fun getJavaWildcard(
+        type: KSType,
+        scope: KSTypeVarianceResolverScope,
+        typeStack: ReferenceStack = ReferenceStack(),
+        typeArgStack: List<KSTypeArgument> = emptyList(),
+        typeParamStack: List<KSTypeParameter> = emptyList(),
     ): KSType {
-        if (arguments.isEmpty()) return this
-        return referenceStack.withReference(this) {
-            // arrays don't inherit variance unless it is in an inherited method
-            if (this.declaration.qualifiedName?.asString() == KOTLIN_ARRAY_Q_NAME &&
-                declarationType == null
-            ) {
-                return@withReference this
-            }
-
-            // if we have type arguments but the declarationType doesn't, we should consider it like
-            // star projection.
-            // This happens when a given List<X> overrides T. In this case, we need to force X's
-            // wildcards
-            val starProject = declarationType != null && declarationType.arguments.isEmpty()
-
-            // need to swap arguments with the variance from declaration
-            val newArguments = arguments.mapIndexed { index, typeArg ->
-                val param = declaration.typeParameters.getOrNull(index)
-                val declarationArg = declarationType?.arguments?.getOrNull(index)
-                val argWildcardMode = if (starProject) {
-                    WildcardMode.FORCED
-                } else {
-                    wildcardMode
+        if (type.isError || typeStack.queue.contains(type)) {
+            return type
+        }
+        if (type.declaration is KSTypeAlias) {
+            return getJavaWildcard(
+                type = (type.declaration as KSTypeAlias).type.resolve(),
+                scope = scope,
+                typeStack = typeStack,
+                typeArgStack = typeArgStack,
+                typeParamStack = typeParamStack,
+            )
+        }
+        return typeStack.withReference(type) {
+            val resolvedTypeArgs =
+                type.arguments.indices.map { i ->
+                    getJavaWildcard(
+                        typeArg = type.arguments[i],
+                        typeParam = type.declaration.typeParameters[i],
+                        scope = scope,
+                        typeStack = typeStack,
+                        typeArgStack = typeArgStack,
+                        typeParamStack = typeParamStack,
+                    )
                 }
-                typeArg.inheritVariance(declarationArg, argWildcardMode, param, referenceStack)
-            }
-            this.replace(newArguments)
+            type.replace(resolvedTypeArgs)
         }
     }
 
-    private fun KSTypeArgument.inheritVariance(
-        declarationType: KSTypeArgument?,
-        wildcardMode: WildcardMode,
-        param: KSTypeParameter?,
-        referenceStack: ReferenceStack
+    private fun getJavaWildcard(
+        typeArg: KSTypeArgument,
+        typeParam: KSTypeParameter,
+        scope: KSTypeVarianceResolverScope,
+        typeStack: ReferenceStack,
+        typeArgStack: List<KSTypeArgument>,
+        typeParamStack: List<KSTypeParameter>,
     ): KSTypeArgument {
-        if (param == null) {
-            return this
+        val type = typeArg.type?.resolve()
+        if (
+            type == null ||
+            type.isError ||
+            typeArg.variance == Variance.STAR ||
+            typeStack.queue.contains(type)
+        ) {
+            return typeArg
         }
-        val myTypeRef = type ?: return this
-
-        val myType = myTypeRef.resolve()
-
-        if (referenceStack.contains(myType)) {
-            // self referencing type
-            return this
-        }
-        if (variance != Variance.INVARIANT) {
-            return resolver.getTypeArgument(
-                typeRef = myType.inheritVariance(
-                    declarationType?.type?.resolve(),
-                    wildcardMode,
-                    referenceStack
-                ).createTypeReference(),
-                variance = variance
-            )
-        }
-
-        // Now we need to guess from this type. If the type is final, it does not inherit unless
-        // the parameter is CONTRAVARIANT (`in`).
-        val shouldInherit = when {
-            hasJvmWildcardAnnotation() -> {
-                // we actually don't need to check for wildcard annotation here as the TypeName
-                // conversion will do it for the general case. Nevertheless, we check for it for
-                // consistency
-                true
+        val resolvedType = getJavaWildcard(
+            type = type,
+            scope = scope,
+            typeStack = typeStack,
+            typeArgStack = typeArgStack + typeArg,
+            typeParamStack = typeParamStack + typeParam
+        )
+        fun inheritDeclarationSiteVariance(): Boolean {
+            // Before we check the current variance, we need to check the previous variance in the
+            // stack to see if they allow us to inherit the current variance, and that logic differs
+            // depending on the scope.
+            if (scope.isValOrReturnType()) {
+                // For val and return type scopes, we don't use the declaration-site variance if
+                // none of variances in the stack are contravariant.
+                if (typeParamStack.indices.none { i ->
+                        (typeParamStack[i].variance == Variance.CONTRAVARIANT ||
+                            typeArgStack[i].variance == Variance.CONTRAVARIANT) &&
+                        // The declaration and use site variance is ignored when using @JvmWildcard
+                        // explicitly on a type.
+                        !typeArgStack[i].hasJvmWildcardAnnotation()
+                }) {
+                    return false
+                }
+            } else {
+                // For method parameters and var type scopes, we don't use the declaration-site
+                // variance if the last variance in the declaration-site stack was invariant and
+                // the last variance in the use-site stack was not contravariant.
+                if (typeParamStack.lastOrNull()?.variance == Variance.INVARIANT &&
+                    typeArgStack.lastOrNull()?.variance != Variance.CONTRAVARIANT) {
+                    return false
+                }
             }
-            wildcardMode == WildcardMode.SUPPRESSED -> false
-            wildcardMode == WildcardMode.FORCED -> true
-            hasSuppressWildcardsAnnotationInHierarchy() -> false
-            else -> {
-                if (declarationType != null) {
-                    // if there is a declaration type, that means we are being resolved for an
-                    // inherited method/property; hence we should use the variance in the
-                    // declaration
-                    true
-                } else {
-                    param.variance == Variance.CONTRAVARIANT ||
-                        when (val decl = myType.declaration) {
-                            is KSClassDeclaration -> {
-                                decl.isOpen() || decl.classKind == ClassKind.ENUM_CLASS ||
-                                    decl.modifiers.contains(Modifier.SEALED)
-                            }
-                            else -> true
+            return when (typeParam.variance) {
+                // If the current declaration-site variance is invariant then don't inherit it.
+                Variance.INVARIANT -> false
+                // If the current declaration-site variance is contravariant then inherit it.
+                Variance.CONTRAVARIANT -> true
+                // If the current declaration-site variance is covariant then inherit it unless
+                // it's a final class (excluding enum/sealed classes).
+                Variance.COVARIANT -> when (val declaration = type.declaration) {
+                    is KSClassDeclaration -> declaration.isOpen() ||
+                        declaration.classKind == ClassKind.ENUM_CLASS ||
+                        declaration.modifiers.contains(Modifier.SEALED) ||
+                        // For non-open/enum/sealed classes we may still decided to use the
+                        // declaration-site variance based on if any of the type arguments in the
+                        // resolved type has variance and the use-site variance is not equal to
+                        // covariant/contravariant.
+                        resolvedType.arguments.indices.any { i ->
+                            resolvedType.arguments[i].variance != Variance.INVARIANT &&
+                                type.arguments[i].variance != Variance.COVARIANT &&
+                                type.arguments[i].variance != Variance.CONTRAVARIANT
                         }
+                    else -> true
+                }
+                Variance.STAR -> error {
+                    "Declaration site variance was not expected to contain STAR: $typeParam."
                 }
             }
         }
-        val newVariance = if (declarationType?.variance == Variance.STAR) {
-            Variance.COVARIANT
-        } else if (declarationType?.type?.resolve() is KSTypeParameter) {
-            // fallback to the parameter variance if we are swapping a type parameter type
-            param.variance
+        val resolvedVariance = if (inheritDeclarationSiteVariance()) {
+            typeParam.variance
+        } else if (typeParam.variance == typeArg.variance) {
+            // If we're not applying the declaration-site variance, and the use-site variance is the
+            // same as the declaration-site variance then we don't include the use-site variance in
+            // the jvm type either.
+            Variance.INVARIANT
         } else {
-            declarationType?.variance
-        } ?: param.variance
-        return if (shouldInherit) {
-            resolver.getTypeArgument(
-                typeRef = myType.inheritVariance(
-                    declarationType?.type?.resolve(),
-                    wildcardMode,
-                    referenceStack
-                ).createTypeReference(),
-                variance = newVariance
-            )
-        } else {
-            resolver.getTypeArgument(
-                typeRef = myType.inheritVariance(null, wildcardMode, referenceStack)
-                    .createTypeReference(),
-                variance = variance
-            )
+            typeArg.variance
+        }
+        return createTypeArgument(resolvedType, resolvedVariance)
+    }
+
+    private fun getJavaWildcardWithTypeVariables(
+        type: KSType,
+        declarationType: KSType? = null,
+        scope: KSTypeVarianceResolverScope,
+        typeStack: ReferenceStack = ReferenceStack(),
+    ): KSType {
+        if (type.isError || typeStack.queue.contains(type)) {
+            return type
+        }
+        return typeStack.withReference(type) {
+            val resolvedTypeArgs =
+                if (declarationType != null && !declarationType.isTypeParameter()) {
+                    declarationType.arguments.indices.map { i ->
+                        getJavaWildcardWithTypeVariablesForOuterType(
+                            typeArg = type.arguments[i],
+                            declarationTypeArg = declarationType.arguments[i],
+                            scope = scope,
+                            typeStack = typeStack,
+                        )
+                    }
+                } else {
+                    type.arguments.indices.map { i ->
+                        getJavaWildcardWithTypeVariablesForInnerType(
+                            typeArg = type.arguments[i],
+                            declarationTypeParameter = type.declaration.typeParameters[i],
+                            scope = scope,
+                            typeStack = typeStack,
+                        )
+                    }
+                }
+            type.replace(resolvedTypeArgs)
         }
     }
 
-    enum class WildcardMode {
-        /**
-         * Force wildcard inheritance that is commonly used when there is star projection involved
-         */
-        FORCED,
+    private fun getJavaWildcardWithTypeVariablesForInnerType(
+        typeArg: KSTypeArgument,
+        declarationTypeParameter: KSTypeParameter,
+        scope: KSTypeVarianceResolverScope,
+        typeStack: ReferenceStack,
+    ): KSTypeArgument {
+        val type = typeArg.type?.resolve()
+        if (
+            type == null ||
+            type.isError ||
+            typeArg.variance == Variance.STAR ||
+            typeStack.queue.contains(type)
+        ) {
+            return typeArg
+        }
+        val resolvedType = getJavaWildcardWithTypeVariables(
+            type = type,
+            scope = scope,
+            typeStack = typeStack,
+        )
+        val resolvedVariance = if (declarationTypeParameter.variance != Variance.INVARIANT) {
+            declarationTypeParameter.variance
+        } else {
+            typeArg.variance
+        }
+        return createTypeArgument(resolvedType, resolvedVariance)
+    }
 
-        /**
-         * Apply wildcard inheritance when necessary.
-         */
-        PREFERRED,
+    private fun getJavaWildcardWithTypeVariablesForOuterType(
+        typeArg: KSTypeArgument,
+        declarationTypeArg: KSTypeArgument,
+        scope: KSTypeVarianceResolverScope,
+        typeStack: ReferenceStack,
+    ): KSTypeArgument {
+        val type = typeArg.type?.resolve()
+        if (
+            type == null ||
+            type.isError ||
+            typeArg.variance == Variance.STAR ||
+            typeStack.queue.contains(type)
+        ) {
+            return typeArg
+        }
+        val resolvedType = getJavaWildcardWithTypeVariables(
+            type = type,
+            declarationType = declarationTypeArg.type?.resolve(),
+            scope = scope,
+            typeStack = typeStack
+        )
+        val resolvedVariance = if (declarationTypeArg.variance != Variance.INVARIANT &&
+            (!scope.isValOrReturnType() || declarationTypeArg.variance != Variance.COVARIANT)) {
+            declarationTypeArg.variance
+        } else {
+            typeArg.variance
+        }
+        return createTypeArgument(resolvedType, resolvedVariance)
+    }
 
-        /**
-         * Apply wildcard inheritance only if it is explicitly stated with JvmWildcards annotation.
-         */
-        SUPPRESSED
+    private fun applyJvmWildcardAnnotations(
+        type: KSType,
+        typeStack: ReferenceStack = ReferenceStack(),
+    ): KSType {
+        if (type.isError || typeStack.queue.contains(type)) {
+            return type
+        }
+        return typeStack.withReference(type) {
+            val resolvedTypeArgs =
+                type.arguments.indices.map { i ->
+                    applyJvmWildcardAnnotations(
+                        typeArg = type.arguments[i],
+                        typeParameter = type.declaration.typeParameters[i],
+                        typeStack = typeStack,
+                    )
+                }
+            type.replace(resolvedTypeArgs)
+        }
+    }
+
+    private fun applyJvmWildcardAnnotations(
+        typeArg: KSTypeArgument,
+        typeParameter: KSTypeParameter,
+        typeStack: ReferenceStack,
+    ): KSTypeArgument {
+        val type = typeArg.type?.resolve()
+        if (
+            type == null ||
+            type.isError ||
+            typeArg.variance == Variance.STAR ||
+            typeStack.queue.contains(type)
+        ) {
+            return typeArg
+        }
+        val resolvedType = applyJvmWildcardAnnotations(
+            type = type,
+            typeStack = typeStack,
+        )
+        val resolvedVariance = when {
+            typeParameter.variance == Variance.INVARIANT &&
+                typeArg.variance != Variance.INVARIANT -> typeArg.variance
+            typeArg.hasJvmWildcardAnnotation() -> typeParameter.variance
+                typeStack.queue.any { it.hasSuppressJvmWildcardAnnotation() } ||
+                typeArg.hasSuppressWildcardsAnnotationInHierarchy() ||
+                typeParameter.hasSuppressWildcardsAnnotationInHierarchy() -> Variance.INVARIANT
+            else -> typeArg.variance
+        }
+        return createTypeArgument(resolvedType, resolvedVariance)
+    }
+
+    private fun KSType.isTypeParameter(): Boolean {
+        return createTypeReference().isTypeParameterReference()
+    }
+
+    private fun createTypeArgument(type: KSType, variance: Variance): KSTypeArgument {
+        return resolver.getTypeArgument(type.createTypeReference(), variance)
     }
 }
 
@@ -212,20 +370,17 @@
  * if a type argument resolves to it, it will stop recursion.
  */
 private class ReferenceStack {
-    @Suppress("PropertyName")
-    val _queue = ArrayDeque<KSType>()
-
-    fun contains(ksType: KSType) = _queue.contains(ksType)
+    val queue = ArrayDeque<KSType>()
 
     inline fun <T> withReference(
         ksType: KSType,
         crossinline block: () -> T
     ): T {
         return try {
-            _queue.addLast(ksType)
+            queue.addLast(ksType)
             block()
         } finally {
-            _queue.removeLast()
+            queue.removeLast()
         }
     }
-}
\ No newline at end of file
+}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverScope.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverScope.kt
new file mode 100644
index 0000000..9b4c646
--- /dev/null
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverScope.kt
@@ -0,0 +1,120 @@
+/*
+ * 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.room.compiler.processing.ksp
+
+import androidx.room.compiler.processing.ksp.synthetic.KspSyntheticPropertyMethodElement
+import com.google.devtools.ksp.symbol.KSAnnotated
+import com.google.devtools.ksp.symbol.KSDeclaration
+import com.google.devtools.ksp.symbol.KSNode
+import com.google.devtools.ksp.symbol.KSType
+import com.google.devtools.ksp.symbol.Origin
+
+/**
+ * Provides KSType resolution scope for a type.
+ */
+internal sealed class KSTypeVarianceResolverScope(
+    private val annotated: KSAnnotated,
+    private val container: KSDeclaration?
+) {
+    /**
+     * Checks whether we need wildcard resolution at all. It is only necessary if either the method
+     * parameter is in kotlin or the containing class, which inherited the method, is in kotlin.
+     */
+    val needsWildcardResolution: Boolean by lazy {
+        (annotated.isInKotlinCode() || container?.isInKotlinCode() == true) &&
+            !annotated.hasSuppressWildcardsAnnotationInHierarchy()
+    }
+
+    private fun KSAnnotated.isInKotlinCode(): Boolean {
+        // find the true origin by skipping synthetics.
+        var current: KSNode? = this
+        while (current != null) {
+            val origin = current.origin
+            if (origin != Origin.SYNTHETIC) {
+                return origin == Origin.KOTLIN || origin == Origin.KOTLIN_LIB
+            }
+            current = current.parent
+        }
+        return false
+    }
+
+    /** Finds the [KSType] from the declaration. */
+    abstract fun declarationType(): KSType
+
+    /** Returns `true` if this scope represents a val property or a return type. */
+    abstract fun isValOrReturnType(): Boolean
+
+    internal class MethodParameter(
+        private val kspExecutableElement: KspExecutableElement,
+        private val parameterIndex: Int,
+        annotated: KSAnnotated,
+        container: KSDeclaration?,
+    ) : KSTypeVarianceResolverScope(annotated, container) {
+        override fun declarationType() =
+            (kspExecutableElement.parameters[parameterIndex].type as KspType).ksType
+
+        override fun isValOrReturnType() = false
+    }
+
+    internal class PropertySetterParameterType(
+        private val setterMethod: KspSyntheticPropertyMethodElement.Setter
+    ) : KSTypeVarianceResolverScope(
+        annotated = setterMethod.accessor,
+        container = setterMethod.field.enclosingElement.declaration
+    ) {
+        override fun declarationType(): KSType {
+            // We return the declaration from the setter, not the field because the setter parameter
+            // will have a different type in jvm (due to jvm wildcard resolution)
+            return (setterMethod.field.syntheticSetter!!.parameters.single().type as KspType).ksType
+        }
+
+        override fun isValOrReturnType() = false
+    }
+
+    internal class PropertyGetterMethodReturnType(
+        private val getterMethod: KspSyntheticPropertyMethodElement.Getter
+    ) : KSTypeVarianceResolverScope(
+        annotated = getterMethod.accessor,
+        container = getterMethod.field.enclosingElement.declaration
+    ) {
+        override fun declarationType(): KSType {
+            // We return the declaration from the getter, not the field because the getter return
+            // type will have a different type in jvm (due to jvm wildcard resolution)
+            return (getterMethod.field.syntheticAccessors.first().returnType as KspType).ksType
+        }
+
+        override fun isValOrReturnType() = true
+    }
+
+    internal class PropertyType(val field: KspFieldElement) : KSTypeVarianceResolverScope(
+        annotated = field.declaration,
+        container = field.enclosingElement.declaration
+    ) {
+        override fun declarationType() = field.type.ksType
+
+        override fun isValOrReturnType() = field.isFinal()
+    }
+
+    internal class MethodReturnType(val method: KspMethodElement) : KSTypeVarianceResolverScope(
+        annotated = method.declaration,
+        container = method.enclosingElement.declaration
+    ) {
+        override fun declarationType() = method.returnType.ksType
+
+        override fun isValOrReturnType() = true
+    }
+}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspArrayType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspArrayType.kt
index a787112..21a2942 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspArrayType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspArrayType.kt
@@ -17,7 +17,6 @@
 package androidx.room.compiler.processing.ksp
 
 import androidx.room.compiler.codegen.JArrayTypeName
-import androidx.room.compiler.codegen.XTypeName
 import androidx.room.compiler.processing.XArrayType
 import androidx.room.compiler.processing.XNullability
 import androidx.room.compiler.processing.XType
@@ -29,11 +28,8 @@
 internal sealed class KspArrayType(
     env: KspProcessingEnv,
     ksType: KSType,
-    jvmTypeResolver: KspJvmTypeResolver?
-) : KspType(
-    env, ksType, jvmTypeResolver
-),
-    XArrayType {
+    scope: KSTypeVarianceResolverScope?
+) : KspType(env, ksType, scope), XArrayType {
 
     abstract override val componentType: KspType
 
@@ -56,20 +52,15 @@
     private class BoxedArray(
         env: KspProcessingEnv,
         ksType: KSType,
-        jvmTypeResolver: KspJvmTypeResolver?
-    ) : KspArrayType(
-        env, ksType, jvmTypeResolver
-    ) {
-        private val xTypeName: XTypeName by lazy {
-            val componentTypeName = componentType.asTypeName()
-            XTypeName(
-                java = JArrayTypeName.of(componentTypeName.java.box()),
-                kotlin = ksType.asKTypeName(env.resolver),
-                nullability = nullability,
-            )
+        scope: KSTypeVarianceResolverScope?
+    ) : KspArrayType(env, ksType, scope) {
+        override fun resolveJTypeName(): JTypeName {
+            return JArrayTypeName.of(componentType.asTypeName().java.box())
         }
 
-        override fun asTypeName() = xTypeName
+        override fun resolveKTypeName(): KTypeName {
+            return ksType.asKTypeName(env.resolver)
+        }
 
         override val componentType: KspType by lazy {
             val arg = ksType.arguments.single()
@@ -85,15 +76,15 @@
             return BoxedArray(
                 env = env,
                 ksType = ksType.withNullability(nullability),
-                jvmTypeResolver = jvmTypeResolver,
+                scope = scope,
             )
         }
 
-        override fun copyWithJvmTypeResolver(jvmTypeResolver: KspJvmTypeResolver): KspType {
+        override fun copyWithScope(scope: KSTypeVarianceResolverScope): KspType {
             return BoxedArray(
                 env = env,
                 ksType = ksType,
-                jvmTypeResolver = jvmTypeResolver
+                scope = scope
             )
         }
     }
@@ -104,37 +95,32 @@
     private class PrimitiveArray(
         env: KspProcessingEnv,
         ksType: KSType,
-        jvmTypeResolver: KspJvmTypeResolver?,
+        scope: KSTypeVarianceResolverScope?,
         override val componentType: KspType
-    ) : KspArrayType(
-        env, ksType, jvmTypeResolver
-    ) {
-        private val xTypeName: XTypeName by lazy {
-            val componentTypeName = componentType.asTypeName()
-            XTypeName(
-                java = JArrayTypeName.of(componentTypeName.java.unbox()),
-                kotlin = ksType.asKTypeName(env.resolver),
-                nullability = nullability,
-            )
+    ) : KspArrayType(env, ksType, scope) {
+        override fun resolveJTypeName(): JTypeName {
+            return JArrayTypeName.of(componentType.asTypeName().java.unbox())
         }
 
-        override fun asTypeName() = xTypeName
+        override fun resolveKTypeName(): KTypeName {
+            return ksType.asKTypeName(env.resolver)
+        }
 
         override fun copyWithNullability(nullability: XNullability): PrimitiveArray {
             return PrimitiveArray(
                 env = env,
                 ksType = ksType.withNullability(nullability),
                 componentType = componentType,
-                jvmTypeResolver = jvmTypeResolver
+                scope = scope
             )
         }
 
-        override fun copyWithJvmTypeResolver(jvmTypeResolver: KspJvmTypeResolver): KspType {
+        override fun copyWithScope(scope: KSTypeVarianceResolverScope): KspType {
             return PrimitiveArray(
                 env = env,
                 ksType = ksType,
                 componentType = componentType,
-                jvmTypeResolver = jvmTypeResolver
+                scope = scope
             )
         }
     }
@@ -170,7 +156,7 @@
                             primitiveArrayEntry.key
                         ),
                         componentType = primitiveArrayEntry.value,
-                        jvmTypeResolver = null
+                        scope = null
                     )
                 }
             }
@@ -185,7 +171,7 @@
                         )
                     )
                 ),
-                jvmTypeResolver = null
+                scope = null
             )
         }
 
@@ -199,7 +185,7 @@
                 return BoxedArray(
                     env = env,
                     ksType = ksType,
-                    jvmTypeResolver = null
+                    scope = null
                 )
             }
             builtInArrays[qName]?.let { primitiveType ->
@@ -207,7 +193,7 @@
                     env = env,
                     ksType = ksType,
                     componentType = primitiveType,
-                    jvmTypeResolver = null
+                    scope = null
                 )
             }
             return null
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt
index fe11246..84cf572 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt
@@ -22,7 +22,6 @@
 import androidx.room.compiler.processing.XType
 import androidx.room.compiler.processing.ksp.KspAnnotated.UseSiteFilter.Companion.NO_USE_SITE_OR_METHOD_PARAMETER
 import androidx.room.compiler.processing.ksp.synthetic.KspSyntheticPropertyMethodElement
-import com.google.devtools.ksp.symbol.KSDeclaration
 import com.google.devtools.ksp.symbol.KSFunctionDeclaration
 import com.google.devtools.ksp.symbol.KSPropertySetter
 import com.google.devtools.ksp.symbol.KSType
@@ -48,15 +47,6 @@
     override val hasDefaultValue: Boolean
         get() = parameter.hasDefault
 
-    private fun jvmTypeResolver(container: KSDeclaration?): KspJvmTypeResolutionScope {
-        return KspJvmTypeResolutionScope.MethodParameter(
-            kspExecutableElement = enclosingElement,
-            parameterIndex = parameterIndex,
-            annotated = parameter.type,
-            container = container
-        )
-    }
-
     override val type: KspType by lazy {
         asMemberOf(enclosingElement.enclosingElement.type?.ksType)
     }
@@ -83,8 +73,11 @@
                 functionDeclaration = enclosingElement.declaration,
                 ksType = ksType
             )
-        ).withJvmTypeResolver(
-            jvmTypeResolver(
+        ).copyWithScope(
+            KSTypeVarianceResolverScope.MethodParameter(
+                kspExecutableElement = enclosingElement,
+                parameterIndex = parameterIndex,
+                annotated = parameter.type,
                 container = ksType?.declaration
             )
         )
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFieldElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFieldElement.kt
index 6963639..b8bad187 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFieldElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFieldElement.kt
@@ -103,7 +103,7 @@
         return env.wrap(
             originatingReference = declaration.type,
             ksType = declaration.typeAsMemberOf(ksType)
-        )
+        ).copyWithScope(KSTypeVarianceResolverScope.PropertyType(this))
     }
 
     companion object {
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspJvmTypeResolver.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspJvmTypeResolver.kt
deleted file mode 100644
index ba92d38..0000000
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspJvmTypeResolver.kt
+++ /dev/null
@@ -1,140 +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.room.compiler.processing.ksp
-
-import androidx.room.compiler.processing.XType
-import androidx.room.compiler.processing.ksp.synthetic.KspSyntheticPropertyMethodElement
-import com.google.devtools.ksp.symbol.KSAnnotated
-import com.google.devtools.ksp.symbol.KSDeclaration
-import com.google.devtools.ksp.symbol.KSNode
-import com.google.devtools.ksp.symbol.Origin
-
-/**
- * JvmType of a Kotlin type depends on where the type is declared.
- *
- * This resolver is used to resolve that type when necessary (computing TypeName).
- * See [KSTypeVarianceResolver] for details.
- */
-internal class KspJvmTypeResolver(
-    val scope: KspJvmTypeResolutionScope,
-    val delegate: KspType
-) {
-    internal fun resolveJvmType(
-        env: KspProcessingEnv
-    ): KspType {
-        if (!scope.needsWildcardResolution) {
-            return delegate
-        }
-        val wildcardMode = if (scope.suppressesWildcards) {
-            KSTypeVarianceResolver.WildcardMode.SUPPRESSED
-        } else {
-            KSTypeVarianceResolver.WildcardMode.PREFERRED
-        }
-
-        val declarationType = scope.findDeclarationType() as? KspType
-        return env.resolveWildcards(
-            ksType = delegate.ksType,
-            wildcardMode = wildcardMode,
-            // See KSTypeVarianceResolver#applyTypeVariance: "If the ksType is from the original
-            // declaration, declarationType should be null".
-            declarationType = if (declarationType == delegate) {
-                null
-            } else {
-                // use the jvm type of the declaration so that it also gets its jvm wildcards
-                // resolved.
-                declarationType?.jvmWildcardTypeOrSelf?.ksType
-            }
-        ).let {
-            env.wrap(
-                ksType = it,
-                allowPrimitives = delegate is KspPrimitiveType
-            )
-        }
-    }
-}
-
-/**
- * Provides KSType resolution scope for parameter types.
- */
-internal sealed class KspJvmTypeResolutionScope(
-    private val annotated: KSAnnotated,
-    private val container: KSDeclaration?
-) {
-    /**
-     * Checks whether we need wildcard resolution at all. It is only necessary if either the method
-     * parameter is in kotlin or the containing class, which inherited the method, is in kotlin.
-     */
-    val needsWildcardResolution: Boolean by lazy {
-        annotated.isInKotlinCode() || container?.isInKotlinCode() == true
-    }
-
-    /**
-     * Checks if the wildcards are suppressed by checking the hierarchy of the declaration to see if
-     * it has the @JvmSuppressWildcards annotation.
-     */
-    val suppressesWildcards by lazy {
-        // suppress wildcards depend on the declaration site.
-        annotated.hasSuppressWildcardsAnnotationInHierarchy()
-    }
-
-    private fun KSAnnotated.isInKotlinCode(): Boolean {
-        // find the true origin by skipping synthetics.
-        var current: KSNode? = this
-        while (current != null) {
-            val origin = current.origin
-            if (origin != Origin.SYNTHETIC) {
-                return origin == Origin.KOTLIN || origin == Origin.KOTLIN_LIB
-            }
-            current = current.parent
-        }
-        return false
-    }
-
-    /**
-     * Finds the XType from the declaration if and only if this method is inherited from another
-     * class / interface.
-     */
-    abstract fun findDeclarationType(): XType?
-
-    internal class MethodParameter(
-        private val kspExecutableElement: KspExecutableElement,
-        private val parameterIndex: Int,
-        annotated: KSAnnotated,
-        container: KSDeclaration?,
-    ) : KspJvmTypeResolutionScope(annotated, container) {
-        override fun findDeclarationType(): XType? {
-            return if (kspExecutableElement is KspMethodElement) {
-                kspExecutableElement.executableType.parameterTypes.getOrNull(parameterIndex)
-            } else {
-                null
-            }
-        }
-    }
-
-    internal class PropertySetterParameter(
-        val declaration: KspSyntheticPropertyMethodElement
-    ) : KspJvmTypeResolutionScope(
-        annotated = declaration.accessor,
-        container = declaration.field.enclosingElement.declaration
-    ) {
-        override fun findDeclarationType(): XType? {
-            // We return the declaration from the setter, not the field because the setter parameter
-            // will have a different type in jvm (due to jvm wildcard resolution)
-            return declaration.field.syntheticSetter?.parameters?.firstOrNull()?.type
-        }
-    }
-}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt
index 4d06d47..131b645 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt
@@ -112,15 +112,17 @@
 
     override fun isKotlinPropertyMethod() = false
 
+    abstract override val returnType: KspType
+
     private class KspNormalMethodElement(
         env: KspProcessingEnv,
         declaration: KSFunctionDeclaration
     ) : KspMethodElement(env, declaration) {
-        override val returnType: XType by lazy {
+        override val returnType: KspType by lazy {
             declaration.returnKspType(
                 env = env,
                 containing = enclosingElement.type
-            )
+            ).copyWithScope(KSTypeVarianceResolverScope.MethodReturnType(this))
         }
         override fun isSuspendFunction() = false
     }
@@ -131,11 +133,11 @@
     ) : KspMethodElement(env, declaration) {
         override fun isSuspendFunction() = true
 
-        override val returnType: XType by lazy {
+        override val returnType: KspType by lazy {
             env.wrap(
                 ksType = env.resolver.builtIns.anyType.makeNullable(),
                 allowPrimitives = false
-            )
+            ).copyWithScope(KSTypeVarianceResolverScope.MethodReturnType(this))
         }
 
         override val parameters: List<XExecutableParameterElement>
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt
index ec72704..fba2cbc 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt
@@ -47,7 +47,7 @@
             origin.declaration.returnKspType(
                 env = env,
                 containing = containing
-            )
+            ).copyWithScope(KSTypeVarianceResolverScope.MethodReturnType(origin))
         }
     }
 
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspPrimitiveType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspPrimitiveType.kt
index 771dba1..73d675c 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspPrimitiveType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspPrimitiveType.kt
@@ -32,8 +32,8 @@
 internal class KspPrimitiveType(
     env: KspProcessingEnv,
     ksType: KSType,
-    jvmTypeResolver: KspJvmTypeResolver?
-) : KspType(env, ksType, jvmTypeResolver) {
+    scope: KSTypeVarianceResolverScope?
+) : KspType(env, ksType, scope) {
     override fun resolveJTypeName(): JTypeName {
         return ksType.asJTypeName(env.resolver).tryUnbox()
     }
@@ -66,11 +66,11 @@
         }
     }
 
-    override fun copyWithJvmTypeResolver(jvmTypeResolver: KspJvmTypeResolver): KspType {
+    override fun copyWithScope(scope: KSTypeVarianceResolverScope): KspType {
         return KspPrimitiveType(
             env = env,
             ksType = ksType,
-            jvmTypeResolver = jvmTypeResolver
+            scope = scope
         )
     }
 }
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 232bacd..acf2615 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
@@ -105,7 +105,7 @@
             env = this,
             ksType = resolver.builtIns.unitType,
             boxed = false,
-            jvmTypeResolver = null
+            scope = null
         )
 
     override fun findTypeElement(qName: String): KspTypeElement? {
@@ -227,7 +227,7 @@
         return KspTypeArgumentType(
             env = this,
             typeArg = ksTypeArgument,
-            jvmTypeResolver = null
+            scope = null
         )
     }
 
@@ -258,14 +258,14 @@
             return KspTypeVariableType(
                 env = this,
                 ksType = ksType,
-                jvmTypeResolver = null
+                scope = null
             )
         }
         if (allowPrimitives && qName != null && ksType.nullability == Nullability.NOT_NULL) {
             // check for primitives
             val javaPrimitive = KspTypeMapper.getPrimitiveJavaTypeName(qName)
             if (javaPrimitive != null) {
-                return KspPrimitiveType(this, ksType, jvmTypeResolver = null)
+                return KspPrimitiveType(this, ksType, scope = null)
             }
             // special case for void
             if (qName == "kotlin.Unit") {
@@ -275,7 +275,7 @@
         return arrayTypeFactory.createIfArray(ksType) ?: DefaultKspType(
             this,
             ksType,
-            jvmTypeResolver = null
+            scope = null
         )
     }
 
@@ -295,26 +295,8 @@
     /**
      * Resolves the wildcards for the given ksType. See [KSTypeVarianceResolver] for details.
      */
-    fun resolveWildcards(
-        /**
-         * The KSType whose wildcards variance will be resolved
-         */
-        ksType: KSType,
-        /**
-         * Default wildcard resolution strategy
-         */
-        wildcardMode: KSTypeVarianceResolver.WildcardMode,
-        /**
-         * The original declaration type if [ksType] is obtained via inheritance.
-         */
-        declarationType: KSType?
-    ): KSType {
-        return ksTypeVarianceResolver.applyTypeVariance(
-            ksType = ksType,
-            wildcardMode = wildcardMode,
-            declarationType = declarationType
-        )
-    }
+    internal fun resolveWildcards(ksType: KSType, scope: KSTypeVarianceResolverScope) =
+        ksTypeVarianceResolver.applyTypeVariance(ksType, scope)
 
     internal fun clearCache() {
         typeElementStore.clear()
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
index d6b75dd..8fc4f16 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
@@ -52,7 +52,7 @@
     /**
      * Type resolver to convert KSType into its JVM representation.
      */
-    protected val jvmTypeResolver: KspJvmTypeResolver?
+    protected val scope: KSTypeVarianceResolverScope?
 ) : KspAnnotated(env), XType, XEquality {
     override val rawType by lazy {
         KspRawType(this)
@@ -62,27 +62,34 @@
         xTypeName.java
     }
 
-    private val xTypeName: XTypeName by lazy {
-        XTypeName(
-            jvmWildcardType?.asTypeName()?.java ?: resolveJTypeName(),
-            jvmWildcardType?.asTypeName()?.kotlin ?: resolveKTypeName(),
-            nullability
-        )
-    }
-
     override fun asTypeName() = xTypeName
 
     /**
-     * A Kotlin type might have a slightly different type in JVM due to wildcards.
-     * This fields holds onto that value which will be used when creating JVM types.
+     * A Kotlin type might have a slightly different type in JVM vs Kotlin due to wildcards.
+     * The [XTypeName] represents those differences as [JTypeName] and [KTypeName], respectively.
      */
-    private val jvmWildcardType by lazy {
-        jvmTypeResolver?.resolveJvmType(env)
+    private val xTypeName: XTypeName by lazy {
+        val jvmWildcardType = if (scope == null) {
+            this
+        } else {
+            env.resolveWildcards(ksType, scope).let {
+                if (it == ksType) {
+                    this
+                } else {
+                    env.wrap(
+                        ksType = it,
+                        allowPrimitives = this is KspPrimitiveType
+                    ).copyWithScope(scope)
+                }
+            }
+        }
+        XTypeName(
+            jvmWildcardType.resolveJTypeName(),
+            jvmWildcardType.resolveKTypeName(),
+            nullability
+        )
     }
 
-    internal val jvmWildcardTypeOrSelf
-        get() = jvmWildcardType ?: this
-
     protected abstract fun resolveJTypeName(): JTypeName
 
     protected abstract fun resolveKTypeName(): KTypeName
@@ -266,20 +273,7 @@
 
     abstract override fun boxed(): KspType
 
-    fun withJvmTypeResolver(
-        jvmTypeResolver: KspJvmTypeResolutionScope
-    ): KspType {
-        return copyWithJvmTypeResolver(
-            KspJvmTypeResolver(
-                scope = jvmTypeResolver,
-                delegate = this
-            )
-        )
-    }
-
-    abstract fun copyWithJvmTypeResolver(
-        jvmTypeResolver: KspJvmTypeResolver
-    ): KspType
+    abstract fun copyWithScope(scope: KSTypeVarianceResolverScope): KspType
 
     /**
      * Create a copy of this type with the given nullability.
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeArgumentType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeArgumentType.kt
index ffacdbd..7593b7f 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeArgumentType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeArgumentType.kt
@@ -31,11 +31,11 @@
 internal class KspTypeArgumentType(
     env: KspProcessingEnv,
     val typeArg: KSTypeArgument,
-    jvmTypeResolver: KspJvmTypeResolver?
+    scope: KSTypeVarianceResolverScope?
 ) : KspType(
     env = env,
     ksType = typeArg.requireType(),
-    jvmTypeResolver = jvmTypeResolver
+    scope = scope
 ) {
     /**
      * When KSP resolves classes, it always resolves to the upper bound. Hence, the ksType we
@@ -77,15 +77,15 @@
                 original = typeArg,
                 type = ksType.withNullability(nullability).createTypeReference()
             ),
-            jvmTypeResolver = jvmTypeResolver
+            scope = scope
         )
     }
 
-    override fun copyWithJvmTypeResolver(jvmTypeResolver: KspJvmTypeResolver): KspType {
+    override fun copyWithScope(scope: KSTypeVarianceResolverScope): KspType {
         return KspTypeArgumentType(
             env = env,
             typeArg = typeArg,
-            jvmTypeResolver = jvmTypeResolver
+            scope = scope
         )
     }
 
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeVariableType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeVariableType.kt
index 9d91f0c4..cd2b9e6 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeVariableType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeVariableType.kt
@@ -27,12 +27,8 @@
 internal class KspTypeVariableType(
     env: KspProcessingEnv,
     ksType: KSType,
-    jvmTypeResolver: KspJvmTypeResolver?
-) : KspType(
-    env = env,
-    ksType = ksType,
-    jvmTypeResolver = jvmTypeResolver
-), XTypeVariableType {
+    scope: KSTypeVarianceResolverScope?
+) : KspType(env, ksType, scope), XTypeVariableType {
     private val typeVariable: KSTypeParameter by lazy {
         // Note: This is a workaround for a bug in KSP where we may get ERROR_TYPE in the bounds
         // (https://github.com/google/ksp/issues/1250). To work around it we get the matching
@@ -60,15 +56,15 @@
         return KspTypeVariableType(
             env = env,
             ksType = ksType,
-            jvmTypeResolver = jvmTypeResolver
+            scope = scope
         )
     }
 
-    override fun copyWithJvmTypeResolver(jvmTypeResolver: KspJvmTypeResolver): KspType {
+    override fun copyWithScope(scope: KSTypeVarianceResolverScope): KspType {
         return KspTypeVariableType(
             env = env,
             ksType = ksType,
-            jvmTypeResolver = jvmTypeResolver
+            scope = scope
         )
     }
 }
\ No newline at end of file
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspVoidType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspVoidType.kt
index 87d50ca..a68b298 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspVoidType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspVoidType.kt
@@ -32,8 +32,8 @@
     env: KspProcessingEnv,
     ksType: KSType,
     val boxed: Boolean,
-    jvmTypeResolver: KspJvmTypeResolver?
-) : KspType(env, ksType, jvmTypeResolver) {
+    scope: KSTypeVarianceResolverScope?
+) : KspType(env, ksType, scope) {
     override fun resolveJTypeName(): JTypeName {
         return if (boxed || nullability == XNullability.NULLABLE) {
             JTypeName.VOID.box()
@@ -54,7 +54,7 @@
                 env = env,
                 ksType = ksType,
                 boxed = true,
-                jvmTypeResolver = jvmTypeResolver
+                scope = scope
             )
         }
     }
@@ -64,16 +64,16 @@
             env = env,
             ksType = ksType.withNullability(nullability),
             boxed = boxed || nullability == XNullability.NULLABLE,
-            jvmTypeResolver = jvmTypeResolver
+            scope = scope
         )
     }
 
-    override fun copyWithJvmTypeResolver(jvmTypeResolver: KspJvmTypeResolver): KspType {
+    override fun copyWithScope(scope: KSTypeVarianceResolverScope): KspType {
         return KspVoidType(
             env = env,
             ksType = ksType,
             boxed = boxed,
-            jvmTypeResolver = jvmTypeResolver
+            scope = scope
         )
     }
 }
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticContinuationParameterElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticContinuationParameterElement.kt
index 66b4c84..1fbc669 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticContinuationParameterElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticContinuationParameterElement.kt
@@ -21,16 +21,15 @@
 import androidx.room.compiler.processing.XExecutableParameterElement
 import androidx.room.compiler.processing.XMemberContainer
 import androidx.room.compiler.processing.XType
+import androidx.room.compiler.processing.ksp.KSTypeVarianceResolverScope
 import androidx.room.compiler.processing.ksp.KspAnnotated
 import androidx.room.compiler.processing.ksp.KspAnnotated.UseSiteFilter.Companion.NO_USE_SITE
-import androidx.room.compiler.processing.ksp.KspJvmTypeResolutionScope
 import androidx.room.compiler.processing.ksp.KspMethodElement
 import androidx.room.compiler.processing.ksp.KspProcessingEnv
 import androidx.room.compiler.processing.ksp.KspType
 import androidx.room.compiler.processing.ksp.requireContinuationClass
 import androidx.room.compiler.processing.ksp.returnTypeAsMemberOf
 import androidx.room.compiler.processing.ksp.swapResolvedType
-import com.google.devtools.ksp.symbol.KSDeclaration
 import com.google.devtools.ksp.symbol.KSType
 import com.google.devtools.ksp.symbol.Variance
 
@@ -75,15 +74,6 @@
     override val hasDefaultValue: Boolean
         get() = false
 
-    private fun jvmTypeResolutionScope(container: KSDeclaration?): KspJvmTypeResolutionScope {
-        return KspJvmTypeResolutionScope.MethodParameter(
-            kspExecutableElement = enclosingElement,
-            parameterIndex = enclosingElement.parameters.size - 1,
-            annotated = enclosingElement.declaration,
-            container = container
-        )
-    }
-
     override val type: KspType by lazy {
         asMemberOf(enclosingElement.enclosingElement.type?.ksType)
     }
@@ -124,8 +114,11 @@
         return env.wrap(
             ksType = contType,
             allowPrimitives = false
-        ).withJvmTypeResolver(
-            jvmTypeResolutionScope(
+        ).copyWithScope(
+            KSTypeVarianceResolverScope.MethodParameter(
+                kspExecutableElement = enclosingElement,
+                parameterIndex = enclosingElement.parameters.size - 1,
+                annotated = enclosingElement.declaration,
                 container = ksType?.declaration
             )
         )
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt
index ec5190d..b5e1a70 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt
@@ -27,13 +27,13 @@
 import androidx.room.compiler.processing.XTypeElement
 import androidx.room.compiler.processing.XTypeParameterElement
 import androidx.room.compiler.processing.javac.kotlin.JvmAbi
+import androidx.room.compiler.processing.ksp.KSTypeVarianceResolverScope
 import androidx.room.compiler.processing.ksp.KspAnnotated
 import androidx.room.compiler.processing.ksp.KspAnnotated.UseSiteFilter.Companion.NO_USE_SITE_OR_GETTER
 import androidx.room.compiler.processing.ksp.KspAnnotated.UseSiteFilter.Companion.NO_USE_SITE_OR_SETTER
 import androidx.room.compiler.processing.ksp.KspAnnotated.UseSiteFilter.Companion.NO_USE_SITE_OR_SET_PARAM
 import androidx.room.compiler.processing.ksp.KspFieldElement
 import androidx.room.compiler.processing.ksp.KspHasModifiers
-import androidx.room.compiler.processing.ksp.KspJvmTypeResolutionScope
 import androidx.room.compiler.processing.ksp.KspProcessingEnv
 import androidx.room.compiler.processing.ksp.KspType
 import androidx.room.compiler.processing.ksp.findEnclosingMemberContainer
@@ -144,7 +144,7 @@
 
     override fun isKotlinPropertyMethod() = true
 
-    private class Getter(
+    internal class Getter(
         env: KspProcessingEnv,
         field: KspFieldElement,
         override val accessor: KSPropertyGetter
@@ -167,7 +167,9 @@
             get() = this.jvmDescriptor()
 
         override val returnType: XType by lazy {
-            field.type
+            field.type.copyWithScope(
+                KSTypeVarianceResolverScope.PropertyGetterMethodReturnType(this)
+            )
         }
 
         override val typeParameters: List<XTypeParameterElement>
@@ -181,7 +183,7 @@
         }
     }
 
-    private class Setter(
+    internal class Setter(
         env: KspProcessingEnv,
         field: KspFieldElement,
         override val accessor: KSPropertySetter
@@ -238,18 +240,14 @@
 
             override fun isKotlinPropertyParam() = true
 
-            private val jvmTypeResolutionScope = KspJvmTypeResolutionScope.PropertySetterParameter(
-                declaration = enclosingElement
-            )
-
             override val name: String by lazy {
                 val originalName = enclosingElement.accessor.parameter.name?.asString()
                 originalName.sanitizeAsJavaParameterName(0)
             }
 
             override val type: KspType by lazy {
-                enclosingElement.field.type.withJvmTypeResolver(
-                    jvmTypeResolutionScope
+                enclosingElement.field.type.copyWithScope(
+                    KSTypeVarianceResolverScope.PropertySetterParameterType(enclosingElement)
                 )
             }
 
@@ -265,7 +263,9 @@
 
             override fun asMemberOf(other: XType): KspType {
                 return enclosingElement.field.asMemberOf(other)
-                    .withJvmTypeResolver(jvmTypeResolutionScope)
+                    .copyWithScope(
+                        KSTypeVarianceResolverScope.PropertySetterParameterType(enclosingElement)
+                    )
             }
 
             override val docComment: String?
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodType.kt
index e2221aa..a482093 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodType.kt
@@ -19,6 +19,7 @@
 import androidx.room.compiler.processing.XExecutableType
 import androidx.room.compiler.processing.XMethodType
 import androidx.room.compiler.processing.XType
+import androidx.room.compiler.processing.ksp.KSTypeVarianceResolverScope
 import androidx.room.compiler.processing.ksp.KspProcessingEnv
 import com.google.devtools.ksp.symbol.KSPropertyGetter
 import com.google.devtools.ksp.symbol.KSPropertySetter
@@ -94,7 +95,11 @@
                 origin.field.type
             } else {
                 origin.field.asMemberOf(containingType)
-            }
+            }.copyWithScope(
+                KSTypeVarianceResolverScope.PropertyGetterMethodReturnType(
+                    getterMethod = origin as KspSyntheticPropertyMethodElement.Getter
+                )
+            )
         }
     }
 
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticReceiverParameterElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticReceiverParameterElement.kt
index acef3af..94224fe 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticReceiverParameterElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticReceiverParameterElement.kt
@@ -21,12 +21,11 @@
 import androidx.room.compiler.processing.XExecutableParameterElement
 import androidx.room.compiler.processing.XMemberContainer
 import androidx.room.compiler.processing.XType
+import androidx.room.compiler.processing.ksp.KSTypeVarianceResolverScope
 import androidx.room.compiler.processing.ksp.KspAnnotated
-import androidx.room.compiler.processing.ksp.KspJvmTypeResolutionScope
 import androidx.room.compiler.processing.ksp.KspMethodElement
 import androidx.room.compiler.processing.ksp.KspProcessingEnv
 import androidx.room.compiler.processing.ksp.KspType
-import com.google.devtools.ksp.symbol.KSDeclaration
 import com.google.devtools.ksp.symbol.KSType
 import com.google.devtools.ksp.symbol.KSTypeReference
 
@@ -60,15 +59,6 @@
     override val hasDefaultValue: Boolean
         get() = false
 
-    private fun jvmTypeResolutionScope(container: KSDeclaration?): KspJvmTypeResolutionScope {
-        return KspJvmTypeResolutionScope.MethodParameter(
-            kspExecutableElement = enclosingElement,
-            parameterIndex = 0, // Receiver param is the 1st one
-            annotated = enclosingElement.declaration,
-            container = container
-        )
-    }
-
     override val type: KspType by lazy {
         asMemberOf(enclosingElement.enclosingElement.type?.ksType)
     }
@@ -102,8 +92,11 @@
         return env.wrap(
             originatingReference = receiverType,
             ksType = asMemberReceiverType,
-        ).withJvmTypeResolver(
-            jvmTypeResolutionScope(
+        ).copyWithScope(
+            KSTypeVarianceResolverScope.MethodParameter(
+                kspExecutableElement = enclosingElement,
+                parameterIndex = 0, // Receiver param is the 1st one
+                annotated = enclosingElement.declaration,
                 container = ksType?.declaration
             )
         )
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeInheritanceTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeInheritanceTest.kt
index 40d916e..f337713 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeInheritanceTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeInheritanceTest.kt
@@ -60,19 +60,23 @@
         runProcessorTest(sources = listOf(src), handler = handler)
     }
 
-    private fun XTestInvocation.assertFieldType(fieldName: String, expectedTypeName: String) {
+    private fun XTestInvocation.assertFieldType(
+        fieldName: String,
+        expectedJTypeName: String,
+    ) {
+        val expectedKTypeName = expectedJTypeName.replace("? extends", "out")
         val sub = processingEnv.requireTypeElement("SubClass")
         val subField = sub.getField(fieldName).asMemberOf(sub.type)
-        assertThat(subField.asTypeName().java.toString()).isEqualTo(expectedTypeName)
+        assertThat(subField.asTypeName().java.toString()).isEqualTo(expectedJTypeName)
         if (isKsp) {
-            assertThat(subField.asTypeName().kotlin.toString()).isEqualTo(expectedTypeName)
+            assertThat(subField.asTypeName().kotlin.toString()).isEqualTo(expectedKTypeName)
         }
 
         val base = processingEnv.requireTypeElement("BaseClass")
         val baseField = base.getField(fieldName).asMemberOf(sub.type)
-        assertThat(baseField.asTypeName().java.toString()).isEqualTo(expectedTypeName)
+        assertThat(baseField.asTypeName().java.toString()).isEqualTo(expectedJTypeName)
         if (isKsp) {
-            assertThat(baseField.asTypeName().kotlin.toString()).isEqualTo(expectedTypeName)
+            assertThat(baseField.asTypeName().kotlin.toString()).isEqualTo(expectedKTypeName)
         }
     }
 
@@ -80,8 +84,8 @@
         methodName: String,
         paramName: String,
         expectedJTypeName: String,
-        expectedKTypeName: String,
     ) {
+        val expectedKTypeName = expectedJTypeName.replace("? extends", "out")
         val sub = processingEnv.requireTypeElement("SubClass")
         val subMethod = sub.getMethodByJvmName(methodName)
         val paramIndex = subMethod.parameters.indexOf(subMethod.getParameter(paramName))
@@ -123,9 +127,9 @@
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
@@ -145,9 +149,9 @@
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
@@ -167,9 +171,9 @@
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
@@ -189,9 +193,9 @@
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
@@ -211,9 +215,9 @@
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
@@ -233,9 +237,9 @@
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
@@ -255,9 +259,9 @@
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
@@ -277,9 +281,9 @@
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
@@ -298,24 +302,13 @@
             invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
+            invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
-            }
         }
     }
 
@@ -331,24 +324,13 @@
             invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
+            invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
-            }
         }
     }
 
@@ -362,38 +344,15 @@
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "param",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
-            invocation.assertParamType(
-                "method",
-                "paramT1",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
+            invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
+            invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<Baz>>")
+            invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "param", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
-            }
         }
     }
 
@@ -409,24 +368,13 @@
             invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
+            invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
-            }
         }
     }
 
@@ -440,38 +388,15 @@
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "param",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
-            invocation.assertParamType(
-                "method",
-                "paramT1",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
+            invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
+            invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<Baz>>")
+            invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "param", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
-            }
         }
     }
 
@@ -487,24 +412,13 @@
             invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
+            invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
-            }
         }
     }
 
@@ -518,38 +432,15 @@
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "param",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
-            invocation.assertParamType(
-                "method",
-                "paramT1",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
+            invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
+            invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<Baz>>")
+            invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "param", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
-            }
         }
     }
 
@@ -563,38 +454,15 @@
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "param",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
-            invocation.assertParamType(
-                "method",
-                "paramT1",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
+            invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
+            invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<Baz>>")
+            invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "param", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
-            }
         }
     }
 
@@ -607,40 +475,16 @@
         ) { invocation ->
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+            invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<Bar<? extends Baz>>",
-                "Foo<Bar<out Baz>>"
-            )
+            invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<Bar<? extends Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<Bar<? extends Baz>>",
-                    "Foo<Bar<out Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<Bar<Baz>>",
-                    "Foo<Bar<Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
-            }
+            invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
         }
     }
 
@@ -653,35 +497,16 @@
         ) { invocation ->
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+            invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<Bar<? extends Baz>>",
-                "Foo<Bar<out Baz>>"
-            )
+            invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<Bar<? extends Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<Bar<? extends Baz>>",
-                    "Foo<Bar<out Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
-            }
+            invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
         }
     }
 
@@ -694,35 +519,16 @@
         ) { invocation ->
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+            invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<Bar<? extends Baz>>",
-                "Foo<Bar<out Baz>>"
-            )
+            invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<Bar<? extends Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<Bar<? extends Baz>>",
-                    "Foo<Bar<out Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
-            }
+            invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
         }
     }
 
@@ -735,41 +541,16 @@
         ) { invocation ->
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+            invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<Bar<? extends Baz>>",
-                "Foo<Bar<out Baz>>"
-            )
+            invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<Bar<? extends Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "param",
-                    "Foo<Bar<? extends Baz>>",
-                    "Foo<Bar<out Baz>>"
-                )
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<Bar<? extends Baz>>",
-                    "Foo<Bar<out Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-                invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
-            }
+            invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
         }
     }
 
@@ -782,40 +563,16 @@
         ) { invocation ->
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+            invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<Bar<? extends Baz>>",
-                "Foo<Bar<out Baz>>"
-            )
+            invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<Bar<? extends Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<Bar<? extends Baz>>",
-                    "Foo<Bar<out Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<Bar<Baz>>",
-                    "Foo<Bar<Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
-            }
+            invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
         }
     }
 
@@ -828,46 +585,16 @@
         ) { invocation ->
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+            invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<Bar<? extends Baz>>",
-                "Foo<Bar<out Baz>>"
-            )
+            invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<Bar<? extends Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "param",
-                    "Foo<Bar<? extends Baz>>",
-                    "Foo<Bar<out Baz>>"
-                )
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<Bar<? extends Baz>>",
-                    "Foo<Bar<out Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<Bar<Baz>>",
-                    "Foo<Bar<Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
-            }
+            invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
         }
     }
 
@@ -880,46 +607,16 @@
         ) { invocation ->
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+            invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<Bar<? extends Baz>>",
-                "Foo<Bar<out Baz>>"
-            )
+            invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<Bar<? extends Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "param",
-                    "Foo<Bar<? extends Baz>>",
-                    "Foo<Bar<out Baz>>"
-                )
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<Bar<? extends Baz>>",
-                    "Foo<Bar<out Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<Bar<Baz>>",
-                    "Foo<Bar<Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
-            }
+            invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
         }
     }
 
@@ -932,17 +629,16 @@
         ) { invocation ->
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+            invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
-            }
+            invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<Bar<? extends Baz>>")
+            invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
+            invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
+            invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
         }
     }
 
@@ -955,41 +651,16 @@
         ) { invocation ->
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+            invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<? extends Bar<? extends Baz>>",
-                "Foo<out Bar<out Baz>>"
-            )
+            invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<? extends Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<Bar<? extends Baz>>",
-                    "Foo<Bar<out Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<? extends Bar<? extends Baz>>",
-                    "Foo<out Bar<out Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
-            }
+            invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
         }
     }
 
@@ -1002,38 +673,16 @@
         ) { invocation ->
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+            invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
             invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
-            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<? extends Bar<? extends Baz>>",
-                "Foo<out Bar<out Baz>>"
-            )
+            invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<? extends Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertParamType(
-                    "method", "paramT1", "Foo<Bar<? extends Baz>>", "Foo<Bar<out Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<? extends Bar<? extends Baz>>",
-                    "Foo<out Bar<out Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
-            }
+            invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
         }
     }
 
@@ -1046,43 +695,16 @@
         ) { invocation ->
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
-
-            invocation.assertParamType(
-                "method",
-                "param",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
-            invocation.assertParamType(
-                "method",
-                "paramT1",
-                "Foo<? extends Bar<? extends Baz>>",
-                "Foo<out Bar<out Baz>>"
-            )
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<? extends Bar<? extends Baz>>",
-                "Foo<out Bar<out Baz>>"
-            )
-
+            invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
+            invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
+            invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "param", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<? extends Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
-            }
+            invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
         }
     }
 
@@ -1095,53 +717,16 @@
         ) { invocation ->
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+            invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
+            invocation.assertFieldType("varField", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "param", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<? extends Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<? extends Bar<? extends Baz>>",
-                "Foo<out Bar<out Baz>>"
-            )
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "param",
-                    "Foo<Bar<? extends Baz>>",
-                    "Foo<Bar<out Baz>>"
-                )
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<Bar<? extends Baz>>",
-                    "Foo<Bar<out Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertFieldType("varField", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "param",
-                    "Foo<? extends Bar<? extends Baz>>",
-                    "Foo<out Bar<out Baz>>"
-                )
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<? extends Bar<? extends Baz>>",
-                    "Foo<out Bar<out Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
-            }
+            invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
         }
     }
 
@@ -1154,41 +739,16 @@
         ) { invocation ->
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "param",
-                "Foo<? extends Bar<Baz>>",
-                "Foo<out Bar<Baz>>"
-            )
-            invocation.assertParamType(
-                "method",
-                "paramT1",
-                "Foo<? extends Bar<? extends Baz>>",
-                "Foo<out Bar<out Baz>>"
-            )
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<? extends Bar<? extends Baz>>",
-                "Foo<out Bar<out Baz>>"
-            )
+            invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
+            invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
+            invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "param", "Foo<? extends Bar<Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<? extends Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
-            }
+            invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
         }
     }
 
@@ -1201,53 +761,16 @@
         ) { invocation ->
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<? extends Bar<? extends Baz>>",
-                "Foo<out Bar<out Baz>>"
-            )
+            invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
+            invocation.assertFieldType("varField", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "param", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<? extends Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "param",
-                    "Foo<Bar<? extends Baz>>",
-                    "Foo<Bar<out Baz>>"
-                )
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<Bar<? extends Baz>>",
-                    "Foo<Bar<out Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertFieldType("varField", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertParamType(
-                    "method",
-                    "param",
-                    "Foo<? extends Bar<? extends Baz>>",
-                    "Foo<out Bar<out Baz>>"
-                )
-                invocation.assertParamType(
-                    "method",
-                    "paramT1",
-                    "Foo<? extends Bar<? extends Baz>>",
-                    "Foo<out Bar<out Baz>>"
-                )
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
-            }
+            invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
         }
     }
 
@@ -1260,41 +783,16 @@
         ) { invocation ->
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "param",
-                "Foo<? extends Bar<? extends Baz>>",
-                "Foo<out Bar<out Baz>>"
-            )
-            invocation.assertParamType(
-                "method",
-                "paramT1",
-                "Foo<? extends Bar<? extends Baz>>",
-                "Foo<out Bar<out Baz>>"
-            )
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<? extends Bar<? extends Baz>>",
-                "Foo<out Bar<out Baz>>"
-            )
+            invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
+            invocation.assertFieldType("varField", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "param", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<? extends Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertFieldType("varField", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
-            }
+            invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
         }
     }
 
@@ -1307,41 +805,16 @@
         ) { invocation ->
             invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
             invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
-            invocation.assertParamType(
-                "method",
-                "param",
-                "Foo<? extends Bar<? extends Baz>>",
-                "Foo<out Bar<out Baz>>"
-            )
-            invocation.assertParamType(
-                "method",
-                "paramT1",
-                "Foo<? extends Bar<? extends Baz>>",
-                "Foo<out Bar<out Baz>>"
-            )
-            invocation.assertParamType(
-                "method",
-                "paramT2",
-                "Foo<? extends Bar<? extends Baz>>",
-                "Foo<out Bar<out Baz>>"
-            )
+            invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
+            invocation.assertFieldType("varField", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "param", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<? extends Baz>>")
+            invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<? extends Baz>>")
             invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
             invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
-            // TODO(b/237280547): Make KSP type name match KAPT.
-            if (invocation.isKsp) {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-            } else {
-                invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
-                invocation.assertFieldType("varField", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
-                invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
-            }
+            invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
         }
     }
 }
\ No newline at end of file
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSAsMemberOfTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSAsMemberOfTest.kt
index f2c68e0..8f9a50a 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSAsMemberOfTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSAsMemberOfTest.kt
@@ -22,10 +22,12 @@
 import androidx.room.compiler.processing.util.getField
 import androidx.room.compiler.processing.util.getMethodByJvmName
 import androidx.room.compiler.processing.util.runKspTest
+import androidx.room.compiler.processing.util.runProcessorTest
 import com.google.common.truth.Truth.assertThat
 import com.squareup.javapoet.ClassName
 import com.squareup.javapoet.ParameterizedTypeName
 import com.squareup.javapoet.TypeName
+import com.squareup.javapoet.WildcardTypeName
 import org.junit.Test
 
 class KSAsMemberOfTest {
@@ -46,7 +48,7 @@
             """.trimIndent()
         )
 
-        runKspTest(sources = listOf(src)) { invocation ->
+        runProcessorTest(sources = listOf(src)) { invocation ->
             val base = invocation.processingEnv.requireTypeElement("BaseClass")
             val sub = invocation.processingEnv.requireType("SubClass")
             base.getField("normalInt").let { prop ->
@@ -77,7 +79,7 @@
             val listOfStringsTypeName =
                 ParameterizedTypeName.get(
                     List::class.className(),
-                    String::class.className()
+                    WildcardTypeName.subtypeOf(String::class.className())
                 )
             base.getField("mapOfStringToGeneric2").let { prop ->
                 assertThat(
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 a2131bd..2bd5ed4 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
@@ -156,6 +156,10 @@
                 package $pkg
                 class MyType
                 class MyGeneric<T>
+                class MyGenericIn<in T>
+                class MyGenericOut<out T>
+                class MyGenericMultipleParameters<T1: MyGeneric<*>, T2: MyGeneric<T1>>
+                typealias MyLambdaTypeAlias = (@JvmWildcard MyType) -> @JvmWildcard MyType
                 enum class MyEnum {
                     VAL1,
                     VAL2;
@@ -221,6 +225,58 @@
                         fun method11(iter: Iterable<String>): Iterable<String> = TODO()
                         fun method12(iter: Iterable<Number>): Iterable<Number> = TODO()
                         fun method13(iter: Iterable<MyType>): Iterable<MyType> = TODO()
+                        fun method14(list: List<MyLambdaTypeAlias>): MyLambdaTypeAlias = TODO()
+                        fun method15(
+                            list: List<MyGenericMultipleParameters<*, *>>
+                        ): List<MyGenericMultipleParameters<*, *>> = TODO()
+                        fun method16(
+                            param: MyGenericIn<MyGeneric<MyGenericIn<MyGeneric<MyType>>>>
+                        ): MyGenericIn<MyGeneric<MyGenericIn<MyGeneric<MyType>>>> = TODO()
+                        fun method17(
+                            param: MyGeneric<MyGeneric<MyGenericIn<MyGeneric<MyType>>>>
+                        ): MyGeneric<MyGeneric<MyGenericIn<MyGeneric<MyType>>>> = TODO()
+                        fun method18(
+                            param: MyGeneric<in MyGeneric<MyGenericIn<MyGeneric<MyType>>>>
+                        ): MyGeneric<in MyGeneric<MyGenericIn<MyGeneric<MyType>>>> = TODO()
+                        fun method19(
+                            param: MyGeneric<out MyGeneric<MyGenericIn<MyGeneric<MyType>>>>
+                        ): MyGeneric<out MyGeneric<MyGenericIn<MyGeneric<MyType>>>> = TODO()
+                        fun method20(
+                            param: MyGeneric<MyGeneric<out MyGenericIn<MyGeneric<MyType>>>>
+                        ): MyGeneric<MyGeneric<out MyGenericIn<MyGeneric<MyType>>>> = TODO()
+                        fun method21(
+                            param: MyGeneric<MyGeneric<in MyGenericIn<MyGeneric<MyType>>>>
+                        ): MyGeneric<MyGeneric<in MyGenericIn<MyGeneric<MyType>>>> = TODO()
+                        fun method22(
+                            param: MyGenericIn<in MyGeneric<MyGenericIn<MyGeneric<MyType>>>>
+                        ): MyGenericIn<in MyGeneric<MyGenericIn<MyGeneric<MyType>>>> = TODO()
+                        fun method23(
+                            param: MyGenericIn<MyGeneric<in MyGenericIn<MyGeneric<MyType>>>>
+                        ): MyGenericIn<MyGeneric<in MyGenericIn<MyGeneric<MyType>>>> = TODO()
+                        fun method24(
+                            param: MyGenericOut<MyGeneric<MyGenericOut<MyGeneric<MyType>>>>
+                        ): MyGenericOut<MyGeneric<MyGenericOut<MyGeneric<MyType>>>> = TODO()
+                        fun method25(
+                            param: MyGeneric<MyGeneric<MyGenericOut<MyGeneric<MyType>>>>
+                        ): MyGeneric<MyGeneric<MyGenericOut<MyGeneric<MyType>>>> = TODO()
+                        fun method26(
+                            param: MyGeneric<in MyGeneric<MyGenericOut<MyGeneric<MyType>>>>
+                        ): MyGeneric<in MyGeneric<MyGenericOut<MyGeneric<MyType>>>> = TODO()
+                        fun method27(
+                            param: MyGeneric<out MyGeneric<MyGenericOut<MyGeneric<MyType>>>>
+                        ): MyGeneric<out MyGeneric<MyGenericOut<MyGeneric<MyType>>>> = TODO()
+                        fun method28(
+                            param: MyGeneric<MyGeneric<out MyGenericOut<MyGeneric<MyType>>>>
+                        ): MyGeneric<MyGeneric<out MyGenericOut<MyGeneric<MyType>>>> = TODO()
+                        fun method29(
+                            param: MyGeneric<MyGeneric<in MyGenericOut<MyGeneric<MyType>>>>
+                        ): MyGeneric<MyGeneric<in MyGenericOut<MyGeneric<MyType>>>> = TODO()
+                        fun method30(
+                            param: MyGenericOut<out MyGeneric<MyGenericOut<MyGeneric<MyType>>>>
+                        ): MyGenericOut<out MyGeneric<MyGenericOut<MyGeneric<MyType>>>> = TODO()
+                        fun method31(
+                            param: MyGenericOut<MyGeneric<out MyGenericOut<MyGeneric<MyType>>>>
+                        ): MyGenericOut<MyGeneric<out MyGenericOut<MyGeneric<MyType>>>> = TODO()
                     }
                 """.trimIndent()
             ), listOf("Subject")
@@ -284,7 +340,7 @@
                     sealedListParent: List<GrandParentSealed.Parent1>,
                     sealedListChild: List<GrandParentSealed.Parent2.Child1>,
                     jvmWildcard: List<@JvmWildcard String>,
-                    suppressJvmWildcard: List<@JvmSuppressWildcards Number>
+                    suppressJvmWildcard: List<@JvmSuppressWildcards Number>,
                 ) {
                     var propWithFinalType: String = ""
                     var propWithOpenType: Number = 3
@@ -305,14 +361,18 @@
                     fun listSealedListGrandParent(list: List<GrandParentSealed>): List<GrandParentSealed> { TODO() }
                     fun listSealedListParent(list: List<GrandParentSealed.Parent1>): List<GrandParentSealed.Parent1> { TODO() }
                     fun listSealedListChild(list: List<GrandParentSealed.Parent2.Child1>): List<GrandParentSealed.Parent2.Child1> { TODO() }
+                    fun explicitOutOnInvariant_onType1(
+                        list: MyGeneric<out MyGeneric<MyType>>
+                    ): MyGeneric<out MyGeneric<MyType>> { TODO() }
+                    fun explicitOutOnInvariant_onType2(
+                        list: MyGeneric<MyGeneric<out MyType>>
+                    ): MyGeneric<MyGeneric<out MyType>> { TODO() }
                     fun explicitJvmWildcard(
                         list: List<@JvmWildcard String>
                     ): List<@JvmWildcard String> { TODO() }
-
                     fun explicitJvmSuppressWildcard_OnType(
                         list: List<@JvmSuppressWildcards Number>
                     ): List<@JvmSuppressWildcards Number> { TODO() }
-
                     fun explicitJvmSuppressWildcard_OnType2(
                         list: @JvmSuppressWildcards List<Number>
                     ): @JvmSuppressWildcards List<Number> { TODO() }
@@ -327,11 +387,9 @@
                     fun suspendExplicitJvmWildcard(
                         list: List<@JvmWildcard String>
                     ): List<@JvmWildcard String> { TODO() }
-
                     fun suspendExplicitJvmSuppressWildcard_OnType(
                         list: List<@JvmSuppressWildcards Number>
                     ): List<@JvmSuppressWildcards Number> { TODO() }
-
                     fun suspendExplicitJvmSuppressWildcard_OnType2(
                         list: @JvmSuppressWildcards List<Number>
                     ): @JvmSuppressWildcards List<Number> { TODO() }
diff --git a/room/room-migration/api/restricted_current.ignore b/room/room-migration/api/restricted_current.ignore
new file mode 100644
index 0000000..1e1b7dd
--- /dev/null
+++ b/room/room-migration/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.room.migration.bundle.SchemaEquality#isSchemaEqual(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter other in androidx.room.migration.bundle.SchemaEquality.isSchemaEqual(T other)
diff --git a/room/room-migration/api/restricted_current.txt b/room/room-migration/api/restricted_current.txt
index 8c3e714..1c948b9 100644
--- a/room/room-migration/api/restricted_current.txt
+++ b/room/room-migration/api/restricted_current.txt
@@ -187,7 +187,7 @@
   }
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface SchemaEquality<T> {
-    method public boolean isSchemaEqual(T? other);
+    method public boolean isSchemaEqual(T other);
   }
 
 }
diff --git a/room/room-runtime/api/current.txt b/room/room-runtime/api/current.txt
index 883d5f0..316622e 100644
--- a/room/room-runtime/api/current.txt
+++ b/room/room-runtime/api/current.txt
@@ -69,7 +69,7 @@
     method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query, optional android.os.CancellationSignal? signal);
     method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query);
     method public void runInTransaction(Runnable body);
-    method public <V> V! runInTransaction(java.util.concurrent.Callable<V> body);
+    method public <V> V runInTransaction(java.util.concurrent.Callable<V> body);
     method @Deprecated public void setTransactionSuccessful();
     property public androidx.room.InvalidationTracker invalidationTracker;
     property public boolean isOpen;
diff --git a/room/room-runtime/api/public_plus_experimental_current.txt b/room/room-runtime/api/public_plus_experimental_current.txt
index 5a5ebdf..5c47de6 100644
--- a/room/room-runtime/api/public_plus_experimental_current.txt
+++ b/room/room-runtime/api/public_plus_experimental_current.txt
@@ -77,7 +77,7 @@
     method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query, optional android.os.CancellationSignal? signal);
     method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query);
     method public void runInTransaction(Runnable body);
-    method public <V> V! runInTransaction(java.util.concurrent.Callable<V> body);
+    method public <V> V runInTransaction(java.util.concurrent.Callable<V> body);
     method @Deprecated public void setTransactionSuccessful();
     property public androidx.room.InvalidationTracker invalidationTracker;
     property public boolean isOpen;
diff --git a/room/room-runtime/api/restricted_current.ignore b/room/room-runtime/api/restricted_current.ignore
index bb7df6a..9a2cd17 100644
--- a/room/room-runtime/api/restricted_current.ignore
+++ b/room/room-runtime/api/restricted_current.ignore
@@ -1,6 +1,20 @@
 // Baseline format: 1.0
+InvalidNullConversion: androidx.room.EntityDeletionOrUpdateAdapter#bind(androidx.sqlite.db.SupportSQLiteStatement, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter entity in androidx.room.EntityDeletionOrUpdateAdapter.bind(androidx.sqlite.db.SupportSQLiteStatement statement, T entity)
+InvalidNullConversion: androidx.room.EntityDeletionOrUpdateAdapter#handle(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter entity in androidx.room.EntityDeletionOrUpdateAdapter.handle(T entity)
 InvalidNullConversion: androidx.room.EntityInsertionAdapter#bind(androidx.sqlite.db.SupportSQLiteStatement, T) parameter #0:
     Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter statement in androidx.room.EntityInsertionAdapter.bind(androidx.sqlite.db.SupportSQLiteStatement statement, T entity)
+InvalidNullConversion: androidx.room.EntityInsertionAdapter#bind(androidx.sqlite.db.SupportSQLiteStatement, T) parameter #1:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter entity in androidx.room.EntityInsertionAdapter.bind(androidx.sqlite.db.SupportSQLiteStatement statement, T entity)
+InvalidNullConversion: androidx.room.EntityInsertionAdapter#insert(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter entity in androidx.room.EntityInsertionAdapter.insert(T entity)
+InvalidNullConversion: androidx.room.EntityInsertionAdapter#insertAndReturnId(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter entity in androidx.room.EntityInsertionAdapter.insertAndReturnId(T entity)
+InvalidNullConversion: androidx.room.EntityUpsertionAdapter#upsert(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter entity in androidx.room.EntityUpsertionAdapter.upsert(T entity)
+InvalidNullConversion: androidx.room.EntityUpsertionAdapter#upsertAndReturnId(T) parameter #0:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter entity in androidx.room.EntityUpsertionAdapter.upsertAndReturnId(T entity)
 
 
 ParameterNameChange: androidx.room.RoomDatabase.JournalMode#valueOf(String) parameter #0:
diff --git a/room/room-runtime/api/restricted_current.txt b/room/room-runtime/api/restricted_current.txt
index 760ce8c..db80a4c 100644
--- a/room/room-runtime/api/restricted_current.txt
+++ b/room/room-runtime/api/restricted_current.txt
@@ -35,19 +35,19 @@
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class EntityDeletionOrUpdateAdapter<T> extends androidx.room.SharedSQLiteStatement {
     ctor public EntityDeletionOrUpdateAdapter(androidx.room.RoomDatabase database);
-    method protected abstract void bind(androidx.sqlite.db.SupportSQLiteStatement statement, T? entity);
-    method public final int handle(T? entity);
+    method protected abstract void bind(androidx.sqlite.db.SupportSQLiteStatement statement, T entity);
+    method public final int handle(T entity);
     method public final int handleMultiple(Iterable<? extends T> entities);
     method public final int handleMultiple(T![] entities);
   }
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class EntityInsertionAdapter<T> extends androidx.room.SharedSQLiteStatement {
     ctor public EntityInsertionAdapter(androidx.room.RoomDatabase database);
-    method protected abstract void bind(androidx.sqlite.db.SupportSQLiteStatement statement, T? entity);
-    method public final void insert(T? entity);
+    method protected abstract void bind(androidx.sqlite.db.SupportSQLiteStatement statement, T entity);
+    method public final void insert(T entity);
     method public final void insert(T![] entities);
     method public final void insert(Iterable<? extends T> entities);
-    method public final long insertAndReturnId(T? entity);
+    method public final long insertAndReturnId(T entity);
     method public final long[] insertAndReturnIdsArray(java.util.Collection<? extends T> entities);
     method public final long[] insertAndReturnIdsArray(T![] entities);
     method public final Long![] insertAndReturnIdsArrayBox(java.util.Collection<? extends T> entities);
@@ -58,10 +58,10 @@
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class EntityUpsertionAdapter<T> {
     ctor public EntityUpsertionAdapter(androidx.room.EntityInsertionAdapter<T> insertionAdapter, androidx.room.EntityDeletionOrUpdateAdapter<T> updateAdapter);
-    method public void upsert(T? entity);
+    method public void upsert(T entity);
     method public void upsert(T![] entities);
     method public void upsert(Iterable<? extends T> entities);
-    method public long upsertAndReturnId(T? entity);
+    method public long upsertAndReturnId(T entity);
     method public long[] upsertAndReturnIdsArray(T![] entities);
     method public long[] upsertAndReturnIdsArray(java.util.Collection<? extends T> entities);
     method public Long![] upsertAndReturnIdsArrayBox(T![] entities);
@@ -122,7 +122,7 @@
     method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query, optional android.os.CancellationSignal? signal);
     method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query);
     method public void runInTransaction(Runnable body);
-    method public <V> V! runInTransaction(java.util.concurrent.Callable<V> body);
+    method public <V> V runInTransaction(java.util.concurrent.Callable<V> body);
     method @Deprecated public void setTransactionSuccessful();
     property public androidx.room.InvalidationTracker invalidationTracker;
     property public boolean isOpen;
@@ -305,7 +305,7 @@
     method public static android.database.Cursor copyAndClose(android.database.Cursor c);
     method public static int getColumnIndex(android.database.Cursor c, String name);
     method public static int getColumnIndexOrThrow(android.database.Cursor c, String name);
-    method public static inline <R> R! useCursor(android.database.Cursor, kotlin.jvm.functions.Function1<? super android.database.Cursor,? extends R> block);
+    method public static inline <R> R useCursor(android.database.Cursor, kotlin.jvm.functions.Function1<? super android.database.Cursor,? extends R> block);
     method public static android.database.Cursor wrapMappedColumns(android.database.Cursor cursor, String![] columnNames, int[] mapping);
   }
 
diff --git a/settings.gradle b/settings.gradle
index f69f595..1a50a33 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -2,6 +2,9 @@
 import androidx.build.gradle.gcpbuildcache.GcpBuildCache
 import androidx.build.gradle.gcpbuildcache.GcpBuildCacheServiceFactory
 
+import java.util.regex.Matcher
+import java.util.regex.Pattern
+
 pluginManagement {
     repositories {
         maven {
@@ -303,6 +306,22 @@
     includeProject(name, null, filter)
 }
 
+// A map of project path to a set of project paths referenced directly by this project.
+@Field Map<String, Set<String>> projectReferences = new HashMap<String, Set<String>>()
+
+// A map of all project paths to their project directory.
+@Field Map<String, File> allProjects = new HashMap<String, File>()
+// A set of projects that the user asked to filter to.
+@Field Set<String> filteredProjects = new HashSet<String>()
+
+@Field Pattern projectReferencePattern = Pattern.compile(
+        "(project|projectOrArtifact)\\((path: )?[\"'](?<name>\\S*)[\"'](, configuration: .*)?\\)"
+)
+@Field Pattern inspection = Pattern.compile("packageInspector\\(project, \"(.*)\"\\)")
+@Field Pattern composePlugin = Pattern.compile("id\\(\"AndroidXComposePlugin\"\\)")
+@Field Pattern paparazziPlugin = Pattern.compile("id\\(\"AndroidXPaparazziPlugin\"\\)")
+@Field Pattern iconGenerator = Pattern.compile("IconGenerationTask\\.register")
+
 // Calling includeProject(name, filePath) is shorthand for:
 //
 //   include(name)
@@ -313,9 +332,7 @@
 //   the Maven artifactId
 //
 def includeProject(name, filePath, List<BuildType> filter = []) {
-    if (!shouldIncludeForFilter(filter)) return
-    settings.include(name)
-
+    if (shouldIncludeForFilter(filter)) filteredProjects.add(name)
     def file
     if (filePath != null) {
         if (filePath instanceof String) {
@@ -326,9 +343,35 @@
         } else {
             file = filePath
         }
-        project(name).projectDir = file
     } else {
-        file = project(name).projectDir
+        file = new File(rootDir, name.substring(1).replace(":", "/"))
+    }
+    allProjects[name] = file
+    File buildGradle = new File(file, "build.gradle")
+    if (buildGradle.exists()) {
+        Set<String> links = new HashSet<String>()
+        for (line in buildGradle.readLines()) {
+            Matcher m = projectReferencePattern.matcher(line)
+            if (m.find()) {
+                links.add(m.group("name"))
+            }
+            Matcher matcherInspection = inspection.matcher(line)
+            if (matcherInspection) {
+                links.add(matcherInspection.group(1))
+            }
+            if (composePlugin.matcher(line).find()) {
+                links.add(":compose:compiler:compiler")
+                links.add(":compose:lint:internal-lint-checks")
+            }
+            if (paparazziPlugin.matcher(line).find()) {
+                links.add(":test:screenshot:screenshot-proto")
+                links.add(":internal-testutils-paparazzi")
+            }
+            if (iconGenerator.matcher(line).find()) {
+                links.add(":compose:material:material:icons:generator")
+            }
+        }
+        projectReferences[name] = links
     }
     if (!file.exists()) {
         // This option is supported so that development/simplify_build_failure.sh can try
@@ -426,7 +469,6 @@
     includeProject(":buildSrc-tests:max-dep-versions:buildSrc-tests-max-dep-versions-dep", [BuildType.MAIN])
     includeProject(":buildSrc-tests:max-dep-versions:buildSrc-tests-max-dep-versions-main", [BuildType.MAIN])
 }
-includeProject(":buildSrc-tests:project-subsets", [BuildType.MAIN])
 includeProject(":camera:camera-camera2", [BuildType.CAMERA])
 includeProject(":camera:camera-camera2-pipe", [BuildType.CAMERA])
 includeProject(":camera:camera-camera2-pipe-integration", [BuildType.CAMERA])
@@ -567,7 +609,7 @@
 includeProject(":compose:ui:ui-graphics", [BuildType.COMPOSE])
 includeProject(":compose:ui:ui-graphics-lint", [BuildType.COMPOSE])
 includeProject(":compose:ui:ui-graphics:ui-graphics-benchmark", "compose/ui/ui-graphics/benchmark", [BuildType.COMPOSE])
-includeProject(":compose:ui:ui-graphics:ui-graphics-benchmark:test", [BuildType.COMPOSE])
+includeProject(":compose:ui:ui-graphics:ui-graphics-benchmark:test", "compose/ui/ui-graphics/benchmark/test", [BuildType.COMPOSE])
 includeProject(":compose:ui:ui-graphics:ui-graphics-samples", "compose/ui/ui-graphics/samples", [BuildType.COMPOSE])
 includeProject(":compose:ui:ui-inspection", [BuildType.COMPOSE])
 includeProject(":compose:ui:ui-lint", [BuildType.COMPOSE])
@@ -680,6 +722,7 @@
 includeProject(":glance:glance-appwidget", [BuildType.GLANCE])
 includeProject(":glance:glance-appwidget-preview", [BuildType.GLANCE])
 includeProject(":glance:glance-appwidget-proto", [BuildType.GLANCE])
+includeProject(":glance:glance-appwidget:glance-appwidget-samples", "glance/glance-appwidget/samples", [BuildType.GLANCE])
 includeProject(":glance:glance-appwidget:integration-tests:demos", [BuildType.GLANCE])
 includeProject(":glance:glance-appwidget:integration-tests:macrobenchmark", [BuildType.GLANCE])
 includeProject(":glance:glance-appwidget:integration-tests:macrobenchmark-target", [BuildType.GLANCE])
@@ -1127,3 +1170,20 @@
 
 // Workaround for b/203825166
 includeBuild("placeholder")
+
+// For a given project path add the transitive project references to the include set.
+void addReferences(String projectPath, Set<String> included) {
+    if (projectPath in included) return
+    included.add(projectPath)
+    for (reference in projectReferences[projectPath]) {
+        addReferences(reference, included)
+    }
+}
+Set<String> projectsToInclude = new HashSet<>()
+for (filteredProject in filteredProjects) {
+    addReferences(filteredProject, projectsToInclude)
+}
+for (entry in projectsToInclude) {
+    settings.include(entry)
+    project(entry).projectDir = allProjects[entry]
+}
diff --git a/sqlite/sqlite-ktx/api/current.txt b/sqlite/sqlite-ktx/api/current.txt
index 26086b4..3b12c09 100644
--- a/sqlite/sqlite-ktx/api/current.txt
+++ b/sqlite/sqlite-ktx/api/current.txt
@@ -2,7 +2,7 @@
 package androidx.sqlite.db {
 
   public final class SupportSQLiteDatabaseKt {
-    method public static inline <T> T! transaction(androidx.sqlite.db.SupportSQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,? extends T> body);
+    method public static inline <T> T transaction(androidx.sqlite.db.SupportSQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,? extends T> body);
   }
 
 }
diff --git a/sqlite/sqlite-ktx/api/public_plus_experimental_current.txt b/sqlite/sqlite-ktx/api/public_plus_experimental_current.txt
index 26086b4..3b12c09 100644
--- a/sqlite/sqlite-ktx/api/public_plus_experimental_current.txt
+++ b/sqlite/sqlite-ktx/api/public_plus_experimental_current.txt
@@ -2,7 +2,7 @@
 package androidx.sqlite.db {
 
   public final class SupportSQLiteDatabaseKt {
-    method public static inline <T> T! transaction(androidx.sqlite.db.SupportSQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,? extends T> body);
+    method public static inline <T> T transaction(androidx.sqlite.db.SupportSQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,? extends T> body);
   }
 
 }
diff --git a/sqlite/sqlite-ktx/api/restricted_current.txt b/sqlite/sqlite-ktx/api/restricted_current.txt
index 26086b4..3b12c09 100644
--- a/sqlite/sqlite-ktx/api/restricted_current.txt
+++ b/sqlite/sqlite-ktx/api/restricted_current.txt
@@ -2,7 +2,7 @@
 package androidx.sqlite.db {
 
   public final class SupportSQLiteDatabaseKt {
-    method public static inline <T> T! transaction(androidx.sqlite.db.SupportSQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,? extends T> body);
+    method public static inline <T> T transaction(androidx.sqlite.db.SupportSQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,? extends T> body);
   }
 
 }
diff --git a/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/ComparableSubject.kt b/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/ComparableSubject.kt
index 846f838..9d1ac4b 100644
--- a/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/ComparableSubject.kt
+++ b/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/ComparableSubject.kt
@@ -37,4 +37,17 @@
             fail("Expected to be less than $other, but was $actual")
         }
     }
+
+    /**
+     * Checks that the subject is greater than or equal to [other].
+     *
+     * @throws NullPointerException if [actual] or [other] is `null`.
+     */
+    fun isAtLeast(other: T?) {
+        requireNonNull(actual) { "Expected to be at least $other, but was $actual" }
+        requireNonNull(other) { "Expected to be at least $other, but was $actual" }
+        if (actual < other) {
+            fail("Expected to be at least $other, but was $actual")
+        }
+    }
 }
\ No newline at end of file
diff --git a/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/ComparableSubjectTest.kt b/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/ComparableSubjectTest.kt
index b37c5d5..548e729 100644
--- a/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/ComparableSubjectTest.kt
+++ b/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/ComparableSubjectTest.kt
@@ -35,6 +35,9 @@
         assertFailsWith<NullPointerException> {
             assertThat(6).isLessThan(null)
         }
+        assertFailsWith<NullPointerException> {
+            assertThat(6).isAtLeast(null)
+        }
     }
 
     @Test
@@ -52,16 +55,31 @@
         }
     }
 
+    @Test
+    fun isAtLeast() {
+        assertThat(4).isAtLeast(3)
+        assertThat(4).isAtLeast(4)
+        assertFailsWith<AssertionError> {
+            assertThat(4).isAtLeast(5)
+        }
+    }
+
     // Brief tests with other comparable types (no negative test cases)
 
     @Test
     fun longs() {
         assertThat(4L).isLessThan(5L)
+
+        assertThat(4L).isAtLeast(4L)
+        assertThat(4L).isAtLeast(3L)
     }
 
     @Test
     fun strings() {
         assertThat("gak").isLessThan("kak")
+
+        assertThat("kak").isAtLeast("kak")
+        assertThat("kak").isAtLeast("gak")
     }
 
     @Test
diff --git a/testutils/testutils-paging/src/main/java/androidx/paging/TestPagingDataDiffer.kt b/testutils/testutils-paging/src/main/java/androidx/paging/TestPagingDataDiffer.kt
index aecc829..dc0d267 100644
--- a/testutils/testutils-paging/src/main/java/androidx/paging/TestPagingDataDiffer.kt
+++ b/testutils/testutils-paging/src/main/java/androidx/paging/TestPagingDataDiffer.kt
@@ -16,11 +16,11 @@
 
 package androidx.paging
 
-import kotlinx.coroutines.CoroutineDispatcher
+import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.Dispatchers
 
-class TestPagingDataDiffer<T : Any>(mainDispatcher: CoroutineDispatcher = Dispatchers.Main) :
-    PagingDataDiffer<T>(noopDifferCallback, mainDispatcher) {
+class TestPagingDataDiffer<T : Any>(mainContext: CoroutineContext = Dispatchers.Main) :
+    PagingDataDiffer<T>(noopDifferCallback, mainContext) {
 
     val currentList: List<T> get() = List(size) { i -> get(i)!! }
 
diff --git a/tracing/tracing-ktx/api/1.2.0-beta04.txt b/tracing/tracing-ktx/api/1.2.0-beta04.txt
index 13d99d1..c866186 100644
--- a/tracing/tracing-ktx/api/1.2.0-beta04.txt
+++ b/tracing/tracing-ktx/api/1.2.0-beta04.txt
@@ -2,10 +2,10 @@
 package androidx.tracing {
 
   public final class TraceKt {
-    method public static inline <T> T! trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
-    method public static inline <T> T! trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
     method public static suspend inline <T> Object? traceAsync(String methodName, int cookie, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static inline <T> T! traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
   }
 
 }
diff --git a/tracing/tracing-ktx/api/current.txt b/tracing/tracing-ktx/api/current.txt
index 13d99d1..c866186 100644
--- a/tracing/tracing-ktx/api/current.txt
+++ b/tracing/tracing-ktx/api/current.txt
@@ -2,10 +2,10 @@
 package androidx.tracing {
 
   public final class TraceKt {
-    method public static inline <T> T! trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
-    method public static inline <T> T! trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
     method public static suspend inline <T> Object? traceAsync(String methodName, int cookie, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static inline <T> T! traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
   }
 
 }
diff --git a/tracing/tracing-ktx/api/public_plus_experimental_1.2.0-beta04.txt b/tracing/tracing-ktx/api/public_plus_experimental_1.2.0-beta04.txt
index 13d99d1..c866186 100644
--- a/tracing/tracing-ktx/api/public_plus_experimental_1.2.0-beta04.txt
+++ b/tracing/tracing-ktx/api/public_plus_experimental_1.2.0-beta04.txt
@@ -2,10 +2,10 @@
 package androidx.tracing {
 
   public final class TraceKt {
-    method public static inline <T> T! trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
-    method public static inline <T> T! trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
     method public static suspend inline <T> Object? traceAsync(String methodName, int cookie, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static inline <T> T! traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
   }
 
 }
diff --git a/tracing/tracing-ktx/api/public_plus_experimental_current.txt b/tracing/tracing-ktx/api/public_plus_experimental_current.txt
index 13d99d1..c866186 100644
--- a/tracing/tracing-ktx/api/public_plus_experimental_current.txt
+++ b/tracing/tracing-ktx/api/public_plus_experimental_current.txt
@@ -2,10 +2,10 @@
 package androidx.tracing {
 
   public final class TraceKt {
-    method public static inline <T> T! trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
-    method public static inline <T> T! trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
     method public static suspend inline <T> Object? traceAsync(String methodName, int cookie, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static inline <T> T! traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
   }
 
 }
diff --git a/tracing/tracing-ktx/api/restricted_1.2.0-beta04.txt b/tracing/tracing-ktx/api/restricted_1.2.0-beta04.txt
index 13d99d1..c866186 100644
--- a/tracing/tracing-ktx/api/restricted_1.2.0-beta04.txt
+++ b/tracing/tracing-ktx/api/restricted_1.2.0-beta04.txt
@@ -2,10 +2,10 @@
 package androidx.tracing {
 
   public final class TraceKt {
-    method public static inline <T> T! trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
-    method public static inline <T> T! trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
     method public static suspend inline <T> Object? traceAsync(String methodName, int cookie, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static inline <T> T! traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
   }
 
 }
diff --git a/tracing/tracing-ktx/api/restricted_current.txt b/tracing/tracing-ktx/api/restricted_current.txt
index 13d99d1..c866186 100644
--- a/tracing/tracing-ktx/api/restricted_current.txt
+++ b/tracing/tracing-ktx/api/restricted_current.txt
@@ -2,10 +2,10 @@
 package androidx.tracing {
 
   public final class TraceKt {
-    method public static inline <T> T! trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
-    method public static inline <T> T! trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
     method public static suspend inline <T> Object? traceAsync(String methodName, int cookie, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static inline <T> T! traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
+    method public static inline <T> T traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
   }
 
 }
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 29b1866..7ecfec8 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
@@ -18,10 +18,16 @@
 
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.onFocusChanged
 import androidx.compose.ui.graphics.Color
 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
 
@@ -30,19 +36,29 @@
 
 @Composable
 fun LazyRowsAndColumns() {
-    TvLazyColumn(verticalArrangement = Arrangement.spacedBy(20.dp)) {
-        items(rowsCount) { SampleLazyRow() }
+    var pivotOffset by remember { mutableStateOf(PivotOffsets()) }
+    TvLazyColumn(
+        pivotOffsets = pivotOffset,
+        verticalArrangement = Arrangement.spacedBy(20.dp)
+    ) {
+        items(rowsCount) { rowIndex ->
+            SampleLazyRow(Modifier.onFocusChanged {
+                if (it.hasFocus) {
+                    pivotOffset = if (rowIndex == 2) PivotOffsets(0f) else PivotOffsets()
+                }
+            })
+        }
     }
 }
 
 @OptIn(ExperimentalTvFoundationApi::class)
 @Composable
-fun SampleLazyRow() {
+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() }
 
     FocusGroup {
-        TvLazyRow(horizontalArrangement = Arrangement.spacedBy(10.dp)) {
+        TvLazyRow(modifier, horizontalArrangement = Arrangement.spacedBy(10.dp)) {
             backgroundColors.forEachIndexed { index, backgroundColor ->
                 item {
                     Card(
diff --git a/tv/tv-foundation/api/api_lint.ignore b/tv/tv-foundation/api/api_lint.ignore
new file mode 100644
index 0000000..599cbcc
--- /dev/null
+++ b/tv/tv-foundation/api/api_lint.ignore
@@ -0,0 +1,13 @@
+// Baseline format: 1.0
+GetterSetterNames: androidx.tv.foundation.lazy.grid.TvLazyGridState#getCanScrollBackward():
+    Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.tv.foundation.lazy.grid.TvLazyGridState#getCanScrollForward():
+    Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.tv.foundation.lazy.list.TvLazyListState#getCanScrollBackward():
+    Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.tv.foundation.lazy.list.TvLazyListState#getCanScrollForward():
+    Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field TvLazyGridLayoutInfo.reverseLayout:
+    Invalid name for boolean property `reverseLayout`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field TvLazyListLayoutInfo.reverseLayout:
+    Invalid name for boolean property `reverseLayout`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListTest.kt
index cec085f..51f87fd 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListTest.kt
@@ -84,7 +84,6 @@
 import java.util.concurrent.CountDownLatch
 import kotlin.math.roundToInt
 import kotlinx.coroutines.runBlocking
-import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
@@ -813,7 +812,6 @@
         }
     }
 
-    @Ignore // b/268211857
     @Test
     fun scroll_makeListSmaller_scroll() {
         var items by mutableStateOf((1..100).toList())
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/ScrollableWithPivot.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/ScrollableWithPivot.kt
index 9d7df7f..635441e 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/ScrollableWithPivot.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/ScrollableWithPivot.kt
@@ -79,7 +79,7 @@
     factory = {
         val coroutineScope = rememberCoroutineScope()
         val keepFocusedChildInViewModifier =
-            remember(coroutineScope, orientation, state, reverseDirection) {
+            remember(coroutineScope, orientation, state, reverseDirection, pivotOffsets) {
                 ContentInViewModifier(
                     coroutineScope, orientation, state, reverseDirection, pivotOffsets)
             }
diff --git a/tv/tv-material/api/public_plus_experimental_current.txt b/tv/tv-material/api/public_plus_experimental_current.txt
index 3f5fc27..bebfaef 100644
--- a/tv/tv-material/api/public_plus_experimental_current.txt
+++ b/tv/tv-material/api/public_plus_experimental_current.txt
@@ -18,12 +18,6 @@
     property public final androidx.tv.material3.Border None;
   }
 
-  @androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class BorderIndication implements androidx.compose.foundation.Indication {
-    ctor public BorderIndication(androidx.compose.ui.graphics.Brush brush, float width, androidx.compose.ui.graphics.Shape shape, optional float inset);
-    ctor public BorderIndication(androidx.tv.material3.Border border);
-    method @androidx.compose.runtime.Composable public androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.interaction.InteractionSource interactionSource);
-  }
-
   @androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class ButtonBorder {
   }
 
@@ -147,6 +141,19 @@
     property public final int activeItemIndex;
   }
 
+  @androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class CheckboxColors {
+  }
+
+  @androidx.tv.material3.ExperimentalTvMaterial3Api public final class CheckboxDefaults {
+    method @androidx.compose.runtime.Composable public androidx.tv.material3.CheckboxColors colors(optional long checkedColor, optional long uncheckedColor, optional long checkmarkColor, optional long disabledCheckedColor, optional long disabledUncheckedColor, optional long disabledIndeterminateColor);
+    field public static final androidx.tv.material3.CheckboxDefaults INSTANCE;
+  }
+
+  public final class CheckboxKt {
+    method @androidx.compose.runtime.Composable @androidx.tv.material3.ExperimentalTvMaterial3Api 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.tv.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable @androidx.tv.material3.ExperimentalTvMaterial3Api 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.tv.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
   @androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class ClickableSurfaceBorder {
   }
 
@@ -292,11 +299,6 @@
     property public final androidx.tv.material3.Glow None;
   }
 
-  @androidx.compose.runtime.Stable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class GlowIndication implements androidx.compose.foundation.Indication {
-    ctor public GlowIndication(long color, androidx.compose.ui.graphics.Shape shape, float glowBlurRadius, float offsetX, float offsetY);
-    method @androidx.compose.runtime.Composable public androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.interaction.InteractionSource interactionSource);
-  }
-
   @androidx.tv.material3.ExperimentalTvMaterial3Api public final class IconButtonDefaults {
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.ButtonBorder border(optional androidx.tv.material3.Border border, optional androidx.tv.material3.Border focusedBorder, optional androidx.tv.material3.Border pressedBorder, optional androidx.tv.material3.Border disabledBorder, optional androidx.tv.material3.Border focusedDisabledBorder);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.ButtonColors colors(optional long containerColor, optional long contentColor, optional long focusedContainerColor, optional long focusedContentColor, optional long pressedContainerColor, optional long pressedContentColor, optional long disabledContainerColor, optional long disabledContentColor);
@@ -350,10 +352,6 @@
     method public androidx.compose.ui.Modifier immersiveListItem(androidx.compose.ui.Modifier, int index);
   }
 
-  public final class IndicationsKt {
-    method @androidx.compose.runtime.Composable @androidx.tv.material3.ExperimentalTvMaterial3Api public static androidx.tv.material3.GlowIndication rememberGlowIndication(optional long color, optional androidx.compose.ui.graphics.Shape shape, optional float glowBlurRadius, optional float offsetX, optional float offsetY);
-  }
-
   public final class MaterialTheme {
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.ColorScheme getColorScheme();
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.Shapes getShapes();
@@ -412,11 +410,6 @@
     field public static final androidx.tv.material3.OutlinedIconButtonDefaults INSTANCE;
   }
 
-  @androidx.compose.runtime.Stable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class ScaleIndication implements androidx.compose.foundation.Indication {
-    ctor public ScaleIndication(float scale);
-    method @androidx.compose.runtime.Composable public androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.interaction.InteractionSource interactionSource);
-  }
-
   @androidx.tv.material3.ExperimentalTvMaterial3Api public sealed interface ScrollPauseHandle {
     method public void resumeAutoScroll();
   }
diff --git a/tv/tv-material/src/androidTest/java/androidx/tv/material3/CheckboxScreenshotTest.kt b/tv/tv-material/src/androidTest/java/androidx/tv/material3/CheckboxScreenshotTest.kt
new file mode 100644
index 0000000..0b5378e
--- /dev/null
+++ b/tv/tv-material/src/androidTest/java/androidx/tv/material3/CheckboxScreenshotTest.kt
@@ -0,0 +1,289 @@
+/*
+ * 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.material3
+
+import android.os.Build
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.testutils.assertAgainstGolden
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.input.InputMode
+import androidx.compose.ui.input.InputModeManager
+import androidx.compose.ui.input.key.Key
+import androidx.compose.ui.platform.LocalInputModeManager
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.state.ToggleableState
+import androidx.compose.ui.test.ExperimentalTestApi
+import androidx.compose.ui.test.captureToImage
+import androidx.compose.ui.test.isToggleable
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.performKeyInput
+import androidx.compose.ui.test.performMouseInput
+import androidx.compose.ui.test.pressKey
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.screenshot.AndroidXScreenshotTestRule
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+@MediumTest
+@RunWith(Parameterized::class)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+@OptIn(ExperimentalTestApi::class, ExperimentalTvMaterial3Api::class)
+class CheckboxScreenshotTest(private val scheme: ColorSchemeWrapper) {
+
+    @get:Rule
+    val rule = createComposeRule()
+
+    @get:Rule
+    val screenshotRule = AndroidXScreenshotTestRule(TV_GOLDEN_MATERIAL3)
+
+    val wrap = Modifier.wrapContentSize(Alignment.TopStart)
+
+    private val wrapperTestTag = "checkboxWrapper"
+
+    @Test
+    fun checkBox_checked() {
+        rule.setMaterialContent(scheme.colorScheme) {
+            Box(wrap.testTag(wrapperTestTag)) {
+                Checkbox(checked = true, onCheckedChange = { })
+            }
+        }
+        assertToggeableAgainstGolden("checkBox_${scheme.name}_checked")
+    }
+
+    @Test
+    fun checkBox_unchecked() {
+        rule.setMaterialContent(scheme.colorScheme) {
+            Box(wrap.testTag(wrapperTestTag)) {
+                Checkbox(modifier = wrap, checked = false, onCheckedChange = { })
+            }
+        }
+        assertToggeableAgainstGolden("checkBox_${scheme.name}_unchecked")
+    }
+
+    @Test
+    fun checkBox_pressed() {
+        rule.setMaterialContent(scheme.colorScheme) {
+            Box(wrap.testTag(wrapperTestTag)) {
+                Checkbox(modifier = wrap, checked = false, onCheckedChange = { })
+            }
+        }
+
+        rule.mainClock.autoAdvance = false
+        rule.onNode(isToggleable())
+            .performKeyInput { pressKey(Key.DirectionCenter) }
+
+        rule.mainClock.advanceTimeByFrame()
+        rule.waitForIdle() // Wait for measure
+        rule.mainClock.advanceTimeBy(milliseconds = 200)
+
+        assertToggeableAgainstGolden("checkBox_${scheme.name}_pressed")
+    }
+
+    @Test
+    fun checkBox_indeterminate() {
+        rule.setMaterialContent(scheme.colorScheme) {
+            Box(wrap.testTag(wrapperTestTag)) {
+                TriStateCheckbox(
+                    state = ToggleableState.Indeterminate,
+                    modifier = wrap,
+                    onClick = {}
+                )
+            }
+        }
+        assertToggeableAgainstGolden("checkBox_${scheme.name}_indeterminate")
+    }
+
+    @Test
+    fun checkBox_disabled_checked() {
+        rule.setMaterialContent(scheme.colorScheme) {
+            Box(wrap.testTag(wrapperTestTag)) {
+                Checkbox(
+                    modifier = wrap,
+                    checked = true,
+                    enabled = false,
+                    onCheckedChange = { })
+            }
+        }
+        assertToggeableAgainstGolden("checkBox_${scheme.name}_disabled_checked")
+    }
+
+    @Test
+    fun checkBox_disabled_unchecked() {
+        rule.setMaterialContent(scheme.colorScheme) {
+            Box(wrap.testTag(wrapperTestTag)) {
+                Checkbox(
+                    modifier = wrap,
+                    checked = false,
+                    enabled = false,
+                    onCheckedChange = { })
+            }
+        }
+        assertToggeableAgainstGolden("checkBox_${scheme.name}_disabled_unchecked")
+    }
+
+    @Test
+    fun checkBox_disabled_indeterminate() {
+        rule.setMaterialContent(scheme.colorScheme) {
+            Box(wrap.testTag(wrapperTestTag)) {
+                TriStateCheckbox(
+                    state = ToggleableState.Indeterminate,
+                    enabled = false,
+                    modifier = wrap,
+                    onClick = {}
+                )
+            }
+        }
+        assertToggeableAgainstGolden("checkBox_${scheme.name}_disabled_indeterminate")
+    }
+
+    @Test
+    fun checkBox_unchecked_animateToChecked() {
+        val isChecked = mutableStateOf(false)
+        rule.setMaterialContent(scheme.colorScheme) {
+            Box(wrap.testTag(wrapperTestTag)) {
+                Checkbox(
+                    modifier = wrap,
+                    checked = isChecked.value,
+                    onCheckedChange = { isChecked.value = it }
+                )
+            }
+        }
+
+        rule.mainClock.autoAdvance = false
+
+        rule.runOnIdle {
+            isChecked.value = true
+        }
+
+        rule.mainClock.advanceTimeByFrame()
+        rule.waitForIdle() // Wait for measure
+        rule.mainClock.advanceTimeBy(milliseconds = 80)
+
+        assertToggeableAgainstGolden("checkBox_${scheme.name}_unchecked_animateToChecked")
+    }
+
+    @Test
+    fun checkBox_checked_animateToUnchecked() {
+        val isChecked = mutableStateOf(true)
+        rule.setMaterialContent(scheme.colorScheme) {
+            Box(wrap.testTag(wrapperTestTag)) {
+                Checkbox(
+                    modifier = wrap,
+                    checked = isChecked.value,
+                    onCheckedChange = { isChecked.value = it }
+                )
+            }
+        }
+
+        rule.mainClock.autoAdvance = false
+
+        rule.runOnIdle {
+            isChecked.value = false
+        }
+
+        rule.mainClock.advanceTimeByFrame()
+        rule.waitForIdle() // Wait for measure
+        rule.mainClock.advanceTimeBy(milliseconds = 80)
+
+        assertToggeableAgainstGolden("checkBox_${scheme.name}_checked_animateToUnchecked")
+    }
+
+    @Test
+    fun checkBox_hover() {
+        rule.setMaterialContent(scheme.colorScheme) {
+            Box(wrap.testTag(wrapperTestTag)) {
+                Checkbox(
+                    modifier = wrap,
+                    checked = true,
+                    onCheckedChange = { }
+                )
+            }
+        }
+
+        rule.onNode(isToggleable())
+            .performMouseInput { enter(center) }
+
+        rule.waitForIdle()
+
+        assertToggeableAgainstGolden("checkBox_${scheme.name}_hover")
+    }
+
+    @Test
+    fun checkBox_focus() {
+        val focusRequester = FocusRequester()
+        var localInputModeManager: InputModeManager? = null
+
+        rule.setMaterialContent(scheme.colorScheme) {
+            localInputModeManager = LocalInputModeManager.current
+            Box(wrap.testTag(wrapperTestTag)) {
+                Checkbox(
+                    modifier = wrap
+                        .focusRequester(focusRequester),
+                    checked = true,
+                    onCheckedChange = { }
+                )
+            }
+        }
+
+        rule.runOnIdle {
+            @OptIn(ExperimentalComposeUiApi::class)
+            localInputModeManager!!.requestInputMode(InputMode.Keyboard)
+            focusRequester.requestFocus()
+        }
+
+        rule.waitForIdle()
+
+        assertToggeableAgainstGolden("checkBox_${scheme.name}_focus")
+    }
+
+    private fun assertToggeableAgainstGolden(goldenName: String) {
+        // TODO: replace with find(isToggeable()) after b/157687898 is fixed
+        rule.onNodeWithTag(wrapperTestTag)
+            .captureToImage()
+            .assertAgainstGolden(screenshotRule, goldenName)
+    }
+
+    // Provide the ColorScheme and their name parameter in a ColorSchemeWrapper.
+    // This makes sure that the default method name and the initial Scuba image generated
+    // name is as expected.
+    companion object {
+        @OptIn(ExperimentalTvMaterial3Api::class)
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun parameters() = arrayOf(
+            ColorSchemeWrapper("lightTheme", lightColorScheme()),
+            ColorSchemeWrapper("darkTheme", darkColorScheme()),
+        )
+    }
+
+    @OptIn(ExperimentalTvMaterial3Api::class)
+    class ColorSchemeWrapper constructor(val name: String, val colorScheme: ColorScheme) {
+        override fun toString(): String {
+            return name
+        }
+    }
+}
diff --git a/tv/tv-material/src/androidTest/java/androidx/tv/material3/CheckboxTest.kt b/tv/tv-material/src/androidTest/java/androidx/tv/material3/CheckboxTest.kt
new file mode 100644
index 0000000..d83784a
--- /dev/null
+++ b/tv/tv-material/src/androidTest/java/androidx/tv/material3/CheckboxTest.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.tv.material3
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.SemanticsProperties
+import androidx.compose.ui.semantics.focused
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.test.SemanticsMatcher
+import androidx.compose.ui.test.assert
+import androidx.compose.ui.test.assertHasClickAction
+import androidx.compose.ui.test.assertHasNoClickAction
+import androidx.compose.ui.test.assertIsEnabled
+import androidx.compose.ui.test.assertIsOff
+import androidx.compose.ui.test.assertIsOn
+import androidx.compose.ui.test.isFocusable
+import androidx.compose.ui.test.isNotFocusable
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.performClick
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+@OptIn(ExperimentalTvMaterial3Api::class)
+class CheckboxTest {
+
+    @get:Rule
+    val rule = createComposeRule()
+
+    private val defaultTag = "checkbox"
+
+    @Test
+    fun checkBoxTest_defaultSemantics() {
+        rule.setContent {
+            LightMaterialTheme {
+                Column {
+                    Checkbox(false, {}, modifier = Modifier.testTag("checkboxUnchecked"))
+                    Checkbox(true, {}, modifier = Modifier.testTag("checkboxChecked"))
+                }
+            }
+        }
+
+        rule.onNodeWithTag("checkboxUnchecked")
+            .assert(SemanticsMatcher.expectValue(SemanticsProperties.Role, Role.Checkbox))
+            .assertIsEnabled()
+            .assertIsOff()
+
+        rule.onNodeWithTag("checkboxChecked")
+            .assert(SemanticsMatcher.expectValue(SemanticsProperties.Role, Role.Checkbox))
+            .assertIsEnabled()
+            .assertIsOn()
+    }
+
+    @Test
+    fun checkBoxTest_toggle() {
+        rule.setContent {
+            LightMaterialTheme {
+                val (checked, onCheckedChange) = remember { mutableStateOf(false) }
+                Checkbox(checked, onCheckedChange, modifier = Modifier.testTag(defaultTag))
+            }
+        }
+
+        rule.onNodeWithTag(defaultTag)
+            .assertIsOff()
+            .performClick()
+            .assertIsOn()
+    }
+
+    @Test
+    fun checkBoxTest_toggle_twice() {
+        rule.setContent {
+            LightMaterialTheme {
+                val (checked, onCheckedChange) = remember { mutableStateOf(false) }
+                Checkbox(checked, onCheckedChange, modifier = Modifier.testTag(defaultTag))
+            }
+        }
+
+        rule.onNodeWithTag(defaultTag)
+            .assertIsOff()
+            .performClick()
+            .assertIsOn()
+            .performClick()
+            .assertIsOff()
+    }
+
+    @Test
+    fun checkBoxTest_untoggleable_whenEmptyLambda() {
+        val parentTag = "parent"
+
+        rule.setContent {
+            LightMaterialTheme {
+                val (checked, _) = remember { mutableStateOf(false) }
+                Box(
+                    Modifier
+                        .semantics(mergeDescendants = true) {}
+                        .testTag(parentTag)) {
+                    Checkbox(
+                        checked,
+                        {},
+                        enabled = false,
+                        modifier = Modifier
+                            .testTag(defaultTag)
+                            .semantics { focused = true }
+                    )
+                }
+            }
+        }
+
+        rule.onNodeWithTag(defaultTag)
+            .assertHasClickAction()
+
+        // Check not merged into parent
+        rule.onNodeWithTag(parentTag)
+            .assert(isNotFocusable())
+    }
+
+    @Test
+    fun checkBoxTest_untoggleableAndMergeable_whenNullLambda() {
+        rule.setContent {
+            LightMaterialTheme {
+                val (checked, _) = remember { mutableStateOf(false) }
+                Box(
+                    Modifier
+                        .semantics(mergeDescendants = true) {}
+                        .testTag(defaultTag)) {
+                    Checkbox(
+                        checked,
+                        null,
+                        modifier = Modifier.semantics { focused = true }
+                    )
+                }
+            }
+        }
+
+        rule.onNodeWithTag(defaultTag)
+            .assertHasNoClickAction()
+            .assert(isFocusable()) // Check merged into parent
+    }
+}
\ No newline at end of file
diff --git a/tv/tv-material/src/androidTest/java/androidx/tv/material3/MaterialThemeCommon.kt b/tv/tv-material/src/androidTest/java/androidx/tv/material3/MaterialThemeCommon.kt
index 9267ce5..19df4f2 100644
--- a/tv/tv-material/src/androidTest/java/androidx/tv/material3/MaterialThemeCommon.kt
+++ b/tv/tv-material/src/androidTest/java/androidx/tv/material3/MaterialThemeCommon.kt
@@ -17,6 +17,7 @@
 package androidx.tv.material3
 
 import androidx.compose.runtime.Composable
+import androidx.compose.ui.test.junit4.ComposeContentTestRule
 
 @OptIn(ExperimentalTvMaterial3Api::class)
 @Composable
@@ -33,3 +34,21 @@
         content()
     }
 }
+
+/**
+ * Wraps Compose content in a [MaterialTheme].
+ *
+ * @param colorScheme a [ColorScheme] to provide to the theme. Usually a [lightColorScheme],
+ * [darkColorScheme], or a dynamic one
+ */
+@OptIn(ExperimentalTvMaterial3Api::class)
+fun ComposeContentTestRule.setMaterialContent(
+    colorScheme: ColorScheme,
+    content: @Composable () -> Unit
+) {
+    setContent {
+        MaterialTheme(colorScheme = colorScheme) {
+            content()
+        }
+    }
+}
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/Checkbox.kt b/tv/tv-material/src/main/java/androidx/tv/material3/Checkbox.kt
new file mode 100644
index 0000000..960df60
--- /dev/null
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/Checkbox.kt
@@ -0,0 +1,501 @@
+/*
+ * 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.material3
+
+import androidx.compose.animation.animateColorAsState
+import androidx.compose.animation.core.animateFloat
+import androidx.compose.animation.core.snap
+import androidx.compose.animation.core.spring
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.core.updateTransition
+import androidx.compose.foundation.Canvas
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.requiredSize
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.foundation.selection.triStateToggleable
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
+import androidx.compose.runtime.State
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberUpdatedState
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.CornerRadius
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Size
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Path
+import androidx.compose.ui.graphics.PathMeasure
+import androidx.compose.ui.graphics.StrokeCap
+import androidx.compose.ui.graphics.drawscope.DrawScope
+import androidx.compose.ui.graphics.drawscope.Fill
+import androidx.compose.ui.graphics.drawscope.Stroke
+import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.state.ToggleableState
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.lerp
+import androidx.tv.material3.tokens.CheckboxTokens
+import kotlin.math.floor
+import kotlin.math.max
+
+/**
+ * <a href="https://m3.material.io/components/checkbox/overview" class="external" target="_blank">Material Design checkbox</a>.
+ *
+ * Checkboxes allow users to select one or more items from a set. Checkboxes can turn an option on
+ * or off.
+ *
+ * ![Checkbox image](https://developer.android.com/images/reference/androidx/compose/material3/checkbox.png)
+ *
+ * @see [TriStateCheckbox] if you require support for an indeterminate state.
+ *
+ * @param checked whether this checkbox is checked or unchecked
+ * @param onCheckedChange called when this checkbox is clicked. If `null`, then this checkbox will
+ * not be interactable, unless something else handles its input events and updates its state.
+ * @param modifier the [Modifier] to be applied to this checkbox
+ * @param enabled controls the enabled state of this checkbox. When `false`, this component will not
+ * respond to user input, and it will appear visually disabled and disabled to accessibility
+ * services.
+ * @param colors [CheckboxColors] that will be used to resolve the colors used for this checkbox in
+ * different states. See [CheckboxDefaults.colors].
+ * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
+ * for this checkbox. You can create and pass in your own `remember`ed instance to observe
+ * [Interaction]s and customize the appearance / behavior of this checkbox in different states.
+ */
+@ExperimentalTvMaterial3Api
+@Composable
+fun Checkbox(
+    checked: Boolean,
+    onCheckedChange: ((Boolean) -> Unit)?,
+    modifier: Modifier = Modifier,
+    enabled: Boolean = true,
+    colors: CheckboxColors = CheckboxDefaults.colors(),
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+) {
+    TriStateCheckbox(
+        state = ToggleableState(checked),
+        onClick = if (onCheckedChange != null) {
+            { onCheckedChange(!checked) }
+        } else {
+            null
+        },
+        modifier = modifier,
+        enabled = enabled,
+        colors = colors,
+        interactionSource = interactionSource
+    )
+}
+
+/**
+ * <a href="https://m3.material.io/components/checkbox/guidelines" class="external" target="_blank">Material Design checkbox</a> parent.
+ *
+ * Checkboxes can have a parent-child relationship with other checkboxes. When the parent checkbox
+ * is checked, all child checkboxes are checked. If a parent checkbox is unchecked, all child
+ * checkboxes are unchecked. If some, but not all, child checkboxes are checked, the parent checkbox
+ * becomes an indeterminate checkbox.
+ *
+ * ![Checkbox image](https://developer.android.com/images/reference/androidx/compose/material3/indeterminate-checkbox.png)
+ *
+ * @see [Checkbox] if you want a simple component that represents Boolean state
+ *
+ * @param state whether this checkbox is checked, unchecked, or in an indeterminate state
+ * @param onClick called when this checkbox is clicked. If `null`, then this checkbox will not be
+ * interactable, unless something else handles its input events and updates its [state].
+ * @param modifier the [Modifier] to be applied to this checkbox
+ * @param enabled controls the enabled state of this checkbox. When `false`, this component will not
+ * respond to user input, and it will appear visually disabled and disabled to accessibility
+ * services.
+ * @param colors [CheckboxColors] that will be used to resolve the colors used for this checkbox in
+ * different states. See [CheckboxDefaults.colors].
+ * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
+ * for this checkbox. You can create and pass in your own `remember`ed instance to observe
+ * [Interaction]s and customize the appearance / behavior of this checkbox in different states.
+ */
+@ExperimentalTvMaterial3Api
+@Composable
+fun TriStateCheckbox(
+    state: ToggleableState,
+    onClick: (() -> Unit)?,
+    modifier: Modifier = Modifier,
+    enabled: Boolean = true,
+    colors: CheckboxColors = CheckboxDefaults.colors(),
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+) {
+    val toggleableModifier =
+        if (onClick != null) {
+            Modifier.triStateToggleable(
+                state = state,
+                onClick = onClick,
+                enabled = enabled,
+                role = Role.Checkbox,
+                interactionSource = interactionSource,
+                indication = null
+            )
+        } else {
+            Modifier
+        }
+    CheckboxImpl(
+        enabled = enabled,
+        value = state,
+        modifier = modifier
+            .then(toggleableModifier)
+            .padding(CheckboxDefaultPadding),
+        colors = colors
+    )
+}
+
+/**
+ * Defaults used in [Checkbox] and [TriStateCheckbox].
+ */
+@ExperimentalTvMaterial3Api
+object CheckboxDefaults {
+    /**
+     * Creates a [CheckboxColors] that will animate between the provided colors according to the
+     * Material specification.
+     *
+     * @param checkedColor the color that will be used for the border and box when checked
+     * @param uncheckedColor color that will be used for the border when unchecked
+     * @param checkmarkColor color that will be used for the checkmark when checked
+     * @param disabledCheckedColor color that will be used for the box and border when disabled and
+     * checked
+     * @param disabledUncheckedColor color that will be used for the box and border when disabled
+     * and not checked
+     * @param disabledIndeterminateColor color that will be used for the box and
+     * border in a [TriStateCheckbox] when disabled AND in an [ToggleableState.Indeterminate] state.
+     */
+    @Composable
+    fun colors(
+        checkedColor: Color =
+            MaterialTheme.colorScheme.fromToken(CheckboxTokens.SelectedContainerColor),
+        uncheckedColor: Color =
+            MaterialTheme.colorScheme.fromToken(CheckboxTokens.UnselectedOutlineColor),
+        checkmarkColor: Color =
+            MaterialTheme.colorScheme.fromToken(CheckboxTokens.SelectedIconColor),
+        disabledCheckedColor: Color =
+            MaterialTheme.colorScheme
+                .fromToken(CheckboxTokens.SelectedDisabledContainerColor)
+                .copy(alpha = CheckboxTokens.SelectedDisabledContainerOpacity),
+        disabledUncheckedColor: Color =
+            MaterialTheme.colorScheme
+                .fromToken(CheckboxTokens.UnselectedDisabledOutlineColor)
+                .copy(alpha = CheckboxTokens.UnselectedDisabledContainerOpacity),
+        disabledIndeterminateColor: Color = disabledCheckedColor
+    ): CheckboxColors = CheckboxColors(
+        checkedBorderColor = checkedColor,
+        checkedBoxColor = checkedColor,
+        checkedCheckmarkColor = checkmarkColor,
+        uncheckedCheckmarkColor = checkmarkColor.copy(alpha = 0f),
+        uncheckedBoxColor = checkedColor.copy(alpha = 0f),
+        disabledCheckedBoxColor = disabledCheckedColor,
+        disabledUncheckedBoxColor = disabledUncheckedColor.copy(alpha = 0f),
+        disabledIndeterminateBoxColor = disabledIndeterminateColor,
+        uncheckedBorderColor = uncheckedColor,
+        disabledBorderColor = disabledCheckedColor,
+        disabledIndeterminateBorderColor = disabledIndeterminateColor,
+    )
+}
+
+@OptIn(ExperimentalTvMaterial3Api::class)
+@Composable
+private fun CheckboxImpl(
+    enabled: Boolean,
+    value: ToggleableState,
+    modifier: Modifier,
+    colors: CheckboxColors
+) {
+    val transition = updateTransition(value)
+    val checkDrawFraction = transition.animateFloat(
+        transitionSpec = {
+            when {
+                initialState == ToggleableState.Off -> tween(CheckAnimationDuration)
+                targetState == ToggleableState.Off -> snap(BoxOutDuration)
+                else -> spring()
+            }
+        }
+    ) {
+        when (it) {
+            ToggleableState.On -> 1f
+            ToggleableState.Off -> 0f
+            ToggleableState.Indeterminate -> 1f
+        }
+    }
+
+    val checkCenterGravitationShiftFraction = transition.animateFloat(
+        transitionSpec = {
+            when {
+                initialState == ToggleableState.Off -> snap()
+                targetState == ToggleableState.Off -> snap(BoxOutDuration)
+                else -> tween(durationMillis = CheckAnimationDuration)
+            }
+        }
+    ) {
+        when (it) {
+            ToggleableState.On -> 0f
+            ToggleableState.Off -> 0f
+            ToggleableState.Indeterminate -> 1f
+        }
+    }
+    val checkCache = remember { CheckDrawingCache() }
+    val checkColor = colors.checkmarkColor(value)
+    val boxColor = colors.boxColor(enabled, value)
+    val borderColor = colors.borderColor(enabled, value)
+    Canvas(
+        modifier
+            .wrapContentSize(Alignment.Center)
+            .requiredSize(CheckboxSize)
+    ) {
+        val strokeWidthPx = floor(StrokeWidth.toPx())
+        drawBox(
+            boxColor = boxColor.value,
+            borderColor = borderColor.value,
+            radius = RadiusSize.toPx(),
+            strokeWidth = strokeWidthPx
+        )
+        drawCheck(
+            checkColor = checkColor.value,
+            checkFraction = checkDrawFraction.value,
+            crossCenterGravitation = checkCenterGravitationShiftFraction.value,
+            strokeWidthPx = strokeWidthPx,
+            drawingCache = checkCache
+        )
+    }
+}
+
+private fun DrawScope.drawBox(
+    boxColor: Color,
+    borderColor: Color,
+    radius: Float,
+    strokeWidth: Float
+) {
+    val halfStrokeWidth = strokeWidth / 2.0f
+    val stroke = Stroke(strokeWidth)
+    val checkboxSize = size.width
+    if (boxColor == borderColor) {
+        drawRoundRect(
+            boxColor,
+            size = Size(checkboxSize, checkboxSize),
+            cornerRadius = CornerRadius(radius),
+            style = Fill
+        )
+    } else {
+        drawRoundRect(
+            boxColor,
+            topLeft = Offset(strokeWidth, strokeWidth),
+            size = Size(checkboxSize - strokeWidth * 2, checkboxSize - strokeWidth * 2),
+            cornerRadius = CornerRadius(max(0f, radius - strokeWidth)),
+            style = Fill
+        )
+        drawRoundRect(
+            borderColor,
+            topLeft = Offset(halfStrokeWidth, halfStrokeWidth),
+            size = Size(checkboxSize - strokeWidth, checkboxSize - strokeWidth),
+            cornerRadius = CornerRadius(radius - halfStrokeWidth),
+            style = stroke
+        )
+    }
+}
+
+private fun DrawScope.drawCheck(
+    checkColor: Color,
+    checkFraction: Float,
+    crossCenterGravitation: Float,
+    strokeWidthPx: Float,
+    drawingCache: CheckDrawingCache
+) {
+    val stroke = Stroke(width = strokeWidthPx, cap = StrokeCap.Square)
+    val width = size.width
+    val checkCrossX = 0.4f
+    val checkCrossY = 0.7f
+    val leftX = 0.2f
+    val leftY = 0.5f
+    val rightX = 0.8f
+    val rightY = 0.3f
+
+    val gravitatedCrossX = lerp(checkCrossX, 0.5f, crossCenterGravitation)
+    val gravitatedCrossY = lerp(checkCrossY, 0.5f, crossCenterGravitation)
+    // gravitate only Y for end to achieve center line
+    val gravitatedLeftY = lerp(leftY, 0.5f, crossCenterGravitation)
+    val gravitatedRightY = lerp(rightY, 0.5f, crossCenterGravitation)
+
+    with(drawingCache) {
+        checkPath.reset()
+        checkPath.moveTo(width * leftX, width * gravitatedLeftY)
+        checkPath.lineTo(width * gravitatedCrossX, width * gravitatedCrossY)
+        checkPath.lineTo(width * rightX, width * gravitatedRightY)
+        // TODO: replace with proper declarative non-android alternative when ready (b/158188351)
+        pathMeasure.setPath(checkPath, false)
+        pathToDraw.reset()
+        pathMeasure.getSegment(
+            0f, pathMeasure.length * checkFraction, pathToDraw, true
+        )
+    }
+    drawPath(drawingCache.pathToDraw, checkColor, style = stroke)
+}
+
+@Immutable
+private class CheckDrawingCache(
+    val checkPath: Path = Path(),
+    val pathMeasure: PathMeasure = PathMeasure(),
+    val pathToDraw: Path = Path()
+)
+
+/**
+ * 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.
+ */
+@ExperimentalTvMaterial3Api
+@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
+) {
+    /**
+     * Represents the color used for the checkmark inside the checkbox, depending on [state].
+     *
+     * @param state the [ToggleableState] of the checkbox
+     */
+    @Composable
+    internal fun checkmarkColor(state: ToggleableState): State<Color> {
+        val target = if (state == ToggleableState.Off) {
+            uncheckedCheckmarkColor
+        } else {
+            checkedCheckmarkColor
+        }
+
+        val duration = if (state == ToggleableState.Off) BoxOutDuration else BoxInDuration
+        return animateColorAsState(target, tween(durationMillis = duration))
+    }
+
+    /**
+     * Represents the color used for the box (background) of the checkbox, depending on [enabled]
+     * and [state].
+     *
+     * @param enabled whether the checkbox is enabled or not
+     * @param state the [ToggleableState] of the checkbox
+     */
+    @Composable
+    internal fun boxColor(enabled: Boolean, state: ToggleableState): State<Color> {
+        val target = if (enabled) {
+            when (state) {
+                ToggleableState.On, ToggleableState.Indeterminate -> checkedBoxColor
+                ToggleableState.Off -> uncheckedBoxColor
+            }
+        } else {
+            when (state) {
+                ToggleableState.On -> disabledCheckedBoxColor
+                ToggleableState.Indeterminate -> disabledIndeterminateBoxColor
+                ToggleableState.Off -> disabledUncheckedBoxColor
+            }
+        }
+
+        // If not enabled 'snap' to the disabled state, as there should be no animations between
+        // enabled / disabled.
+        return if (enabled) {
+            val duration = if (state == ToggleableState.Off) BoxOutDuration else BoxInDuration
+            animateColorAsState(target, tween(durationMillis = duration))
+        } else {
+            rememberUpdatedState(target)
+        }
+    }
+
+    /**
+     * Represents the color used for the border of the checkbox, depending on [enabled] and [state].
+     *
+     * @param enabled whether the checkbox is enabled or not
+     * @param state the [ToggleableState] of the checkbox
+     */
+    @Composable
+    internal fun borderColor(enabled: Boolean, state: ToggleableState): State<Color> {
+        val target = if (enabled) {
+            when (state) {
+                ToggleableState.On, ToggleableState.Indeterminate -> checkedBorderColor
+                ToggleableState.Off -> uncheckedBorderColor
+            }
+        } else {
+            when (state) {
+                ToggleableState.Indeterminate -> disabledIndeterminateBorderColor
+                ToggleableState.On, ToggleableState.Off -> disabledBorderColor
+            }
+        }
+
+        // If not enabled 'snap' to the disabled state, as there should be no animations between
+        // enabled / disabled.
+        return if (enabled) {
+            val duration = if (state == ToggleableState.Off) BoxOutDuration else BoxInDuration
+            animateColorAsState(target, tween(durationMillis = duration))
+        } else {
+            rememberUpdatedState(target)
+        }
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other == null || other !is CheckboxColors) return false
+
+        if (checkedCheckmarkColor != other.checkedCheckmarkColor) return false
+        if (uncheckedCheckmarkColor != other.uncheckedCheckmarkColor) return false
+        if (checkedBoxColor != other.checkedBoxColor) return false
+        if (uncheckedBoxColor != other.uncheckedBoxColor) return false
+        if (disabledCheckedBoxColor != other.disabledCheckedBoxColor) return false
+        if (disabledUncheckedBoxColor != other.disabledUncheckedBoxColor) return false
+        if (disabledIndeterminateBoxColor != other.disabledIndeterminateBoxColor) return false
+        if (checkedBorderColor != other.checkedBorderColor) return false
+        if (uncheckedBorderColor != other.uncheckedBorderColor) return false
+        if (disabledBorderColor != other.disabledBorderColor) return false
+        if (disabledIndeterminateBorderColor != other.disabledIndeterminateBorderColor) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = checkedCheckmarkColor.hashCode()
+        result = 31 * result + uncheckedCheckmarkColor.hashCode()
+        result = 31 * result + checkedBoxColor.hashCode()
+        result = 31 * result + uncheckedBoxColor.hashCode()
+        result = 31 * result + disabledCheckedBoxColor.hashCode()
+        result = 31 * result + disabledUncheckedBoxColor.hashCode()
+        result = 31 * result + disabledIndeterminateBoxColor.hashCode()
+        result = 31 * result + checkedBorderColor.hashCode()
+        result = 31 * result + uncheckedBorderColor.hashCode()
+        result = 31 * result + disabledBorderColor.hashCode()
+        result = 31 * result + disabledIndeterminateBorderColor.hashCode()
+        return result
+    }
+}
+
+private const val BoxInDuration = 50
+private const val BoxOutDuration = 100
+private const val CheckAnimationDuration = 100
+
+// TODO(b/188529841): Update the padding and size when the Checkbox spec is finalized.
+private val CheckboxDefaultPadding = 2.dp
+private val CheckboxSize = 20.dp
+private val StrokeWidth = 2.dp
+private val RadiusSize = 2.dp
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/Indications.kt b/tv/tv-material/src/main/java/androidx/tv/material3/Indications.kt
index 0b0626d..b6f5fda 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/Indications.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/Indications.kt
@@ -61,9 +61,8 @@
  * applied to. It takes in parameters like [Color], [Shape], blur radius, and Offset to let users
  * customise it to their brand personality.
  */
-@ExperimentalTvMaterial3Api
 @Stable
-class GlowIndication(
+internal class GlowIndication(
     private val color: Color,
     private val shape: Shape,
     private val glowBlurRadius: Dp,
@@ -84,7 +83,6 @@
     }
 }
 
-@ExperimentalTvMaterial3Api
 private class GlowIndicationInstance(
     color: Color,
     private val shape: Shape,
@@ -154,9 +152,9 @@
  * @param offsetY describes the vertical offset of the glow from the composable.
  * @return A remembered instance of [GlowIndication].
  */
-@ExperimentalTvMaterial3Api
+@OptIn(ExperimentalTvMaterial3Api::class)
 @Composable
-fun rememberGlowIndication(
+internal fun rememberGlowIndication(
     color: Color = MaterialTheme.colorScheme.primaryContainer,
     shape: Shape = RectangleShape,
     glowBlurRadius: Dp = 0.dp,
@@ -181,9 +179,8 @@
  * it's being applied to.
  * @param inset describes the offset of the border from the composable it's being applied to.
  */
-@ExperimentalTvMaterial3Api
 @Immutable
-class BorderIndication(
+internal class BorderIndication(
     private val brush: Brush,
     private val width: Dp,
     private val shape: Shape,
@@ -195,6 +192,7 @@
      * @param border the [androidx.tv.material3.Border] instance that is used to create and return
      * an [BorderIndication] instance
      */
+    @OptIn(ExperimentalTvMaterial3Api::class)
     constructor(border: Border) :
         this(
             brush = border.border.brush,
@@ -262,9 +260,8 @@
  * ScaleIndication is an [Indication] that scales the composable by the provided factor. This
  * indication by default will create a smooth animation between the state changes.
  */
-@ExperimentalTvMaterial3Api
 @Stable
-class ScaleIndication(private val scale: Float) : Indication {
+internal class ScaleIndication(private val scale: Float) : Indication {
     @Composable
     override fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance {
         val interaction by interactionSource.interactions.collectAsState(
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/tokens/CheckboxTokens.kt b/tv/tv-material/src/main/java/androidx/tv/material3/tokens/CheckboxTokens.kt
new file mode 100644
index 0000000..3bd10be
--- /dev/null
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/tokens/CheckboxTokens.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.
+ */
+// VERSION: v0_001 (Inspired by androidx.compose.material3.tokens v0_103)
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+package androidx.tv.material3.tokens
+
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.ui.unit.dp
+
+internal object CheckboxTokens {
+    val ContainerHeight = 18.0.dp
+    val ContainerShape = RoundedCornerShape(2.0.dp)
+    val ContainerWidth = 18.0.dp
+    val IconSize = 18.0.dp
+    val SelectedContainerColor = ColorSchemeKeyTokens.Primary
+    val SelectedDisabledContainerColor = ColorSchemeKeyTokens.OnSurface
+    const val SelectedDisabledContainerOpacity = 0.38f
+    val SelectedDisabledContainerOutlineWidth = 0.0.dp
+    val SelectedDisabledIconColor = ColorSchemeKeyTokens.Surface
+    val SelectedErrorContainerColor = ColorSchemeKeyTokens.Error
+    val SelectedErrorFocusContainerColor = ColorSchemeKeyTokens.Error
+    val SelectedErrorFocusIconColor = ColorSchemeKeyTokens.OnError
+    val SelectedErrorFocusOutlineWidth = 0.0.dp
+    val SelectedErrorHoverContainerColor = ColorSchemeKeyTokens.Error
+    val SelectedErrorHoverIconColor = ColorSchemeKeyTokens.OnError
+    val SelectedErrorHoverOutlineWidth = 0.0.dp
+    val SelectedErrorIconColor = ColorSchemeKeyTokens.OnError
+    val SelectedErrorPressedContainerColor = ColorSchemeKeyTokens.Error
+    val SelectedErrorPressedIconColor = ColorSchemeKeyTokens.OnError
+    val SelectedErrorPressedOutlineWidth = 0.0.dp
+    val SelectedFocusContainerColor = ColorSchemeKeyTokens.Primary
+    val SelectedFocusIconColor = ColorSchemeKeyTokens.OnPrimary
+    val SelectedFocusOutlineWidth = 0.0.dp
+    val SelectedHoverContainerColor = ColorSchemeKeyTokens.Primary
+    val SelectedHoverIconColor = ColorSchemeKeyTokens.OnPrimary
+    val SelectedHoverOutlineWidth = 0.0.dp
+    val SelectedIconColor = ColorSchemeKeyTokens.OnPrimary
+    val SelectedOutlineWidth = 0.0.dp
+    val SelectedPressedContainerColor = ColorSchemeKeyTokens.Primary
+    val SelectedPressedIconColor = ColorSchemeKeyTokens.OnPrimary
+    val SelectedPressedOutlineWidth = 0.0.dp
+    val StateLayerShape = ShapeKeyTokens.CornerFull
+    val StateLayerSize = 40.0.dp
+    const val UnselectedDisabledContainerOpacity = 0.38f
+    val UnselectedDisabledOutlineColor = ColorSchemeKeyTokens.OnSurface
+    val UnselectedDisabledOutlineWidth = 2.0.dp
+    val UnselectedErrorFocusOutlineColor = ColorSchemeKeyTokens.Error
+    val UnselectedErrorFocusOutlineWidth = 2.0.dp
+    val UnselectedErrorHoverOutlineColor = ColorSchemeKeyTokens.Error
+    val UnselectedErrorHoverOutlineWidth = 2.0.dp
+    val UnselectedErrorOutlineColor = ColorSchemeKeyTokens.Error
+    val UnselectedErrorPressedOutlineColor = ColorSchemeKeyTokens.Error
+    val UnselectedErrorPressedOutlineWidth = 2.0.dp
+    val UnselectedFocusOutlineColor = ColorSchemeKeyTokens.OnSurface
+    val UnselectedFocusOutlineWidth = 2.0.dp
+    val UnselectedHoverOutlineColor = ColorSchemeKeyTokens.OnSurface
+    val UnselectedHoverOutlineWidth = 2.0.dp
+    val UnselectedOutlineColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val UnselectedOutlineWidth = 2.0.dp
+    val UnselectedPressedOutlineColor = ColorSchemeKeyTokens.OnSurface
+    val UnselectedPressedOutlineWidth = 2.0.dp
+}
diff --git a/wear/compose/OWNERS b/wear/compose/OWNERS
index f346c9b..b369ef6 100644
--- a/wear/compose/OWNERS
+++ b/wear/compose/OWNERS
@@ -1,3 +1,4 @@
 # Bug component: 1077984
 jnichol@google.com
 stevebower@google.com
+ssancho@google.com
diff --git a/wear/compose/compose-foundation/api/api_lint.ignore b/wear/compose/compose-foundation/api/api_lint.ignore
new file mode 100644
index 0000000..edcb394
--- /dev/null
+++ b/wear/compose/compose-foundation/api/api_lint.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+GetterSetterNames: androidx.wear.compose.foundation.lazy.ScalingLazyListState#getCanScrollBackward():
+    Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.wear.compose.foundation.lazy.ScalingLazyListState#getCanScrollForward():
+    Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field ExpandableState.expanded:
+    Invalid name for boolean property `expanded`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ScalingLazyListLayoutInfo.reverseLayout:
+    Invalid name for boolean property `reverseLayout`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/wear/compose/compose-material/api/api_lint.ignore b/wear/compose/compose-material/api/api_lint.ignore
new file mode 100644
index 0000000..6051f9d
--- /dev/null
+++ b/wear/compose/compose-material/api/api_lint.ignore
@@ -0,0 +1,13 @@
+// Baseline format: 1.0
+GetterSetterNames: androidx.wear.compose.material.PickerState#getCanScrollBackward():
+    Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.wear.compose.material.PickerState#getCanScrollForward():
+    Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.wear.compose.material.ScalingLazyListState#getCanScrollBackward():
+    Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.wear.compose.material.ScalingLazyListState#getCanScrollForward():
+    Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field PickerState.repeatItems:
+    Invalid name for boolean property `repeatItems`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ScalingLazyListLayoutInfo.reverseLayout:
+    Invalid name for boolean property `reverseLayout`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/wear/compose/compose-material/api/public_plus_experimental_current.txt b/wear/compose/compose-material/api/public_plus_experimental_current.txt
index 3dd2192..fb0f899 100644
--- a/wear/compose/compose-material/api/public_plus_experimental_current.txt
+++ b/wear/compose/compose-material/api/public_plus_experimental_current.txt
@@ -633,13 +633,13 @@
   }
 
   @androidx.compose.runtime.Immutable @androidx.wear.compose.material.ExperimentalWearMaterialApi public final class SwipeProgress<T> {
-    ctor public SwipeProgress(T? from, T? to, float fraction);
+    ctor public SwipeProgress(T from, T to, float fraction);
     method public float getFraction();
-    method public T! getFrom();
-    method public T! getTo();
+    method public T getFrom();
+    method public T getTo();
     property public final float fraction;
-    property public final T! from;
-    property public final T! to;
+    property public final T from;
+    property public final T to;
   }
 
   public final class SwipeToDismissBoxDefaults {
@@ -699,9 +699,9 @@
   }
 
   @androidx.compose.runtime.Stable @androidx.wear.compose.material.ExperimentalWearMaterialApi 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.wear.compose.material.ExperimentalWearMaterialApi 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();
+    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.wear.compose.material.ExperimentalWearMaterialApi 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();
@@ -709,8 +709,8 @@
     method public final T! getTargetValue();
     method public final boolean isAnimationRunning();
     method @androidx.wear.compose.material.ExperimentalWearMaterialApi public final suspend Object? performFling(float velocity, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method @androidx.wear.compose.material.ExperimentalWearMaterialApi public final suspend Object? snapTo(T? targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final T! currentValue;
+    method @androidx.wear.compose.material.ExperimentalWearMaterialApi public final suspend Object? snapTo(T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final T currentValue;
     property @androidx.wear.compose.material.ExperimentalWearMaterialApi public final float direction;
     property public final boolean isAnimationRunning;
     property @androidx.wear.compose.material.ExperimentalWearMaterialApi public final androidx.compose.runtime.State<java.lang.Float> offset;
diff --git a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ChipTest.kt b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ChipTest.kt
index 934752c..c0dfbe8 100644
--- a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ChipTest.kt
+++ b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ChipTest.kt
@@ -74,14 +74,14 @@
       Chip(
         onClick = {},
         colors = ChipDefaults.primaryChipColors(),
-        modifier = Modifier.testTag("test-item"),
+        modifier = Modifier.testTag(TEST_TAG),
         border = ChipDefaults.chipBorder()
       ) {
         TestImage()
       }
     }
 
-    rule.onNodeWithTag("test-item").assertExists()
+    rule.onNodeWithTag(TEST_TAG).assertExists()
   }
 
   @Test
@@ -91,14 +91,14 @@
         onClick = {},
         colors = ChipDefaults.primaryChipColors(),
         enabled = true,
-        modifier = Modifier.testTag("test-item"),
+        modifier = Modifier.testTag(TEST_TAG),
         border = ChipDefaults.chipBorder()
       ) {
         TestImage()
       }
     }
 
-    rule.onNodeWithTag("test-item").assertHasClickAction()
+    rule.onNodeWithTag(TEST_TAG).assertHasClickAction()
   }
 
   @Test
@@ -108,14 +108,14 @@
         onClick = {},
         colors = ChipDefaults.primaryChipColors(),
         enabled = false,
-        modifier = Modifier.testTag("test-item"),
+        modifier = Modifier.testTag(TEST_TAG),
         border = ChipDefaults.chipBorder()
       ) {
         TestImage()
       }
     }
 
-    rule.onNodeWithTag("test-item").assertHasClickAction()
+    rule.onNodeWithTag(TEST_TAG).assertHasClickAction()
   }
 
   @Test
@@ -125,14 +125,14 @@
         onClick = {},
         colors = ChipDefaults.primaryChipColors(),
         enabled = true,
-        modifier = Modifier.testTag("test-item"),
+        modifier = Modifier.testTag(TEST_TAG),
         border = ChipDefaults.chipBorder()
       ) {
         TestImage()
       }
     }
 
-    rule.onNodeWithTag("test-item").assertIsEnabled()
+    rule.onNodeWithTag(TEST_TAG).assertIsEnabled()
   }
 
   @Test
@@ -142,14 +142,14 @@
         onClick = {},
         colors = ChipDefaults.primaryChipColors(),
         enabled = false,
-        modifier = Modifier.testTag("test-item"),
+        modifier = Modifier.testTag(TEST_TAG),
         border = ChipDefaults.chipBorder()
       ) {
         TestImage()
       }
     }
 
-    rule.onNodeWithTag("test-item").assertIsNotEnabled()
+    rule.onNodeWithTag(TEST_TAG).assertIsNotEnabled()
   }
 
   @Test
@@ -161,14 +161,14 @@
         onClick = { clicked = true },
         colors = ChipDefaults.primaryChipColors(),
         enabled = true,
-        modifier = Modifier.testTag("test-item"),
+        modifier = Modifier.testTag(TEST_TAG),
         border = ChipDefaults.chipBorder()
       ) {
         TestImage()
       }
     }
 
-    rule.onNodeWithTag("test-item").performClick()
+    rule.onNodeWithTag(TEST_TAG).performClick()
 
     rule.runOnIdle {
       assertEquals(true, clicked)
@@ -184,14 +184,14 @@
         onClick = { clicked = true },
         colors = ChipDefaults.primaryChipColors(),
         enabled = false,
-        modifier = Modifier.testTag("test-item"),
+        modifier = Modifier.testTag(TEST_TAG),
         border = ChipDefaults.chipBorder()
       ) {
         TestImage()
       }
     }
 
-    rule.onNodeWithTag("test-item").performClick()
+    rule.onNodeWithTag(TEST_TAG).performClick()
 
     rule.runOnIdle {
       assertEquals(false, clicked)
@@ -205,14 +205,59 @@
         onClick = {},
         colors = ChipDefaults.primaryChipColors(),
         enabled = false,
-        modifier = Modifier.testTag("test-item"),
+        modifier = Modifier.testTag(TEST_TAG),
         border = ChipDefaults.chipBorder()
       ) {
         TestImage()
       }
     }
 
-    rule.onNodeWithTag("test-item")
+    rule.onNodeWithTag(TEST_TAG)
+      .assert(
+        SemanticsMatcher.expectValue(
+          SemanticsProperties.Role,
+          Role.Button
+        )
+      )
+  }
+
+  @Test
+  fun has_role_button_for_three_slot_chip() {
+    rule.setContentWithTheme {
+      Chip(
+        onClick = {},
+        label = {},
+        secondaryLabel = {},
+        icon = { TestImage() },
+        colors = ChipDefaults.primaryChipColors(),
+        enabled = false,
+        modifier = Modifier.testTag(TEST_TAG),
+      )
+    }
+
+    rule.onNodeWithTag(TEST_TAG)
+      .assert(
+        SemanticsMatcher.expectValue(
+          SemanticsProperties.Role,
+          Role.Button
+        )
+      )
+  }
+
+  @Test
+  fun has_role_button_for_compact_chip() {
+    rule.setContentWithTheme {
+      CompactChip(
+        onClick = {},
+        label = {},
+        icon = { TestImage() },
+        colors = ChipDefaults.primaryChipColors(),
+        enabled = false,
+        modifier = Modifier.testTag(TEST_TAG),
+      )
+    }
+
+    rule.onNodeWithTag(TEST_TAG)
       .assert(
         SemanticsMatcher.expectValue(
           SemanticsProperties.Role,
@@ -225,7 +270,7 @@
   fun is_stadium_shape_under_ltr() =
     rule.isStadiumShape(LayoutDirection.Ltr) {
       Chip(
-        modifier = Modifier.testTag("test-item"),
+        modifier = Modifier.testTag(TEST_TAG),
         border = ChipDefaults.chipBorder(),
         onClick = {},
         colors = ChipDefaults.primaryChipColors(),
@@ -236,7 +281,7 @@
   fun is_stadium_shape_under_rtl() =
     rule.isStadiumShape(LayoutDirection.Rtl) {
       Chip(
-        modifier = Modifier.testTag("test-item"),
+        modifier = Modifier.testTag(TEST_TAG),
         border = ChipDefaults.chipBorder(),
         onClick = {},
         colors = ChipDefaults.primaryChipColors(),
@@ -612,13 +657,13 @@
           content = {},
           colors = ChipDefaults.primaryChipColors(backgroundColor = overrideColor),
           enabled = true,
-          modifier = Modifier.testTag("test-item"),
+          modifier = Modifier.testTag(TEST_TAG),
           border = ChipDefaults.chipBorder()
         )
       }
     }
 
-    rule.onNodeWithTag("test-item")
+    rule.onNodeWithTag(TEST_TAG)
       .captureToImage()
       .assertContainsColor(overrideColor, 50.0f)
   }
@@ -634,13 +679,13 @@
           content = {},
           colors = ChipDefaults.chipColors(disabledBackgroundColor = overrideColor),
           enabled = false,
-          modifier = Modifier.testTag("test-item"),
+          modifier = Modifier.testTag(TEST_TAG),
           border = ChipDefaults.chipBorder()
         )
       }
     }
 
-    rule.onNodeWithTag("test-item")
+    rule.onNodeWithTag(TEST_TAG)
       .captureToImage()
       .assertContainsColor(overrideColor, 50.0f)
   }
@@ -659,7 +704,7 @@
           actualContentColor = LocalContentColor.current
         },
         enabled = true,
-        modifier = Modifier.testTag("test-item"),
+        modifier = Modifier.testTag(TEST_TAG),
         border = ChipDefaults.chipBorder()
       )
     }
@@ -687,7 +732,7 @@
           actualSecondaryContentColor = LocalContentColor.current
         },
         enabled = true,
-        modifier = Modifier.testTag("test-item")
+        modifier = Modifier.testTag(TEST_TAG)
       )
     }
     assertEquals(expectedContent, actualContentColor)
@@ -714,7 +759,7 @@
           actualIconColor = LocalContentColor.current
         },
         enabled = true,
-        modifier = Modifier.testTag("test-item")
+        modifier = Modifier.testTag(TEST_TAG)
       )
     }
     assertEquals(expectedContent, actualContentColor)
@@ -735,7 +780,7 @@
           actualContentColor = LocalContentColor.current
         },
         enabled = false,
-        modifier = Modifier.testTag("test-item"),
+        modifier = Modifier.testTag(TEST_TAG),
         border = ChipDefaults.chipBorder()
       )
     }
@@ -768,7 +813,7 @@
           colors = testChipColors.chipColors(),
           content = { actualContent = LocalContentColor.current },
           enabled = status.enabled(),
-          modifier = Modifier.testTag("test-item"),
+          modifier = Modifier.testTag(TEST_TAG),
           border = ChipDefaults.chipBorder()
         )
       }
@@ -819,7 +864,7 @@
             colors = testChipColors.chipColors(),
             label = { actualContent = LocalContentColor.current },
             enabled = status.enabled(),
-            modifier = Modifier.testTag("test-item"),
+            modifier = Modifier.testTag(TEST_TAG),
             border = ChipDefaults.chipBorder()
           )
         } else {
@@ -828,7 +873,7 @@
             colors = testChipColors.chipColors(),
             content = { actualContent = LocalContentColor.current },
             enabled = status.enabled(),
-            modifier = Modifier.testTag("test-item"),
+            modifier = Modifier.testTag(TEST_TAG),
             border = ChipDefaults.chipBorder()
           )
         }
@@ -837,7 +882,7 @@
 
     assertEquals(expectedContent, actualContent)
 
-    rule.onNodeWithTag("test-item")
+    rule.onNodeWithTag(TEST_TAG)
       .captureToImage()
       .assertContainsColor(
         if (expectedBackground != Color.Transparent) expectedBackground else testBackground,
@@ -898,7 +943,7 @@
             label = { actualContent = LocalContentColor.current },
             icon = { actualIcon = LocalContentColor.current },
             enabled = status.enabled(),
-            modifier = Modifier.testTag("test-item")
+            modifier = Modifier.testTag(TEST_TAG)
           )
         } else {
           Chip(
@@ -908,7 +953,7 @@
             secondaryLabel = { actualSecondaryContent = LocalContentColor.current },
             icon = { actualIcon = LocalContentColor.current },
             enabled = status.enabled(),
-            modifier = Modifier.testTag("test-item")
+            modifier = Modifier.testTag(TEST_TAG)
           )
         }
       }
@@ -920,7 +965,7 @@
     }
     assertEquals(expectedIcon, actualIcon)
 
-    rule.onNodeWithTag("test-item")
+    rule.onNodeWithTag(TEST_TAG)
       .captureToImage()
       .assertContainsColor(
         if (expectedBackground != Color.Transparent) expectedBackground else testBackground,
@@ -967,7 +1012,7 @@
             label = { actualContent = LocalContentColor.current },
             icon = { actualIcon = LocalContentColor.current },
             enabled = status.enabled(),
-            modifier = Modifier.testTag("test-item")
+            modifier = Modifier.testTag(TEST_TAG)
           )
         } else {
           Chip(
@@ -977,7 +1022,7 @@
             secondaryLabel = { actualSecondaryContent = LocalContentColor.current },
             icon = { actualIcon = LocalContentColor.current },
             enabled = status.enabled(),
-            modifier = Modifier.testTag("test-item")
+            modifier = Modifier.testTag(TEST_TAG)
           )
         }
       }
@@ -1008,7 +1053,7 @@
           actualTextStyle = LocalTextStyle.current
         },
         enabled = true,
-        modifier = Modifier.testTag("test-item"),
+        modifier = Modifier.testTag(TEST_TAG),
         border = ChipDefaults.chipBorder()
       )
     }
@@ -1034,7 +1079,7 @@
           actualSecondaryLabelTextStyle = LocalTextStyle.current
         },
         enabled = true,
-        modifier = Modifier.testTag("test-item")
+        modifier = Modifier.testTag(TEST_TAG)
       )
     }
     assertEquals(expectedTextStyle, actualLabelTextStyle)
@@ -1116,12 +1161,12 @@
       chipColor = MaterialTheme.colors.primary
       content(
         Modifier
-          .testTag("test-item")
+          .testTag(TEST_TAG)
           .padding(padding)
           .background(background))
     }
 
-    rule.onNodeWithTag("test-item")
+    rule.onNodeWithTag(TEST_TAG)
       .captureToImage()
       .assertShape(
         density = rule.density,
@@ -1165,7 +1210,7 @@
     }
   }
 
-  onNodeWithTag("test-item")
+  onNodeWithTag(TEST_TAG)
     .captureToImage()
     .assertShape(
       density = density,
diff --git a/wear/compose/compose-material/src/androidMain/kotlin/androidx/wear/compose/material/Resources.android.kt b/wear/compose/compose-material/src/androidMain/kotlin/androidx/wear/compose/material/Resources.android.kt
index e1b7374..ae59fc3 100644
--- a/wear/compose/compose-material/src/androidMain/kotlin/androidx/wear/compose/material/Resources.android.kt
+++ b/wear/compose/compose-material/src/androidMain/kotlin/androidx/wear/compose/material/Resources.android.kt
@@ -20,13 +20,19 @@
 import android.text.format.DateFormat
 import android.view.Surface
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
 import androidx.compose.ui.graphics.painter.Painter
 import androidx.compose.ui.platform.LocalConfiguration
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.painterResource
 
 @Composable
-internal actual fun isRoundDevice(): Boolean = LocalConfiguration.current.isScreenRound
+internal actual fun isRoundDevice(): Boolean {
+    val configuration = LocalConfiguration.current
+    return remember(configuration) {
+        configuration.isScreenRound
+    }
+}
 
 @Composable
 internal actual fun imageResource(image: ImageResources): Painter =
@@ -45,12 +51,16 @@
 internal actual fun currentTimeMillis(): Long = System.currentTimeMillis()
 
 @Composable
-internal actual fun isLeftyModeEnabled() =
-    Settings.System.getInt(
-        LocalContext.current.contentResolver,
-        Settings.System.USER_ROTATION,
-        Surface.ROTATION_0
-    ) == Surface.ROTATION_180
+internal actual fun isLeftyModeEnabled(): Boolean {
+    val context = LocalContext.current
+    return remember(context) {
+        Settings.System.getInt(
+            context.contentResolver,
+            Settings.System.USER_ROTATION,
+            Surface.ROTATION_0
+        ) == Surface.ROTATION_180
+    }
+}
 
 @Composable
 internal actual fun screenHeightDp() = LocalContext.current.resources.configuration.screenHeightDp
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Chip.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Chip.kt
index d426bb2..2408507 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Chip.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Chip.kt
@@ -362,7 +362,7 @@
         shape = shape,
         border = { border.borderStroke(enabled = it) },
         defaultIconSpacing = ChipDefaults.IconSpacing,
-        role = null
+        role = Role.Button
     )
 }
 
@@ -646,7 +646,7 @@
         defaultIconOnlyCompactChipWidth = ChipDefaults.IconOnlyCompactChipWidth,
         defaultCompactChipTapTargetPadding = ChipDefaults.CompactChipTapTargetPadding,
         defaultIconSpacing = ChipDefaults.IconSpacing,
-        role = null,
+        role = Role.Button,
     )
 }
 
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PositionIndicator.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PositionIndicator.kt
index 424101c..3f9434c 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PositionIndicator.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PositionIndicator.kt
@@ -20,16 +20,16 @@
 import androidx.wear.compose.foundation.lazy.ScalingLazyColumn as ScalingLazyColumn
 import androidx.wear.compose.foundation.lazy.ScalingLazyListItemInfo as ScalingLazyListItemInfo
 import androidx.wear.compose.foundation.lazy.ScalingLazyListAnchorType as ScalingLazyListAnchorType
-import androidx.compose.animation.AnimatedVisibility
 import androidx.compose.animation.core.Animatable
 import androidx.compose.animation.core.AnimationSpec
 import androidx.compose.animation.core.AnimationVector
 import androidx.compose.animation.core.AnimationVector2D
 import androidx.compose.animation.core.CubicBezierEasing
+import androidx.compose.animation.core.Spring
 import androidx.compose.animation.core.TwoWayConverter
+import androidx.compose.animation.core.animateFloatAsState
+import androidx.compose.animation.core.spring
 import androidx.compose.animation.core.tween
-import androidx.compose.animation.fadeIn
-import androidx.compose.animation.fadeOut
 import androidx.compose.foundation.ScrollState
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxScope
@@ -38,6 +38,7 @@
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.lazy.LazyListState
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.Stable
@@ -50,6 +51,7 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.AbsoluteAlignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.alpha
 import androidx.compose.ui.draw.drawWithContent
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Size
@@ -488,27 +490,29 @@
         )
     }
 
-    AnimatedVisibility(
-        visible = actuallyVisible.value,
-        enter = fadeIn(),
-        exit = fadeOut()
+    // Using same animation spec as AnimatedVisibility's fadeIn and fadeOut
+    val positionIndicatorAlpha by animateFloatAsState(
+        targetValue = if (actuallyVisible.value) 1f else 0f,
+        spring(stiffness = Spring.StiffnessMediumLow)
+    )
+
+    BoundsLimiter(boundsOffset, boundsSize, modifier, onSizeChanged = {
+            containerSize = it
+        }
     ) {
-        BoundsLimiter(boundsOffset, boundsSize, modifier, onSizeChanged = {
-                containerSize = it
-            }
-        ) {
-            Box(
-                modifier = Modifier
+        Box(
+            modifier = Modifier
                 .fillMaxSize()
+                .alpha(positionIndicatorAlpha)
                 .drawWithContent {
                     // We need to invert reverseDirection when the screen is round and we are on
                     // the left.
-                        val actualReverseDirection =
-                            if (isScreenRound && !indicatorOnTheRight) {
-                        !reverseDirection
-                    } else {
-                        reverseDirection
-                    }
+                    val actualReverseDirection =
+                        if (isScreenRound && !indicatorOnTheRight) {
+                            !reverseDirection
+                        } else {
+                            reverseDirection
+                        }
 
                     val indicatorPosition = if (actualReverseDirection) {
                         1 - animatedDisplayState.value.position
@@ -520,12 +524,13 @@
 
                     // We want position = 0 be the indicator aligned at the top of its area and
                     // position = 1 be aligned at the bottom of the area.
-                        val indicatorStart =
-                            indicatorPosition * (1 - animatedDisplayState.value.size)
+                    val indicatorStart =
+                        indicatorPosition * (1 - animatedDisplayState.value.size)
 
-                        val diameter = max(containerSize.width, containerSize.height)
+                    val diameter = max(containerSize.width, containerSize.height)
 
                     val paddingHorizontalPx = paddingHorizontal.toPx()
+
                     if (isScreenRound) {
                         val usableHalf = diameter / 2f - paddingHorizontalPx
                         val sweepDegrees =
@@ -556,8 +561,7 @@
                         )
                     }
                 }
-            )
-        }
+        )
     }
 }
 
@@ -596,10 +600,30 @@
     return animatable.asState()
 }
 
+@Immutable
 internal class DisplayState(
     val position: Float,
     val size: Float
-)
+) {
+    override fun hashCode(): Int {
+        var result = position.hashCode()
+        result = 31 * result + size.hashCode()
+        return result
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other == null) return false
+        if (this::class != other::class) return false
+
+        other as DisplayState
+
+        if (position != other.position) return false
+        if (size != other.size) return false
+
+        return true
+    }
+}
 
 internal val DisplayStateTwoWayConverter: TwoWayConverter<DisplayState, AnimationVector2D> =
     TwoWayConverter(
diff --git a/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/ButtonTest.kt b/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/ButtonTest.kt
index d3ad096..ede1df5 100644
--- a/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/ButtonTest.kt
+++ b/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/ButtonTest.kt
@@ -198,6 +198,28 @@
     }
 
     @Test
+    fun has_role_button_for_three_slot_chip() {
+        rule.setContentWithTheme {
+            Button(
+                onClick = {},
+                label = {},
+                secondaryLabel = {},
+                icon = { TestImage() },
+                enabled = false,
+                modifier = Modifier.testTag(TEST_TAG),
+            )
+        }
+
+        rule.onNodeWithTag(TEST_TAG)
+            .assert(
+                SemanticsMatcher.expectValue(
+                    SemanticsProperties.Role,
+                    Role.Button
+                )
+            )
+    }
+
+    @Test
     fun gives_base_button_correct_text_style() {
         var actualTextStyle = TextStyle.Default
         var expectedTextStyle = TextStyle.Default
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 b21f208..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
@@ -19,15 +19,11 @@
 import android.annotation.SuppressLint
 import android.content.Context
 import android.os.Build
-import android.view.MotionEvent
 import android.view.accessibility.AccessibilityManager
 import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener
 import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener
 import androidx.annotation.RequiresApi
 import androidx.compose.foundation.focusable
-import androidx.compose.foundation.gestures.FlingBehavior
-import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.foundation.gestures.scrollable
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxScope
@@ -44,6 +40,7 @@
 import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Check
+import androidx.compose.material.icons.filled.KeyboardArrowRight
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.LaunchedEffect
@@ -54,15 +51,11 @@
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
-import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.composed
 import androidx.compose.ui.focus.FocusRequester
 import androidx.compose.ui.focus.focusRequester
-import androidx.compose.ui.input.pointer.pointerInteropFilter
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.platform.LocalFocusManager
 import androidx.compose.ui.platform.LocalLifecycleOwner
 import androidx.compose.ui.semantics.clearAndSetSemantics
 import androidx.compose.ui.semantics.focused
@@ -526,21 +519,26 @@
             fontSize = with(LocalDensity.current) { 34.dp.toSp() }
         )
     )
-    val touchExplorationServicesEnabled by DefaultTouchExplorationStateProvider()
+    val touchExplorationStateProvider = remember { DefaultTouchExplorationStateProvider() }
+    val touchExplorationServicesEnabled by touchExplorationStateProvider
         .touchExplorationState()
 
     MaterialTheme(typography = typography) {
-        var focusedElement by remember {
-            mutableStateOf(
-                if (touchExplorationServicesEnabled)
-                    FocusableElementDatePicker.NONE else FocusableElementDatePicker.DAY
-            )
+        // When the time picker loads, none of the individual pickers are selected in talkback mode,
+        // otherwise day picker should be focused.
+        val pickerGroupState = if (touchExplorationServicesEnabled) {
+            rememberPickerGroupState(FocusableElementDatePicker.NONE.index)
+        } else {
+            rememberPickerGroupState(FocusableElementDatePicker.DAY.index)
         }
-        val focusRequesterDay = remember { FocusRequester() }
-        val focusRequesterMonth = remember { FocusRequester() }
-        val focusRequesterYear = remember { FocusRequester() }
+        val textStyle = MaterialTheme.typography.display3
+        val optionColor = MaterialTheme.colors.secondary
         val focusRequesterConfirmButton = remember { FocusRequester() }
 
+        val yearString = "Year"
+        val monthString = "Month"
+        val dayString = "Day"
+
         LaunchedEffect(
             datePickerState.yearState.selectedOption,
             datePickerState.monthState.selectedOption
@@ -557,62 +555,45 @@
         }
         val shortMonthNames = remember { getMonthNames("MMM") }
         val fullMonthNames = remember { getMonthNames("MMMM") }
-        val yearContentDescription by remember(focusedElement, datePickerState.currentYear()) {
+        val yearContentDescription by remember(
+            pickerGroupState.selectedIndex,
+            datePickerState.currentYear()
+        ) {
             derivedStateOf {
                 createDescriptionDatePicker(
-                    focusedElement,
+                    pickerGroupState,
                     datePickerState.currentYear(),
-                    "${datePickerState.currentYear()}"
+                    yearString
                 )
             }
         }
-        val monthContentDescription by remember(focusedElement, datePickerState.currentMonth()) {
+        val monthContentDescription by remember(
+            pickerGroupState.selectedIndex,
+            datePickerState.currentMonth()
+        ) {
             derivedStateOf {
-                createDescriptionDatePicker(
-                    focusedElement,
-                    datePickerState.currentMonth(),
+                if (pickerGroupState.selectedIndex == FocusableElementDatePicker.NONE.index) {
+                    monthString
+                } else {
                     fullMonthNames[(datePickerState.currentMonth() - 1) % 12]
-                )
-            } }
-        val dayContentDescription by remember(focusedElement, datePickerState.currentDay()) {
-            derivedStateOf {
-                createDescriptionDatePicker(
-                    focusedElement, datePickerState.currentDay(), "${datePickerState.currentDay()}"
-                )
-            } }
-
-        val focusManager = LocalFocusManager.current
-
-        LaunchedEffect(focusedElement) {
-            when (focusedElement) {
-                FocusableElementDatePicker.DAY -> focusRequesterDay.requestFocus()
-                FocusableElementDatePicker.MONTH -> focusRequesterMonth.requestFocus()
-                FocusableElementDatePicker.YEAR -> focusRequesterYear.requestFocus()
-                else -> focusManager.clearFocus()
+                }
             }
         }
-
+        val dayContentDescription by remember(
+            pickerGroupState.selectedIndex,
+            datePickerState.currentDay()
+        ) {
+            derivedStateOf {
+                createDescriptionDatePicker(
+                    pickerGroupState,
+                    datePickerState.currentDay(),
+                    dayString
+                )
+            }
+        }
         BoxWithConstraints(
             modifier = modifier
                 .fillMaxSize()
-                .then(
-                    if (touchExplorationServicesEnabled) {
-                        when (focusedElement) {
-                            FocusableElementDatePicker.DAY ->
-                                Modifier.scrollablePicker(datePickerState.dayState)
-
-                            FocusableElementDatePicker.MONTH ->
-                                Modifier.scrollablePicker(datePickerState.monthState)
-
-                            FocusableElementDatePicker.YEAR ->
-                                Modifier.scrollablePicker(datePickerState.yearState)
-
-                            else -> Modifier
-                        }
-                    } else {
-                        Modifier
-                    }
-                )
         ) {
             val boxConstraints = this
             Column(
@@ -621,15 +602,15 @@
             ) {
                 Spacer(Modifier.height(16.dp))
                 Text(
-                    text = when (focusedElement) {
-                        FocusableElementDatePicker.DAY -> "Day"
-                        FocusableElementDatePicker.MONTH -> "Month"
-                        FocusableElementDatePicker.YEAR -> "Year"
+                    text = when (FocusableElementDatePicker[pickerGroupState.selectedIndex]) {
+                        FocusableElementDatePicker.DAY -> dayString
+                        FocusableElementDatePicker.MONTH -> monthString
+                        FocusableElementDatePicker.YEAR -> yearString
                         else -> ""
                     },
-                    color = MaterialTheme.colors.secondary,
+                    color = optionColor,
                     style = MaterialTheme.typography.button,
-                    maxLines = 1,
+                    maxLines = 1
                 )
                 val weightsToCenterVertically = 0.5f
                 Spacer(
@@ -640,84 +621,86 @@
                 val spacerWidth = 8.dp
                 val dayWidth = 54.dp
                 val monthWidth = 80.dp
-                val yearWidth = 128.dp
-                val doubleTapToNext = {
-                        position: FocusableElementDatePicker, next: FocusableElementDatePicker ->
-                    focusedElement = when (focusedElement) {
-                        position -> next
-                        else -> position
+                val yearWidth = 100.dp
+                val numberOfSpacers = 2
+                val onPickerSelected =
+                    { current: FocusableElementDatePicker, next: FocusableElementDatePicker ->
+                        if (pickerGroupState.selectedIndex != current.index) {
+                            pickerGroupState.selectedIndex = current.index
+                    } else {
+                        pickerGroupState.selectedIndex = next.index
+                        if (next == FocusableElementDatePicker.CONFIRM_BUTTON) {
+                            focusRequesterConfirmButton.requestFocus()
+                        }
                     }
                 }
-                val offset = when (focusedElement) {
-                    FocusableElementDatePicker.DAY -> (boxConstraints.maxWidth - dayWidth) / 2
-                    FocusableElementDatePicker.MONTH ->
-                        (boxConstraints.maxWidth - monthWidth) / 2 - dayWidth - spacerWidth
-                    FocusableElementDatePicker.NONE -> (boxConstraints.maxWidth - dayWidth) / 2
-                    else -> (boxConstraints.maxWidth - yearWidth) / 2 - monthWidth
-                }
+
                 Row(
                     modifier = Modifier
                         .fillMaxWidth()
-                        .offset(offset)
+                        .offset(
+                            getPickerGroupRowOffset(
+                                boxConstraints.maxWidth,
+                                dayWidth,
+                                monthWidth,
+                                yearWidth,
+                                spacerWidth,
+                                numberOfSpacers,
+                                touchExplorationServicesEnabled,
+                                pickerGroupState
+                            )
+                        ),
+                    verticalAlignment = Alignment.CenterVertically,
+                    horizontalArrangement = Arrangement.Center
                 ) {
-                    if (focusedElement.index < 2) {
-                        DatePickerImpl(
-                            state = datePickerState.dayState,
-                            readOnly = focusedElement != FocusableElementDatePicker.DAY,
+                    PickerGroup(
+                        pickerGroupItemWithRSB(
+                            pickerState = datePickerState.dayState,
+                            modifier = Modifier.size(dayWidth, 100.dp),
+                            contentDescription = dayContentDescription,
                             onSelected = {
-                                doubleTapToNext(
+                                onPickerSelected(
                                     FocusableElementDatePicker.DAY,
                                     FocusableElementDatePicker.MONTH
                                 )
                             },
-                            text = { day: Int -> "%d".format(datePickerState.currentDay(day)) },
-                            width = dayWidth,
-                            focusRequester = focusRequesterDay,
-                            contentDescription = dayContentDescription,
-                            userScrollEnabled = !touchExplorationServicesEnabled ||
-                                focusedElement == FocusableElementDatePicker.DAY,
-                            touchExplorationServicesEnabled = touchExplorationServicesEnabled
-                        )
-                        Spacer(modifier = Modifier.width(spacerWidth))
-                    }
-                    DatePickerImpl(
-                        state = datePickerState.monthState,
-                        readOnly = focusedElement != FocusableElementDatePicker.MONTH,
-                        onSelected = {
-                            doubleTapToNext(
-                                FocusableElementDatePicker.MONTH,
-                                FocusableElementDatePicker.YEAR
-                            )
-                        },
-                        text = { month: Int ->
-                            shortMonthNames[(datePickerState.currentMonth(month) - 1) % 12] },
-                        width = monthWidth,
-                        focusRequester = focusRequesterMonth,
-                        contentDescription = monthContentDescription,
-                        userScrollEnabled = !touchExplorationServicesEnabled ||
-                            focusedElement == FocusableElementDatePicker.MONTH,
-                        touchExplorationServicesEnabled = touchExplorationServicesEnabled
-                    )
-                    if (focusedElement.index > 0) {
-                        Spacer(modifier = Modifier.width(spacerWidth))
-                        DatePickerImpl(
-                            state = datePickerState.yearState,
-                            readOnly = focusedElement != FocusableElementDatePicker.YEAR,
+                            option = pickerTextOption(textStyle) {
+                                "%d".format(datePickerState.currentDay(it))
+                            }
+                        ),
+                        pickerGroupItemWithRSB(
+                            pickerState = datePickerState.monthState,
+                            modifier = Modifier.size(monthWidth, 100.dp),
                             onSelected = {
-                                doubleTapToNext(
+                                onPickerSelected(
+                                    FocusableElementDatePicker.MONTH,
+                                    FocusableElementDatePicker.YEAR
+                                )
+                            },
+                            contentDescription = monthContentDescription,
+                            option = pickerTextOption(textStyle) {
+                                shortMonthNames[(datePickerState.currentMonth(it) - 1) % 12]
+                            }
+                        ),
+                        pickerGroupItemWithRSB(
+                            pickerState = datePickerState.yearState,
+                            modifier = Modifier.size(yearWidth, 100.dp),
+                            onSelected = {
+                                onPickerSelected(
                                     FocusableElementDatePicker.YEAR,
                                     FocusableElementDatePicker.CONFIRM_BUTTON
                                 )
                             },
-                            text = { year: Int -> "%4d".format(datePickerState.currentYear(year)) },
-                            width = yearWidth,
-                            focusRequester = focusRequesterYear,
                             contentDescription = yearContentDescription,
-                            userScrollEnabled = !touchExplorationServicesEnabled ||
-                                focusedElement == FocusableElementDatePicker.YEAR,
-                            touchExplorationServicesEnabled = touchExplorationServicesEnabled
-                        )
-                    }
+                            option = pickerTextOption(textStyle) {
+                                "%4d".format(datePickerState.currentYear(it))
+                            }
+                        ),
+                        pickerGroupState = pickerGroupState,
+                        autoCenter = true,
+                        separator = { Spacer(modifier = Modifier.width(spacerWidth)) },
+                        touchExplorationStateProvider = touchExplorationStateProvider
+                    )
                 }
                 Spacer(
                     Modifier
@@ -726,20 +709,22 @@
                 )
                 Button(
                     onClick = {
-                        if (focusedElement.index >= 2) {
+                        if (pickerGroupState.selectedIndex >= 2) {
                             val confirmedYear: Int = datePickerState.currentYear()
                             val confirmedMonth: Int = datePickerState.currentMonth()
                             val confirmedDay: Int = datePickerState.currentDay()
                             val confirmedDate =
                                 LocalDate.of(confirmedYear, confirmedMonth, confirmedDay)
                             onDateConfirm(confirmedDate)
-                        } else if (focusedElement == FocusableElementDatePicker.DAY) {
-                            doubleTapToNext(
+                        } else if (pickerGroupState.selectedIndex ==
+                            FocusableElementDatePicker.DAY.index) {
+                            onPickerSelected(
                                 FocusableElementDatePicker.DAY,
                                 FocusableElementDatePicker.MONTH
                             )
-                        } else if (focusedElement == FocusableElementDatePicker.MONTH) {
-                            doubleTapToNext(
+                        } else if (pickerGroupState.selectedIndex ==
+                            FocusableElementDatePicker.MONTH.index) {
+                            onPickerSelected(
                                 FocusableElementDatePicker.MONTH,
                                 FocusableElementDatePicker.YEAR
                             )
@@ -747,17 +732,22 @@
                     },
                     modifier = Modifier
                         .semantics {
-                            focused = focusedElement == FocusableElementDatePicker.CONFIRM_BUTTON
+                            focused = pickerGroupState.selectedIndex ==
+                                FocusableElementDatePicker.CONFIRM_BUTTON.index
                         }
                         .focusRequester(focusRequesterConfirmButton)
+                        .focusable()
                 ) {
-                    DemoIcon(
-                        resourceId =
-                        if (focusedElement.index < 2) R.drawable.ic_chevron_right_24
-                        else R.drawable.ic_check_24px,
-                        contentDescription =
-                        if (focusedElement.index >= 2) "confirm"
-                        else "next"
+                    Icon(
+                        imageVector = if (pickerGroupState.selectedIndex < 2)
+                            Icons.Filled.KeyboardArrowRight else Icons.Filled.Check,
+                        contentDescription = if (pickerGroupState.selectedIndex < 2)
+                            "next"
+                        else
+                            "confirm",
+                        modifier = Modifier
+                            .size(24.dp)
+                            .wrapContentSize(align = Alignment.Center)
                     )
                 }
                 Spacer(Modifier.height(12.dp))
@@ -766,67 +756,37 @@
     }
 }
 
-@Composable
-private fun DatePickerImpl(
-    state: PickerState,
-    readOnly: Boolean,
-    onSelected: () -> Unit,
-    text: (option: Int) -> String,
-    focusRequester: FocusRequester,
-    width: Dp,
-    contentDescription: String,
-    userScrollEnabled: Boolean,
-    touchExplorationServicesEnabled: Boolean
-) {
-    PickerWithRSB(
-        readOnly = readOnly,
-        state = state,
-        focusRequester = focusRequester,
-        modifier = Modifier.size(width, 100.dp),
-        onSelected = onSelected,
-        contentDescription = contentDescription,
-        userScrollEnabled = userScrollEnabled
-    ) { option ->
-        TimePiece(
-            selected = !readOnly,
-            onSelected = onSelected,
-            text = text(option),
-            style = MaterialTheme.typography.display2,
-            touchExplorationServicesEnabled = touchExplorationServicesEnabled
-        )
-    }
-}
+// getPickerGroupRowOffset function calculates the offset of the picker group row in talkback mode.
+// Autocenter doesn't work when no index is selected which is the case in talkback mode.
+// Offset is required to move the first picker to the center.
+private fun getPickerGroupRowOffset(
+    rowWidth: Dp,
+    dayPickerWidth: Dp,
+    monthPickerWidth: Dp,
+    yearPickerWidth: Dp,
+    spacerWidth: Dp,
+    numberOfSpacers: Int,
+    touchExplorationServicesEnabled: Boolean,
+    pickerGroupState: PickerGroupState
+): Dp {
+    // Calculates the extra offset named currentOffset because the total content width is more than the screen width
+    var finalRowOffset = 0.dp
+    val totalContentWidth =
+        (dayPickerWidth + monthPickerWidth + yearPickerWidth + (spacerWidth * numberOfSpacers))
+    val currentOffset = (rowWidth - totalContentWidth) / 2
 
-// This is a demo file, suppressing the annotation group error.
-@SuppressLint("NullAnnotationGroup")
-@OptIn(ExperimentalComposeUiApi::class)
-@Composable
-internal fun TimePiece(
-    selected: Boolean,
-    onSelected: () -> Unit,
-    text: String,
-    style: TextStyle,
-    touchExplorationServicesEnabled: Boolean = false
-) {
-    Box(modifier = Modifier.fillMaxSize()) {
-        val modifier = Modifier
-            .align(Alignment.Center)
-            .wrapContentSize()
-        Text(
-            text = text,
-            maxLines = 1,
-            style = style,
-            color =
-            if (selected) MaterialTheme.colors.secondary
-            else MaterialTheme.colors.onBackground,
-            modifier =
-            if (selected || touchExplorationServicesEnabled) modifier
-            else modifier.pointerInteropFilter {
-                if (it.action == MotionEvent.ACTION_DOWN) onSelected()
-                true
-            },
-        )
+    if (touchExplorationServicesEnabled &&
+        pickerGroupState.selectedIndex < 0 // When talkback is on and no picker is selected
+    ) {
+        finalRowOffset = ((rowWidth - dayPickerWidth) / 2) - currentOffset
+    } else if (touchExplorationServicesEnabled &&
+        pickerGroupState.selectedIndex > 2 // When talkback is on and focus goes to confirm button
+    ) {
+        finalRowOffset = ((rowWidth - yearPickerWidth) / 2) -
+            (dayPickerWidth + monthPickerWidth + (spacerWidth * numberOfSpacers) + currentOffset)
     }
+
+    return finalRowOffset
 }
 
 @Composable
@@ -862,38 +822,6 @@
 )
 
 @Composable
-fun PickerWithRSB(
-    state: PickerState,
-    readOnly: Boolean,
-    modifier: Modifier,
-    focusRequester: FocusRequester,
-    contentDescription: String?,
-    readOnlyLabel: @Composable (BoxScope.() -> Unit)? = null,
-    userScrollEnabled: Boolean = true,
-    flingBehavior: FlingBehavior = PickerDefaults.flingBehavior(state = state),
-    onSelected: () -> Unit = {},
-    option: @Composable PickerScope.(optionIndex: Int) -> Unit
-) {
-    Picker(
-        state = state,
-        modifier = if (userScrollEnabled) {
-            modifier.rsbScroll(
-                scrollableState = state,
-                flingBehavior = flingBehavior,
-                focusRequester = focusRequester,
-            )
-        } else modifier,
-        flingBehavior = flingBehavior,
-        readOnly = readOnly,
-        readOnlyLabel = readOnlyLabel,
-        userScrollEnabled = userScrollEnabled,
-        onSelected = onSelected,
-        contentDescription = contentDescription,
-        option = option
-    )
-}
-
-@Composable
 fun PickerWithoutGradient() {
     val items = listOf("One", "Two", "Three", "Four", "Five")
     val state = rememberPickerState(items.size)
@@ -934,17 +862,6 @@
     }
 }
 
-private fun Modifier.scrollablePicker(
-    pickerState: PickerState
-) = Modifier.composed {
-    this.scrollable(
-        state = pickerState,
-        orientation = Orientation.Vertical,
-        flingBehavior = PickerDefaults.flingBehavior(state = pickerState),
-        reverseDirection = true
-    )
-}
-
 private fun createDescription(
     pickerGroupState: PickerGroupState,
     selectedValue: Int,
@@ -976,18 +893,13 @@
 }
 
 private fun createDescriptionDatePicker(
-    focusedElement: FocusableElementDatePicker,
+    pickerGroupState: PickerGroupState,
     selectedValue: Int,
     label: String
 ): String {
-    return when (focusedElement) {
-        FocusableElementDatePicker.DAY -> {
-            "$selectedValue"
-        }
-        FocusableElementDatePicker.YEAR -> {
-            "$selectedValue"
-        }
-        else -> label
+    return when (pickerGroupState.selectedIndex) {
+        FocusableElementDatePicker.NONE.index -> label
+        else -> "$label, $selectedValue"
     }
 }
 
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/dimension.proto b/wear/protolayout/protolayout-proto/src/main/proto/dimension.proto
index 5dc5751..2a15694 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/dimension.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/dimension.proto
@@ -150,9 +150,9 @@
   }
 }
 
-// A dimension that can be applied to a VendorExtension element.
-message VendorExtensionDimension {
-  oneof inner {
+// A dimension that can be applied to a ExtensionLayoutElement element.
+message ExtensionDimension {
+      oneof inner {
     DpProp linear_dimension = 1;
   }
 }
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/layout.proto b/wear/protolayout/protolayout-proto/src/main/proto/layout.proto
index 1403194..db32f5c 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/layout.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/layout.proto
@@ -47,8 +47,8 @@
   // Font variant suited for body text.
   FONT_VARIANT_BODY = 2;
 
-  // Font variant suited for Vendor specified use.
-  FONT_VARIANT_VENDOR_1 = 3;
+  // Placeholder for a custom font variant in the renderer.
+  FONT_VARIANT_EXTENSION_1 = 3;
 }
 
 // An extensible FontVariant property.
@@ -657,28 +657,30 @@
   BoolProp rotate_contents = 2;
 }
 
-// A layout element which can be defined by a vendor renderer extension. The
-// payload in this message will be passed verbatim to any registered vendor
-// extension in the layout renderer. It is then expected that the extension can
+// A layout element which can be defined by a renderer extension. The
+// payload in this message will be passed verbatim to any registered renderer
+// extension in the renderer. It is then expected that the extension can
 // parse this message, and emit the relevant element.
 //
-// If a vendor extension is not installed, this resource will not render
+// If a renderer extension is not installed, this resource will not render
 // any element, although the specified space will still be occupied. If the
-// payload cannot be parsed by the vendor extension, then still nothing should
-// be rendered, although this behaviour is defined by the vendor extension.
-message VendorExtension {
-  // The content of the vendor extension. This can be any data; it is expected
-  // that the vendor extension knows how to parse this field.
+// payload cannot be parsed by the renderer extension, then still nothing should
+// be rendered, although this behaviour is defined by the renderer extension.
+message ExtensionLayoutElement {
+
+    // The content of the renderer extension element. This can be any data; it is
+  // expected that the renderer extension knows how to parse this field.
   bytes payload = 1;
 
-  // The Vendor ID that this extension is for.
-  string vendor_id = 2;
+  // The ID of the renderer extension that should be used for rendering this
+  // layout element.
+  string extension_id = 2;
 
   // The width of this element.
-  VendorExtensionDimension width = 3;
+  ExtensionDimension width = 3;
 
   // The height of this element.
-  VendorExtensionDimension height = 4;
+  ExtensionDimension height = 4;
 }
 
 // The root of all layout elements. This exists to act as a holder for all of
@@ -693,7 +695,8 @@
     Image image = 6;
     Arc arc = 7;
     Spannable spannable = 8;
-    VendorExtension vendor_extension = 1000;
+
+    ExtensionLayoutElement extension = 1000;
   }
 }
 
diff --git a/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflater.java b/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflater.java
index bc82951..de2ee97 100644
--- a/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflater.java
+++ b/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflater.java
@@ -3151,7 +3151,7 @@
                                 nodePosId,
                                 pipelineMaker);
                 break;
-            case VENDOR_EXTENSION:
+            case EXTENSION:
                 // TODO(b/276703002): Add support for vendor extension.
                 break;
             case INNER_NOT_SET:
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java
index 404813e..f97ed264 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java
@@ -89,8 +89,14 @@
      * can be selected using this field.
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY)
-    @IntDef({FONT_VARIANT_UNDEFINED, FONT_VARIANT_TITLE, FONT_VARIANT_BODY})
+    @IntDef({
+            FONT_VARIANT_UNDEFINED,
+            FONT_VARIANT_TITLE,
+            FONT_VARIANT_BODY,
+            FONT_VARIANT_CUSTOM_1
+    })
     @Retention(RetentionPolicy.SOURCE)
+    @OptIn(markerClass = ProtoLayoutExperimental.class)
     public @interface FontVariant {}
 
     /** Font variant is undefined. */
@@ -102,6 +108,13 @@
     /** Font variant suited for body text. */
     public static final int FONT_VARIANT_BODY = 2;
 
+    /** Renderer dependent Font variant. If not supported, will behave similar to
+     *  {@link #FONT_VARIANT_UNDEFINED}.
+     */
+    @ProtoLayoutExperimental
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    public static final int FONT_VARIANT_CUSTOM_1 = 3;
+
     /**
      * The alignment of a {@link SpanImage} within the line height of the surrounding {@link
      * Spannable}.
diff --git a/wear/tiles/tiles/api/current.txt b/wear/tiles/tiles/api/current.txt
index beab05b..45fe573 100644
--- a/wear/tiles/tiles/api/current.txt
+++ b/wear/tiles/tiles/api/current.txt
@@ -250,35 +250,43 @@
   }
 
   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 {
@@ -873,6 +881,7 @@
     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();
   }
 
@@ -882,6 +891,7 @@
     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);
   }
 
@@ -890,6 +900,7 @@
     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 {
@@ -899,6 +910,7 @@
     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 {
diff --git a/wear/tiles/tiles/api/public_plus_experimental_current.txt b/wear/tiles/tiles/api/public_plus_experimental_current.txt
index 1a18796..0b4241a 100644
--- a/wear/tiles/tiles/api/public_plus_experimental_current.txt
+++ b/wear/tiles/tiles/api/public_plus_experimental_current.txt
@@ -250,35 +250,43 @@
   }
 
   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 {
@@ -889,6 +897,7 @@
     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();
   }
 
@@ -898,6 +907,7 @@
     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);
   }
 
@@ -906,6 +916,7 @@
     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 {
@@ -915,6 +926,7 @@
     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 {
diff --git a/wear/tiles/tiles/api/restricted_current.txt b/wear/tiles/tiles/api/restricted_current.txt
index beab05b..45fe573 100644
--- a/wear/tiles/tiles/api/restricted_current.txt
+++ b/wear/tiles/tiles/api/restricted_current.txt
@@ -250,35 +250,43 @@
   }
 
   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 {
@@ -873,6 +881,7 @@
     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();
   }
 
@@ -882,6 +891,7 @@
     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);
   }
 
@@ -890,6 +900,7 @@
     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 {
@@ -899,6 +910,7 @@
     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 {
diff --git a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/EventBuilders.java b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/EventBuilders.java
index 96a8f60..0d962f5 100644
--- a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/EventBuilders.java
+++ b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/EventBuilders.java
@@ -37,6 +37,18 @@
             this.mImpl = impl;
         }
 
+
+        /**
+         * Gets the instance ID of the tile, allocated when the tile instance is added to the
+         * carousel. This ID will remain the same for this tile instance as long it is not removed
+         * from the carousel.
+         *
+         * @since 1.0
+         */
+        public int getTileId() {
+            return mImpl.getTileId();
+        }
+
         /**
          * Creates a new wrapper instance from the proto.
          *
@@ -57,11 +69,11 @@
             return mImpl;
         }
 
-        @Override
-        @NonNull
-        public String toString() {
-            return "TileAddEvent{" + "}";
-        }
+    @Override
+    @NonNull
+    public String toString() {
+      return "TileAddEvent{" + "tileId=" + getTileId() + "}";
+    }
 
         /** Builder for {@link TileAddEvent} */
         public static final class Builder {
@@ -70,6 +82,17 @@
 
             public Builder() {}
 
+            /**
+             * Sets the ID of the tile added to the carousel.
+             *
+             * @since 1.0
+             */
+            @NonNull
+            public Builder setTileId(int tileId) {
+                mImpl.setTileId(tileId);
+                return this;
+            }
+
             /** Builds an instance from accumulated values. */
             @NonNull
             public TileAddEvent build() {
@@ -91,6 +114,17 @@
         }
 
         /**
+         * Gets the instance ID of the tile, allocated when the tile instance is added to the
+         * carousel. This ID will remain the same for this tile instance as long it is not removed
+         * from the carousel.
+         *
+         * @since 1.0
+         */
+        public int getTileId() {
+            return mImpl.getTileId();
+        }
+
+        /**
          * Creates a new wrapper instance from the proto.
          *
          */
@@ -110,11 +144,11 @@
             return mImpl;
         }
 
-        @Override
-        @NonNull
-        public String toString() {
-            return "TileRemoveEvent{" + "}";
-        }
+    @Override
+    @NonNull
+    public String toString() {
+      return "TileRemoveEvent{" + "tileId=" + getTileId() + "}";
+    }
 
         /** Builder for {@link TileRemoveEvent} */
         public static final class Builder {
@@ -123,6 +157,17 @@
 
             public Builder() {}
 
+            /**
+             * Sets the ID of the tile removed from the carousel.
+             *
+             * @since 1.0
+             */
+            @NonNull
+            public Builder setTileId(int tileId) {
+                mImpl.setTileId(tileId);
+                return this;
+            }
+
             /** Builds an instance from accumulated values. */
             @NonNull
             public TileRemoveEvent build() {
@@ -144,6 +189,17 @@
         }
 
         /**
+         * Gets the instance ID of the tile, allocated when the tile instance is added to the
+         * carousel. This ID will remain the same for this tile instance as long it is not removed
+         * from the carousel.
+         *
+         * @since 1.0
+         */
+        public int getTileId() {
+            return mImpl.getTileId();
+        }
+
+        /**
          * Creates a new wrapper instance from the proto.
          *
          */
@@ -163,11 +219,11 @@
             return mImpl;
         }
 
-        @Override
-        @NonNull
-        public String toString() {
-            return "TileEnterEvent{" + "}";
-        }
+    @Override
+    @NonNull
+    public String toString() {
+      return "TileEnterEvent{" + "tileId=" + getTileId() + "}";
+    }
 
         /** Builder for {@link TileEnterEvent} */
         public static final class Builder {
@@ -176,6 +232,17 @@
 
             public Builder() {}
 
+            /**
+             * Sets the ID of the entered tile.
+             *
+             * @since 1.0
+             */
+            @NonNull
+            public Builder setTileId(int tileId) {
+                mImpl.setTileId(tileId);
+                return this;
+            }
+
             /** Builds an instance from accumulated values. */
             @NonNull
             public TileEnterEvent build() {
@@ -198,6 +265,17 @@
         }
 
         /**
+         * Gets the instance ID of the tile, allocated when the tile instance is added to the
+         * carousel. This ID will remain the same for this tile instance as long it is not removed
+         * from the carousel.
+         *
+         * @since 1.0
+         */
+        public int getTileId() {
+            return mImpl.getTileId();
+        }
+
+        /**
          * Creates a new wrapper instance from the proto.
          *
          */
@@ -220,7 +298,10 @@
         @Override
         @NonNull
         public String toString() {
-            return "TileLeaveEvent{" + "}";
+            return "TileLeaveEvent{"
+                    + "tileId="
+                    + getTileId()
+                    + "}";
         }
 
         /** Builder for {@link TileLeaveEvent} */
@@ -230,6 +311,17 @@
 
             public Builder() {}
 
+            /**
+             * Sets the ID of the tile.
+             *
+             * @since 1.0
+             */
+            @NonNull
+            public Builder setTileId(int tileId) {
+                mImpl.setTileId(tileId);
+                return this;
+            }
+
             /** Builds an instance from accumulated values. */
             @NonNull
             public TileLeaveEvent build() {
diff --git a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/RequestBuilders.java b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/RequestBuilders.java
index 00023c6..cde0e81 100644
--- a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/RequestBuilders.java
+++ b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/RequestBuilders.java
@@ -76,6 +76,17 @@
         }
 
         /**
+         * Gets the instance ID of the tile being requested, allocated when the tile instance is
+         * added to the carousel. This ID will remain the same for this tile instance as long it
+         * is not removed from the carousel.
+         *
+         * @since 1.0
+         */
+        public int getTileId() {
+            return mImpl.getTileId();
+        }
+
+        /**
          * Gets the {@link androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters} object
          * describing the device requesting the tile update.
          *
@@ -157,6 +168,17 @@
             }
 
             /**
+             * Sets the ID of the tile being requested.
+             *
+             * @since 1.0
+             */
+            @NonNull
+            public Builder setTileId(int tileId) {
+                mImpl.setTileId(tileId);
+                return this;
+            }
+
+            /**
              * Sets a {@link androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters} object
              * describing the device requesting the tile update.
              *
@@ -252,6 +274,17 @@
         }
 
         /**
+         * Gets the instance ID of the tile for which resources are being requested, allocated when
+         * the tile instance is added to the carousel. This ID will remain the same for this tile
+         * instance as long it is not removed from the carousel.
+         *
+         * @since 1.0
+         */
+        public int getTileId() {
+            return mImpl.getTileId();
+        }
+
+        /**
          * Gets the {@link androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters} object
          * describing the device requesting the resources.
          *
@@ -334,6 +367,17 @@
             }
 
             /**
+             * Sets the ID of the tile for which resources are being requested.
+             *
+             * @since 1.0
+             */
+            @NonNull
+            public Builder setTileId(int tileId) {
+                mImpl.setTileId(tileId);
+                return this;
+            }
+
+            /**
              * Sets a {@link androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters} object
              * describing the device requesting the resources.
              *
diff --git a/wear/tiles/tiles/src/test/java/androidx/wear/tiles/TileServiceTest.java b/wear/tiles/tiles/src/test/java/androidx/wear/tiles/TileServiceTest.java
index 8f414a4..4bd3db4 100644
--- a/wear/tiles/tiles/src/test/java/androidx/wear/tiles/TileServiceTest.java
+++ b/wear/tiles/tiles/src/test/java/androidx/wear/tiles/TileServiceTest.java
@@ -194,6 +194,7 @@
         shadowOf(Looper.getMainLooper()).idle();
 
         expect.that(mFakeTileServiceController.get().mOnTileAddCalled).isTrue();
+        expect.that(mFakeTileServiceController.get().mTileId).isEqualTo(TILE_ID);
     }
 
     @Test
@@ -206,6 +207,7 @@
         shadowOf(Looper.getMainLooper()).idle();
 
         expect.that(mFakeTileServiceController.get().mOnTileRemoveCalled).isTrue();
+        expect.that(mFakeTileServiceController.get().mTileId).isEqualTo(TILE_ID);
     }
 
     @Test
@@ -218,6 +220,7 @@
         shadowOf(Looper.getMainLooper()).idle();
 
         expect.that(mFakeTileServiceController.get().mOnTileEnterCalled).isTrue();
+        expect.that(mFakeTileServiceController.get().mTileId).isEqualTo(TILE_ID);
     }
 
     @Test
@@ -230,6 +233,23 @@
         shadowOf(Looper.getMainLooper()).idle();
 
         expect.that(mFakeTileServiceController.get().mOnTileLeaveCalled).isTrue();
+        expect.that(mFakeTileServiceController.get().mTileId).isEqualTo(TILE_ID);
+    }
+
+    @Test
+    public void tileService_tileRequest_setsTileId() throws Exception {
+        mTileProviderServiceStub.onTileRequest(
+                TILE_ID,
+                new TileRequestData(
+                        RequestProto.TileRequest.newBuilder()
+                                .build()
+                                .toByteArray(),
+                        TileRequestData.VERSION_PROTOBUF),
+                mMockTileCallback);
+
+        shadowOf(Looper.getMainLooper()).idle();
+
+        expect.that(mFakeTileServiceController.get().mTileId).isEqualTo(TILE_ID);
     }
 
     @Test
@@ -291,6 +311,23 @@
     }
 
     @Test
+    public void tileService_resourcesRequest_setsTileId() throws Exception {
+        // Resources request needs to have DeviceParameters least to fill in the default.
+        mTileProviderServiceStub.onResourcesRequest(
+                TILE_ID,
+                new ResourcesRequestData(
+                        RequestProto.ResourcesRequest.newBuilder()
+                                .build()
+                                .toByteArray(),
+                        ResourcesRequestData.VERSION_PROTOBUF),
+                mMockResourcesCallback);
+
+        shadowOf(Looper.getMainLooper()).idle();
+
+        expect.that(mFakeTileServiceController.get().mTileId).isEqualTo(TILE_ID);
+    }
+
+    @Test
     public void tileService_resourcesRequest_defaultVersionIfNotSet() throws Exception {
         // Resources request needs to have DeviceParameters least to fill in the default.
         mTileProviderServiceStub.onResourcesRequest(
@@ -402,25 +439,30 @@
         @Nullable TileRequest mTileRequestParams = null;
         @Nullable ResourcesRequest mResourcesRequestParams = null;
         @Nullable RuntimeException mRequestFailure = null;
+        int mTileId = -1;
 
         @Override
         protected void onTileAddEvent(@NonNull TileAddEvent requestParams) {
             mOnTileAddCalled = true;
+            mTileId = requestParams.getTileId();
         }
 
         @Override
         protected void onTileRemoveEvent(@NonNull TileRemoveEvent requestParams) {
             mOnTileRemoveCalled = true;
+            mTileId = requestParams.getTileId();
         }
 
         @Override
         protected void onTileEnterEvent(@NonNull TileEnterEvent requestParams) {
             mOnTileEnterCalled = true;
+            mTileId = requestParams.getTileId();
         }
 
         @Override
         protected void onTileLeaveEvent(@NonNull TileLeaveEvent requestParams) {
             mOnTileLeaveCalled = true;
+            mTileId = requestParams.getTileId();
         }
 
         @Override
@@ -428,6 +470,7 @@
         protected ListenableFuture<TileBuilders.Tile> onTileRequest(
                 @NonNull TileRequest requestParams) {
             mTileRequestParams = requestParams;
+            mTileId = requestParams.getTileId();
             if (mRequestFailure != null) {
                 return Futures.immediateFailedFuture(mRequestFailure);
             }
@@ -439,6 +482,7 @@
         protected ListenableFuture<Resources> onTileResourcesRequest(
                 @NonNull ResourcesRequest requestParams) {
             mResourcesRequestParams = requestParams;
+            mTileId = requestParams.getTileId();
             if (mRequestFailure != null) {
                 return Futures.immediateFailedFuture(mRequestFailure);
             }
diff --git a/wear/watchface/watchface-client/api/api_lint.ignore b/wear/watchface/watchface-client/api/api_lint.ignore
index b09bed7..abc1577 100644
--- a/wear/watchface/watchface-client/api/api_lint.ignore
+++ b/wear/watchface/watchface-client/api/api_lint.ignore
@@ -1,3 +1,7 @@
 // Baseline format: 1.0
-ListenerLast: androidx.wear.watchface.client.WatchFaceControlClient#getOrCreateInteractiveWatchFaceClient(String, androidx.wear.watchface.client.DeviceConfig, androidx.wear.watchface.client.WatchUiState, androidx.wear.watchface.style.UserStyleData, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>, java.util.concurrent.Executor, androidx.wear.watchface.client.WatchFaceControlClient.PreviewImageUpdateRequestedListener, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>) parameter #7:
-    Listeners should always be at end of argument list (method `getOrCreateInteractiveWatchFaceClient`)
+GetterSetterNames: field ComplicationSlotMetadata.fixedComplicationDataSource:
+    Invalid name for boolean property `fixedComplicationDataSource`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ComplicationSlotState.fixedComplicationDataSource:
+    Invalid name for boolean property `fixedComplicationDataSource`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field WatchUiState.inAmbientMode:
+    Invalid name for boolean property `inAmbientMode`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/wear/watchface/watchface-complications-data-source/api/api_lint.ignore b/wear/watchface/watchface-complications-data-source/api/api_lint.ignore
index 51e6476..399a31e 100644
--- a/wear/watchface/watchface-complications-data-source/api/api_lint.ignore
+++ b/wear/watchface/watchface-complications-data-source/api/api_lint.ignore
@@ -1,4 +1,8 @@
 // Baseline format: 1.0
+GetterSetterNames: field ComplicationRequest.immediateResponseRequired:
+    Invalid name for boolean property `immediateResponseRequired`. Should start with one of `has`, `can`, `should`, `is`.
+
+
 InvalidNullabilityOverride: androidx.wear.watchface.complications.datasource.ComplicationDataSourceService#onBind(android.content.Intent):
     Invalid nullability on method `onBind` return. Overrides of unannotated super method cannot be Nullable.
 InvalidNullabilityOverride: androidx.wear.watchface.complications.datasource.ComplicationDataSourceService#onBind(android.content.Intent) parameter #0:
diff --git a/wear/watchface/watchface-complications-data/api/api_lint.ignore b/wear/watchface/watchface-complications-data/api/api_lint.ignore
index 36ca3c6..6481583 100644
--- a/wear/watchface/watchface-complications-data/api/api_lint.ignore
+++ b/wear/watchface/watchface-complications-data/api/api_lint.ignore
@@ -1,4 +1,10 @@
 // Baseline format: 1.0
+GetterSetterNames: field ColorRamp.interpolated:
+    Invalid name for boolean property `interpolated`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ComplicationData.tapActionLostDueToSerialization:
+    Invalid name for boolean property `tapActionLostDueToSerialization`. Should start with one of `has`, `can`, `should`, `is`.
+
+
 MissingGetterMatchingBuilder: androidx.wear.watchface.complications.data.TimeDifferenceComplicationText.Builder#setDisplayAsNow(boolean):
     androidx.wear.watchface.complications.data.TimeDifferenceComplicationText does not declare a `isDisplayAsNow()` method matching method androidx.wear.watchface.complications.data.TimeDifferenceComplicationText.Builder.setDisplayAsNow(boolean)
 MissingGetterMatchingBuilder: androidx.wear.watchface.complications.data.TimeDifferenceComplicationText.Builder#setText(CharSequence):
diff --git a/wear/watchface/watchface-editor-guava/api/api_lint.ignore b/wear/watchface/watchface-editor-guava/api/api_lint.ignore
index 1276c29..493947c 100644
--- a/wear/watchface/watchface-editor-guava/api/api_lint.ignore
+++ b/wear/watchface/watchface-editor-guava/api/api_lint.ignore
@@ -5,3 +5,7 @@
     Methods returning com.google.common.util.concurrent.ListenableFuture should have a suffix *Async to reserve unmodified name for a suspend function
 AsyncSuffixFuture: androidx.wear.watchface.editor.ListenableEditorSession.Companion#listenableCreateOnWatchEditorSession(androidx.activity.ComponentActivity):
     Methods returning com.google.common.util.concurrent.ListenableFuture should have a suffix *Async to reserve unmodified name for a suspend function
+
+
+GetterSetterNames: field ListenableEditorSession.commitChangesOnClose:
+    Invalid name for boolean property `commitChangesOnClose`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/wear/watchface/watchface-editor/api/api_lint.ignore b/wear/watchface/watchface-editor/api/api_lint.ignore
index d7ed79d..f504b74 100644
--- a/wear/watchface/watchface-editor/api/api_lint.ignore
+++ b/wear/watchface/watchface-editor/api/api_lint.ignore
@@ -7,3 +7,7 @@
     Methods must not throw unchecked exceptions
 BannedThrow: androidx.wear.watchface.editor.EditorSession.Companion#createOnWatchEditorSession(androidx.activity.ComponentActivity, kotlin.coroutines.Continuation<? super androidx.wear.watchface.editor.EditorSession>):
     Methods must not throw unchecked exceptions
+
+
+GetterSetterNames: field EditorSession.commitChangesOnClose:
+    Invalid name for boolean property `commitChangesOnClose`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/wear/watchface/watchface-style/api/api_lint.ignore b/wear/watchface/watchface-style/api/api_lint.ignore
new file mode 100644
index 0000000..a8815f1
--- /dev/null
+++ b/wear/watchface/watchface-style/api/api_lint.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+GetterSetterNames: field UserStyleSetting.BooleanUserStyleSetting.BooleanOption.value:
+    Invalid name for boolean property `value`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/wear/watchface/watchface/api/api_lint.ignore b/wear/watchface/watchface/api/api_lint.ignore
index c4ab5b2..85d6935 100644
--- a/wear/watchface/watchface/api/api_lint.ignore
+++ b/wear/watchface/watchface/api/api_lint.ignore
@@ -1,4 +1,16 @@
 // Baseline format: 1.0
+GetterSetterNames: field ComplicationSlot.enabled:
+    Invalid name for boolean property `enabled`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ComplicationSlot.fixedComplicationDataSource:
+    Invalid name for boolean property `fixedComplicationDataSource`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ComplicationSlot.initiallyEnabled:
+    Invalid name for boolean property `initiallyEnabled`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Renderer.CanvasRenderer.clearWithBackgroundTintBeforeRenderingHighlightLayer:
+    Invalid name for boolean property `clearWithBackgroundTintBeforeRenderingHighlightLayer`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field WatchFace.LegacyWatchFaceOverlayStyle.tapEventsAccepted:
+    Invalid name for boolean property `tapEventsAccepted`. Should start with one of `has`, `can`, `should`, `is`.
+
+
 InvalidNullabilityOverride: androidx.wear.watchface.WatchFaceService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
     Invalid nullability on parameter `fd` in method `dump`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.wear.watchface.WatchFaceService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
diff --git a/wear/wear/api/api_lint.ignore b/wear/wear/api/api_lint.ignore
index 5be9b59..61244fa 100644
--- a/wear/wear/api/api_lint.ignore
+++ b/wear/wear/api/api_lint.ignore
@@ -25,6 +25,10 @@
     Symmetric method for `isAutoPeekEnabled` must be named `setAutoPeekEnabled`; was `setIsAutoPeekEnabled`
 GetterSetterNames: androidx.wear.widget.drawer.WearableDrawerView#setIsLocked(boolean):
     Symmetric method for `isLocked` must be named `setLocked`; was `setIsLocked`
+GetterSetterNames: field AmbientLifecycleObserver.AmbientDetails.burnInProtectionRequired:
+    Invalid name for boolean property `burnInProtectionRequired`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field AmbientLifecycleObserver.AmbientDetails.deviceHasLowBitAmbient:
+    Invalid name for boolean property `deviceHasLowBitAmbient`. Should start with one of `has`, `can`, `should`, `is`.
 
 
 InvalidNullabilityOverride: androidx.wear.widget.ArcLayout#checkLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
diff --git a/window/extensions/extensions/build.gradle b/window/extensions/extensions/build.gradle
index 8830606..279cbba 100644
--- a/window/extensions/extensions/build.gradle
+++ b/window/extensions/extensions/build.gradle
@@ -26,7 +26,7 @@
     api(libs.kotlinStdlib)
     implementation("androidx.annotation:annotation:1.6.0")
     implementation("androidx.annotation:annotation-experimental:1.1.0")
-    implementation("androidx.window.extensions.core:core:1.0.0-beta01")
+    implementation("androidx.window.extensions.core:core:1.0.0-rc01")
 
     testImplementation(libs.robolectric)
     testImplementation(libs.testExtJunit)
diff --git a/window/window/api/api_lint.ignore b/window/window/api/api_lint.ignore
new file mode 100644
index 0000000..24bf744
--- /dev/null
+++ b/window/window/api/api_lint.ignore
@@ -0,0 +1,7 @@
+// Baseline format: 1.0
+GetterSetterNames: field ActivityRule.alwaysExpand:
+    Invalid name for boolean property `alwaysExpand`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field SplitAttributesCalculatorParams.areDefaultConstraintsSatisfied:
+    Invalid name for boolean property `areDefaultConstraintsSatisfied`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field SplitPairRule.clearTop:
+    Invalid name for boolean property `clearTop`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/window/window/build.gradle b/window/window/build.gradle
index 32d38d8..4e4170e 100644
--- a/window/window/build.gradle
+++ b/window/window/build.gradle
@@ -49,9 +49,11 @@
     implementation("androidx.collection:collection:1.1.0")
     implementation("androidx.core:core:1.8.0")
 
-    implementation("androidx.window.extensions.core:core:1.0.0-beta01")
+    def extensions_core_version = "androidx.window.extensions.core:core:1.0.0-rc01"
+    def extensions_version = "androidx.window.extensions:extensions:1.1.0-rc01"
+    implementation(extensions_core_version)
     compileOnly(project(":window:sidecar:sidecar"))
-    compileOnly("androidx.window.extensions:extensions:1.1.0-beta01")
+    compileOnly(extensions_version)
 
     testImplementation(libs.testCore)
     testImplementation(libs.testRunner)
@@ -61,9 +63,9 @@
     testImplementation(libs.mockitoCore4)
     testImplementation(libs.mockitoKotlin4)
     testImplementation(libs.kotlinCoroutinesTest)
-    testImplementation("androidx.window.extensions.core:core:1.0.0-beta01")
+    testImplementation(extensions_core_version)
     testImplementation(compileOnly(project(":window:sidecar:sidecar")))
-    testImplementation(compileOnly("androidx.window.extensions:extensions:1.1.0-beta01"))
+    testImplementation(compileOnly(extensions_version))
 
     androidTestImplementation(libs.testCore)
     androidTestImplementation(libs.kotlinTestJunit)
@@ -77,9 +79,9 @@
     androidTestImplementation(libs.multidex)
     androidTestImplementation(libs.truth)
     androidTestImplementation(libs.junit) // Needed for Assert.assertThrows
-    androidTestImplementation("androidx.window.extensions.core:core:1.0.0-beta01")
+    androidTestImplementation(extensions_core_version)
     androidTestImplementation(compileOnly(project(":window:sidecar:sidecar")))
-    androidTestImplementation(compileOnly("androidx.window.extensions:extensions:1.1.0-beta01"))
+    androidTestImplementation(compileOnly(extensions_version))
 }
 
 androidx {
diff --git a/window/window/src/main/java/androidx/window/layout/SafeWindowLayoutComponentProvider.kt b/window/window/src/main/java/androidx/window/layout/SafeWindowLayoutComponentProvider.kt
index fdc25a2..bc0dac5 100644
--- a/window/window/src/main/java/androidx/window/layout/SafeWindowLayoutComponentProvider.kt
+++ b/window/window/src/main/java/androidx/window/layout/SafeWindowLayoutComponentProvider.kt
@@ -101,7 +101,6 @@
      */
     private fun hasValidVendorApiLevel2(): Boolean {
         return hasValidVendorApiLevel1() &&
-            isMethodWindowLayoutInfoListenerJavaConsumerUiContextValid() &&
             isMethodWindowLayoutInfoListenerWindowConsumerValid()
     }
 
@@ -179,24 +178,6 @@
         }
     }
 
-    private fun isMethodWindowLayoutInfoListenerJavaConsumerUiContextValid(): Boolean {
-        return validateReflection(
-            "WindowLayoutComponent#addWindowLayoutInfoListener" +
-                "(${Context::class.java.name}, $JAVA_CONSUMER) is not valid"
-        ) {
-            val consumerClass =
-                consumerAdapter.consumerClassOrNull() ?: return@validateReflection false
-            val windowLayoutComponent = windowLayoutComponentClass
-            val addListenerMethod = windowLayoutComponent
-                .getMethod(
-                    "addWindowLayoutInfoListener",
-                    Context::class.java,
-                    consumerClass
-                )
-            addListenerMethod.isPublic
-        }
-    }
-
     private val windowExtensionsProviderClass: Class<*>
         get() {
             return loader.loadClass(WINDOW_EXTENSIONS_PROVIDER_CLASS)