Merge "Reduce re-reading state in compositions" into androidx-main
diff --git a/activity/activity/api/current.txt b/activity/activity/api/current.txt
index efb5f4a..7d61b26 100644
--- a/activity/activity/api/current.txt
+++ b/activity/activity/api/current.txt
@@ -59,9 +59,9 @@
   }
 
   public final class EdgeToEdge {
-    method public static void setUp(androidx.activity.ComponentActivity, optional androidx.activity.SystemBarStyle statusBarStyle, optional androidx.activity.SystemBarStyle navigationBarStyle);
-    method public static void setUp(androidx.activity.ComponentActivity, optional androidx.activity.SystemBarStyle statusBarStyle);
-    method public static void setUp(androidx.activity.ComponentActivity);
+    method public static void enable(androidx.activity.ComponentActivity, optional androidx.activity.SystemBarStyle statusBarStyle, optional androidx.activity.SystemBarStyle navigationBarStyle);
+    method public static void enable(androidx.activity.ComponentActivity, optional androidx.activity.SystemBarStyle statusBarStyle);
+    method public static void enable(androidx.activity.ComponentActivity);
   }
 
   public final class FullyDrawnReporter {
diff --git a/activity/activity/api/public_plus_experimental_current.txt b/activity/activity/api/public_plus_experimental_current.txt
index efb5f4a..7d61b26 100644
--- a/activity/activity/api/public_plus_experimental_current.txt
+++ b/activity/activity/api/public_plus_experimental_current.txt
@@ -59,9 +59,9 @@
   }
 
   public final class EdgeToEdge {
-    method public static void setUp(androidx.activity.ComponentActivity, optional androidx.activity.SystemBarStyle statusBarStyle, optional androidx.activity.SystemBarStyle navigationBarStyle);
-    method public static void setUp(androidx.activity.ComponentActivity, optional androidx.activity.SystemBarStyle statusBarStyle);
-    method public static void setUp(androidx.activity.ComponentActivity);
+    method public static void enable(androidx.activity.ComponentActivity, optional androidx.activity.SystemBarStyle statusBarStyle, optional androidx.activity.SystemBarStyle navigationBarStyle);
+    method public static void enable(androidx.activity.ComponentActivity, optional androidx.activity.SystemBarStyle statusBarStyle);
+    method public static void enable(androidx.activity.ComponentActivity);
   }
 
   public final class FullyDrawnReporter {
diff --git a/activity/activity/api/restricted_current.txt b/activity/activity/api/restricted_current.txt
index 600cec5..dc7e159 100644
--- a/activity/activity/api/restricted_current.txt
+++ b/activity/activity/api/restricted_current.txt
@@ -58,9 +58,9 @@
   }
 
   public final class EdgeToEdge {
-    method public static void setUp(androidx.activity.ComponentActivity, optional androidx.activity.SystemBarStyle statusBarStyle, optional androidx.activity.SystemBarStyle navigationBarStyle);
-    method public static void setUp(androidx.activity.ComponentActivity, optional androidx.activity.SystemBarStyle statusBarStyle);
-    method public static void setUp(androidx.activity.ComponentActivity);
+    method public static void enable(androidx.activity.ComponentActivity, optional androidx.activity.SystemBarStyle statusBarStyle, optional androidx.activity.SystemBarStyle navigationBarStyle);
+    method public static void enable(androidx.activity.ComponentActivity, optional androidx.activity.SystemBarStyle statusBarStyle);
+    method public static void enable(androidx.activity.ComponentActivity);
   }
 
   public final class FullyDrawnReporter {
diff --git a/activity/activity/src/androidTest/java/androidx/activity/EdgeToEdgeTest.kt b/activity/activity/src/androidTest/java/androidx/activity/EdgeToEdgeTest.kt
index bd3a8a8..a92f11b 100644
--- a/activity/activity/src/androidTest/java/androidx/activity/EdgeToEdgeTest.kt
+++ b/activity/activity/src/androidTest/java/androidx/activity/EdgeToEdgeTest.kt
@@ -33,10 +33,10 @@
 class EdgeToEdgeTest {
 
     @Test
-    fun setUpAuto() {
+    fun enableAuto() {
         withUse(ActivityScenario.launch(ComponentActivity::class.java)) {
             withActivity {
-                setUpEdgeToEdge()
+                enableEdgeToEdge()
                 val view = window.decorView
                 if (Build.VERSION.SDK_INT >= 29) {
                     assertThat(window.statusBarColor).isEqualTo(Color.TRANSPARENT)
@@ -64,10 +64,10 @@
     }
 
     @Test
-    fun setUpDark() {
+    fun enableDark() {
         withUse(ActivityScenario.launch(ComponentActivity::class.java)) {
             withActivity {
-                setUpEdgeToEdge(
+                enableEdgeToEdge(
                     statusBarStyle = SystemBarStyle.dark(Color.DKGRAY),
                     navigationBarStyle = SystemBarStyle.dark(Color.DKGRAY)
                 )
@@ -91,10 +91,10 @@
     }
 
     @Test
-    fun setUpLight() {
+    fun enableLight() {
         withUse(ActivityScenario.launch(ComponentActivity::class.java)) {
             withActivity {
-                setUpEdgeToEdge(
+                enableEdgeToEdge(
                     statusBarStyle = SystemBarStyle.light(Color.CYAN, Color.DKGRAY),
                     navigationBarStyle = SystemBarStyle.light(Color.CYAN, Color.DKGRAY),
                 )
diff --git a/activity/activity/src/main/java/androidx/activity/EdgeToEdge.kt b/activity/activity/src/main/java/androidx/activity/EdgeToEdge.kt
index 837544a..921fcad 100644
--- a/activity/activity/src/main/java/androidx/activity/EdgeToEdge.kt
+++ b/activity/activity/src/main/java/androidx/activity/EdgeToEdge.kt
@@ -46,12 +46,12 @@
 private var Impl: EdgeToEdgeImpl? = null
 
 /**
- * Sets up edge-to-edge display for this [ComponentActivity].
+ * Enables the edge-to-edge display for this [ComponentActivity].
  *
  * To set it up with the default style, call this method in your Activity's onCreate method:
  * ```
  *     override fun onCreate(savedInstanceState: Bundle?) {
- *         setUpEdgeToEdge()
+ *         enableEdgeToEdge()
  *         super.onCreate(savedInstanceState)
  *         ...
  *     }
@@ -66,9 +66,9 @@
  * @param statusBarStyle The [SystemBarStyle] for the status bar.
  * @param navigationBarStyle The [SystemBarStyle] for the navigation bar.
  */
-@JvmName("setUp")
+@JvmName("enable")
 @JvmOverloads
-fun ComponentActivity.setUpEdgeToEdge(
+fun ComponentActivity.enableEdgeToEdge(
     statusBarStyle: SystemBarStyle = SystemBarStyle.auto(Color.TRANSPARENT, Color.TRANSPARENT),
     navigationBarStyle: SystemBarStyle = SystemBarStyle.auto(DefaultLightScrim, DefaultDarkScrim)
 ) {
@@ -92,7 +92,7 @@
 }
 
 /**
- * The style for the status bar or the navigation bar used in [setUpEdgeToEdge].
+ * The style for the status bar or the navigation bar used in [enableEdgeToEdge].
  */
 class SystemBarStyle private constructor(
     private val lightScrim: Int,
diff --git a/activity/integration-tests/testapp/lint-baseline.xml b/activity/integration-tests/testapp/lint-baseline.xml
index 35ee08b..2790d4a 100644
--- a/activity/integration-tests/testapp/lint-baseline.xml
+++ b/activity/integration-tests/testapp/lint-baseline.xml
@@ -2,15 +2,6 @@
 <issues format="6" by="lint 8.0.0-alpha05" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-alpha05)" variant="all" version="8.0.0-alpha05">
 
     <issue
-        id="UnspecifiedImmutableFlag"
-        message="Missing `PendingIntent` mutability flag"
-        errorLine1="                            0, Intent(MediaStore.ACTION_IMAGE_CAPTURE), 0"
-        errorLine2="                                                                        ~">
-        <location
-            file="src/main/java/androidx/activity/integration/testapp/MainActivity.kt"/>
-    </issue>
-
-    <issue
         id="UnknownNullness"
         message="Should explicitly declare type here since implicit type does not specify nullness (ActivityResultLauncher&lt;(Uri or Uri?)>)"
         errorLine1="    val takePicture = registerForActivityResult(TakePicture()) { success ->"
diff --git a/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/EdgeToEdgeActivity.kt b/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/EdgeToEdgeActivity.kt
index 1f5d11a..ed45d7b5 100644
--- a/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/EdgeToEdgeActivity.kt
+++ b/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/EdgeToEdgeActivity.kt
@@ -22,7 +22,7 @@
 import android.os.Bundle
 import android.view.View
 import androidx.activity.SystemBarStyle
-import androidx.activity.setUpEdgeToEdge
+import androidx.activity.enableEdgeToEdge
 import androidx.appcompat.app.AlertDialog
 import androidx.appcompat.app.AppCompatActivity
 import androidx.appcompat.app.AppCompatDelegate
@@ -35,7 +35,7 @@
         if (Build.VERSION.SDK_INT >= 21) {
             installSplashScreen()
         }
-        setUpEdgeToEdge()
+        enableEdgeToEdge()
         super.onCreate(savedInstanceState)
         findViewById<View>(R.id.default_config).setOnClickListener {
             // The default style.
@@ -43,7 +43,7 @@
             // API 26-28: Transparent status. Light or dark scrim on nav.
             // API 23-25: Transparent status. Dark scrim on nav.
             // API 21,22: Dark scrim (system default).
-            setUpEdgeToEdge()
+            enableEdgeToEdge()
         }
         findViewById<View>(R.id.custom_config).setOnClickListener {
             // API 29+: Transparent on gesture nav, Auto scrim on 3-button nav (same as default).
@@ -53,13 +53,13 @@
                 lightScrim = Color.argb(0x64, 0xff, 0xeb, 0x3b),
                 darkScrim = Color.argb(0x64, 0x4a, 0x14, 0x8c)
             )
-            setUpEdgeToEdge(statusBarStyle = style, navigationBarStyle = style)
+            enableEdgeToEdge(statusBarStyle = style, navigationBarStyle = style)
         }
         findViewById<View>(R.id.transparent_config).setOnClickListener {
             // API 23+: Transparent regardless of the nav mode.
             // API 21,22: Dark scrim (system default).
             val style = SystemBarStyle.dark(Color.TRANSPARENT)
-            setUpEdgeToEdge(statusBarStyle = style, navigationBarStyle = style)
+            enableEdgeToEdge(statusBarStyle = style, navigationBarStyle = style)
         }
         findViewById<View>(R.id.purple_config).setOnClickListener {
             // API 23+: Purple.
@@ -67,7 +67,7 @@
             val style = SystemBarStyle.dark(
                 scrim = Color.argb(0x64, 0x4a, 0x14, 0x8c)
             )
-            setUpEdgeToEdge(statusBarStyle = style, navigationBarStyle = style)
+            enableEdgeToEdge(statusBarStyle = style, navigationBarStyle = style)
         }
         findViewById<View>(R.id.yellow_config).setOnClickListener {
             // API 23+: Yellow.
@@ -76,7 +76,7 @@
                 scrim = Color.argb(0x64, 0xff, 0xeb, 0x3b),
                 darkScrim = Color.rgb(0xf5, 0x7f, 0x17)
             )
-            setUpEdgeToEdge(statusBarStyle = style, navigationBarStyle = style)
+            enableEdgeToEdge(statusBarStyle = style, navigationBarStyle = style)
         }
         findViewById<View>(R.id.light_mode).setOnClickListener { setDarkMode(false) }
         findViewById<View>(R.id.dark_mode).setOnClickListener { setDarkMode(true) }
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 0bfa1d5..5e3dcf4 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
@@ -35,13 +35,13 @@
             .bindMemberType(
                 memberGetter = ParticipantValue::asParticipant,
                 ctor = { ParticipantValue(it) },
-                typeSpec = TypeConverters.ParticipantTypeSpec(),
+                typeSpec = TypeConverters.PARTICIPANT_TYPE_SPEC,
             )
             .bindMemberType(
                 memberGetter = ParticipantValue::asParticipantFilter,
                 ctor = { ParticipantValue(it) },
                 typeSpec = TypeConverters.createSearchActionTypeSpec(
-                    TypeConverters.ParticipantTypeSpec(),
+                    TypeConverters.PARTICIPANT_TYPE_SPEC,
                 ),
             )
             .build()
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 06f037b..637f6b5 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
@@ -36,13 +36,13 @@
             .bindMemberType(
                 memberGetter = RecipientValue::asRecipient,
                 ctor = { RecipientValue(it) },
-                typeSpec = TypeConverters.RecipientTypeSpec(),
+                typeSpec = TypeConverters.RECIPIENT_TYPE_SPEC,
             )
             .bindMemberType(
                 memberGetter = RecipientValue::asRecipientFilter,
                 ctor = { RecipientValue(it) },
                 typeSpec = TypeConverters.createSearchActionTypeSpec(
-                    TypeConverters.RecipientTypeSpec(),
+                    TypeConverters.RECIPIENT_TYPE_SPEC,
                 ),
             )
             .build()
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 7f689b5..8e872f3 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,6 +17,7 @@
 package androidx.appactions.interaction.capabilities.core.impl.converters;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.appactions.interaction.capabilities.core.ExecutionResult;
 import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
 import androidx.appactions.interaction.capabilities.core.values.Alarm;
@@ -52,7 +53,6 @@
 import java.time.format.DateTimeParseException;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Optional;
 
 /** Converters for capability argument values. Convert from internal proto types to public types. */
 public final class TypeConverters {
@@ -94,13 +94,14 @@
                             ParcelDelivery::getTrackingNumber,
                             ParcelDelivery.Builder::setTrackingNumber)
                     .bindStringField(
-                            "trackingUrl", ParcelDelivery::getTrackingUrl,
+                            "trackingUrl",
+                            ParcelDelivery::getTrackingUrl,
                             ParcelDelivery.Builder::setTrackingUrl)
                     .build();
     public static final TypeSpec<Order> ORDER_TYPE_SPEC =
             TypeSpecBuilder.newBuilderForThing("Order", Order::newBuilder)
-                    .bindZonedDateTimeField("orderDate", Order::getOrderDate,
-                            Order.Builder::setOrderDate)
+                    .bindZonedDateTimeField(
+                            "orderDate", Order::getOrderDate, Order.Builder::setOrderDate)
                     .bindSpecField(
                             "orderDelivery",
                             Order::getOrderDelivery,
@@ -117,24 +118,34 @@
                             Order.Builder::setOrderStatus,
                             Order.OrderStatus.class)
                     .bindSpecField(
-                            "seller", Order::getSeller, Order.Builder::setSeller,
+                            "seller",
+                            Order::getSeller,
+                            Order.Builder::setSeller,
                             ORGANIZATION_TYPE_SPEC)
                     .build();
     public static final TypeSpec<Person> PERSON_TYPE_SPEC =
             TypeSpecBuilder.newBuilderForThing("Person", Person::newBuilder)
                     .bindStringField("email", Person::getEmail, Person.Builder::setEmail)
-                    .bindStringField("telephone", Person::getTelephone,
-                            Person.Builder::setTelephone)
+                    .bindStringField(
+                            "telephone", Person::getTelephone, Person.Builder::setTelephone)
                     .bindStringField("name", Person::getName, Person.Builder::setName)
                     .build();
     public static final TypeSpec<Alarm> ALARM_TYPE_SPEC =
             TypeSpecBuilder.newBuilderForThing("Alarm", Alarm::newBuilder).build();
     public static final TypeSpec<Timer> TIMER_TYPE_SPEC =
             TypeSpecBuilder.newBuilderForThing("Timer", Timer::newBuilder).build();
+    public static final TypeSpec<Attendee> ATTENDEE_TYPE_SPEC =
+            new UnionTypeSpec.Builder<Attendee>()
+                    .bindMemberType(
+                            (attendee) -> attendee.asPerson().orElse(null),
+                            (person) -> new Attendee(person),
+                            PERSON_TYPE_SPEC)
+                    .build();
     public static final TypeSpec<CalendarEvent> CALENDAR_EVENT_TYPE_SPEC =
             TypeSpecBuilder.newBuilderForThing("CalendarEvent", CalendarEvent::newBuilder)
                     .bindZonedDateTimeField(
-                            "startDate", CalendarEvent::getStartDate,
+                            "startDate",
+                            CalendarEvent::getStartDate,
                             CalendarEvent.Builder::setStartDate)
                     .bindZonedDateTimeField(
                             "endDate", CalendarEvent::getEndDate, CalendarEvent.Builder::setEndDate)
@@ -142,16 +153,31 @@
                             "attendee",
                             CalendarEvent::getAttendeeList,
                             CalendarEvent.Builder::addAllAttendee,
-                            new AttendeeTypeSpec())
+                            ATTENDEE_TYPE_SPEC)
                     .build();
     public static final TypeSpec<SafetyCheck> SAFETY_CHECK_TYPE_SPEC =
             TypeSpecBuilder.newBuilderForThing("SafetyCheck", SafetyCheck::newBuilder)
-                    .bindDurationField("duration", SafetyCheck::getDuration,
-                            SafetyCheck.Builder::setDuration)
+                    .bindDurationField(
+                            "duration", SafetyCheck::getDuration, SafetyCheck.Builder::setDuration)
                     .bindZonedDateTimeField(
-                            "checkinTime", SafetyCheck::getCheckinTime,
+                            "checkinTime",
+                            SafetyCheck::getCheckinTime,
                             SafetyCheck.Builder::setCheckinTime)
                     .build();
+    public static final TypeSpec<Recipient> RECIPIENT_TYPE_SPEC =
+            new UnionTypeSpec.Builder<Recipient>()
+                    .bindMemberType(
+                            (recipient) -> recipient.asPerson().orElse(null),
+                            (person) -> new Recipient(person),
+                            PERSON_TYPE_SPEC)
+                    .build();
+    public static final TypeSpec<Participant> PARTICIPANT_TYPE_SPEC =
+            new UnionTypeSpec.Builder<Participant>()
+                    .bindMemberType(
+                            (participant) -> participant.asPerson().orElse(null),
+                            (person) -> new Participant(person),
+                            PERSON_TYPE_SPEC)
+                    .build();
     private static final String FIELD_NAME_CALL_FORMAT = "callFormat";
     private static final String FIELD_NAME_PARTICIPANT = "participant";
     private static final String FIELD_NAME_TYPE_CALL = "Call";
@@ -160,8 +186,7 @@
     private static final String FIELD_NAME_RECIPIENT = "recipient";
     private static final String FIELD_NAME_TEXT = "text";
 
-    private TypeConverters() {
-    }
+    private TypeConverters() {}
 
     /**
      * @param paramValue
@@ -201,7 +226,8 @@
         return (int) paramValue.getNumberValue();
     }
 
-    /** Converts a ParamValue to a Boolean object.
+    /**
+     * Converts a ParamValue to a Boolean object.
      *
      * @param paramValue
      * @return
@@ -230,8 +256,8 @@
             try {
                 return LocalDate.parse(paramValue.getStringValue());
             } catch (DateTimeParseException e) {
-                throw new StructConversionException("Failed to parse ISO 8601 string to LocalDate",
-                        e);
+                throw new StructConversionException(
+                        "Failed to parse ISO 8601 string to LocalDate", e);
             }
         }
         throw new StructConversionException(
@@ -250,8 +276,8 @@
             try {
                 return LocalTime.parse(paramValue.getStringValue());
             } catch (DateTimeParseException e) {
-                throw new StructConversionException("Failed to parse ISO 8601 string to LocalTime",
-                        e);
+                throw new StructConversionException(
+                        "Failed to parse ISO 8601 string to LocalTime", e);
             }
         }
         throw new StructConversionException(
@@ -313,8 +339,8 @@
      */
     @NonNull
     public static Entity toEntity(@NonNull ItemList itemList) {
-        Entity.Builder builder = Entity.newBuilder().setValue(
-                ITEM_LIST_TYPE_SPEC.toStruct(itemList));
+        Entity.Builder builder =
+                Entity.newBuilder().setValue(ITEM_LIST_TYPE_SPEC.toStruct(itemList));
         itemList.getId().ifPresent(builder::setIdentifier);
         return builder.build();
     }
@@ -327,8 +353,8 @@
      */
     @NonNull
     public static Entity toEntity(@NonNull ListItem listItem) {
-        Entity.Builder builder = Entity.newBuilder().setValue(
-                LIST_ITEM_TYPE_SPEC.toStruct(listItem));
+        Entity.Builder builder =
+                Entity.newBuilder().setValue(LIST_ITEM_TYPE_SPEC.toStruct(listItem));
         listItem.getId().ifPresent(builder::setIdentifier);
         return builder.build();
     }
@@ -417,9 +443,12 @@
      */
     @NonNull
     public static Entity toEntity(@NonNull Participant participant) {
-        ParticipantTypeSpec typeSpec = new ParticipantTypeSpec();
-        Entity.Builder builder = Entity.newBuilder().setValue(typeSpec.toStruct(participant));
-        typeSpec.getId(participant).ifPresent(builder::setIdentifier);
+        Entity.Builder builder =
+                Entity.newBuilder().setValue(PARTICIPANT_TYPE_SPEC.toStruct(participant));
+        @Nullable String identifier = PARTICIPANT_TYPE_SPEC.getIdentifier(participant);
+        if (identifier != null) {
+            builder.setIdentifier(identifier);
+        }
         return builder.build();
     }
 
@@ -429,9 +458,12 @@
      */
     @NonNull
     public static Entity toEntity(@NonNull Recipient recipient) {
-        RecipientTypeSpec typeSpec = new RecipientTypeSpec();
-        Entity.Builder builder = Entity.newBuilder().setValue(typeSpec.toStruct(recipient));
-        typeSpec.getId(recipient).ifPresent(builder::setIdentifier);
+        Entity.Builder builder =
+                Entity.newBuilder().setValue(RECIPIENT_TYPE_SPEC.toStruct(recipient));
+        @Nullable String identifier = RECIPIENT_TYPE_SPEC.getIdentifier(recipient);
+        if (identifier != null) {
+            builder.setIdentifier(identifier);
+        }
         return builder.build();
     }
 
@@ -557,8 +589,8 @@
             @NonNull TypeSpec<T> nestedTypeSpec) {
         return TypeSpecBuilder.<SearchAction<T>, SearchAction.Builder<T>>newBuilder(
                         "SearchAction", SearchAction::newBuilder)
-                .bindStringField("query", SearchAction<T>::getQuery,
-                        SearchAction.Builder<T>::setQuery)
+                .bindStringField(
+                        "query", SearchAction<T>::getQuery, SearchAction.Builder<T>::setQuery)
                 .bindSpecField(
                         "object",
                         SearchAction<T>::getObject,
@@ -657,20 +689,24 @@
     /** Converts a Participant to a ParamValue. */
     @NonNull
     public static ParamValue toParamValue(@NonNull Participant value) {
-        ParticipantTypeSpec typeSpec = new ParticipantTypeSpec();
-        ParamValue.Builder builder = ParamValue.newBuilder().setStructValue(
-                typeSpec.toStruct(value));
-        typeSpec.getId(value).ifPresent(builder::setIdentifier);
+        ParamValue.Builder builder =
+                ParamValue.newBuilder().setStructValue(PARTICIPANT_TYPE_SPEC.toStruct(value));
+        @Nullable String identifier = PARTICIPANT_TYPE_SPEC.getIdentifier(value);
+        if (identifier != null) {
+            builder.setIdentifier(identifier);
+        }
         return builder.build();
     }
 
     /** Converts a Recipient to a ParamValue. */
     @NonNull
     public static ParamValue toParamValue(@NonNull Recipient value) {
-        RecipientTypeSpec typeSpec = new RecipientTypeSpec();
-        ParamValue.Builder builder = ParamValue.newBuilder().setStructValue(
-                typeSpec.toStruct(value));
-        typeSpec.getId(value).ifPresent(builder::setIdentifier);
+        ParamValue.Builder builder =
+                ParamValue.newBuilder().setStructValue(RECIPIENT_TYPE_SPEC.toStruct(value));
+        @Nullable String identifier = RECIPIENT_TYPE_SPEC.getIdentifier(value);
+        if (identifier != null) {
+            builder.setIdentifier(identifier);
+        }
         return builder.build();
     }
 
@@ -679,13 +715,14 @@
     public static ParamValue toParamValue(@NonNull Call value) {
         ParamValue.Builder builder = ParamValue.newBuilder();
         Map<String, Value> fieldsMap = new HashMap<>();
-        fieldsMap.put(FIELD_NAME_TYPE,
-                Value.newBuilder().setStringValue(FIELD_NAME_TYPE_CALL).build());
+        fieldsMap.put(
+                FIELD_NAME_TYPE, Value.newBuilder().setStringValue(FIELD_NAME_TYPE_CALL).build());
         if (value.getCallFormat().isPresent()) {
             fieldsMap.put(
                     FIELD_NAME_CALL_FORMAT,
-                    Value.newBuilder().setStringValue(
-                            value.getCallFormat().get().toString()).build());
+                    Value.newBuilder()
+                            .setStringValue(value.getCallFormat().get().toString())
+                            .build());
         }
         ListValue.Builder participantListBuilder = ListValue.newBuilder();
         for (Participant participant : value.getParticipantList()) {
@@ -746,112 +783,4 @@
         }
         return fieldsMap.get(FIELD_NAME_TYPE).getStringValue();
     }
-
-    /** {@link TypeSpec} for {@link Participant}. */
-    public static class ParticipantTypeSpec implements TypeSpec<Participant> {
-        @Override
-        @NonNull
-        public Struct toStruct(@NonNull Participant object) {
-            if (object.asPerson().isPresent()) {
-                return PERSON_TYPE_SPEC.toStruct(object.asPerson().get());
-            }
-            return Struct.getDefaultInstance();
-        }
-
-        @Override
-        @NonNull
-        public Participant fromStruct(@NonNull Struct struct) throws StructConversionException {
-            if (FIELD_NAME_TYPE_PERSON.equals(getStructType(struct))) {
-                return new Participant(PERSON_TYPE_SPEC.fromStruct(struct));
-            }
-            throw new StructConversionException(
-                    String.format(
-                            "Unexpected type, expected type is %s while actual type is %s",
-                            FIELD_NAME_TYPE_PERSON, getStructType(struct)));
-        }
-
-        /**
-         * Retrieves identifier from the object within union value.
-         *
-         * @param object
-         * @return
-         */
-        @NonNull
-        public Optional<String> getId(@NonNull Participant object) {
-            return object.asPerson().isPresent() ? object.asPerson().get().getId()
-                    : Optional.empty();
-        }
-    }
-
-    /** {@link TypeSpec} for {@link Recipient}. */
-    public static class RecipientTypeSpec implements TypeSpec<Recipient> {
-        @NonNull
-        @Override
-        public Struct toStruct(@NonNull Recipient object) {
-            if (object.asPerson().isPresent()) {
-                return PERSON_TYPE_SPEC.toStruct(object.asPerson().get());
-            }
-            return Struct.getDefaultInstance();
-        }
-
-        @Override
-        @NonNull
-        public Recipient fromStruct(@NonNull Struct struct) throws StructConversionException {
-            if (FIELD_NAME_TYPE_PERSON.equals(getStructType(struct))) {
-                return new Recipient(PERSON_TYPE_SPEC.fromStruct(struct));
-            }
-            throw new StructConversionException(
-                    String.format(
-                            "Unexpected type, expected type is %s while actual type is %s",
-                            FIELD_NAME_TYPE_PERSON, getStructType(struct)));
-        }
-
-        /**
-         * Retrieves identifier from the object within union value.
-         *
-         * @param object
-         * @return
-         */
-        @NonNull
-        public Optional<String> getId(@NonNull Recipient object) {
-            return object.asPerson().isPresent() ? object.asPerson().get().getId()
-                    : Optional.empty();
-        }
-    }
-
-    /** {@link TypeSpec} for {@link Attendee}. */
-    public static class AttendeeTypeSpec implements TypeSpec<Attendee> {
-        @Override
-        @NonNull
-        public Struct toStruct(@NonNull Attendee object) {
-            if (object.asPerson().isPresent()) {
-                return PERSON_TYPE_SPEC.toStruct(object.asPerson().get());
-            }
-            return Struct.getDefaultInstance();
-        }
-
-        @NonNull
-        @Override
-        public Attendee fromStruct(@NonNull Struct struct) throws StructConversionException {
-            if (FIELD_NAME_TYPE_PERSON.equals(getStructType(struct))) {
-                return new Attendee(TypeConverters.PERSON_TYPE_SPEC.fromStruct(struct));
-            }
-            throw new StructConversionException(
-                    String.format(
-                            "Unexpected type, expected type is %s while actual type is %s",
-                            FIELD_NAME_TYPE_PERSON, getStructType(struct)));
-        }
-
-        /**
-         * Retrieves identifier from the object within union value.
-         *
-         * @param object
-         * @return
-         */
-        @NonNull
-        public Optional<String> getId(@NonNull Attendee object) {
-            return object.asPerson().isPresent() ? object.asPerson().get().getId()
-                    : Optional.empty();
-        }
-    }
 }
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpec.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpec.kt
similarity index 61%
rename from appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpec.java
rename to appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpec.kt
index 11181a6..7e07afe 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpec.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpec.kt
@@ -14,28 +14,26 @@
  * limitations under the License.
  */
 
-package androidx.appactions.interaction.capabilities.core.impl.converters;
+package androidx.appactions.interaction.capabilities.core.impl.converters
 
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
-import androidx.appactions.interaction.protobuf.Struct;
+import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException
+import androidx.appactions.interaction.protobuf.Struct
 
 /**
- * TypeSpec is used to convert between java objects in capabilities/values and Struct proto.
- *
- * @param <T>
+ * TypeSpec is used to convert between native objects in capabilities/values and Struct proto.
  */
-public interface TypeSpec<T> {
+interface TypeSpec<T> {
+    /* Given the object, returns its identifier, which can be null. */
+    fun getIdentifier(obj: T): String?
 
-    /** Converts a java object into a Struct proto. */
-    @NonNull
-    Struct toStruct(@NonNull T object);
+    /** Converts a object into a Struct proto. */
+    fun toStruct(obj: T): Struct
 
     /**
-     * Converts a Struct into java object.
+     * Converts a Struct into object.
      *
      * @throws StructConversionException if the Struct is malformed.
      */
-    @NonNull
-    T fromStruct(@NonNull Struct struct) throws StructConversionException;
+    @Throws(StructConversionException::class)
+    fun fromStruct(struct: Struct): T
 }
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 46aa2d1..8cd3ede 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
@@ -42,6 +42,7 @@
     private final List<FieldBinding<T, BuilderT>> mBindings = new ArrayList<>();
     private final Supplier<BuilderT> mBuilderSupplier;
     private CheckedInterfaces.Consumer<Struct> mStructValidator;
+    private Function<T, Optional<String>> mIdentifierGetter = (unused) -> Optional.empty();
 
     private TypeSpecBuilder(Supplier<BuilderT> builderSupplier) {
         this.mBuilderSupplier = builderSupplier;
@@ -66,29 +67,30 @@
      * 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 {
         try {
             return struct.getFieldsOrThrow(key);
         } catch (IllegalArgumentException e) {
-            throw new StructConversionException(String.format("%s does not exist in Struct", key),
-                    e);
+            throw new StructConversionException(
+                    String.format("%s does not exist in Struct", key), e);
         }
     }
 
     static <T, BuilderT extends BuilderOf<T>> TypeSpecBuilder<T, BuilderT> newBuilder(
             String typeName, Supplier<BuilderT> builderSupplier) {
         return new TypeSpecBuilder<>(builderSupplier)
-                .bindStringField("@type", (unused) -> Optional.of(typeName), (builder, val) -> {
-                })
+                .bindStringField("@type", (unused) -> Optional.of(typeName), (builder, val) -> {})
                 .setStructValidator(
                         struct -> {
-                            if (!getFieldFromStruct(struct, "@type").getStringValue().equals(
-                                    typeName)) {
+                            if (!getFieldFromStruct(struct, "@type")
+                                    .getStringValue()
+                                    .equals(typeName)) {
                                 throw new StructConversionException(
-                                        String.format("Struct @type field must be equal to %s.",
+                                        String.format(
+                                                "Struct @type field must be equal to %s.",
                                                 typeName));
                             }
                         });
@@ -103,6 +105,7 @@
             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);
     }
@@ -113,6 +116,11 @@
         return this;
     }
 
+    TypeSpecBuilder<T, BuilderT> bindIdentifier(Function<T, Optional<String>> identifierGetter) {
+        this.mIdentifierGetter = identifierGetter;
+        return this;
+    }
+
     private TypeSpecBuilder<T, BuilderT> bindFieldInternal(
             String name,
             Function<T, Optional<Value>> valueGetter,
@@ -166,8 +174,7 @@
                 name,
                 (object) -> stringGetter.apply(object).map(TypeSpecBuilder::getStringValue),
                 (builder, value) ->
-                        value
-                                .map(Value::getStringValue)
+                        value.map(Value::getStringValue)
                                 .ifPresent(
                                         stringValue -> stringSetter.accept(builder, stringValue)));
     }
@@ -184,8 +191,10 @@
         return bindFieldInternal(
                 name,
                 (object) ->
-                        valueGetter.apply(object).map(Enum::toString).map(
-                                TypeSpecBuilder::getStringValue),
+                        valueGetter
+                                .apply(object)
+                                .map(Enum::toString)
+                                .map(TypeSpecBuilder::getStringValue),
                 (builder, value) -> {
                     if (value.isPresent()) {
                         String stringValue = value.get().getStringValue();
@@ -215,13 +224,15 @@
         return bindFieldInternal(
                 name,
                 (object) ->
-                        valueGetter.apply(object).map(Duration::toString).map(
-                                TypeSpecBuilder::getStringValue),
+                        valueGetter
+                                .apply(object)
+                                .map(Duration::toString)
+                                .map(TypeSpecBuilder::getStringValue),
                 (builder, value) -> {
                     if (value.isPresent()) {
                         try {
-                            valueSetter.accept(builder,
-                                    Duration.parse(value.get().getStringValue()));
+                            valueSetter.accept(
+                                    builder, Duration.parse(value.get().getStringValue()));
                         } catch (DateTimeParseException e) {
                             throw new StructConversionException(
                                     "Failed to parse ISO 8601 string to Duration", e);
@@ -249,8 +260,8 @@
                 (builder, value) -> {
                     if (value.isPresent()) {
                         try {
-                            valueSetter.accept(builder,
-                                    ZonedDateTime.parse(value.get().getStringValue()));
+                            valueSetter.accept(
+                                    builder, ZonedDateTime.parse(value.get().getStringValue()));
                         } catch (DateTimeParseException e) {
                             throw new StructConversionException(
                                     "Failed to parse ISO 8601 string to ZonedDateTime", e);
@@ -270,9 +281,7 @@
                 (object) ->
                         valueGetter
                                 .apply(object)
-                                .map(
-                                        Function
-                                                .identity()) // Static analyzer incorrectly
+                                .map(Function.identity()) // Static analyzer incorrectly
                                 // throws error stating that the
                                 // input to toStruct is nullable. This is a workaround to avoid
                                 // the error from the analyzer.
@@ -296,12 +305,16 @@
                 valueGetter,
                 valueSetter,
                 (element) ->
-                        Optional.ofNullable(element).map(
-                                value -> getStructValue(spec.toStruct(value))),
+                        Optional.ofNullable(element)
+                                .map(value -> getStructValue(spec.toStruct(value))),
                 (value) -> spec.fromStruct(value.getStructValue()));
     }
 
     TypeSpec<T> build() {
-        return new TypeSpecImpl<>(mBindings, mBuilderSupplier, Optional.ofNullable(mStructValidator));
+        return new TypeSpecImpl<>(
+                mIdentifierGetter,
+                mBindings,
+                mBuilderSupplier,
+                Optional.ofNullable(mStructValidator));
     }
 }
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImpl.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImpl.java
index 25ac2fc..c49c3b1 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImpl.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImpl.java
@@ -17,6 +17,7 @@
 package androidx.appactions.interaction.capabilities.core.impl.converters;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
 import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
 import androidx.appactions.interaction.protobuf.Struct;
@@ -26,10 +27,13 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.function.Function;
 import java.util.function.Supplier;
 
 /** TypeSpecImpl is used to convert between java objects in capabilities/values and Struct proto. */
 final class TypeSpecImpl<T, BuilderT extends BuilderOf<T>> implements TypeSpec<T> {
+    /* The function to retrieve the identifier. */
+    final Function<T, Optional<String>> mIdentifierGetter;
 
     /** The list of FieldBinding objects. */
     final List<FieldBinding<T, BuilderT>> mBindings;
@@ -41,23 +45,31 @@
     final Supplier<BuilderT> mBuilderSupplier;
 
     TypeSpecImpl(
+            Function<T, Optional<String>> identifierGetter,
             List<FieldBinding<T, BuilderT>> bindings,
             Supplier<BuilderT> builderSupplier,
             Optional<CheckedInterfaces.Consumer<Struct>> structValidator) {
+        this.mIdentifierGetter = identifierGetter;
         this.mBindings = Collections.unmodifiableList(bindings);
         this.mBuilderSupplier = builderSupplier;
         this.mStructValidator = structValidator;
     }
 
+    @Nullable
+    @Override
+    public String getIdentifier(T obj) {
+        return mIdentifierGetter.apply(obj).orElse(null);
+    }
+
     /** Converts a java object into a Struct proto using List of FieldBinding. */
     @NonNull
     @Override
-    public Struct toStruct(@NonNull T object) {
+    public Struct toStruct(@NonNull T obj) {
         Struct.Builder builder = Struct.newBuilder();
         for (FieldBinding<T, BuilderT> binding : mBindings) {
             binding
                     .valueGetter()
-                    .apply(object)
+                    .apply(obj)
                     .ifPresent(value -> builder.putFields(binding.name(), value));
         }
         return builder.build();
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/UnionTypeSpec.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/UnionTypeSpec.kt
index e0990c1..b249bee 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/UnionTypeSpec.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/UnionTypeSpec.kt
@@ -29,15 +29,44 @@
         val ctor: (M) -> T,
         val typeSpec: TypeSpec<M>,
     ) {
+        @Throws(StructConversionException::class)
         fun tryDeserialize(struct: Struct): T {
             return ctor(typeSpec.fromStruct(struct))
         }
 
-        fun trySerialize(obj: T): Struct? {
-            return memberGetter(obj)?.let { typeSpec.toStruct(it) }
+        fun serialize(obj: T): Struct {
+            return typeSpec.toStruct(memberGetter(obj)!!)
+        }
+
+        fun getIdentifier(obj: T): String? {
+            return typeSpec.getIdentifier(memberGetter(obj)!!)
+        }
+
+        fun isMemberSet(obj: T): Boolean {
+            return memberGetter(obj) != null
         }
     }
 
+    private fun getApplicableBinding(obj: T): MemberBinding<T, *> {
+        var applicableBindings = bindings.filter { it.isMemberSet(obj) }
+        return when (applicableBindings.size) {
+            0 -> throw IllegalStateException("$obj is invalid, all union members are null.")
+            1 -> applicableBindings[0]
+            else -> throw IllegalStateException(
+                "$obj is invalid, multiple union members are non-null."
+            )
+        }
+    }
+
+    override fun getIdentifier(obj: T): String? {
+        return getApplicableBinding(obj).getIdentifier(obj)
+    }
+
+    override fun toStruct(obj: T): Struct {
+        return getApplicableBinding(obj).serialize(obj)
+    }
+
+    @Throws(StructConversionException::class)
     override fun fromStruct(struct: Struct): T {
         for (binding in bindings) {
             try {
@@ -46,16 +75,7 @@
                 continue
             }
         }
-        throw StructConversionException("failed to deserialize union type")
-    }
-
-    override fun toStruct(obj: T): Struct {
-        for (binding in bindings) {
-            binding.trySerialize(obj)?.let {
-                return it
-            }
-        }
-        throw StructConversionException("failed to serialize union type")
+        throw StructConversionException("all member TypeSpecs failed to deserialize input Struct.")
     }
 
     class Builder<T : Any> {
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImplTest.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImplTest.java
index 6a09135..648cb5e 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImplTest.java
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImplTest.java
@@ -38,6 +38,20 @@
 public final class TypeSpecImplTest {
 
     @Test
+    public void bindIdentifier_success() {
+        TypeSpec<TestEntity> entityTypeSpec =
+                TypeSpecBuilder.newBuilder("TestEntity", TestEntity::newBuilder)
+                        .bindIdentifier(TestEntity::getId)
+                        .build();
+        assertThat(entityTypeSpec.getIdentifier(
+                TestEntity.newBuilder().setId("identifier1").build()
+        )).isEqualTo("identifier1");
+        assertThat(entityTypeSpec.getIdentifier(
+                TestEntity.newBuilder().build()
+        )).isNull();
+    }
+
+    @Test
     public void bindEnumField_convertsSuccessfully() throws Exception {
         TypeSpec<TestEntity> entityTypeSpec =
                 TypeSpecBuilder.newBuilder("TestEntity", TestEntity::newBuilder)
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
new file mode 100644
index 0000000..cad1967
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/UnionTypeSpecTest.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.appactions.interaction.capabilities.core.impl.converters
+
+import androidx.appactions.interaction.capabilities.core.values.Alarm
+import androidx.appactions.interaction.capabilities.core.values.Timer
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+/* Union type for testing */
+class AlarmOrTimer private constructor(
+  val asAlarm: Alarm? = null,
+  val asTimer: Timer? = null,
+) {
+  constructor(alarm: Alarm) : this(asAlarm = alarm)
+  constructor(timer: Timer) : this(asTimer = timer)
+}
+
+private val ALARM_OR_TIMER_TYPE_SPEC = UnionTypeSpec.Builder<AlarmOrTimer>()
+  .bindMemberType(
+    memberGetter = AlarmOrTimer::asAlarm,
+    ctor = { AlarmOrTimer(it) },
+    typeSpec = TypeConverters.ALARM_TYPE_SPEC,
+  )
+  .bindMemberType(
+    memberGetter = AlarmOrTimer::asTimer,
+    ctor = { AlarmOrTimer(it) },
+    typeSpec = TypeConverters.TIMER_TYPE_SPEC,
+  ).build()
+
+@RunWith(JUnit4::class)
+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())
+    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()
+  }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEntity.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEntity.java
index ee3db39..a8d103c 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEntity.java
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEntity.java
@@ -33,6 +33,8 @@
         return new AutoValue_TestEntity.Builder();
     }
 
+    public abstract Optional<String> getId();
+
     public abstract Optional<String> getName();
 
     public abstract Optional<Duration> getDuration();
@@ -63,6 +65,8 @@
     @AutoValue.Builder
     public abstract static class Builder implements BuilderOf<TestEntity> {
 
+        public abstract Builder setId(String id);
+
         public abstract Builder setName(String name);
 
         public abstract Builder setDuration(Duration duration);
diff --git a/appactions/interaction/interaction-service/build.gradle b/appactions/interaction/interaction-service/build.gradle
index c6d43133..4299a03a 100644
--- a/appactions/interaction/interaction-service/build.gradle
+++ b/appactions/interaction/interaction-service/build.gradle
@@ -47,6 +47,9 @@
     implementation(libs.kotlinStdlib)
     implementation(libs.jsr250)
 
+    // Force upgrade since 1.2.0 is not compatible with latest lint.
+    implementation("androidx.annotation:annotation-experimental:1.3.0")
+
     testImplementation(project(":appactions:interaction:interaction-capabilities-core"))
     testImplementation(project(":appactions:interaction:interaction-service-proto"))
     testImplementation(libs.grpcTesting)
diff --git a/appactions/interaction/interaction-service/lint-baseline.xml b/appactions/interaction/interaction-service/lint-baseline.xml
new file mode 100644
index 0000000..8aac06f
--- /dev/null
+++ b/appactions/interaction/interaction-service/lint-baseline.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.tiles.TilesExperimental` or `@OptIn(markerClass = androidx.wear.tiles.TilesExperimental.class)`"
+        errorLine1="            .setLayout(ByteString.copyFrom(layout.toByteArray()))"
+        errorLine2="                                                  ~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/appactions/interaction/service/TileLayoutInternal.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.tiles.TilesExperimental` or `@OptIn(markerClass = androidx.wear.tiles.TilesExperimental.class)`"
+        errorLine1="            .setResources(ByteString.copyFrom(resources.toByteArray()))"
+        errorLine2="                                                        ~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/appactions/interaction/service/TileLayoutInternal.kt"/>
+    </issue>
+
+</issues>
diff --git a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/AppInteractionServiceGrpcImplTest.kt b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/AppInteractionServiceGrpcImplTest.kt
index 9b7e7e6..9bd5f1e 100644
--- a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/AppInteractionServiceGrpcImplTest.kt
+++ b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/AppInteractionServiceGrpcImplTest.kt
@@ -40,14 +40,14 @@
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.argumentCaptor
-import com.nhaarman.mockitokotlin2.doAnswer
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.never
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
-import com.nhaarman.mockitokotlin2.whenever
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.doAnswer
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
 import io.grpc.BindableService
 import io.grpc.ManagedChannel
 import io.grpc.Server
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 1ed52d5..8b3f190 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
@@ -29,8 +29,8 @@
 import androidx.wear.tiles.LayoutElementBuilders
 import androidx.wear.tiles.ResourceBuilders
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.doReturn
-import com.nhaarman.mockitokotlin2.mock
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
 import org.junit.After
 import org.junit.Before
 import org.junit.Test
diff --git a/appcompat/appcompat-resources/lint-baseline.xml b/appcompat/appcompat-resources/lint-baseline.xml
index 29410e5..296a941 100644
--- a/appcompat/appcompat-resources/lint-baseline.xml
+++ b/appcompat/appcompat-resources/lint-baseline.xml
@@ -107,6 +107,9 @@
         errorLine2="                           ~~~~~~~~">
         <location
             file="src/main/java/androidx/appcompat/widget/TintContextWrapper.java"/>
+        <location
+            file="src/main/java/androidx/appcompat/widget/TintContextWrapper.java"
+            message="Setter here"/>
     </issue>
 
     <issue
diff --git a/appcompat/appcompat/lint-baseline.xml b/appcompat/appcompat/lint-baseline.xml
index 30de28f..0936e35 100644
--- a/appcompat/appcompat/lint-baseline.xml
+++ b/appcompat/appcompat/lint-baseline.xml
@@ -48,24 +48,6 @@
 
     <issue
         id="NewApi"
-        message="Call requires API level 24 (current min is 14): `onDropForTextView`"
-        errorLine1="                    ? OnDropApi24Impl.onDropForTextView(event, (TextView) view, activity)"
-        errorLine2="                                      ~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appcompat/widget/AppCompatReceiveContentHelper.java"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 24 (current min is 14): `onDropForView`"
-        errorLine1="                    : OnDropApi24Impl.onDropForView(event, view, activity);"
-        errorLine2="                                      ~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appcompat/widget/AppCompatReceiveContentHelper.java"/>
-    </issue>
-
-    <issue
-        id="NewApi"
         message="Call requires API level 17 (current min is 14): `android.view.ContextThemeWrapper#applyOverrideConfiguration`"
         errorLine1="        wrappedBase.applyOverrideConfiguration(overrideConfig);"
         errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -458,6 +440,9 @@
         errorLine2="                ~~~~~~~~~~~~~~~">
         <location
             file="src/main/java/androidx/appcompat/widget/ActionBarContainer.java"/>
+        <location
+            file="src/main/java/androidx/appcompat/widget/ActionBarContainer.java"
+            message="Setter here"/>
     </issue>
 
     <issue
@@ -476,6 +461,9 @@
         errorLine2="                     ~~~~~~~~~~~~~~~~~~~">
         <location
             file="src/main/java/androidx/appcompat/app/AppCompatActivity.java"/>
+        <location
+            file="src/main/java/androidx/appcompat/app/AppCompatActivity.java"
+            message="Setter here"/>
     </issue>
 
     <issue
@@ -485,6 +473,9 @@
         errorLine2="                              ~~~~~~~~~~~~~~~~~~~">
         <location
             file="src/main/java/androidx/appcompat/app/AppCompatDelegate.java"/>
+        <location
+            file="src/main/java/androidx/appcompat/app/AppCompatDelegate.java"
+            message="Setter here"/>
     </issue>
 
     <issue
@@ -494,6 +485,9 @@
         errorLine2="                           ~~~~~~~~">
         <location
             file="src/main/java/androidx/appcompat/view/ContextThemeWrapper.java"/>
+        <location
+            file="src/main/java/androidx/appcompat/view/ContextThemeWrapper.java"
+            message="Setter here"/>
     </issue>
 
     <issue
@@ -539,6 +533,9 @@
         errorLine2="                   ~~~~~~~~~~">
         <location
             file="src/main/java/androidx/appcompat/view/menu/MenuItemImpl.java"/>
+        <location
+            file="src/main/java/androidx/appcompat/view/menu/MenuItemImpl.java"
+            message="Setter here"/>
     </issue>
 
     <issue
@@ -3433,15 +3430,6 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    protected synchronized void onDraw(Canvas canvas) {"
-        errorLine2="                                       ~~~~~~">
-        <location
-            file="src/main/java/androidx/appcompat/widget/AppCompatSeekBar.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
         errorLine1="            int defStyleAttr, int mode, Resources.Theme popupTheme) {"
         errorLine2="                                        ~~~~~~~~~~~~~~~">
         <location
@@ -7105,15 +7093,6 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    protected void onDraw(Canvas canvas) {"
-        errorLine2="                          ~~~~~~">
-        <location
-            file="src/main/java/androidx/appcompat/widget/SwitchCompat.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
         errorLine1="    public static TintTypedArray obtainStyledAttributes(Context context, AttributeSet set,"
         errorLine2="                  ~~~~~~~~~~~~~~">
         <location
@@ -7969,15 +7948,6 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    protected void dispatchDraw(Canvas canvas) {"
-        errorLine2="                                ~~~~~~">
-        <location
-            file="src/main/java/androidx/appcompat/widget/ViewStubCompat.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
         errorLine1="    public View inflate() {"
         errorLine2="           ~~~~">
         <location
diff --git a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPlugin.kt b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPlugin.kt
index cb98bc2..2f158b7 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPlugin.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPlugin.kt
@@ -21,7 +21,6 @@
 import androidx.baselineprofile.gradle.consumer.task.MergeBaselineProfileTask
 import androidx.baselineprofile.gradle.consumer.task.PrintConfigurationForVariantTask
 import androidx.baselineprofile.gradle.consumer.task.maybeCreateGenerateTask
-import androidx.baselineprofile.gradle.utils.R8Utils
 import androidx.baselineprofile.gradle.utils.AgpPlugin
 import androidx.baselineprofile.gradle.utils.AgpPluginId
 import androidx.baselineprofile.gradle.utils.BUILD_TYPE_BASELINE_PROFILE_PREFIX
@@ -29,6 +28,7 @@
 import androidx.baselineprofile.gradle.utils.INTERMEDIATES_BASE_FOLDER
 import androidx.baselineprofile.gradle.utils.MAX_AGP_VERSION_REQUIRED
 import androidx.baselineprofile.gradle.utils.MIN_AGP_VERSION_REQUIRED
+import androidx.baselineprofile.gradle.utils.R8Utils
 import androidx.baselineprofile.gradle.utils.RELEASE
 import androidx.baselineprofile.gradle.utils.camelCase
 import com.android.build.api.dsl.ApplicationExtension
@@ -219,7 +219,8 @@
             hasDependencies = baselineProfileConfiguration.allDependencies.isNotEmpty(),
             sourceProfilesFileCollection = baselineProfileConfiguration,
             outputDir = mergedTaskOutputDir,
-            filterRules = variantConfiguration.filterRules
+            filterRules = variantConfiguration.filterRules,
+            library = isLibraryModule()
         )
 
         // If `saveInSrc` is true, we create an additional task to copy the output
@@ -242,6 +243,7 @@
             val copyTaskProvider = MergeBaselineProfileTask.maybeRegisterForCopy(
                 project = project,
                 variantName = mergeAwareVariantName,
+                library = isLibraryModule(),
                 sourceDir = mergeTaskProvider.flatMap { it.baselineProfileDir },
                 outputDir = project.provider { srcOutputDir },
             )
diff --git a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/task/MergeBaselineProfileTask.kt b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/task/MergeBaselineProfileTask.kt
index 2a3c367..7067cde0 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/task/MergeBaselineProfileTask.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/task/MergeBaselineProfileTask.kt
@@ -19,6 +19,7 @@
 import androidx.baselineprofile.gradle.consumer.RuleType
 import androidx.baselineprofile.gradle.utils.TASK_NAME_SUFFIX
 import androidx.baselineprofile.gradle.utils.maybeRegister
+import java.io.File
 import org.gradle.api.DefaultTask
 import org.gradle.api.GradleException
 import org.gradle.api.Project
@@ -57,13 +58,19 @@
         private const val MERGE_TASK_NAME = "merge"
         private const val COPY_TASK_NAME = "copy"
 
+        // Filename parts to differentiate how to use the profile rules
+        private const val FILENAME_MATCHER_BASELINE_PROFILE = "baseline-prof"
+        private const val FILENAME_MATCHER_STARTUP_PROFILE = "startup-prof"
+
         // The output file for the HRF baseline profile file in `src/main`
         private const val BASELINE_PROFILE_FILENAME = "baseline-prof.txt"
+        private const val STARTUP_PROFILE_FILENAME = "startup-prof.txt"
 
         internal fun maybeRegisterForMerge(
             project: Project,
             variantName: String,
             hasDependencies: Boolean = false,
+            library: Boolean,
             sourceProfilesFileCollection: FileCollection,
             outputDir: Provider<Directory>,
             filterRules: List<Pair<RuleType, String>> = listOf(),
@@ -92,12 +99,17 @@
                     // Sets the package filter rules. Note that if this task already exists
                     // because of a mergeIntoMain rule, rules are added to the existing ones.
                     task.filterRules.addAll(filterRules)
+
+                    // Sets whether this task has been configured for a library. In this case,
+                    // startup profiles are not handled.
+                    task.library.set(library)
                 }
         }
 
         internal fun maybeRegisterForCopy(
             project: Project,
             variantName: String,
+            library: Boolean,
             sourceDir: Provider<Directory>,
             outputDir: Provider<Directory>,
         ): TaskProvider<MergeBaselineProfileTask> {
@@ -106,6 +118,7 @@
                 .maybeRegister(COPY_TASK_NAME, variantName, "baselineProfileIntoSrc") { task ->
                     task.baselineProfileFileCollection.from.add(sourceDir)
                     task.baselineProfileDir.set(outputDir)
+                    task.library.set(library)
                 }
         }
     }
@@ -118,6 +131,9 @@
     @get: Optional
     abstract val hasDependencies: Property<Boolean>
 
+    @get: Input
+    abstract val library: Property<Boolean>
+
     @get:InputFiles
     @get:PathSensitive(PathSensitivity.NONE)
     abstract val baselineProfileFileCollection: ConfigurableFileCollection
@@ -157,22 +173,7 @@
         // Read the profile rules from the file collection that contains the profile artifacts from
         // all the configurations for this variant and merge them in a single list.
         val profileRules = baselineProfileFileCollection.files
-            .flatMap {
-                if (!it.exists()) {
-                    // Note that this can happen only if this task is misconfigured because of a
-                    // bug and not because of any user configuration.
-                    throw GradleException(
-                        """
-                        The specified merge task input `${it.absolutePath}` does not exist.
-                    """.trimIndent()
-                    )
-                }
-                if (it.isFile) {
-                    it.readLines()
-                } else {
-                    it.listFiles()!!.flatMap { f -> f.readLines() }
-                }
-            }
+            .readLines { FILENAME_MATCHER_BASELINE_PROFILE in it.name }
 
         if (variantName.isPresent && profileRules.isEmpty()) {
             logger.warn(
@@ -232,6 +233,32 @@
             .get()
             .asFile
             .writeText(filteredProfileRules.joinToString(System.lineSeparator()))
+
+        // If this is a library we can stop here and don't manage the startup profiles.
+        if (library.get()) {
+            return
+        }
+
+        // Same process with startup profiles.
+        val startupRules = baselineProfileFileCollection.files
+            .readLines { FILENAME_MATCHER_STARTUP_PROFILE in it.name }
+
+        // Use same sorting without filter for startup profiles.
+        val sortedProfileRules = startupRules
+            .asSequence()
+            .sorted()
+            .mapNotNull { ProfileRule.parse(it) }
+            .groupBy { it.classDescriptor + it.methodDescriptor }
+            .map { it.value[0] }
+            .sortedWith(ProfileRule.comparator)
+            .map { it.underlying }
+            .toList()
+
+        baselineProfileDir
+            .file(STARTUP_PROFILE_FILENAME)
+            .get()
+            .asFile
+            .writeText(sortedProfileRules.joinToString(System.lineSeparator()))
     }
 
     private fun Pair<RuleType, String>.isInclude(): Boolean = first == RuleType.INCLUDE
@@ -261,4 +288,9 @@
             }
         }
     }
+
+    private fun Iterable<File>.readLines(filterBlock: (File) -> (Boolean)): List<String> = this
+        .flatMap { if (it.isFile) listOf(it) else listOf(*it.listFiles()!!) }
+        .filter(filterBlock)
+        .flatMap { it.readLines() }
 }
diff --git a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/producer/tasks/CollectBaselineProfileTask.kt b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/producer/tasks/CollectBaselineProfileTask.kt
index 646a9dd..20b47cd 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/producer/tasks/CollectBaselineProfileTask.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/producer/tasks/CollectBaselineProfileTask.kt
@@ -147,10 +147,14 @@
                         .filter {
                             // The label for this artifact is `additionaltestoutput.benchmark.trace`
                             // https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:utp/android-test-plugin-host-additional-test-output/src/main/java/com/android/tools/utp/plugins/host/additionaltestoutput/AndroidAdditionalTestOutputPlugin.kt;l=199?q=additionaltestoutput.benchmark.trace
-                            it.label.label == "additionaltestoutput.benchmark.trace" &&
-                                "-baseline-prof-" in it.sourcePath.path
+                            it.label.label == "additionaltestoutput.benchmark.trace"
                         }
                         .map { File(it.sourcePath.path) }
+                        .filter {
+                            it.extension == "txt" &&
+                                ("-baseline-prof-" in it.name || "-startup-prof-" in it.name)
+                        }
+
                     if (baselineProfileFiles.isEmpty()) {
                         continue
                     }
diff --git a/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPluginTest.kt b/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPluginTest.kt
index d597426..09d2d7a 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPluginTest.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPluginTest.kt
@@ -52,15 +52,21 @@
         "src/$variantName/$EXPECTED_PROFILE_FOLDER/baseline-prof.txt"
     )
 
+    private fun startupProfileFile(variantName: String) = File(
+        projectSetup.consumer.rootDir,
+        "src/$variantName/$EXPECTED_PROFILE_FOLDER/startup-prof.txt"
+    )
+
     private fun readBaselineProfileFileContent(variantName: String): List<String> =
         baselineProfileFile(variantName).readLines()
 
+    private fun readStartupProfileFileContent(variantName: String): List<String> =
+        startupProfileFile(variantName).readLines()
+
     @Test
-    fun testGenerateTaskWithNoFlavors() {
+    fun testGenerateTaskWithNoFlavorsForLibrary() {
         projectSetup.consumer.setup(
-            androidPlugin = ANDROID_LIBRARY_PLUGIN,
-            dependencyOnProducerProject = true,
-            flavors = false
+            androidPlugin = ANDROID_LIBRARY_PLUGIN
         )
         projectSetup.producer.setupWithoutFlavors(
             releaseProfileLines = listOf(
@@ -68,6 +74,12 @@
                 Fixtures.CLASS_1,
                 Fixtures.CLASS_2_METHOD_1,
                 Fixtures.CLASS_2
+            ),
+            releaseStartupProfileLines = listOf(
+                Fixtures.CLASS_3_METHOD_1,
+                Fixtures.CLASS_3,
+                Fixtures.CLASS_4_METHOD_1,
+                Fixtures.CLASS_4
             )
         )
 
@@ -82,6 +94,49 @@
                 Fixtures.CLASS_2,
                 Fixtures.CLASS_2_METHOD_1,
             )
+
+        assertThat(startupProfileFile("main").exists()).isFalse()
+    }
+
+    @Test
+    fun testGenerateTaskWithNoFlavorsForApplication() {
+        projectSetup.consumer.setup(
+            androidPlugin = ANDROID_APPLICATION_PLUGIN
+        )
+        projectSetup.producer.setupWithoutFlavors(
+            releaseProfileLines = listOf(
+                Fixtures.CLASS_1_METHOD_1,
+                Fixtures.CLASS_1,
+                Fixtures.CLASS_2_METHOD_1,
+                Fixtures.CLASS_2
+            ),
+            releaseStartupProfileLines = listOf(
+                Fixtures.CLASS_3_METHOD_1,
+                Fixtures.CLASS_3,
+                Fixtures.CLASS_4_METHOD_1,
+                Fixtures.CLASS_4
+            )
+        )
+
+        gradleRunner
+            .withArguments("generateBaselineProfile", "--stacktrace")
+            .build()
+
+        assertThat(readBaselineProfileFileContent("release"))
+            .containsExactly(
+                Fixtures.CLASS_1,
+                Fixtures.CLASS_1_METHOD_1,
+                Fixtures.CLASS_2,
+                Fixtures.CLASS_2_METHOD_1,
+            )
+
+        assertThat(readStartupProfileFileContent("release"))
+            .containsExactly(
+                Fixtures.CLASS_3,
+                Fixtures.CLASS_3_METHOD_1,
+                Fixtures.CLASS_4,
+                Fixtures.CLASS_4_METHOD_1,
+            )
     }
 
     @Test
diff --git a/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/utils/BaselineProfileProjectSetupRule.kt b/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/utils/BaselineProfileProjectSetupRule.kt
index 606e105..37bd55b 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/utils/BaselineProfileProjectSetupRule.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/utils/BaselineProfileProjectSetupRule.kt
@@ -171,7 +171,8 @@
 data class VariantProfile(
     val flavor: String?,
     val buildType: String = "release",
-    val profileFileLines: Map<String, List<String>> = mapOf()
+    val profileFileLines: Map<String, List<String>> = mapOf(),
+    val startupFileLines: Map<String, List<String>> = mapOf()
 ) {
     val nonMinifiedVariant = "${flavor ?: ""}NonMinified${buildType.capitalized()}"
 }
@@ -224,30 +225,38 @@
     fun setupWithFreeAndPaidFlavors(
         freeReleaseProfileLines: List<String>,
         paidReleaseProfileLines: List<String>,
+        freeReleaseStartupProfileLines: List<String> = listOf(),
+        paidReleaseStartupProfileLines: List<String> = listOf(),
     ) {
         setup(
             variantProfiles = listOf(
                 VariantProfile(
                     flavor = "free",
                     buildType = "release",
-                    profileFileLines = mapOf("myTest" to freeReleaseProfileLines)
+                    profileFileLines = mapOf("myTest" to freeReleaseProfileLines),
+                    startupFileLines = mapOf("myStartupTest" to freeReleaseStartupProfileLines)
                 ),
                 VariantProfile(
                     flavor = "paid",
                     buildType = "release",
-                    profileFileLines = mapOf("myTest" to paidReleaseProfileLines)
+                    profileFileLines = mapOf("myTest" to paidReleaseProfileLines),
+                    startupFileLines = mapOf("myStartupTest" to paidReleaseStartupProfileLines)
                 ),
             )
         )
     }
 
-    fun setupWithoutFlavors(releaseProfileLines: List<String>) {
+    fun setupWithoutFlavors(
+        releaseProfileLines: List<String>,
+        releaseStartupProfileLines: List<String> = listOf(),
+    ) {
         setup(
             variantProfiles = listOf(
                 VariantProfile(
                     flavor = null,
                     buildType = "release",
-                    profileFileLines = mapOf("myTest" to releaseProfileLines)
+                    profileFileLines = mapOf("myTest" to releaseProfileLines),
+                    startupFileLines = mapOf("myStartupTest" to releaseStartupProfileLines)
                 )
             )
         )
@@ -265,7 +274,15 @@
                         Fixtures.CLASS_2,
                         Fixtures.CLASS_1
                     )
-                )
+                ),
+                startupFileLines = mapOf(
+                    "myStartupTest" to listOf(
+                        Fixtures.CLASS_3_METHOD_1,
+                        Fixtures.CLASS_4_METHOD_1,
+                        Fixtures.CLASS_3,
+                        Fixtures.CLASS_4
+                    )
+                ),
             )
         ),
         baselineProfileBlock: String = "",
@@ -324,7 +341,8 @@
             writeFakeTestResultsProto(
                 testResultsOutputDir = testResultsOutputDir,
                 profilesOutputDir = profilesOutputDir,
-                profileFileLines = it.profileFileLines
+                profileFileLines = it.profileFileLines,
+                startupFileLines = it.startupFileLines
             )
 
             // Gradle script to injects a fake and disable the actual task execution for
@@ -378,32 +396,42 @@
     private fun writeFakeTestResultsProto(
         testResultsOutputDir: File,
         profilesOutputDir: File,
-        profileFileLines: Map<String, List<String>>
+        profileFileLines: Map<String, List<String>>,
+        startupFileLines: Map<String, List<String>>
     ) {
 
         val testResultProtoBuilder = TestResultProto.TestResult.newBuilder()
 
-        // Writes a fake baseline profile for each item of the given map
-        profileFileLines.forEach {
-            val fakeProfileFile = File(profilesOutputDir, "fake-baseline-prof-${it.key}.txt")
-                .apply { writeText(it.value.joinToString(System.lineSeparator())) }
+        // This function writes a profile file for each key of the map, containing for lines
+        // the strings in the list in the value.
+        val writeProfiles: (Map<String, List<String>>, String) -> (Unit) = { map, fileNamePart ->
+            map.forEach {
 
-            testResultProtoBuilder.addOutputArtifact(
-                TestArtifactProto.Artifact.newBuilder()
-                    .setLabel(
-                        LabelProto.Label.newBuilder()
-                            .setLabel("additionaltestoutput.benchmark.trace")
-                            .build()
-                    )
-                    .setSourcePath(
-                        PathProto.Path.newBuilder()
-                            .setPath(fakeProfileFile.absolutePath)
-                            .build()
-                    )
-                    .build()
-            )
+                val fakeProfileFile = File(
+                    profilesOutputDir,
+                    "fake-$fileNamePart-${it.key}.txt"
+                ).apply { writeText(it.value.joinToString(System.lineSeparator())) }
+
+                testResultProtoBuilder.addOutputArtifact(
+                    TestArtifactProto.Artifact.newBuilder()
+                        .setLabel(
+                            LabelProto.Label.newBuilder()
+                                .setLabel("additionaltestoutput.benchmark.trace")
+                                .build()
+                        )
+                        .setSourcePath(
+                            PathProto.Path.newBuilder()
+                                .setPath(fakeProfileFile.absolutePath)
+                                .build()
+                        )
+                        .build()
+                )
+            }
         }
 
+        writeProfiles(profileFileLines, "baseline-prof")
+        writeProfiles(startupFileLines, "startup-prof")
+
         val testSuiteResultProto = TestSuiteResultProto.TestSuiteResult.newBuilder()
             .setTestStatus(TestStatusProto.TestStatus.PASSED)
             .addTestResult(testResultProtoBuilder.build())
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/Arguments.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/Arguments.kt
index 7af3fa9..8b9c181 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/Arguments.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/Arguments.kt
@@ -193,7 +193,7 @@
             arguments.getBenchmarkArgument("killProcessDelayMillis")?.toLong() ?: 0L
 
         enableStartupProfiles =
-            arguments.getBenchmarkArgument("startupProfiles.enable")?.toBoolean() ?: false
+            arguments.getBenchmarkArgument("startupProfiles.enable")?.toBoolean() ?: true
 
         strictStartupProfiles =
             arguments.getBenchmarkArgument("startupProfiles.strict")?.toBoolean() ?: false
diff --git a/benchmark/benchmark-macro-junit4/api/current.txt b/benchmark/benchmark-macro-junit4/api/current.txt
index 3358929..0bcc71e 100644
--- a/benchmark/benchmark-macro-junit4/api/current.txt
+++ b/benchmark/benchmark-macro-junit4/api/current.txt
@@ -4,7 +4,8 @@
   @RequiresApi(28) public final class BaselineProfileRule implements org.junit.rules.TestRule {
     ctor public BaselineProfileRule();
     method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description description);
-    method public void collectBaselineProfile(String packageName, optional int iterations, optional String? outputFilePrefix, optional kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.Boolean>? filterPredicate, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collectBaselineProfile(String packageName, optional int iterations, optional String? outputFilePrefix, optional boolean includeInStartupProfile, optional kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.Boolean>? filterPredicate, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collectBaselineProfile(String packageName, optional int iterations, optional String? outputFilePrefix, optional boolean includeInStartupProfile, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
     method public void collectBaselineProfile(String packageName, optional int iterations, optional String? outputFilePrefix, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
     method public void collectBaselineProfile(String packageName, optional int iterations, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
     method public void collectBaselineProfile(String packageName, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
diff --git a/benchmark/benchmark-macro-junit4/api/public_plus_experimental_current.txt b/benchmark/benchmark-macro-junit4/api/public_plus_experimental_current.txt
index 6b25fae..bd292b7 100644
--- a/benchmark/benchmark-macro-junit4/api/public_plus_experimental_current.txt
+++ b/benchmark/benchmark-macro-junit4/api/public_plus_experimental_current.txt
@@ -4,12 +4,14 @@
   @RequiresApi(28) public final class BaselineProfileRule implements org.junit.rules.TestRule {
     ctor public BaselineProfileRule();
     method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description description);
-    method public void collectBaselineProfile(String packageName, optional int iterations, optional String? outputFilePrefix, optional kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.Boolean>? filterPredicate, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collectBaselineProfile(String packageName, optional int iterations, optional String? outputFilePrefix, optional boolean includeInStartupProfile, optional kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.Boolean>? filterPredicate, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collectBaselineProfile(String packageName, optional int iterations, optional String? outputFilePrefix, optional boolean includeInStartupProfile, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
     method public void collectBaselineProfile(String packageName, optional int iterations, optional String? outputFilePrefix, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
     method public void collectBaselineProfile(String packageName, optional int iterations, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
     method public void collectBaselineProfile(String packageName, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
-    method @androidx.benchmark.macro.ExperimentalStableBaselineProfilesApi public void collectStableBaselineProfile(String packageName, int maxIterations, optional int stableIterations, optional String? outputFilePrefix, optional boolean strictStability, optional kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.Boolean>? filterPredicate, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
-    method @androidx.benchmark.macro.ExperimentalStableBaselineProfilesApi public void collectStableBaselineProfile(String packageName, int maxIterations, optional int stableIterations, optional String? outputFilePrefix, optional boolean strictStability, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method @androidx.benchmark.macro.ExperimentalStableBaselineProfilesApi public void collectStableBaselineProfile(String packageName, int maxIterations, optional int stableIterations, optional String? outputFilePrefix, optional boolean includeInStartupProfile, optional boolean strictStability, optional kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.Boolean>? filterPredicate, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method @androidx.benchmark.macro.ExperimentalStableBaselineProfilesApi public void collectStableBaselineProfile(String packageName, int maxIterations, optional int stableIterations, optional String? outputFilePrefix, optional boolean includeInStartupProfile, optional boolean strictStability, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method @androidx.benchmark.macro.ExperimentalStableBaselineProfilesApi public void collectStableBaselineProfile(String packageName, int maxIterations, optional int stableIterations, optional String? outputFilePrefix, optional boolean includeInStartupProfile, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
     method @androidx.benchmark.macro.ExperimentalStableBaselineProfilesApi public void collectStableBaselineProfile(String packageName, int maxIterations, optional int stableIterations, optional String? outputFilePrefix, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
     method @androidx.benchmark.macro.ExperimentalStableBaselineProfilesApi public void collectStableBaselineProfile(String packageName, int maxIterations, optional int stableIterations, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
     method @androidx.benchmark.macro.ExperimentalStableBaselineProfilesApi public void collectStableBaselineProfile(String packageName, int maxIterations, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
diff --git a/benchmark/benchmark-macro-junit4/api/restricted_current.txt b/benchmark/benchmark-macro-junit4/api/restricted_current.txt
index 3358929..0bcc71e 100644
--- a/benchmark/benchmark-macro-junit4/api/restricted_current.txt
+++ b/benchmark/benchmark-macro-junit4/api/restricted_current.txt
@@ -4,7 +4,8 @@
   @RequiresApi(28) public final class BaselineProfileRule implements org.junit.rules.TestRule {
     ctor public BaselineProfileRule();
     method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description description);
-    method public void collectBaselineProfile(String packageName, optional int iterations, optional String? outputFilePrefix, optional kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.Boolean>? filterPredicate, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collectBaselineProfile(String packageName, optional int iterations, optional String? outputFilePrefix, optional boolean includeInStartupProfile, optional kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.Boolean>? filterPredicate, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method public void collectBaselineProfile(String packageName, optional int iterations, optional String? outputFilePrefix, optional boolean includeInStartupProfile, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
     method public void collectBaselineProfile(String packageName, optional int iterations, optional String? outputFilePrefix, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
     method public void collectBaselineProfile(String packageName, optional int iterations, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
     method public void collectBaselineProfile(String packageName, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
diff --git a/benchmark/benchmark-macro-junit4/src/main/java/androidx/benchmark/macro/junit4/BaselineProfileRule.kt b/benchmark/benchmark-macro-junit4/src/main/java/androidx/benchmark/macro/junit4/BaselineProfileRule.kt
index b9be975..12dca06 100644
--- a/benchmark/benchmark-macro-junit4/src/main/java/androidx/benchmark/macro/junit4/BaselineProfileRule.kt
+++ b/benchmark/benchmark-macro-junit4/src/main/java/androidx/benchmark/macro/junit4/BaselineProfileRule.kt
@@ -108,6 +108,12 @@
      * @param outputFilePrefix An optional file name prefix used when creating the output
      *    file with the contents of the human readable baseline profile.
      *    For example: `outputFilePrefix-baseline-prof.txt`
+     * @param includeInStartupProfile determines whether the generated profile should be also used
+     *   as a startup profile. A startup profile is utilized during the build process in order to
+     *   determine which classes are needed in the primary dex to optimize the startup time. This
+     *   flag should be used only for startup flows, such as main application startup pre and post
+     *   login or other entry points of the app. Note that methods collected in a startup profiles
+     *   are also utilized for baseline profiles.
      * @param filterPredicate Function used to filter individual rules / lines of the baseline
      *   profile. By default, no filters are applied. Note that this works only when the target
      *   application's code is not obfuscated.
@@ -118,6 +124,7 @@
         packageName: String,
         iterations: Int = 3,
         outputFilePrefix: String? = null,
+        includeInStartupProfile: Boolean = false,
         filterPredicate: ((String) -> Boolean)? = null,
         profileBlock: MacrobenchmarkScope.() -> Unit
     ) {
@@ -125,6 +132,7 @@
             uniqueName = outputFilePrefix ?: currentDescription.toUniqueName(),
             packageName = packageName,
             iterations = iterations,
+            includeInStartupProfile = includeInStartupProfile,
             filterPredicate = filterPredicate,
             profileBlock = profileBlock
         )
@@ -141,6 +149,12 @@
      * @param outputFilePrefix An optional file name prefix used when creating the output
      *    file with the contents of the human readable baseline profile.
      *    For example: `outputFilePrefix-baseline-prof.txt`
+     * @param includeInStartupProfile determines whether the generated profile should be also used
+     *   as a startup profile. A startup profile is utilized during the build process in order to
+     *   determine which classes are needed in the primary dex to optimize the startup time. This
+     *   flag should be used only for startup flows, such as main application startup pre and post
+     *   login or other entry points of the app. Note that methods collected in a startup profiles
+     *   are also utilized for baseline profiles.
      * @param strictStability Enforce if the generated profile was stable
      * @param filterPredicate Function used to filter individual rules / lines of the baseline
      *  profile. By default, no filters are applied. Note that this works only when the target
@@ -154,6 +168,7 @@
         maxIterations: Int,
         stableIterations: Int = 3,
         outputFilePrefix: String? = null,
+        includeInStartupProfile: Boolean = false,
         strictStability: Boolean = false,
         filterPredicate: ((String) -> Boolean)? = null,
         profileBlock: MacrobenchmarkScope.() -> Unit
@@ -163,6 +178,7 @@
             packageName = packageName,
             stableIterations = stableIterations,
             maxIterations = maxIterations,
+            includeInStartupProfile = includeInStartupProfile,
             strictStability = strictStability,
             filterPredicate = filterPredicate,
             profileBlock = profileBlock
diff --git a/benchmark/benchmark-macro/api/restricted_current.txt b/benchmark/benchmark-macro/api/restricted_current.txt
index 2176d91..a5eae3b 100644
--- a/benchmark/benchmark-macro/api/restricted_current.txt
+++ b/benchmark/benchmark-macro/api/restricted_current.txt
@@ -10,8 +10,8 @@
   }
 
   public final class BaselineProfilesKt {
-    method @RequiresApi(28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void collectStableBaselineProfile(String uniqueName, String packageName, int stableIterations, int maxIterations, optional boolean strictStability, kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.Boolean>? filterPredicate, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
-    method @RequiresApi(28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void collectStableBaselineProfile(String uniqueName, String packageName, int stableIterations, int maxIterations, kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.Boolean>? filterPredicate, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method @RequiresApi(28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void collectStableBaselineProfile(String uniqueName, String packageName, int stableIterations, int maxIterations, optional boolean strictStability, boolean includeInStartupProfile, kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.Boolean>? filterPredicate, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
+    method @RequiresApi(28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void collectStableBaselineProfile(String uniqueName, String packageName, int stableIterations, int maxIterations, boolean includeInStartupProfile, kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.Boolean>? filterPredicate, kotlin.jvm.functions.Function1<? super androidx.benchmark.macro.MacrobenchmarkScope,kotlin.Unit> profileBlock);
   }
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class BatteryCharge {
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/StartupProfilesTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/StartupProfilesTest.kt
deleted file mode 100644
index f99856a..0000000
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/StartupProfilesTest.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.benchmark.macro
-
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import org.junit.Assert.assertEquals
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-@SmallTest
-class StartupProfilesTest {
-    @Test
-    fun startupProfiles() {
-        // https://youtrack.jetbrains.com/issue/KT-2425
-        val dollar = "$"
-        val profile = """
-            Landroidx/Foo/Bar;
-            Lfoo/bar/Baz$dollar<Suffix>;
-            HSPLjava/io/DataOutputStream;->writeByte(I)V+]Ljava/io/OutputStream;missing_types
-        """.trimIndent()
-
-        val startupRules = startupProfile(profile, includeStartupOnly = false)
-        val expectedRules = """
-            SLandroidx/Foo/Bar;
-            SLfoo/bar/Baz;
-            SLjava/io/DataOutputStream;
-        """.trimIndent()
-        assertEquals(expectedRules, startupRules)
-    }
-
-    @Test
-    fun startupProfiles_includeStartupOnly() {
-        // https://youtrack.jetbrains.com/issue/KT-2425
-        val dollar = "$"
-        val profile = """
-            Landroidx/Foo/Bar;
-            Lfoo/bar/Baz$dollar<Suffix>;
-            HSPLjava/io/DataOutputStream;->writeByte(I)V+]Ljava/io/OutputStream;missing_types
-            HPLandroidx/startup/AppInitializer;->**(**)**
-        """.trimIndent()
-
-        val startupRules = startupProfile(profile, includeStartupOnly = true)
-        val expectedRules = """
-            SLandroidx/Foo/Bar;
-            SLfoo/bar/Baz;
-            SLjava/io/DataOutputStream;
-        """.trimIndent()
-        assertEquals(expectedRules, startupRules)
-    }
-}
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt
index b6bc2ca..232202d 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt
@@ -47,7 +47,7 @@
 import org.junit.runners.Parameterized
 import org.junit.runners.Parameterized.Parameters
 
-private const val tracingPerfettoVersion = "1.0.0-alpha13" // TODO(224510255): get by 'reflection'
+private const val tracingPerfettoVersion = "1.0.0-alpha14" // TODO(224510255): get by 'reflection'
 private const val minSupportedSdk = Build.VERSION_CODES.R // TODO(234351579): Support API < 30
 
 @RunWith(Parameterized::class)
diff --git a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/BaselineProfiles.kt b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/BaselineProfiles.kt
index 6a31a42..e41a947 100644
--- a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/BaselineProfiles.kt
+++ b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/BaselineProfiles.kt
@@ -41,6 +41,7 @@
     uniqueName: String,
     packageName: String,
     iterations: Int = 3,
+    includeInStartupProfile: Boolean,
     filterPredicate: ((String) -> Boolean)?,
     profileBlock: MacrobenchmarkScope.() -> Unit,
 ) {
@@ -84,7 +85,13 @@
         // Filter
         val profile = filterProfileRulesToTargetP(unfilteredProfile, sortRules = true)
         // Report
-        reportResults(profile, filterPredicate, uniqueName, startTime)
+        reportResults(
+            profile = profile,
+            filterPredicate = filterPredicate,
+            uniqueFilePrefix = uniqueName,
+            startTime = startTime,
+            includeInStartupProfile = includeInStartupProfile
+        )
     } finally {
         killProcessBlock.invoke()
     }
@@ -104,6 +111,7 @@
     stableIterations: Int,
     maxIterations: Int,
     strictStability: Boolean = false,
+    includeInStartupProfile: Boolean,
     filterPredicate: ((String) -> Boolean)?,
     profileBlock: MacrobenchmarkScope.() -> Unit
 ) {
@@ -188,7 +196,13 @@
         }
 
         val profile = filterProfileRulesToTargetP(lastProfile, sortRules = true)
-        reportResults(profile, filterPredicate, uniqueName, startTime)
+        reportResults(
+            profile = profile,
+            filterPredicate = filterPredicate,
+            uniqueFilePrefix = uniqueName,
+            startTime = startTime,
+            includeInStartupProfile = includeInStartupProfile
+        )
     } finally {
         killProcessBlock.invoke()
     }
@@ -231,53 +245,41 @@
     profile: String,
     filterPredicate: ((String) -> Boolean)?,
     uniqueFilePrefix: String,
-    startTime: Long
+    startTime: Long,
+    includeInStartupProfile: Boolean
 ) {
-    // Build a startup profile
-    var startupProfile: String? = null
-    if (Arguments.enableStartupProfiles) {
-        startupProfile =
-            startupProfile(profile, includeStartupOnly = Arguments.strictStartupProfiles)
-    }
-
     // Filter profile if necessary based on filters
     val filteredProfile = applyPackageFilters(profile, filterPredicate)
 
     // Write a file with a timestamp to be able to disambiguate between runs with the same
     // unique name.
 
-    val fileName = "$uniqueFilePrefix-baseline-prof.txt"
-    val absolutePath = Outputs.writeFile(fileName, "baseline-profile") {
-        it.writeText(filteredProfile)
-    }
-    var startupProfilePath: String? = null
-    if (startupProfile != null) {
-        val startupProfileFileName = "$uniqueFilePrefix-startup-prof.txt"
-        startupProfilePath = Outputs.writeFile(startupProfileFileName, "startup-profile") {
-            it.writeText(startupProfile)
+    val (fileName, reportKey, tsFileName) =
+        if (includeInStartupProfile && Arguments.enableStartupProfiles) {
+            arrayOf(
+                "$uniqueFilePrefix-startup-prof.txt",
+                "startup-profile",
+                "$uniqueFilePrefix-startup-prof-${Outputs.dateToFileName()}.txt"
+            )
+        } else {
+            arrayOf(
+                "$uniqueFilePrefix-baseline-prof.txt",
+                "baseline-profile",
+                "$uniqueFilePrefix-baseline-prof-${Outputs.dateToFileName()}.txt"
+            )
         }
-    }
-    val tsFileName = "$uniqueFilePrefix-baseline-prof-${Outputs.dateToFileName()}.txt"
+
+    val absolutePath = Outputs.writeFile(fileName, reportKey) { it.writeText(filteredProfile) }
     val tsAbsolutePath = Outputs.writeFile(tsFileName, "baseline-profile-ts") {
         Log.d(TAG, "Pull Baseline Profile with: `adb pull \"${it.absolutePath}\" .`")
         it.writeText(filteredProfile)
     }
-    var tsStartupAbsolutePath: String? = null
-    if (startupProfile != null) {
-        val tsStartupFileName = "$uniqueFilePrefix-startup-prof-${Outputs.dateToFileName()}.txt"
-        tsStartupAbsolutePath = Outputs.writeFile(tsStartupFileName, "startup-profile-ts") {
-            Log.d(TAG, "Pull Startup Profile with: `adb pull \"${it.absolutePath}\" .`")
-            it.writeText(startupProfile)
-        }
-    }
 
     val totalRunTime = System.nanoTime() - startTime
     val results = Summary(
         totalRunTime = totalRunTime,
         profilePath = absolutePath,
-        profileTsPath = tsAbsolutePath,
-        startupProfilePath = startupProfilePath,
-        startupTsProfilePath = tsStartupAbsolutePath
+        profileTsPath = tsAbsolutePath
     )
     InstrumentationResults.instrumentationReport {
         val summary = summaryRecord(results)
@@ -411,21 +413,7 @@
         """.trimIndent()
     )
 
-    // Link to a path with timestamp to prevent studio from caching the file
-    val startupTsProfilePath = record.startupTsProfilePath
-    if (!startupTsProfilePath.isNullOrBlank()) {
-        val startupRelativePath = Outputs.relativePathFor(startupTsProfilePath)
-            .replace("(", "\\(")
-            .replace(")", "\\)")
-        summary.append("\n").append(
-            """
-                Startup profile [results](file://$startupRelativePath)
-            """.trimIndent()
-        )
-    }
-
     // Add commands that can be used to pull these files.
-
     summary.append("\n")
         .append("\n")
         .append(
@@ -434,18 +422,6 @@
                 adb ${deviceSpecifier}pull "${record.profilePath}" .
             """.trimIndent()
         )
-
-    val startupProfilePath = record.startupProfilePath
-    if (!startupProfilePath.isNullOrBlank()) {
-        summary.append("\n")
-            .append("\n")
-            .append(
-                """
-                    To copy the startup profile use:
-                    adb ${deviceSpecifier}pull "${record.startupProfilePath}" .
-                """.trimIndent()
-            )
-    }
     return summary.toString()
 }
 
@@ -471,14 +447,4 @@
     val totalRunTime: Long,
     val profilePath: String,
     val profileTsPath: String,
-    val startupProfilePath: String? = null,
-    val startupTsProfilePath: String? = null
-) {
-    init {
-        if (startupProfilePath.isNullOrBlank()) {
-            require(startupTsProfilePath.isNullOrBlank())
-        } else {
-            require(!startupTsProfilePath.isNullOrBlank())
-        }
-    }
-}
+)
diff --git a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/StartupProfiles.kt b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/StartupProfiles.kt
deleted file mode 100644
index 8b50582..0000000
--- a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/StartupProfiles.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-@file:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-
-package androidx.benchmark.macro
-
-import androidx.annotation.RestrictTo
-
-private val PROFILE_RULE_REGEX = "(H?S?P?)L([^$;]*)(.*)".toRegex()
-
-/**
- * Builds a startup profile for a given baseline profile.
- *
- * This startup profile can be used for dex layout optimizations.
- */
-fun startupProfile(profile: String, includeStartupOnly: Boolean = false): String {
-    val rules = profile.lines().mapNotNull { rule ->
-        when (val result = PROFILE_RULE_REGEX.find(rule)) {
-            null -> null
-            else -> {
-                val (flags, classPrefix, _) = result.destructured
-                // Empty flags are indicative that the class needs to be aggressively preloaded
-                // Therefore the class belongs in the primary dex.
-                val isStartup = flags.isEmpty() || flags.contains("S")
-                if (includeStartupOnly && !isStartup) {
-                    null
-                } else {
-                    "SL$classPrefix;"
-                }
-            }
-        }
-    }
-    val ruleSet = mutableSetOf<String>()
-    val startupRules = mutableListOf<String>()
-    // Try and keep the same order
-    rules.forEach { rule ->
-        if (!ruleSet.contains(rule)) {
-            ruleSet += rule
-            startupRules += rule
-        }
-    }
-    return startupRules.joinToString(separator = "\n")
-}
diff --git a/benchmark/integration-tests/baselineprofile-producer/src/main/java/androidx/benchmark/integration/baselineprofile/producer/BaselineProfileTest.kt b/benchmark/integration-tests/baselineprofile-producer/src/main/java/androidx/benchmark/integration/baselineprofile/producer/BaselineProfileTest.kt
index 1fb8eee..29b8503 100644
--- a/benchmark/integration-tests/baselineprofile-producer/src/main/java/androidx/benchmark/integration/baselineprofile/producer/BaselineProfileTest.kt
+++ b/benchmark/integration-tests/baselineprofile-producer/src/main/java/androidx/benchmark/integration/baselineprofile/producer/BaselineProfileTest.kt
@@ -23,6 +23,7 @@
 import androidx.test.filters.LargeTest
 import androidx.test.filters.SdkSuppress
 import org.junit.Assume.assumeTrue
+import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 
@@ -33,20 +34,31 @@
     @get:Rule
     val baselineRule = BaselineProfileRule()
 
-    @Test
-    fun startupBaselineProfile() {
+    @Before
+    fun setUp() {
         assumeTrue(DeviceInfo.isRooted || Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
-
-        // Collects the baseline profile
-        baselineRule.collectBaselineProfile(
-            packageName = PACKAGE_NAME,
-            profileBlock = {
-                startActivityAndWait(Intent(ACTION))
-                device.waitForIdle()
-            }
-        )
     }
 
+    @Test
+    fun standardBaselineProfile() = baselineRule.collectBaselineProfile(
+        packageName = PACKAGE_NAME,
+        includeInStartupProfile = false,
+        profileBlock = {
+            startActivityAndWait(Intent(ACTION))
+            device.waitForIdle()
+        }
+    )
+
+    @Test
+    fun startupBaselineProfile() = baselineRule.collectBaselineProfile(
+        packageName = PACKAGE_NAME,
+        includeInStartupProfile = true,
+        profileBlock = {
+            startActivityAndWait(Intent(ACTION))
+            device.waitForIdle()
+        }
+    )
+
     companion object {
         private const val PACKAGE_NAME =
             "androidx.benchmark.integration.baselineprofile.consumer"
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/BaselineProfileRuleTest.kt b/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/BaselineProfileRuleTest.kt
index 4c36dffb3..9bbca93 100644
--- a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/BaselineProfileRuleTest.kt
+++ b/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/BaselineProfileRuleTest.kt
@@ -40,6 +40,8 @@
     @get:Rule
     val baselineRule = BaselineProfileRule()
 
+    private val filterRegex = "^.*L${PACKAGE_NAME.replace(".", "/")}".toRegex()
+
     @Test
     fun appNotInstalled() {
         val error = assertFailsWith<AssertionError> {
@@ -64,9 +66,7 @@
         // Collects the baseline profile
         baselineRule.collectBaselineProfile(
             packageName = PACKAGE_NAME,
-            filterPredicate = {
-                it.contains("^.*L${PACKAGE_NAME.replace(".", "/")}".toRegex())
-            },
+            filterPredicate = { it.contains(filterRegex) },
             profileBlock = {
                 assertEquals(expectedIteration++, iteration)
                 startActivityAndWait(Intent(ACTION))
@@ -75,8 +75,13 @@
         )
         assertEquals(3, expectedIteration)
 
+        // Note: this name is automatically generated starting from class and method name,
+        // according to the patter `<class>_<method>-baseline-prof.txt`. Changes for class and
+        // method names should be reflected here in order for the test to succeed.
+        val baselineProfileOutputFileName = "BaselineProfileRuleTest_filter-baseline-prof.txt"
+
         // Asserts the output of the baseline profile
-        val lines = File(Outputs.outputDirectory, BASELINE_PROFILE_OUTPUT_FILE_NAME).readLines()
+        val lines = File(Outputs.outputDirectory, baselineProfileOutputFileName).readLines()
         assertThat(lines).containsExactly(
             "HSPLandroidx/benchmark/integration/macrobenchmark/target/EmptyActivity;" +
                 "-><init>()V",
@@ -86,16 +91,44 @@
         )
     }
 
+    @Test
+    fun profileType() {
+        assumeTrue(Build.VERSION.SDK_INT >= 33 || Shell.isSessionRooted())
+
+        data class TestConfig(val includeInStartupProfile: Boolean, val outputFileName: String)
+
+        arrayOf(
+            TestConfig(true, "BaselineProfileRuleTest_profileType-startup-prof.txt"),
+            TestConfig(false, "BaselineProfileRuleTest_profileType-baseline-prof.txt"),
+        ).forEach { (includeInStartupProfile, outputFilename) ->
+
+            // Collects the baseline profile
+            baselineRule.collectBaselineProfile(
+                packageName = PACKAGE_NAME,
+                filterPredicate = { it.contains(filterRegex) },
+                includeInStartupProfile = includeInStartupProfile,
+                profileBlock = {
+                    startActivityAndWait(Intent(ACTION))
+                    device.waitForIdle()
+                }
+            )
+
+            // Asserts the output of the baseline profile
+            val lines = File(Outputs.outputDirectory, outputFilename).readLines()
+            assertThat(lines).containsExactly(
+                "HSPLandroidx/benchmark/integration/macrobenchmark/target/EmptyActivity;" +
+                    "-><init>()V",
+                "HSPLandroidx/benchmark/integration/macrobenchmark/target/EmptyActivity;" +
+                    "->onCreate(Landroid/os/Bundle;)V",
+                "Landroidx/benchmark/integration/macrobenchmark/target/EmptyActivity;",
+            )
+        }
+    }
+
     companion object {
         private const val PACKAGE_NAME =
             "androidx.benchmark.integration.macrobenchmark.target"
         private const val ACTION =
             "androidx.benchmark.integration.macrobenchmark.target.EMPTY_ACTIVITY"
-
-        // Note: this name is automatically generated starting from class and method name,
-        // according to the patter `<class>_<method>-baseline-prof.txt`. Changes for class and
-        // method names should be reflected here in order for the test to succeed.
-        private const val BASELINE_PROFILE_OUTPUT_FILE_NAME =
-            "BaselineProfileRuleTest_filter-baseline-prof.txt"
     }
 }
diff --git a/bluetooth/bluetooth/api/current.txt b/bluetooth/bluetooth/api/current.txt
index e6f50d0..2bfa765 100644
--- a/bluetooth/bluetooth/api/current.txt
+++ b/bluetooth/bluetooth/api/current.txt
@@ -1 +1,14 @@
 // Signature format: 4.0
+package androidx.bluetooth {
+
+  public final class BluetoothDevice {
+    method @RequiresPermission(anyOf={"android.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT"}) public int getBondState();
+    method public java.util.UUID getId();
+    method @RequiresPermission(anyOf={"android.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT"}) public String? getName();
+    property @RequiresPermission(anyOf={"android.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT"}) public final int bondState;
+    property public final java.util.UUID id;
+    property @RequiresPermission(anyOf={"android.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT"}) public final String? name;
+  }
+
+}
+
diff --git a/bluetooth/bluetooth/api/public_plus_experimental_current.txt b/bluetooth/bluetooth/api/public_plus_experimental_current.txt
index e6f50d0..2bfa765 100644
--- a/bluetooth/bluetooth/api/public_plus_experimental_current.txt
+++ b/bluetooth/bluetooth/api/public_plus_experimental_current.txt
@@ -1 +1,14 @@
 // Signature format: 4.0
+package androidx.bluetooth {
+
+  public final class BluetoothDevice {
+    method @RequiresPermission(anyOf={"android.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT"}) public int getBondState();
+    method public java.util.UUID getId();
+    method @RequiresPermission(anyOf={"android.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT"}) public String? getName();
+    property @RequiresPermission(anyOf={"android.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT"}) public final int bondState;
+    property public final java.util.UUID id;
+    property @RequiresPermission(anyOf={"android.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT"}) public final String? name;
+  }
+
+}
+
diff --git a/bluetooth/bluetooth/api/restricted_current.txt b/bluetooth/bluetooth/api/restricted_current.txt
index e6f50d0..2bfa765 100644
--- a/bluetooth/bluetooth/api/restricted_current.txt
+++ b/bluetooth/bluetooth/api/restricted_current.txt
@@ -1 +1,14 @@
 // Signature format: 4.0
+package androidx.bluetooth {
+
+  public final class BluetoothDevice {
+    method @RequiresPermission(anyOf={"android.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT"}) public int getBondState();
+    method public java.util.UUID getId();
+    method @RequiresPermission(anyOf={"android.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT"}) public String? getName();
+    property @RequiresPermission(anyOf={"android.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT"}) public final int bondState;
+    property public final java.util.UUID id;
+    property @RequiresPermission(anyOf={"android.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT"}) public final String? name;
+  }
+
+}
+
diff --git a/bluetooth/bluetooth/build.gradle b/bluetooth/bluetooth/build.gradle
index d030c42..445c7ab 100644
--- a/bluetooth/bluetooth/build.gradle
+++ b/bluetooth/bluetooth/build.gradle
@@ -24,8 +24,17 @@
 
 dependencies {
     implementation(libs.kotlinStdlib)
+    implementation(libs.kotlinCoroutinesCore)
 
-    implementation "androidx.annotation:annotation:1.4.0"
+    implementation(project(":annotation:annotation-experimental"))
+
+    implementation("androidx.annotation:annotation:1.6.0")
+
+    androidTestImplementation(libs.testExtJunit)
+    androidTestImplementation(libs.testExtTruth)
+    androidTestImplementation(libs.testRunner)
+    androidTestImplementation(libs.junit)
+    androidTestImplementation(libs.testRules)
 }
 
 androidx {
diff --git a/bluetooth/bluetooth/src/androidTest/AndroidManifest.xml b/bluetooth/bluetooth/src/androidTest/AndroidManifest.xml
index 8e90956..9c08c63 100644
--- a/bluetooth/bluetooth/src/androidTest/AndroidManifest.xml
+++ b/bluetooth/bluetooth/src/androidTest/AndroidManifest.xml
@@ -14,4 +14,9 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
-<manifest />
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+    <uses-permission android:name="android.permission.BLUETOOTH"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
+</manifest>
diff --git a/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/BluetoothDeviceTest.kt b/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/BluetoothDeviceTest.kt
new file mode 100644
index 0000000..28671933
--- /dev/null
+++ b/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/BluetoothDeviceTest.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.bluetooth
+
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothManager
+import android.content.Context
+import android.os.Build
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.rule.GrantPermissionRule
+import junit.framework.TestCase.assertEquals
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class BluetoothDeviceTest {
+    @Rule
+    @JvmField
+    val permissionRule: GrantPermissionRule =
+        if (Build.VERSION.SDK_INT >= 31) {
+            GrantPermissionRule.grant(
+                android.Manifest.permission.ACCESS_FINE_LOCATION,
+                android.Manifest.permission.BLUETOOTH_CONNECT,
+                android.Manifest.permission.BLUETOOTH_SCAN
+            )
+        } else GrantPermissionRule.grant(
+            android.Manifest.permission.ACCESS_FINE_LOCATION,
+            android.Manifest.permission.BLUETOOTH
+        )
+
+    private val context: Context = ApplicationProvider.getApplicationContext()
+    private val bluetoothManager: BluetoothManager =
+        context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
+    private val bluetoothAdapter: BluetoothAdapter = bluetoothManager.adapter
+
+    @Test
+    fun constructorWithFwkInstance() {
+        val fwkBluetoothDevice = bluetoothAdapter.getRemoteDevice("00:01:02:03:04:05")
+
+        val bluetoothDevice = BluetoothDevice(fwkBluetoothDevice)
+
+        assertEquals(bluetoothDevice.bondState, fwkBluetoothDevice.bondState)
+        assertEquals(bluetoothDevice.name, fwkBluetoothDevice.name)
+    }
+}
\ No newline at end of file
diff --git a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/BluetoothDevice.kt b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/BluetoothDevice.kt
new file mode 100644
index 0000000..306d336
--- /dev/null
+++ b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/BluetoothDevice.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.bluetooth
+
+import android.bluetooth.BluetoothDevice as FwkBluetoothDevice
+import androidx.annotation.RequiresPermission
+import java.util.UUID
+
+/**
+ * Represents a remote Bluetooth device. A BluetoothDevice lets you query information about it, such
+ * as the name and bond state of the device.
+ *
+ * @property id the unique id for this BluetoothDevice
+ * @property name the name for this BluetoothDevice
+ * @property bondState the bondState for this BluetoothDevice
+ *
+ */
+class BluetoothDevice internal constructor(private val fwkDevice: FwkBluetoothDevice) {
+    val id: UUID = UUID.randomUUID()
+
+    @get:RequiresPermission(
+        anyOf = ["android.permission.BLUETOOTH",
+            "android.permission.BLUETOOTH_CONNECT"]
+    )
+    val name: String?
+        get() = fwkDevice.name
+
+    @get:RequiresPermission(
+        anyOf = ["android.permission.BLUETOOTH",
+            "android.permission.BLUETOOTH_CONNECT"]
+    )
+    val bondState: Int
+        get() = fwkDevice.bondState
+}
\ No newline at end of file
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/checkapi/CheckApiTest.kt b/buildSrc-tests/src/test/kotlin/androidx/build/checkapi/CheckApiTest.kt
new file mode 100644
index 0000000..7bf5f5a
--- /dev/null
+++ b/buildSrc-tests/src/test/kotlin/androidx/build/checkapi/CheckApiTest.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.build.checkapi
+
+import androidx.build.Version
+import java.io.File
+import org.junit.Assert.assertEquals
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
+
+class CheckApiTest {
+    @Rule
+    @JvmField
+    val tmpFolder = TemporaryFolder()
+
+    @Test
+    fun getRequiredCompatibilityApiFileFromDirTest() {
+        val apiDir = createTempDir("api", CORE_API_FILES)
+
+        assertEquals(
+            "1.1.0-beta02.txt",
+            getRequiredCompatibilityApiFileFromDir(
+                apiDir,
+                Version("1.1.0-beta03"),
+                ApiType.CLASSAPI
+            )?.name
+        )
+
+        assertEquals(
+            "1.3.0-beta01.txt",
+            getRequiredCompatibilityApiFileFromDir(
+                apiDir,
+                Version("1.4.0-alpha01"),
+                ApiType.CLASSAPI
+            )?.name
+        )
+    }
+
+    @Suppress("SameParameterValue")
+    private fun createTempDir(dirName: String, fileNames: List<String>): File =
+        tmpFolder.newFolder(dirName).also { apiDir ->
+            fileNames.forEach { fileName ->
+                File(apiDir, fileName).createNewFile()
+            }
+        }
+}
+
+/**
+ * List of API files representing `androidx.core:core:1.3.0-beta01`.
+ */
+private val CORE_API_FILES = listOf(
+    "1.1.0-beta01.txt",
+    "1.1.0-beta02.txt",
+    "1.1.0-rc01.txt",
+    "1.2.0-beta01.txt",
+    "1.2.0-beta02.txt",
+    "1.3.0-beta01.txt",
+    "api_lint.ignore",
+    "current.txt",
+    "public_plus_experimental_1.0.0.txt",
+    "public_plus_experimental_1.1.0-beta01.txt",
+    "public_plus_experimental_1.1.0-rc01.txt",
+    "public_plus_experimental_1.2.0-beta01.txt",
+    "public_plus_experimental_1.2.0-beta02.txt",
+    "public_plus_experimental_1.3.0-beta01.txt",
+    "res-1.1.0-beta01.txt",
+    "res-1.1.0-beta02.txt",
+    "res-1.1.0-rc01.txt",
+    "res-1.2.0-beta01.txt",
+    "res-1.2.0-beta02.txt",
+    "res-1.3.0-beta01.txt",
+    "res-current.txt",
+    "restricted_1.0.0.txt",
+    "restricted_1.1.0-beta01.txt",
+    "restricted_1.1.0-beta02.txt",
+    "restricted_1.1.0-rc01.txt",
+    "restricted_1.2.0-beta01.txt",
+    "restricted_1.2.0-beta02.txt",
+    "restricted_1.3.0-beta01.txt",
+    "restricted_current.txt"
+)
diff --git a/buildSrc/lint.xml b/buildSrc/lint.xml
index 62dda35..f766c40 100644
--- a/buildSrc/lint.xml
+++ b/buildSrc/lint.xml
@@ -40,4 +40,8 @@
     <issue id="WrongThread" severity="fatal" />
     <issue id="MissingTestSizeAnnotation" severity="fatal" />
     <issue id="IgnoreClassLevelDetector" severity="fatal" />
+    <!-- Disable all lint checks on transformed classes by default. -->
+    <issue id="all">
+        <ignore path="**/.transforms/**" />
+    </issue>
 </lint>
diff --git a/buildSrc/lint_samples.xml b/buildSrc/lint_samples.xml
index 8ec48c4..d22a4d4 100644
--- a/buildSrc/lint_samples.xml
+++ b/buildSrc/lint_samples.xml
@@ -30,6 +30,7 @@
     <!-- Re-enable sampled lint checks for all projects. -->
     <issue id="InvalidSamplesLocation" severity="fatal" />
     <issue id="MultipleSampledFunctions" severity="fatal" />
-    <issue id="UnresolvedSampleLink" severity="fatal" />
-    <issue id="ObsoleteSampledAnnotation" severity="fatal" />
+    <!-- Temporarily ignore checks that fail when using CI flag. -->
+    <issue id="UnresolvedSampleLink" severity="ignore" />
+    <issue id="ObsoleteSampledAnnotation" severity="ignore" />
 </lint>
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/VerifyVersionFilesTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/VerifyVersionFilesTask.kt
index 9db2e62..14eacb9 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/VerifyVersionFilesTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/VerifyVersionFilesTask.kt
@@ -40,9 +40,9 @@
     @TaskAction
     fun verifyVersionFilesPresent() {
         repositoryDirectory.walk().forEach { file ->
-            var expectedGroup = "androidx"
+            var expectedPrefix = "androidx"
             if (file.path.contains("/libyuv/"))
-                expectedGroup = "libyuv" // external library that we don't publish
+                expectedPrefix = "libyuv_libyuv" // external library that we don't publish
             if (file.extension == "aar") {
                 val inputStream = FileInputStream(file)
                 val aarFileInputStream = ZipInputStream(inputStream)
@@ -53,7 +53,7 @@
                         val classesJarInputStream = ZipInputStream(aarFileInputStream)
                         var jarEntry = classesJarInputStream.nextEntry
                         while (jarEntry != null) {
-                            if (jarEntry.name.startsWith("META-INF/$expectedGroup.") &&
+                            if (jarEntry.name.startsWith("META-INF/$expectedPrefix.") &&
                                 jarEntry.name.endsWith(".version")
                             ) {
                                 foundVersionFile = true
@@ -63,7 +63,7 @@
                         }
                         if (!foundVersionFile) {
                             throw Exception(
-                                "Missing classes.jar/META-INF/$expectedGroup.*version " +
+                                "Missing classes.jar/META-INF/$expectedPrefix.*version " +
                                 "file in ${file.absolutePath}"
                             )
                         }
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/checkapi/ApiLocation.kt b/buildSrc/private/src/main/kotlin/androidx/build/checkapi/ApiLocation.kt
index 9f10512..d9587ea 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/checkapi/ApiLocation.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/checkapi/ApiLocation.kt
@@ -84,8 +84,8 @@
             return fromBaseName(apiFileDir, CURRENT)
         }
 
-        fun isResourceApiFile(apiFile: File): Boolean {
-            return apiFile.name.startsWith(PREFIX_RESOURCE)
+        fun isResourceApiFilename(filename: String): Boolean {
+            return filename.startsWith(PREFIX_RESOURCE)
         }
 
         private fun fromBaseName(apiFileDir: File, baseName: String): ApiLocation {
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/checkapi/CheckApi.kt b/buildSrc/private/src/main/kotlin/androidx/build/checkapi/CheckApi.kt
index b08f626..9fec2fd 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/checkapi/CheckApi.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/checkapi/CheckApi.kt
@@ -17,11 +17,14 @@
 package androidx.build.checkapi
 
 import androidx.build.Version
-import androidx.build.checkapi.ApiLocation.Companion.isResourceApiFile
+import androidx.build.checkapi.ApiLocation.Companion.isResourceApiFilename
 import androidx.build.version
 import org.gradle.api.GradleException
 import org.gradle.api.Project
 import java.io.File
+import java.nio.file.Files
+import java.nio.file.Path
+import kotlin.io.path.name
 
 enum class ApiType {
     CLASSAPI,
@@ -88,28 +91,30 @@
  */
 fun getRequiredCompatibilityApiFileFromDir(
     apiDir: File,
-    version: Version,
+    apiVersion: Version,
     apiType: ApiType
 ): File? {
-    var lastFile: File? = null
-    var lastVersion: Version? = null
-    apiDir.listFiles()
-        ?.filter { file ->
-            (apiType == ApiType.RESOURCEAPI && isResourceApiFile(file)) ||
-                (apiType == ApiType.CLASSAPI && !isResourceApiFile(file))
-        }
-        ?.forEach { file ->
-            val parsed = Version.parseOrNull(file)
-            parsed?.let { otherVersion ->
-                if ((lastFile == null || lastVersion!! < otherVersion) &&
-                    (otherVersion < version) &&
-                    (otherVersion.isFinalApi()) &&
-                    (otherVersion.major == version.major)
-                ) {
-                    lastFile = file
-                    lastVersion = otherVersion
-                }
+    var highestPath: Path? = null
+    var highestVersion: Version? = null
+
+    // Find the path with highest version that is lower than the current API version.
+    Files.newDirectoryStream(apiDir.toPath()).forEach { path ->
+        val pathName = path.name
+        if ((apiType == ApiType.RESOURCEAPI && isResourceApiFilename(pathName)) ||
+            (apiType == ApiType.CLASSAPI && !isResourceApiFilename(pathName))
+        ) {
+            val pathVersion = Version.parseFilenameOrNull(pathName)
+            if (pathVersion != null &&
+                (highestVersion == null || pathVersion > highestVersion!!) &&
+                pathVersion < apiVersion &&
+                pathVersion.isFinalApi() &&
+                pathVersion.major == apiVersion.major
+            ) {
+                highestPath = path
+                highestVersion = pathVersion
             }
         }
-    return lastFile
+    }
+
+    return highestPath?.toFile()
 }
diff --git a/buildSrc/public/src/main/kotlin/androidx/build/Version.kt b/buildSrc/public/src/main/kotlin/androidx/build/Version.kt
index 33825d2..d385d9b 100644
--- a/buildSrc/public/src/main/kotlin/androidx/build/Version.kt
+++ b/buildSrc/public/src/main/kotlin/androidx/build/Version.kt
@@ -92,7 +92,14 @@
          */
         fun parseOrNull(file: File): Version? {
             if (!file.isFile) return null
-            val matcher = VERSION_FILE_REGEX.matcher(file.name)
+            return parseFilenameOrNull(file.name)
+        }
+
+        /**
+         * @return Version or null, if a name of the given file doesn't match
+         */
+        fun parseFilenameOrNull(filename: String): Version? {
+            val matcher = VERSION_FILE_REGEX.matcher(filename)
             return if (matcher.matches()) parseOrNull(matcher.group(2)) else null
         }
 
diff --git a/camera/camera-camera2-pipe-integration/lint-baseline.xml b/camera/camera-camera2-pipe-integration/lint-baseline.xml
index 76fc250..0b6b06f 100644
--- a/camera/camera-camera2-pipe-integration/lint-baseline.xml
+++ b/camera/camera-camera2-pipe-integration/lint-baseline.xml
@@ -2,6 +2,51 @@
 <issues format="6" by="lint 7.4.0-alpha08" type="baseline" client="gradle" dependencies="false" name="AGP (7.4.0-alpha08)" variant="all" version="7.4.0-alpha08">
 
     <issue
+        id="CameraXQuirksClassDetector"
+        message="CameraX quirks should include this template in the javadoc:&#xA;&#xA;* &lt;p>QuirkSummary&#xA;*     Bug Id:&#xA;*     Description:&#xA;*     Device(s):&#xA;&#xA;"
+        errorLine1="class AspectRatioLegacyApi21Quirk : Quirk {"
+        errorLine2="      ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/AspectRatioLegacyApi21Quirk.kt"/>
+    </issue>
+
+    <issue
+        id="CameraXQuirksClassDetector"
+        message="CameraX quirks should include this template in the javadoc:&#xA;&#xA;* &lt;p>QuirkSummary&#xA;*     Bug Id:&#xA;*     Description:&#xA;*     Device(s):&#xA;&#xA;"
+        errorLine1="class ExcludedSupportedSizesQuirk() : Quirk {"
+        errorLine2="      ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/ExcludedSupportedSizesQuirk.kt"/>
+    </issue>
+
+    <issue
+        id="CameraXQuirksClassDetector"
+        message="CameraX quirks should include this template in the javadoc:&#xA;&#xA;* &lt;p>QuirkSummary&#xA;*     Bug Id:&#xA;*     Description:&#xA;*     Device(s):&#xA;&#xA;"
+        errorLine1="class ExtraCroppingQuirk : Quirk {"
+        errorLine2="      ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/ExtraCroppingQuirk.kt"/>
+    </issue>
+
+    <issue
+        id="CameraXQuirksClassDetector"
+        message="CameraX quirks should include this template in the javadoc:&#xA;&#xA;* &lt;p>QuirkSummary&#xA;*     Bug Id:&#xA;*     Description:&#xA;*     Device(s):&#xA;&#xA;"
+        errorLine1="class ExtraSupportedSurfaceCombinationsQuirk : Quirk {"
+        errorLine2="      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/ExtraSupportedSurfaceCombinationsQuirk.kt"/>
+    </issue>
+
+    <issue
+        id="CameraXQuirksClassDetector"
+        message="CameraX quirks should include this template in the javadoc:&#xA;&#xA;* &lt;p>QuirkSummary&#xA;*     Bug Id:&#xA;*     Description:&#xA;*     Device(s):&#xA;&#xA;"
+        errorLine1="class Nexus4AndroidLTargetAspectRatioQuirk : Quirk {"
+        errorLine2="      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/Nexus4AndroidLTargetAspectRatioQuirk.kt"/>
+    </issue>
+
+    <issue
         id="SupportAnnotationUsage"
         message="Did you mean `@get:VisibleForTesting`? Without `get:` this annotates the constructor parameter itself instead of the associated getter."
         errorLine1="    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) internal val requestListener:"
diff --git a/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/integration/CameraControlAdapterDeviceTest.kt b/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/integration/CameraControlAdapterDeviceTest.kt
index 95d9e98..e05e88e 100644
--- a/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/integration/CameraControlAdapterDeviceTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/integration/CameraControlAdapterDeviceTest.kt
@@ -44,6 +44,7 @@
 import android.hardware.camera2.CaptureRequest.FLASH_MODE
 import android.hardware.camera2.CaptureRequest.FLASH_MODE_TORCH
 import android.hardware.camera2.CaptureRequest.SCALER_CROP_REGION
+import android.hardware.camera2.params.MeteringRectangle
 import android.os.Build
 import android.util.Size
 import androidx.camera.camera2.pipe.CameraGraph
@@ -299,20 +300,22 @@
             characteristics.getMaxRegionCount(CONTROL_MAX_REGIONS_AWB).coerceAtMost(1)
         waitForResult(captureCount = 60).verify(
             { requestMeta: RequestMetadata, _ ->
+                // some devices may have a 0 weight region added by default, so weightedRegionCount
+
                 val afRegionMatched = requestMeta.getOrDefault(
                     CONTROL_AF_REGIONS,
                     emptyArray()
-                ).size == expectedAfCount
+                ).weightedRegionCount == expectedAfCount
 
                 val aeRegionMatched = requestMeta.getOrDefault(
                     CONTROL_AE_REGIONS,
                     emptyArray()
-                ).size == expectedAeCount
+                ).weightedRegionCount == expectedAeCount
 
                 val awbRegionMatched = requestMeta.getOrDefault(
                     CONTROL_AWB_REGIONS,
                     emptyArray()
-                ).size == expectedAwbCount
+                ).weightedRegionCount == expectedAwbCount
 
                 afRegionMatched && aeRegionMatched && awbRegionMatched
             },
@@ -552,4 +555,16 @@
     private fun CameraCharacteristics.isAeModeSupported(
         aeMode: Int
     ) = (get(CONTROL_AE_AVAILABLE_MODES) ?: intArrayOf(-1)).contains(aeMode)
+
+    /**
+     * Returns the number of metering regions whose weight is greater than 0.
+     */
+    private val Array<MeteringRectangle>.weightedRegionCount: Int
+        get() {
+            var count = 0
+            forEach {
+                count += if (it.meteringWeight != 0) 1 else 0
+            }
+            return count
+        }
 }
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraStateAdapter.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraStateAdapter.kt
index ed435db..268c9a4 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraStateAdapter.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraStateAdapter.kt
@@ -56,7 +56,7 @@
         postCameraState(CameraInternal.State.CLOSED)
     }
 
-    public fun onGraphUpdated(cameraGraph: CameraGraph) = synchronized(lock) {
+    fun onGraphUpdated(cameraGraph: CameraGraph) = synchronized(lock) {
         Log.debug { "Camera graph updated from $currentGraph to $cameraGraph" }
         if (currentCameraInternalState != CameraInternal.State.CLOSED) {
             postCameraState(CameraInternal.State.CLOSING)
@@ -66,7 +66,7 @@
         currentCameraInternalState = CameraInternal.State.CLOSED
     }
 
-    public fun onGraphStateUpdated(cameraGraph: CameraGraph, graphState: GraphState) =
+    fun onGraphStateUpdated(cameraGraph: CameraGraph, graphState: GraphState) =
         synchronized(lock) {
             Log.debug { "$cameraGraph state updated to $graphState" }
             handleStateTransition(cameraGraph, graphState)
@@ -131,12 +131,17 @@
                             graphState.cameraError.toCameraStateError()
                         )
                     } else {
-                        // TODO(b/263201241): Add transition to PENDING_OPEN once we handle errors
-                        //  while a camera is already opened.
-                        CombinedCameraState(
-                            CameraInternal.State.CLOSING,
-                            graphState.cameraError.toCameraStateError()
-                        )
+                        if (isRecoverableError(graphState.cameraError)) {
+                            CombinedCameraState(
+                                CameraInternal.State.PENDING_OPEN,
+                                graphState.cameraError.toCameraStateError()
+                            )
+                        } else {
+                            CombinedCameraState(
+                                CameraInternal.State.CLOSING,
+                                graphState.cameraError.toCameraStateError()
+                            )
+                        }
                     }
 
                 GraphStateStopping -> CombinedCameraState(CameraInternal.State.CLOSING)
@@ -148,8 +153,19 @@
             when (graphState) {
                 GraphStateStopping -> CombinedCameraState(CameraInternal.State.CLOSING)
                 GraphStateStopped -> CombinedCameraState(CameraInternal.State.CLOSED)
-                // TODO(b/263201241): Transition to appropriate states once we handle errors while
-                //  a camera is already opened.
+                is GraphStateError ->
+                    if (isRecoverableError(graphState.cameraError)) {
+                        CombinedCameraState(
+                            CameraInternal.State.PENDING_OPEN,
+                            graphState.cameraError.toCameraStateError()
+                        )
+                    } else {
+                        CombinedCameraState(
+                            CameraInternal.State.CLOSED,
+                            graphState.cameraError.toCameraStateError()
+                        )
+                    }
+
                 else -> null
             }
 
@@ -157,10 +173,34 @@
             when (graphState) {
                 GraphStateStopped -> CombinedCameraState(CameraInternal.State.CLOSED)
                 GraphStateStarting -> CombinedCameraState(CameraInternal.State.OPENING)
+                is GraphStateError -> CombinedCameraState(
+                    CameraInternal.State.CLOSING,
+                    graphState.cameraError.toCameraStateError()
+                )
+
                 else -> null
             }
 
-        // TODO(b/263201241): Add PENDING_OPEN transitions once we have active recovery.
+        CameraInternal.State.PENDING_OPEN ->
+            when (graphState) {
+                GraphStateStarting -> CombinedCameraState(CameraInternal.State.OPENING)
+                GraphStateStarted -> CombinedCameraState(CameraInternal.State.OPEN)
+                is GraphStateError ->
+                    if (isRecoverableError(graphState.cameraError)) {
+                        CombinedCameraState(
+                            CameraInternal.State.PENDING_OPEN,
+                            graphState.cameraError.toCameraStateError()
+                        )
+                    } else {
+                        CombinedCameraState(
+                            CameraInternal.State.CLOSED,
+                            graphState.cameraError.toCameraStateError()
+                        )
+                    }
+
+                else -> null
+            }
+
         else ->
             null
     }
@@ -184,10 +224,14 @@
                         CameraState.ERROR_OTHER_RECOVERABLE_ERROR
 
                     CameraError.ERROR_ILLEGAL_ARGUMENT_EXCEPTION ->
-                        CameraState.ERROR_OTHER_RECOVERABLE_ERROR
+                        CameraState.ERROR_CAMERA_FATAL_ERROR
 
                     CameraError.ERROR_SECURITY_EXCEPTION ->
-                        CameraState.ERROR_OTHER_RECOVERABLE_ERROR
+                        CameraState.ERROR_CAMERA_FATAL_ERROR
+
+                    CameraError.ERROR_GRAPH_CONFIG -> CameraState.ERROR_STREAM_CONFIG
+                    CameraError.ERROR_DO_NOT_DISTURB_ENABLED ->
+                        CameraState.ERROR_DO_NOT_DISTURB_MODE_ENABLED
 
                     else -> throw IllegalArgumentException("Unexpected CameraError: $this")
                 }
@@ -203,6 +247,12 @@
             else -> throw IllegalArgumentException("Unexpected CameraInternal state: $this")
         }
 
+        internal fun isRecoverableError(cameraError: CameraError) =
+            cameraError == CameraError.ERROR_CAMERA_DISCONNECTED ||
+                cameraError == CameraError.ERROR_CAMERA_IN_USE ||
+                cameraError == CameraError.ERROR_CAMERA_LIMIT_EXCEEDED ||
+                cameraError == CameraError.ERROR_CAMERA_DEVICE
+
         internal fun MutableLiveData<CameraState>.setOrPostValue(cameraState: CameraState) {
             if (Looper.myLooper() == Looper.getMainLooper()) {
                 this.value = cameraState
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CameraStateAdapterTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CameraStateAdapterTest.kt
index 4f159bd..bc7dddf 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CameraStateAdapterTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CameraStateAdapterTest.kt
@@ -25,6 +25,9 @@
 import androidx.camera.camera2.pipe.GraphState.GraphStateStopping
 import androidx.camera.camera2.pipe.integration.testing.FakeCameraGraph
 import androidx.camera.core.CameraState
+import androidx.camera.core.CameraState.ERROR_CAMERA_DISABLED
+import androidx.camera.core.CameraState.ERROR_MAX_CAMERAS_IN_USE
+import androidx.camera.core.CameraState.ERROR_OTHER_RECOVERABLE_ERROR
 import androidx.camera.core.impl.CameraInternal
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
@@ -78,12 +81,16 @@
                 CameraInternal.State.OPENING,
                 GraphStateError(CameraError.ERROR_CAMERA_LIMIT_EXCEEDED, willAttemptRetry = true)
             )
-        // TODO(b/263201241): Add tests for PENDING_OPEN transitions.
-        val nextStateWhenGraphStateErrorWillNotRetry =
+        val nextStateWhenGraphStateErrorRecoverableWillNotRetry =
             cameraStateAdapter.calculateNextState(
                 CameraInternal.State.OPENING,
                 GraphStateError(CameraError.ERROR_CAMERA_LIMIT_EXCEEDED, willAttemptRetry = false)
             )
+        val nextStateWhenGraphStateErrorUnrecoverableWillNotRetry =
+            cameraStateAdapter.calculateNextState(
+                CameraInternal.State.OPENING,
+                GraphStateError(CameraError.ERROR_CAMERA_DISABLED, willAttemptRetry = false)
+            )
 
         assertThat(nextStateWhenGraphStateStarting).isEqualTo(null)
         assertThat(nextStateWhenGraphStateStarted!!.state).isEqualTo(CameraInternal.State.OPEN)
@@ -92,15 +99,12 @@
         assertThat(nextStateWhenGraphStateErrorWillRetry!!.state).isEqualTo(
             CameraInternal.State.OPENING
         )
-        assertThat(nextStateWhenGraphStateErrorWillRetry.error!!.code).isEqualTo(
-            CameraState.ERROR_MAX_CAMERAS_IN_USE
+        assertThat(nextStateWhenGraphStateErrorRecoverableWillNotRetry!!.state).isEqualTo(
+            CameraInternal.State.PENDING_OPEN
         )
-        assertThat(nextStateWhenGraphStateErrorWillNotRetry!!.state).isEqualTo(
+        assertThat(nextStateWhenGraphStateErrorUnrecoverableWillNotRetry!!.state).isEqualTo(
             CameraInternal.State.CLOSING
         )
-        assertThat(nextStateWhenGraphStateErrorWillNotRetry.error!!.code).isEqualTo(
-            CameraState.ERROR_MAX_CAMERAS_IN_USE
-        )
     }
 
     @Test
@@ -113,18 +117,27 @@
             cameraStateAdapter.calculateNextState(CameraInternal.State.OPEN, GraphStateStopping)
         val nextStateWhenGraphStateStopped =
             cameraStateAdapter.calculateNextState(CameraInternal.State.OPEN, GraphStateStopped)
-        // TODO(b/263201241): Add tests when we handle errors while camera is already opened.
-        val nextStateWhenGraphStateError =
+        val nextStateWhenGraphStateErrorRecoverable =
             cameraStateAdapter.calculateNextState(
                 CameraInternal.State.OPEN,
                 GraphStateError(CameraError.ERROR_CAMERA_LIMIT_EXCEEDED, true)
             )
+        val nextStateWhenGraphStateErrorUnrecoverable =
+            cameraStateAdapter.calculateNextState(
+                CameraInternal.State.OPEN,
+                GraphStateError(CameraError.ERROR_CAMERA_DISABLED, true)
+            )
 
         assertThat(nextStateWhenGraphStateStarting).isEqualTo(null)
         assertThat(nextStateWhenGraphStateStarted).isEqualTo(null)
         assertThat(nextStateWhenGraphStateStopping!!.state).isEqualTo(CameraInternal.State.CLOSING)
         assertThat(nextStateWhenGraphStateStopped!!.state).isEqualTo(CameraInternal.State.CLOSED)
-        assertThat(nextStateWhenGraphStateError).isEqualTo(null)
+        assertThat(nextStateWhenGraphStateErrorRecoverable!!.state).isEqualTo(
+            CameraInternal.State.PENDING_OPEN
+        )
+        assertThat(nextStateWhenGraphStateErrorUnrecoverable!!.state).isEqualTo(
+            CameraInternal.State.CLOSED
+        )
     }
 
     @Test
@@ -147,7 +160,8 @@
         assertThat(nextStateWhenGraphStateStarted).isEqualTo(null)
         assertThat(nextStateWhenGraphStateStopping).isEqualTo(null)
         assertThat(nextStateWhenGraphStateStopped!!.state).isEqualTo(CameraInternal.State.CLOSED)
-        assertThat(nextStateWhenGraphStateError).isEqualTo(null)
+        assertThat(nextStateWhenGraphStateError!!.state).isEqualTo(CameraInternal.State.CLOSING)
+        assertThat(nextStateWhenGraphStateError.error?.code).isEqualTo(ERROR_MAX_CAMERAS_IN_USE)
     }
 
     @Test
@@ -205,4 +219,115 @@
         cameraStateAdapter.onGraphStateUpdated(cameraGraph1, GraphStateStarting)
         assertThat(cameraStateAdapter.cameraState.value?.type).isEqualTo(CameraState.Type.OPEN)
     }
+
+    @Test
+    fun testStateTransitionsOnRecoverableErrorsWhenOpening() {
+        cameraStateAdapter.onGraphUpdated(cameraGraph1)
+        assertThat(cameraStateAdapter.cameraState.value?.type).isEqualTo(CameraState.Type.CLOSED)
+
+        cameraStateAdapter.onGraphStateUpdated(cameraGraph1, GraphStateStarting)
+        assertThat(cameraStateAdapter.cameraState.value?.type).isEqualTo(CameraState.Type.OPENING)
+
+        // We should transition to OPENING with an error code if we encounter errors during opening.
+        cameraStateAdapter.onGraphStateUpdated(
+            cameraGraph1,
+            GraphStateError(CameraError.ERROR_CAMERA_DISCONNECTED, willAttemptRetry = true)
+        )
+        val cameraStateWillRetry = cameraStateAdapter.cameraState.value!!
+        assertThat(cameraStateWillRetry.type).isEqualTo(CameraState.Type.OPENING)
+        assertThat(cameraStateWillRetry.error?.code).isEqualTo(ERROR_OTHER_RECOVERABLE_ERROR)
+
+        // Now assume we've exceeded retries and will no longer retry.
+        cameraStateAdapter.onGraphStateUpdated(
+            cameraGraph1,
+            GraphStateError(CameraError.ERROR_CAMERA_DISCONNECTED, willAttemptRetry = false)
+        )
+        val cameraStateNotRetry = cameraStateAdapter.cameraState.value!!
+        assertThat(cameraStateNotRetry.type).isEqualTo(CameraState.Type.PENDING_OPEN)
+        assertThat(cameraStateNotRetry.error?.code).isEqualTo(ERROR_OTHER_RECOVERABLE_ERROR)
+
+        // Now we make sure we transition to OPENING and OPEN when the camera does eventually open
+        // when it becomes available.
+        cameraStateAdapter.onGraphStateUpdated(cameraGraph1, GraphStateStarting)
+        assertThat(cameraStateAdapter.cameraState.value?.type).isEqualTo(CameraState.Type.OPENING)
+
+        cameraStateAdapter.onGraphStateUpdated(cameraGraph1, GraphStateStarted)
+        assertThat(cameraStateAdapter.cameraState.value?.type).isEqualTo(CameraState.Type.OPEN)
+    }
+
+    @Test
+    fun testStateTransitionsOnUnrecoverableErrorsWhenOpening() {
+        cameraStateAdapter.onGraphUpdated(cameraGraph1)
+        assertThat(cameraStateAdapter.cameraState.value?.type).isEqualTo(CameraState.Type.CLOSED)
+
+        cameraStateAdapter.onGraphStateUpdated(cameraGraph1, GraphStateStarting)
+        assertThat(cameraStateAdapter.cameraState.value?.type).isEqualTo(CameraState.Type.OPENING)
+
+        cameraStateAdapter.onGraphStateUpdated(
+            cameraGraph1,
+            GraphStateError(CameraError.ERROR_CAMERA_DISABLED, willAttemptRetry = false)
+        )
+        val cameraState = cameraStateAdapter.cameraState.value!!
+        assertThat(cameraState.type).isEqualTo(CameraState.Type.CLOSING)
+        assertThat(cameraState.error?.code).isEqualTo(ERROR_CAMERA_DISABLED)
+    }
+
+    @Test
+    fun testStateTransitionsOnRecoverableErrorsWhenOpen() {
+        cameraStateAdapter.onGraphUpdated(cameraGraph1)
+        assertThat(cameraStateAdapter.cameraState.value?.type).isEqualTo(CameraState.Type.CLOSED)
+
+        cameraStateAdapter.onGraphStateUpdated(cameraGraph1, GraphStateStarting)
+        cameraStateAdapter.onGraphStateUpdated(cameraGraph1, GraphStateStarted)
+        assertThat(cameraStateAdapter.cameraState.value?.type).isEqualTo(CameraState.Type.OPEN)
+
+        // We should transition to OPENING with an error code if we encounter errors during opening.
+        cameraStateAdapter.onGraphStateUpdated(
+            cameraGraph1,
+            GraphStateError(CameraError.ERROR_CAMERA_DISCONNECTED, willAttemptRetry = false)
+        )
+        val cameraState = cameraStateAdapter.cameraState.value!!
+        assertThat(cameraState.type).isEqualTo(CameraState.Type.PENDING_OPEN)
+        assertThat(cameraState.error?.code).isEqualTo(ERROR_OTHER_RECOVERABLE_ERROR)
+    }
+
+    @Test
+    fun testStateTransitionsOnUnrecoverableErrorsWhenOpen() {
+        cameraStateAdapter.onGraphUpdated(cameraGraph1)
+        assertThat(cameraStateAdapter.cameraState.value?.type).isEqualTo(CameraState.Type.CLOSED)
+
+        cameraStateAdapter.onGraphStateUpdated(cameraGraph1, GraphStateStarting)
+        cameraStateAdapter.onGraphStateUpdated(cameraGraph1, GraphStateStarted)
+        assertThat(cameraStateAdapter.cameraState.value?.type).isEqualTo(CameraState.Type.OPEN)
+
+        cameraStateAdapter.onGraphStateUpdated(
+            cameraGraph1,
+            GraphStateError(CameraError.ERROR_CAMERA_DISABLED, willAttemptRetry = false)
+        )
+        val cameraState = cameraStateAdapter.cameraState.value!!
+        assertThat(cameraState.type).isEqualTo(CameraState.Type.CLOSED)
+        assertThat(cameraState.error?.code).isEqualTo(ERROR_CAMERA_DISABLED)
+    }
+
+    @Test
+    fun testStateTransitionsOnErrorsWhenClosing() {
+        cameraStateAdapter.onGraphUpdated(cameraGraph1)
+        assertThat(cameraStateAdapter.cameraState.value?.type).isEqualTo(CameraState.Type.CLOSED)
+
+        cameraStateAdapter.onGraphStateUpdated(cameraGraph1, GraphStateStarting)
+        cameraStateAdapter.onGraphStateUpdated(cameraGraph1, GraphStateStarted)
+        assertThat(cameraStateAdapter.cameraState.value?.type).isEqualTo(CameraState.Type.OPEN)
+
+        cameraStateAdapter.onGraphStateUpdated(cameraGraph1, GraphStateStopping)
+        assertThat(cameraStateAdapter.cameraState.value?.type).isEqualTo(CameraState.Type.CLOSING)
+
+        // We should update the CLOSING state to include an error code.
+        cameraStateAdapter.onGraphStateUpdated(
+            cameraGraph1,
+            GraphStateError(CameraError.ERROR_CAMERA_DISCONNECTED, willAttemptRetry = false)
+        )
+        val cameraState = cameraStateAdapter.cameraState.value!!
+        assertThat(cameraState.type).isEqualTo(CameraState.Type.CLOSING)
+        assertThat(cameraState.error?.code).isEqualTo(ERROR_OTHER_RECOVERABLE_ERROR)
+    }
 }
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/CameraControllerSimulator.kt b/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/CameraControllerSimulator.kt
index 6f6f637..a8b6841 100644
--- a/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/CameraControllerSimulator.kt
+++ b/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/CameraControllerSimulator.kt
@@ -22,6 +22,7 @@
 import androidx.camera.camera2.pipe.CameraController
 import androidx.camera.camera2.pipe.CameraGraph
 import androidx.camera.camera2.pipe.CameraId
+import androidx.camera.camera2.pipe.CameraStatusMonitor
 import androidx.camera.camera2.pipe.GraphState.GraphStateError
 import androidx.camera.camera2.pipe.StreamGraph
 import androidx.camera.camera2.pipe.StreamId
@@ -163,7 +164,7 @@
         }
     }
 
-    override fun tryRestart() {
+    override fun tryRestart(cameraStatus: CameraStatusMonitor.CameraStatus) {
         synchronized(lock) {
             check(!closed) {
                 "Attempted to invoke restart after close."
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraController.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraController.kt
index 29dee61..2271494 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraController.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraController.kt
@@ -53,10 +53,10 @@
 
     /**
      * Restart the current session. This should basically perform stop() then start(). However, the
-     * implementation should handle its internal states correctly, and only restart when the
-     * conditions are appropriate.
+     * implementation should handle its internal states correctly, and only restart under the right
+     * [CameraStatusMonitor.CameraStatus] and [ControllerState].
      */
-    fun tryRestart()
+    fun tryRestart(cameraStatus: CameraStatusMonitor.CameraStatus)
 
     /**
      * Close this instance. [start] and [stop] should not be invoked, and any additional calls will
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 aac3027..b191c82 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
@@ -23,6 +23,7 @@
 import android.hardware.camera2.CameraAccessException.CAMERA_IN_USE
 import android.hardware.camera2.CameraAccessException.MAX_CAMERAS_IN_USE
 import android.hardware.camera2.CameraDevice.StateCallback
+import android.os.Build
 import androidx.annotation.RequiresApi
 
 @JvmInline
@@ -87,13 +88,30 @@
         /** This indicates that we received SecurityException while opening the camera. */
         val ERROR_SECURITY_EXCEPTION = CameraError(8)
 
+        /**
+         * This indicates we've encountered an error while configuring our camera graph, such as
+         * creating, finalizing capture sessions, and creating, submitting capture requests.
+         */
+        val ERROR_GRAPH_CONFIG = CameraError(9)
+
+        /**
+         * The camera cannot be opened because Do Not Disturb (DND) mode is on. This is actually
+         * a quirk for legacy devices on P, where we encounter RuntimeExceptions while opening the
+         * camera when it tries to enable shutter sound.
+         */
+        val ERROR_DO_NOT_DISTURB_ENABLED = CameraError(10)
+
         internal fun from(throwable: Throwable) =
             when (throwable) {
                 is CameraAccessException -> from(throwable)
                 is IllegalArgumentException -> ERROR_ILLEGAL_ARGUMENT_EXCEPTION
                 is SecurityException -> ERROR_SECURITY_EXCEPTION
                 else -> {
-                    throw IllegalArgumentException("Unexpected throwable: $throwable")
+                    if (Build.VERSION.SDK_INT == 28 && isDoNotDisturbException(throwable)) {
+                        ERROR_DO_NOT_DISTURB_ENABLED
+                    } else {
+                        throw IllegalArgumentException("Unexpected throwable: $throwable")
+                    }
                 }
             }
 
@@ -124,5 +142,28 @@
                     )
                 }
             }
+
+        /**
+         * The full stack trace of the Do Not Disturb exception on API level 28 is as follows:
+         *
+         * java.lang.RuntimeException: Camera is being used after Camera.release() was called
+         *  at android.hardware.Camera._enableShutterSound(Native Method)
+         *  at android.hardware.Camera.updateAppOpsPlayAudio(Camera.java:1770)
+         *  at android.hardware.Camera.initAppOps(Camera.java:582)
+         *  at android.hardware.Camera.<init>(Camera.java:575)
+         *  at android.hardware.Camera.getEmptyParameters(Camera.java:2130)
+         *  at android.hardware.camera2.legacy.LegacyMetadataMapper.createCharacteristics
+         *  (LegacyMetadataMapper.java:151)
+         *  at android.hardware.camera2.CameraManager.getCameraCharacteristics
+         *  (CameraManager.java:274)
+         *
+         * This function checks whether the method name of the top element is "_enableShutterSound".
+         */
+        private fun isDoNotDisturbException(throwable: Throwable): Boolean {
+            if (throwable !is RuntimeException) return false
+            val topMethodName =
+                throwable.stackTrace.let { if (it.isNotEmpty()) it[0].methodName else null }
+            return topMethodName == "_enableShutterSound"
+        }
     }
 }
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 53ab8b0..37d48e4e 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
@@ -380,5 +380,8 @@
      * will retry opening the camera (and creating a capture session).
      */
     class GraphStateError(val cameraError: CameraError, val willAttemptRetry: Boolean) :
-        GraphState()
-}
+        GraphState() {
+        override fun toString(): String =
+            super.toString() + "(cameraError = $cameraError, willAttemptRetry = $willAttemptRetry)"
+    }
+}
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CaptureSequenceProcessor.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CaptureSequenceProcessor.kt
index 9c6cc07..facca9b 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CaptureSequenceProcessor.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CaptureSequenceProcessor.kt
@@ -51,7 +51,7 @@
     ): TCaptureSequence?
 
     /** Issue a previously created [CaptureSequence] to the active camera instance. */
-    fun submit(captureSequence: TCaptureSequence): Int
+    fun submit(captureSequence: TCaptureSequence): Int?
 
     /**
      * Opportunistically abort any ongoing captures by the camera. This may or may not complete
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 5ddaf29..0a4c5a5 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
@@ -24,6 +24,7 @@
 import androidx.camera.camera2.pipe.CameraError
 import androidx.camera.camera2.pipe.CameraGraph
 import androidx.camera.camera2.pipe.CameraId
+import androidx.camera.camera2.pipe.CameraStatusMonitor.CameraStatus
 import androidx.camera.camera2.pipe.CameraSurfaceManager
 import androidx.camera.camera2.pipe.StreamId
 import androidx.camera.camera2.pipe.config.Camera2ControllerScope
@@ -66,6 +67,9 @@
     @GuardedBy("lock")
     private var controllerState: ControllerState = ControllerState.STOPPED
 
+    @GuardedBy("lock")
+    private var lastCameraError: CameraError? = null
+
     private var currentCamera: VirtualCamera? = null
     private var currentSession: CaptureSessionState? = null
     private var currentSurfaceMap: Map<StreamId, Surface>? = null
@@ -80,6 +84,7 @@
             Log.warn { "Ignoring start(): Camera2CameraController is already started" }
             return
         }
+        lastCameraError = null
         val camera = virtualCameraManager.open(
             config.camera,
             config.flags.allowMultipleActiveCameras,
@@ -135,11 +140,30 @@
         }
     }
 
-    override fun tryRestart(): Unit = synchronized(lock) {
-        if (controllerState != ControllerState.DISCONNECTED) {
-            Log.debug { "Ignoring restart(): CameraController is $controllerState" }
+    override fun tryRestart(cameraStatus: CameraStatus): Unit = synchronized(lock) {
+        var shouldRestart = false
+        when (controllerState) {
+            ControllerState.DISCONNECTED ->
+                if (cameraStatus is CameraStatus.CameraAvailable ||
+                    cameraStatus is CameraStatus.CameraPrioritiesChanged
+                ) {
+                    shouldRestart = true
+                }
+
+            ControllerState.ERROR ->
+                if (cameraStatus is CameraStatus.CameraAvailable &&
+                    lastCameraError == CameraError.ERROR_CAMERA_DEVICE
+                ) {
+                    shouldRestart = true
+                }
+        }
+        if (!shouldRestart) {
+            Log.debug {
+                "Ignoring tryRestart(): state = $controllerState, cameraStatus = $cameraStatus"
+            }
             return
         }
+        Log.debug { "Restarting Camera2CameraController" }
         stop()
         start()
     }
@@ -222,6 +246,7 @@
                         "unrecoverable error: ${cameraState.cameraErrorCode}"
                 }
             }
+            lastCameraError = cameraState.cameraErrorCode
         } else {
             controllerState = ControllerState.STOPPED
         }
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessor.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessor.kt
index b6be643..73418c4 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessor.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessor.kt
@@ -124,10 +124,8 @@
             // null
             // if the CameraDevice has been closed or disconnected. If this fails, indicate that the
             // request was not submitted.
-            val requestBuilder: CaptureRequest.Builder
-            try {
-                requestBuilder = session.device.createCaptureRequest(requestTemplate)
-            } catch (exception: ObjectUnavailableException) {
+            val requestBuilder = session.device.createCaptureRequest(requestTemplate)
+            if (requestBuilder == null) {
                 Log.info { "  Failed to create a CaptureRequest.Builder from $requestTemplate!" }
                 return null
             }
@@ -247,7 +245,7 @@
         )
     }
 
-    override fun submit(captureSequence: Camera2CaptureSequence): Int {
+    override fun submit(captureSequence: Camera2CaptureSequence): Int? {
         val captureCallback = captureSequence as CameraCaptureSession.CaptureCallback
         // TODO: Update these calls to use executors on newer versions of the OS
         return if (captureSequence.captureRequestList.size == 1 &&
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2ErrorProcessor.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2ErrorProcessor.kt
new file mode 100644
index 0000000..bfae20a
--- /dev/null
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2ErrorProcessor.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.camera2.pipe.compat
+
+import androidx.annotation.GuardedBy
+import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.CameraError
+import androidx.camera.camera2.pipe.CameraId
+import androidx.camera.camera2.pipe.GraphState
+import androidx.camera.camera2.pipe.internal.CameraErrorListener
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * A class responsible for reporting camera errors with a particular [CameraId]. When
+ * [androidx.camera.camera2.pipe.compat.VirtualCameraManager] processes a camera open request, it
+ * should update CameraErrorProcessor with the [VirtualCameraState] that came with the open request.
+ */
+@Singleton
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+class Camera2ErrorProcessor @Inject constructor() : CameraErrorListener {
+    private val lock = Any()
+
+    @GuardedBy("lock")
+    private val virtualCameraStateMap = mutableMapOf<CameraId, VirtualCameraState>()
+
+    override fun onCameraError(
+        cameraId: CameraId,
+        cameraError: CameraError,
+        willAttemptRetry: Boolean
+    ) {
+        val virtualCameraState = synchronized(lock) {
+            virtualCameraStateMap[cameraId]
+        } ?: return
+        virtualCameraState.graphListener.onGraphError(
+            GraphState.GraphStateError(
+                cameraError,
+                willAttemptRetry
+            )
+        )
+    }
+
+    /**
+     * Sets the current active [VirtualCameraState] to report the camera error to. Any attempt to
+     * acquire an open camera creates a [VirtualCameraState], and it's important to keep
+     * Camera2ErrorProcessor updated with the latest [VirtualCameraState].
+     */
+    internal fun setActiveVirtualCamera(
+        cameraId: CameraId,
+        virtualCameraState: VirtualCameraState
+    ) = synchronized(lock) {
+        virtualCameraStateMap[cameraId] = virtualCameraState
+    }
+}
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CameraDeviceWrapper.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CameraDeviceWrapper.kt
index a4461dd..27722eb 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CameraDeviceWrapper.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CameraDeviceWrapper.kt
@@ -37,6 +37,7 @@
 import androidx.camera.camera2.pipe.core.SystemTimeSource
 import androidx.camera.camera2.pipe.core.Timestamps
 import androidx.camera.camera2.pipe.core.Timestamps.formatMs
+import androidx.camera.camera2.pipe.internal.CameraErrorListener
 import androidx.camera.camera2.pipe.writeParameter
 import kotlin.reflect.KClass
 import kotlinx.atomicfu.atomic
@@ -52,64 +53,56 @@
     val cameraId: CameraId
 
     /** @see CameraDevice.createCaptureRequest */
-    @Throws(ObjectUnavailableException::class)
-    fun createCaptureRequest(template: RequestTemplate): CaptureRequest.Builder
+    fun createCaptureRequest(template: RequestTemplate): CaptureRequest.Builder?
 
     /** @see CameraDevice.createReprocessCaptureRequest */
     @RequiresApi(Build.VERSION_CODES.M)
-    @Throws(ObjectUnavailableException::class)
-    fun createReprocessCaptureRequest(inputResult: TotalCaptureResult): CaptureRequest.Builder
+    fun createReprocessCaptureRequest(inputResult: TotalCaptureResult): CaptureRequest.Builder?
 
     /** @see CameraDevice.createCaptureSession */
-    @Throws(ObjectUnavailableException::class)
     fun createCaptureSession(
         outputs: List<Surface>,
         stateCallback: CameraCaptureSessionWrapper.StateCallback,
         handler: Handler?
-    )
+    ): Boolean
 
     /** @see CameraDevice.createReprocessableCaptureSession */
     @RequiresApi(Build.VERSION_CODES.M)
-    @Throws(ObjectUnavailableException::class)
     fun createReprocessableCaptureSession(
         input: InputConfiguration,
         outputs: List<Surface>,
         stateCallback: CameraCaptureSessionWrapper.StateCallback,
         handler: Handler?
-    )
+    ): Boolean
 
     /** @see CameraDevice.createConstrainedHighSpeedCaptureSession */
     @RequiresApi(Build.VERSION_CODES.M)
-    @Throws(ObjectUnavailableException::class)
     fun createConstrainedHighSpeedCaptureSession(
         outputs: List<Surface>,
         stateCallback: CameraCaptureSessionWrapper.StateCallback,
         handler: Handler?
-    )
+    ): Boolean
 
     /** @see CameraDevice.createCaptureSessionByOutputConfigurations */
     @RequiresApi(Build.VERSION_CODES.N)
-    @Throws(ObjectUnavailableException::class)
     fun createCaptureSessionByOutputConfigurations(
         outputConfigurations: List<OutputConfigurationWrapper>,
         stateCallback: CameraCaptureSessionWrapper.StateCallback,
         handler: Handler?
-    )
+    ): Boolean
 
     /** @see CameraDevice.createReprocessableCaptureSessionByConfigurations */
     @RequiresApi(Build.VERSION_CODES.N)
-    @Throws(ObjectUnavailableException::class)
     fun createReprocessableCaptureSessionByConfigurations(
         inputConfig: InputConfigData,
         outputs: List<OutputConfigurationWrapper>,
         stateCallback: CameraCaptureSessionWrapper.StateCallback,
         handler: Handler?
-    )
+    ): Boolean
 
     /** @see CameraDevice.createCaptureSession */
     @RequiresApi(Build.VERSION_CODES.P)
-    @Throws(ObjectUnavailableException::class)
-    fun createCaptureSession(config: SessionConfigData)
+    fun createCaptureSession(config: SessionConfigData): Boolean
 
     /** Invoked when the [CameraDevice] has been closed */
     fun onDeviceClosed()
@@ -138,6 +131,7 @@
     private val cameraMetadata: CameraMetadata,
     private val cameraDevice: CameraDevice,
     override val cameraId: CameraId,
+    private val cameraErrorListener: CameraErrorListener,
     private val interopSessionStateCallback: CameraCaptureSession.StateCallback? = null
 ) : CameraDeviceWrapper {
     private val _lastStateCallback = atomic<CameraCaptureSessionWrapper.StateCallback?>(null)
@@ -146,7 +140,7 @@
         outputs: List<Surface>,
         stateCallback: CameraCaptureSessionWrapper.StateCallback,
         handler: Handler?
-    ) = rethrowCamera2Exceptions {
+    ): Boolean = catchAndReportCameraExceptions(cameraId, cameraErrorListener) {
         val previousStateCallback = _lastStateCallback.value
         check(_lastStateCallback.compareAndSet(previousStateCallback, stateCallback))
 
@@ -156,11 +150,15 @@
         cameraDevice.createCaptureSession(
             outputs,
             AndroidCaptureSessionStateCallback(
-                this, stateCallback, previousStateCallback, interopSessionStateCallback
+                this,
+                stateCallback,
+                previousStateCallback,
+                cameraErrorListener,
+                interopSessionStateCallback
             ),
             handler
         )
-    }
+    } != null
 
     @RequiresApi(23)
     override fun createReprocessableCaptureSession(
@@ -168,7 +166,7 @@
         outputs: List<Surface>,
         stateCallback: CameraCaptureSessionWrapper.StateCallback,
         handler: Handler?
-    ) = rethrowCamera2Exceptions {
+    ): Boolean = catchAndReportCameraExceptions(cameraId, cameraErrorListener) {
         val previousStateCallback = _lastStateCallback.value
         check(_lastStateCallback.compareAndSet(previousStateCallback, stateCallback))
 
@@ -179,18 +177,22 @@
             input,
             outputs,
             AndroidCaptureSessionStateCallback(
-                this, stateCallback, previousStateCallback, interopSessionStateCallback
+                this,
+                stateCallback,
+                previousStateCallback,
+                cameraErrorListener,
+                interopSessionStateCallback
             ),
             handler
         )
-    }
+    } != null
 
     @RequiresApi(23)
     override fun createConstrainedHighSpeedCaptureSession(
         outputs: List<Surface>,
         stateCallback: CameraCaptureSessionWrapper.StateCallback,
         handler: Handler?
-    ) = rethrowCamera2Exceptions {
+    ): Boolean = catchAndReportCameraExceptions(cameraId, cameraErrorListener) {
         val previousStateCallback = _lastStateCallback.value
         check(_lastStateCallback.compareAndSet(previousStateCallback, stateCallback))
 
@@ -200,18 +202,22 @@
             cameraDevice,
             outputs,
             AndroidCaptureSessionStateCallback(
-                this, stateCallback, previousStateCallback, interopSessionStateCallback
+                this,
+                stateCallback,
+                previousStateCallback,
+                cameraErrorListener,
+                interopSessionStateCallback
             ),
             handler
         )
-    }
+    } != null
 
     @RequiresApi(24)
     override fun createCaptureSessionByOutputConfigurations(
         outputConfigurations: List<OutputConfigurationWrapper>,
         stateCallback: CameraCaptureSessionWrapper.StateCallback,
         handler: Handler?
-    ) = rethrowCamera2Exceptions {
+    ): Boolean = catchAndReportCameraExceptions(cameraId, cameraErrorListener) {
         val previousStateCallback = _lastStateCallback.value
         check(_lastStateCallback.compareAndSet(previousStateCallback, stateCallback))
 
@@ -221,11 +227,15 @@
             cameraDevice,
             outputConfigurations.map { it.unwrapAs(OutputConfiguration::class) },
             AndroidCaptureSessionStateCallback(
-                this, stateCallback, previousStateCallback, interopSessionStateCallback
+                this,
+                stateCallback,
+                previousStateCallback,
+                cameraErrorListener,
+                interopSessionStateCallback
             ),
             handler
         )
-    }
+    } != null
 
     @RequiresApi(24)
     override fun createReprocessableCaptureSessionByConfigurations(
@@ -233,7 +243,7 @@
         outputs: List<OutputConfigurationWrapper>,
         stateCallback: CameraCaptureSessionWrapper.StateCallback,
         handler: Handler?
-    ) = rethrowCamera2Exceptions {
+    ): Boolean = catchAndReportCameraExceptions(cameraId, cameraErrorListener) {
         val previousStateCallback = _lastStateCallback.value
         check(_lastStateCallback.compareAndSet(previousStateCallback, stateCallback))
 
@@ -246,66 +256,75 @@
             ),
             outputs.map { it.unwrapAs(OutputConfiguration::class) },
             AndroidCaptureSessionStateCallback(
-                this, stateCallback, previousStateCallback, interopSessionStateCallback
+                this,
+                stateCallback,
+                previousStateCallback,
+                cameraErrorListener,
+                interopSessionStateCallback
             ),
             handler
         )
-    }
+    } != null
 
     @RequiresApi(28)
-    override fun createCaptureSession(config: SessionConfigData) = rethrowCamera2Exceptions {
-        val stateCallback = config.stateCallback
-        val previousStateCallback = _lastStateCallback.value
-        check(_lastStateCallback.compareAndSet(previousStateCallback, stateCallback))
+    override fun createCaptureSession(config: SessionConfigData): Boolean =
+        catchAndReportCameraExceptions(cameraId, cameraErrorListener) {
+            val stateCallback = config.stateCallback
+            val previousStateCallback = _lastStateCallback.value
+            check(_lastStateCallback.compareAndSet(previousStateCallback, stateCallback))
 
-        val sessionConfig =
-            Api28Compat.newSessionConfiguration(
-                config.sessionType,
-                config.outputConfigurations.map { it.unwrapAs(OutputConfiguration::class) },
-                config.executor,
-                AndroidCaptureSessionStateCallback(
-                    this, stateCallback, previousStateCallback, interopSessionStateCallback
+            val sessionConfig =
+                Api28Compat.newSessionConfiguration(
+                    config.sessionType,
+                    config.outputConfigurations.map { it.unwrapAs(OutputConfiguration::class) },
+                    config.executor,
+                    AndroidCaptureSessionStateCallback(
+                        this,
+                        stateCallback,
+                        previousStateCallback,
+                        cameraErrorListener,
+                        interopSessionStateCallback
+                    )
                 )
-            )
 
-        if (config.inputConfiguration != null) {
-            Api28Compat.setInputConfiguration(
-                sessionConfig,
-                Api23Compat.newInputConfiguration(
-                    config.inputConfiguration.width,
-                    config.inputConfiguration.height,
-                    config.inputConfiguration.format
+            if (config.inputConfiguration != null) {
+                Api28Compat.setInputConfiguration(
+                    sessionConfig,
+                    Api23Compat.newInputConfiguration(
+                        config.inputConfiguration.width,
+                        config.inputConfiguration.height,
+                        config.inputConfiguration.format
+                    )
                 )
-            )
-        }
-
-        val requestBuilder = cameraDevice.createCaptureRequest(config.sessionTemplateId)
-
-        // This compares and sets ONLY the session keys for this camera. Setting parameters that are
-        // not listed in availableSessionKeys can cause an unusual amount of extra latency.
-        val sessionKeyNames = cameraMetadata.sessionKeys.map { it.name }
-
-        // Iterate template parameters and CHECK BY NAME, as there have been cases where equality
-        // checks did not pass.
-        for ((key, value) in config.sessionParameters) {
-            if (key !is CaptureRequest.Key<*>) continue
-            if (sessionKeyNames.contains(key.name)) {
-                requestBuilder.writeParameter(key, value)
             }
-        }
-        Api28Compat.setSessionParameters(sessionConfig, requestBuilder.build())
-        Api28Compat.createCaptureSession(cameraDevice, sessionConfig)
-    }
 
-    override fun createCaptureRequest(template: RequestTemplate): CaptureRequest.Builder =
-        rethrowCamera2Exceptions {
+            val requestBuilder = cameraDevice.createCaptureRequest(config.sessionTemplateId)
+
+            // This compares and sets ONLY the session keys for this camera. Setting parameters that are
+            // not listed in availableSessionKeys can cause an unusual amount of extra latency.
+            val sessionKeyNames = cameraMetadata.sessionKeys.map { it.name }
+
+            // Iterate template parameters and CHECK BY NAME, as there have been cases where equality
+            // checks did not pass.
+            for ((key, value) in config.sessionParameters) {
+                if (key !is CaptureRequest.Key<*>) continue
+                if (sessionKeyNames.contains(key.name)) {
+                    requestBuilder.writeParameter(key, value)
+                }
+            }
+            Api28Compat.setSessionParameters(sessionConfig, requestBuilder.build())
+            Api28Compat.createCaptureSession(cameraDevice, sessionConfig)
+        } != null
+
+    override fun createCaptureRequest(template: RequestTemplate): CaptureRequest.Builder? =
+        catchAndReportCameraExceptions(cameraId, cameraErrorListener) {
             cameraDevice.createCaptureRequest(template.value)
         }
 
     @RequiresApi(23)
     override fun createReprocessCaptureRequest(
         inputResult: TotalCaptureResult
-    ): CaptureRequest.Builder = rethrowCamera2Exceptions {
+    ): CaptureRequest.Builder? = catchAndReportCameraExceptions(cameraId, cameraErrorListener) {
         Api23Compat.createReprocessCaptureRequest(cameraDevice, inputResult)
     }
 
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionFactory.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionFactory.kt
index 23fbb4a..254be23 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionFactory.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionFactory.kt
@@ -97,11 +97,10 @@
         surfaces: Map<StreamId, Surface>,
         captureSessionState: CaptureSessionState
     ): Map<StreamId, OutputConfigurationWrapper> {
-        try {
-            cameraDevice.createCaptureSession(
+        if (!cameraDevice.createCaptureSession(
                 surfaces.map { it.value }, captureSessionState, threads.camera2Handler
             )
-        } catch (e: Throwable) {
+        ) {
             Log.warn {
                 "Failed to create capture session from $cameraDevice for $captureSessionState!"
             }
@@ -122,9 +121,8 @@
         captureSessionState: CaptureSessionState
     ): Map<StreamId, OutputConfigurationWrapper> {
         if (graphConfig.input != null) {
-            try {
-                val outputConfig = graphConfig.input.stream.outputs.single()
-                cameraDevice.createReprocessableCaptureSession(
+            val outputConfig = graphConfig.input.stream.outputs.single()
+            if (!cameraDevice.createReprocessableCaptureSession(
                     InputConfiguration(
                         outputConfig.size.width,
                         outputConfig.size.height,
@@ -134,7 +132,7 @@
                     captureSessionState,
                     threads.camera2Handler
                 )
-            } catch (e: Throwable) {
+            ) {
                 Log.warn {
                     "Failed to create reprocessable captures session from $cameraDevice for" +
                         " $captureSessionState!"
@@ -142,11 +140,10 @@
                 captureSessionState.disconnect()
             }
         } else {
-            try {
-                cameraDevice.createCaptureSession(
+            if (!cameraDevice.createCaptureSession(
                     surfaces.map { it.value }, captureSessionState, threads.camera2Handler
                 )
-            } catch (e: Throwable) {
+            ) {
                 Log.warn {
                     "Failed to create captures session from $cameraDevice for $captureSessionState!"
                 }
@@ -165,11 +162,10 @@
         surfaces: Map<StreamId, Surface>,
         captureSessionState: CaptureSessionState
     ): Map<StreamId, OutputConfigurationWrapper> {
-        try {
-            cameraDevice.createConstrainedHighSpeedCaptureSession(
+        if (!cameraDevice.createConstrainedHighSpeedCaptureSession(
                 surfaces.map { it.value }, captureSessionState, threads.camera2Handler
             )
-        } catch (e: Throwable) {
+        ) {
             Log.warn {
                 "Failed to create ConstrainedHighSpeedCaptureSession " +
                     "from $cameraDevice for $captureSessionState!"
@@ -206,25 +202,24 @@
             return emptyMap()
         }
 
-        try {
-            if (graphConfig.input == null) {
-                cameraDevice.createCaptureSessionByOutputConfigurations(
-                    outputs.all, captureSessionState, threads.camera2Handler
-                )
-            } else {
-                val outputConfig = graphConfig.input.stream.outputs.single()
-                cameraDevice.createReprocessableCaptureSessionByConfigurations(
-                    InputConfigData(
-                        outputConfig.size.width,
-                        outputConfig.size.height,
-                        outputConfig.format.value
-                    ),
-                    outputs.all,
-                    captureSessionState,
-                    threads.camera2Handler
-                )
-            }
-        } catch (e: Throwable) {
+        val result = if (graphConfig.input == null) {
+            cameraDevice.createCaptureSessionByOutputConfigurations(
+                outputs.all, captureSessionState, threads.camera2Handler
+            )
+        } else {
+            val outputConfig = graphConfig.input.stream.outputs.single()
+            cameraDevice.createReprocessableCaptureSessionByConfigurations(
+                InputConfigData(
+                    outputConfig.size.width,
+                    outputConfig.size.height,
+                    outputConfig.format.value
+                ),
+                outputs.all,
+                captureSessionState,
+                threads.camera2Handler
+            )
+        }
+        if (!result) {
             Log.warn {
                 "Failed to create capture session from $cameraDevice for $captureSessionState!"
             }
@@ -286,9 +281,7 @@
                 graphConfig.sessionParameters
             )
 
-        try {
-            cameraDevice.createCaptureSession(sessionConfig)
-        } catch (e: Throwable) {
+        if (!cameraDevice.createCaptureSession(sessionConfig)) {
             Log.warn {
                 "Failed to create capture session from $cameraDevice for $captureSessionState!"
             }
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionWrapper.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionWrapper.kt
index 2698852..1b2637b 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionWrapper.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionWrapper.kt
@@ -18,8 +18,6 @@
 
 package androidx.camera.camera2.pipe.compat
 
-import android.hardware.camera2.CameraAccessException
-import android.hardware.camera2.CameraAccessException.CAMERA_ERROR
 import android.hardware.camera2.CameraCaptureSession
 import android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession
 import android.hardware.camera2.CaptureRequest
@@ -31,6 +29,7 @@
 import androidx.annotation.RequiresApi
 import androidx.camera.camera2.pipe.UnsafeWrapper
 import androidx.camera.camera2.pipe.core.Log
+import androidx.camera.camera2.pipe.internal.CameraErrorListener
 import kotlin.reflect.KClass
 import kotlinx.atomicfu.atomic
 
@@ -62,8 +61,7 @@
     val inputSurface: Surface?
 
     /** @see [CameraCaptureSession.abortCaptures]. */
-    @Throws(ObjectUnavailableException::class)
-    fun abortCaptures()
+    fun abortCaptures(): Boolean
 
     /**
      * @param request The settings for this exposure
@@ -73,12 +71,11 @@
      * @return An unique capture sequence id.
      * @see [CameraCaptureSession.capture].
      */
-    @Throws(ObjectUnavailableException::class)
     fun capture(
         request: CaptureRequest,
         listener: CameraCaptureSession.CaptureCallback,
         handler: Handler?
-    ): Int
+    ): Int?
 
     /**
      * @param requests A list of CaptureRequest(s) for this sequence of exposures
@@ -89,12 +86,11 @@
      * @return An unique capture sequence id.
      * @see [CameraCaptureSession.captureBurst].
      */
-    @Throws(ObjectUnavailableException::class)
     fun captureBurst(
         requests: List<CaptureRequest>,
         listener: CameraCaptureSession.CaptureCallback,
         handler: Handler?
-    ): Int
+    ): Int?
 
     /**
      * @param requests A list of settings to cycle through indefinitely.
@@ -105,12 +101,11 @@
      * @return An unique capture sequence ID.
      * @see [CameraCaptureSession.setRepeatingBurst]
      */
-    @Throws(ObjectUnavailableException::class)
     fun setRepeatingBurst(
         requests: List<CaptureRequest>,
         listener: CameraCaptureSession.CaptureCallback,
         handler: Handler?
-    ): Int
+    ): Int?
 
     /**
      * @param request The request to repeat indefinitely.
@@ -120,20 +115,17 @@
      * @return An unique capture sequence ID.
      * @see [CameraCaptureSession.setRepeatingRequest].
      */
-    @Throws(ObjectUnavailableException::class)
     fun setRepeatingRequest(
         request: CaptureRequest,
         listener: CameraCaptureSession.CaptureCallback,
         handler: Handler?
-    ): Int
+    ): Int?
 
     /** @see [CameraCaptureSession.stopRepeating]. */
-    @Throws(ObjectUnavailableException::class)
-    fun stopRepeating()
+    fun stopRepeating(): Boolean
 
     /** Forwards to CameraCaptureSession#finalizeOutputConfigurations */
-    @Throws(ObjectUnavailableException::class)
-    fun finalizeOutputConfigurations(outputConfigs: List<OutputConfigurationWrapper>)
+    fun finalizeOutputConfigurations(outputConfigs: List<OutputConfigurationWrapper>): Boolean
 
     /** @see CameraCaptureSession.StateCallback */
     interface StateCallback {
@@ -183,13 +175,14 @@
     private val device: CameraDeviceWrapper,
     private val stateCallback: CameraCaptureSessionWrapper.StateCallback,
     lastStateCallback: CameraCaptureSessionWrapper.StateCallback?,
+    private val cameraErrorListener: CameraErrorListener,
     private val interopSessionStateCallback: CameraCaptureSession.StateCallback? = null
 ) : CameraCaptureSession.StateCallback() {
     private val _lastStateCallback = atomic(lastStateCallback)
     private val captureSession = atomic<CameraCaptureSessionWrapper?>(null)
 
     override fun onConfigured(session: CameraCaptureSession) {
-        stateCallback.onConfigured(getWrapped(session))
+        stateCallback.onConfigured(getWrapped(session, cameraErrorListener))
 
         // b/249258992 - This is a workaround to ensure previous CameraCaptureSession.StateCallback
         //   instances receive some kind of "finalization" signal if onClosed is not fired by the
@@ -199,48 +192,54 @@
     }
 
     override fun onConfigureFailed(session: CameraCaptureSession) {
-        stateCallback.onConfigureFailed(getWrapped(session))
+        stateCallback.onConfigureFailed(getWrapped(session, cameraErrorListener))
         finalizeSession()
         interopSessionStateCallback?.onConfigureFailed(session)
     }
 
     override fun onReady(session: CameraCaptureSession) {
-        stateCallback.onReady(getWrapped(session))
+        stateCallback.onReady(getWrapped(session, cameraErrorListener))
         interopSessionStateCallback?.onReady(session)
     }
 
     override fun onActive(session: CameraCaptureSession) {
-        stateCallback.onActive(getWrapped(session))
+        stateCallback.onActive(getWrapped(session, cameraErrorListener))
         interopSessionStateCallback?.onActive(session)
     }
 
     override fun onClosed(session: CameraCaptureSession) {
-        stateCallback.onClosed(getWrapped(session))
+        stateCallback.onClosed(getWrapped(session, cameraErrorListener))
         finalizeSession()
         interopSessionStateCallback?.onClosed(session)
     }
 
     override fun onCaptureQueueEmpty(session: CameraCaptureSession) {
-        stateCallback.onCaptureQueueEmpty(getWrapped(session))
+        stateCallback.onCaptureQueueEmpty(getWrapped(session, cameraErrorListener))
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
             Api26CompatImpl.onCaptureQueueEmpty(session, interopSessionStateCallback)
         }
     }
 
-    private fun getWrapped(session: CameraCaptureSession): CameraCaptureSessionWrapper {
+    private fun getWrapped(
+        session: CameraCaptureSession,
+        cameraErrorListener: CameraErrorListener,
+    ): CameraCaptureSessionWrapper {
         var local = captureSession.value
         if (local != null) {
             return local
         }
 
-        local = wrapSession(session)
+        local = wrapSession(session, cameraErrorListener)
         if (captureSession.compareAndSet(null, local)) {
             return local
         }
         return captureSession.value!!
     }
 
-    private fun wrapSession(session: CameraCaptureSession): CameraCaptureSessionWrapper {
+    private fun wrapSession(
+        session: CameraCaptureSession,
+        cameraErrorListener: CameraErrorListener,
+    ): CameraCaptureSessionWrapper {
         // Starting in Android P, it's possible for the standard "createCaptureSession" method to
         // return a CameraConstrainedHighSpeedCaptureSession depending on the configuration. If
         // this happens, several methods are not allowed, the behavior is different, and interacting
@@ -248,9 +247,9 @@
         return if (Build.VERSION.SDK_INT >= 23 &&
             session is CameraConstrainedHighSpeedCaptureSession
         ) {
-            AndroidCameraConstrainedHighSpeedCaptureSession(device, session)
+            AndroidCameraConstrainedHighSpeedCaptureSession(device, session, cameraErrorListener)
         } else {
-            AndroidCameraCaptureSession(device, session)
+            AndroidCameraCaptureSession(device, session, cameraErrorListener)
         }
     }
 
@@ -281,53 +280,54 @@
 @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
 internal open class AndroidCameraCaptureSession(
     override val device: CameraDeviceWrapper,
-    private val cameraCaptureSession: CameraCaptureSession
+    private val cameraCaptureSession: CameraCaptureSession,
+    private val cameraErrorListener: CameraErrorListener,
 ) : CameraCaptureSessionWrapper {
-    override fun abortCaptures() {
-        rethrowCamera2Exceptions { cameraCaptureSession.abortCaptures() }
-    }
+    override fun abortCaptures(): Boolean =
+        catchAndReportCameraExceptions(device.cameraId, cameraErrorListener) {
+            cameraCaptureSession.abortCaptures()
+        } != null
 
     override fun capture(
         request: CaptureRequest,
         listener: CameraCaptureSession.CaptureCallback,
         handler: Handler?
-    ): Int {
-        return rethrowCamera2Exceptions { cameraCaptureSession.capture(request, listener, handler) }
+    ): Int? = catchAndReportCameraExceptions(device.cameraId, cameraErrorListener) {
+        cameraCaptureSession.capture(
+            request,
+            listener,
+            handler
+        )
     }
 
     override fun captureBurst(
         requests: List<CaptureRequest>,
         listener: CameraCaptureSession.CaptureCallback,
         handler: Handler?
-    ): Int {
-        return rethrowCamera2Exceptions {
-            cameraCaptureSession.captureBurst(requests, listener, handler)
-        }
+    ): Int? = catchAndReportCameraExceptions(device.cameraId, cameraErrorListener) {
+        cameraCaptureSession.captureBurst(requests, listener, handler)
     }
 
     override fun setRepeatingBurst(
         requests: List<CaptureRequest>,
         listener: CameraCaptureSession.CaptureCallback,
         handler: Handler?
-    ): Int {
-        return rethrowCamera2Exceptions {
-            cameraCaptureSession.setRepeatingBurst(requests, listener, handler)
-        }
+    ): Int? = catchAndReportCameraExceptions(device.cameraId, cameraErrorListener) {
+        cameraCaptureSession.setRepeatingBurst(requests, listener, handler)
     }
 
     override fun setRepeatingRequest(
         request: CaptureRequest,
         listener: CameraCaptureSession.CaptureCallback,
         handler: Handler?
-    ): Int {
-        return rethrowCamera2Exceptions {
-            cameraCaptureSession.setRepeatingRequest(request, listener, handler)
-        }
+    ): Int? = catchAndReportCameraExceptions(device.cameraId, cameraErrorListener) {
+        cameraCaptureSession.setRepeatingRequest(request, listener, handler)
     }
 
-    override fun stopRepeating() {
-        rethrowCamera2Exceptions { cameraCaptureSession.stopRepeating() }
-    }
+    override fun stopRepeating(): Boolean =
+        catchAndReportCameraExceptions(device.cameraId, cameraErrorListener) {
+            cameraCaptureSession.stopRepeating()
+        } != null
 
     override val isReprocessable: Boolean
         get() {
@@ -349,30 +349,20 @@
         }
 
     @RequiresApi(26)
-    override fun finalizeOutputConfigurations(outputConfigs: List<OutputConfigurationWrapper>) {
+    override fun finalizeOutputConfigurations(
+        outputConfigs: List<OutputConfigurationWrapper>
+    ): Boolean {
         check(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
             "Attempting to call finalizeOutputConfigurations before O is not supported and may " +
                 "lead to to unexpected behavior if an application is expects this call to " +
                 "succeed."
         }
 
-        var exceptionToThrow: Throwable? = null
-        try {
+        return catchAndReportCameraExceptions(device.cameraId, cameraErrorListener) {
             Api26Compat.finalizeOutputConfigurations(
                 cameraCaptureSession,
                 outputConfigs.map { it.unwrapAs(OutputConfiguration::class) })
-        } catch (e: CameraAccessException) {
-            // TODO(b/266734799): There is a possibility that we might finalize output
-            //  configurations on a camera that's been disconnected. In such cases, we'll receive
-            //  CameraAccessException.CAMERA_ERROR. Catch it for now, until we properly report and
-            //  handle capture session errors.
-            if (e.reason != CAMERA_ERROR) {
-                exceptionToThrow = e
-            }
-        } catch (e: Throwable) {
-            exceptionToThrow = e
-        }
-        exceptionToThrow?.let { rethrowCamera2Exceptions { throw it } }
+        } != null
     }
 
     @Suppress("UNCHECKED_CAST")
@@ -395,8 +385,10 @@
 internal class AndroidCameraConstrainedHighSpeedCaptureSession
 internal constructor(
     device: CameraDeviceWrapper,
-    private val session: CameraConstrainedHighSpeedCaptureSession
-) : AndroidCameraCaptureSession(device, session), CameraConstrainedHighSpeedCaptureSessionWrapper {
+    private val session: CameraConstrainedHighSpeedCaptureSession,
+    private val cameraErrorListener: CameraErrorListener,
+) : AndroidCameraCaptureSession(device, session, cameraErrorListener),
+    CameraConstrainedHighSpeedCaptureSessionWrapper {
     @Throws(ObjectUnavailableException::class)
     override fun createHighSpeedRequestList(request: CaptureRequest): List<CaptureRequest> {
         return try {
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Exceptions.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Exceptions.kt
index 85cdd1c..3cf8857 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Exceptions.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Exceptions.kt
@@ -20,7 +20,9 @@
 
 import android.hardware.camera2.CameraAccessException
 import androidx.annotation.RequiresApi
-import androidx.camera.camera2.pipe.core.Log
+import androidx.camera.camera2.pipe.CameraError
+import androidx.camera.camera2.pipe.CameraId
+import androidx.camera.camera2.pipe.internal.CameraErrorListener
 
 /**
  * Thrown when an operation cannot be executed because underlying object is closed or in an unusable
@@ -30,7 +32,11 @@
 
 /** Catch specific exceptions that are not normally thrown, log them, then rethrow. */
 @Throws(ObjectUnavailableException::class)
-internal inline fun <T> rethrowCamera2Exceptions(crossinline block: () -> T): T {
+internal inline fun <T> catchAndReportCameraExceptions(
+    cameraId: CameraId,
+    cameraErrorListener: CameraErrorListener,
+    crossinline block: () -> T
+): T? {
     // Camera2 has, at different points in time, thrown a large number of checked and/or
     // unchecked exceptions under different circumstances that are not listed in the
     // documentation. This method catches and recasts these exceptions into a common exception
@@ -49,17 +55,22 @@
     try {
         return block()
     } catch (e: Exception) {
-        throw when (e) {
+        when (e) {
             is IllegalArgumentException,
             is IllegalStateException,
             is CameraAccessException,
             is SecurityException,
-            is UnsupportedOperationException -> {
-                Log.debug(e) { "Rethrowing ${e::class.java.simpleName} from Camera2" }
-                ObjectUnavailableException(e)
+            is UnsupportedOperationException,
+            is NullPointerException -> {
+                cameraErrorListener.onCameraError(
+                    cameraId,
+                    CameraError.ERROR_GRAPH_CONFIG,
+                    willAttemptRetry = false
+                )
+                return null
             }
 
-            else -> e
+            else -> throw e
         }
     }
 }
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/ExternalRequestProcessor.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/ExternalRequestProcessor.kt
index 151d702..f8cfa64 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/ExternalRequestProcessor.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/ExternalRequestProcessor.kt
@@ -24,6 +24,7 @@
 import androidx.camera.camera2.pipe.CameraController
 import androidx.camera.camera2.pipe.CameraGraph
 import androidx.camera.camera2.pipe.CameraId
+import androidx.camera.camera2.pipe.CameraStatusMonitor
 import androidx.camera.camera2.pipe.CaptureSequence
 import androidx.camera.camera2.pipe.CaptureSequenceProcessor
 import androidx.camera.camera2.pipe.Metadata
@@ -65,7 +66,7 @@
         }
     }
 
-    override fun tryRestart() {
+    override fun tryRestart(cameraStatus: CameraStatusMonitor.CameraStatus) {
         // This is intentionally made a no-op for now as CameraPipe external doesn't support
         // camera status monitoring and camera controller restart.
     }
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/RetryingCameraStateOpener.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/RetryingCameraStateOpener.kt
index f4c438a..6f19a06 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/RetryingCameraStateOpener.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/RetryingCameraStateOpener.kt
@@ -25,7 +25,6 @@
 import androidx.camera.camera2.pipe.CameraError
 import androidx.camera.camera2.pipe.CameraId
 import androidx.camera.camera2.pipe.CameraPipe
-import androidx.camera.camera2.pipe.GraphState.GraphStateError
 import androidx.camera.camera2.pipe.core.Debug
 import androidx.camera.camera2.pipe.core.DurationNs
 import androidx.camera.camera2.pipe.core.Log
@@ -35,7 +34,7 @@
 import androidx.camera.camera2.pipe.core.TimestampNs
 import androidx.camera.camera2.pipe.core.Timestamps
 import androidx.camera.camera2.pipe.core.Timestamps.formatMs
-import androidx.camera.camera2.pipe.graph.GraphListener
+import androidx.camera.camera2.pipe.internal.CameraErrorListener
 import javax.inject.Inject
 import javax.inject.Provider
 import kotlin.coroutines.resume
@@ -151,6 +150,7 @@
 constructor(
     private val cameraOpener: CameraOpener,
     private val camera2MetadataProvider: Camera2MetadataProvider,
+    private val cameraErrorListener: CameraErrorListener,
     private val timeSource: TimeSource,
     private val cameraInteropConfig: CameraPipe.CameraInteropConfig?
 ) {
@@ -167,6 +167,7 @@
                 attempts,
                 requestTimestamp,
                 timeSource,
+                cameraErrorListener,
                 cameraInteropConfig?.cameraDeviceStateCallback,
                 cameraInteropConfig?.cameraSessionStateCallback
             )
@@ -206,13 +207,13 @@
 @Inject
 constructor(
     private val cameraStateOpener: CameraStateOpener,
+    private val cameraErrorListener: CameraErrorListener,
     private val cameraAvailabilityMonitor: CameraAvailabilityMonitor,
     private val timeSource: TimeSource,
     private val devicePolicyManager: DevicePolicyManagerWrapper
 ) {
     internal suspend fun openCameraWithRetry(
         cameraId: CameraId,
-        graphListener: GraphListener
     ): OpenCameraResult {
         val requestTimestamp = Timestamps.now(timeSource)
         var attempts = 0
@@ -220,7 +221,12 @@
         while (true) {
             attempts++
 
-            val result = cameraStateOpener.tryOpenCamera(cameraId, attempts, requestTimestamp)
+            val result =
+                cameraStateOpener.tryOpenCamera(
+                    cameraId,
+                    attempts,
+                    requestTimestamp,
+                )
             with(result) {
                 if (cameraState != null) {
                     return result
@@ -250,7 +256,7 @@
                 // 1 open call to happen silently without generating an error, and notify about each
                 // error after that point.
                 if (!willRetry || attempts > 1) {
-                    graphListener.onGraphError(GraphStateError(errorCode, willRetry))
+                    cameraErrorListener.onCameraError(cameraId, errorCode, willRetry)
                 }
                 if (!willRetry) {
                     Log.error {
@@ -327,6 +333,15 @@
                 CameraError.ERROR_CAMERA_DISCONNECTED -> true
                 CameraError.ERROR_ILLEGAL_ARGUMENT_EXCEPTION -> true
                 CameraError.ERROR_SECURITY_EXCEPTION -> attempts <= 1
+                CameraError.ERROR_DO_NOT_DISTURB_ENABLED ->
+                    // The error indicates that a RuntimeException was encountered when opening the
+                    // camera while Do Not Disturb mode is on. This can happen on legacy devices on
+                    // API level 28 [1]. Retries will always fail and should not be attempted.
+                    //
+                    // [1] b/149413835 - Crash during CameraX initialization when Do Not Disturb
+                    //                   is on.
+                    false
+
                 else -> {
                     Log.error { "Unexpected CameraError: $this" }
                     false
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCamera.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCamera.kt
index b5e7a6d..04cfadb 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCamera.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCamera.kt
@@ -35,6 +35,8 @@
 import androidx.camera.camera2.pipe.core.Timestamps
 import androidx.camera.camera2.pipe.core.Timestamps.formatMs
 import androidx.camera.camera2.pipe.core.Token
+import androidx.camera.camera2.pipe.graph.GraphListener
+import androidx.camera.camera2.pipe.internal.CameraErrorListener
 import kotlin.coroutines.EmptyCoroutineContext
 import kotlinx.atomicfu.atomic
 import kotlinx.coroutines.Job
@@ -113,7 +115,10 @@
 
 internal val virtualCameraDebugIds = atomic(0)
 
-internal class VirtualCameraState(val cameraId: CameraId) : VirtualCamera {
+internal class VirtualCameraState(
+    val cameraId: CameraId,
+    val graphListener: GraphListener
+) : VirtualCamera {
     private val debugId = virtualCameraDebugIds.incrementAndGet()
     private val lock = Any()
 
@@ -208,6 +213,7 @@
     private val attemptNumber: Int,
     private val attemptTimestampNanos: TimestampNs,
     private val timeSource: TimeSource,
+    private val cameraErrorListener: CameraErrorListener,
     private val interopDeviceStateCallback: CameraDevice.StateCallback? = null,
     private val interopSessionStateCallback: CameraCaptureSession.StateCallback? = null
 ) : CameraDevice.StateCallback() {
@@ -293,7 +299,13 @@
         // while if it synchronously calls createCaptureSession.
         _state.value =
             CameraStateOpen(
-                AndroidCameraDevice(metadata, cameraDevice, cameraId, interopSessionStateCallback)
+                AndroidCameraDevice(
+                    metadata,
+                    cameraDevice,
+                    cameraId,
+                    cameraErrorListener,
+                    interopSessionStateCallback
+                )
             )
 
         // Check to see if we received close() or other events in the meantime.
@@ -393,7 +405,17 @@
                 null
             }
         if (closeInfo != null) {
+            // If the camera error is an Exception during open, the error should be reported by
+            // RetryingCameraStateOpener.
+            if (closeInfo.errorCode != null && closeInfo.reason != ClosedReason.CAMERA2_EXCEPTION) {
+                cameraErrorListener.onCameraError(
+                    cameraId,
+                    closeInfo.errorCode,
+                    willAttemptRetry = false
+                )
+            }
             _state.value = CameraStateClosing(closeInfo.errorCode)
+
             cameraDeviceWrapper.closeWithTrace()
             cameraDevice.closeWithTrace()
             _state.value = computeClosedState(closeInfo)
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCameraManager.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCameraManager.kt
index fe27798..06e4e27 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCameraManager.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCameraManager.kt
@@ -60,6 +60,7 @@
 constructor(
     private val permissions: Permissions,
     private val retryingCameraStateOpener: RetryingCameraStateOpener,
+    private val camera2ErrorProcessor: Camera2ErrorProcessor,
     private val threads: Threads
 ) {
     // TODO: Consider rewriting this as a MutableSharedFlow
@@ -75,7 +76,7 @@
         share: Boolean = false,
         graphListener: GraphListener
     ): VirtualCamera {
-        val result = VirtualCameraState(cameraId)
+        val result = VirtualCameraState(cameraId, graphListener)
         offerChecked(RequestOpen(result, share, graphListener))
         return result
     }
@@ -178,10 +179,11 @@
             }
 
             // Stage 3: Open or select an active camera device.
+            camera2ErrorProcessor.setActiveVirtualCamera(cameraIdToOpen, request.virtualCamera)
             var realCamera = activeCameras.firstOrNull { it.cameraId == cameraIdToOpen }
             if (realCamera == null) {
                 val openResult =
-                    openCameraWithRetry(cameraIdToOpen, request.graphListener, scope = this)
+                    openCameraWithRetry(cameraIdToOpen, scope = this)
                 if (openResult.activeCamera != null) {
                     realCamera = openResult.activeCamera
                     activeCameras.add(realCamera)
@@ -200,7 +202,6 @@
 
     private suspend fun openCameraWithRetry(
         cameraId: CameraId,
-        graphListener: GraphListener,
         scope: CoroutineScope
     ): OpenVirtualCameraResult {
         // TODO: Figure out how 1-time permissions work, and see if they can be reset without
@@ -208,14 +209,15 @@
         check(permissions.hasCameraPermission) { "Missing camera permissions!" }
 
         Log.debug { "Opening $cameraId with retries..." }
-        val result = retryingCameraStateOpener.openCameraWithRetry(cameraId, graphListener)
+        val result = retryingCameraStateOpener.openCameraWithRetry(cameraId)
         if (result.cameraState == null) {
             return OpenVirtualCameraResult(lastCameraError = result.errorCode)
         }
         return OpenVirtualCameraResult(
             activeCamera =
             ActiveCamera(
-                androidCameraState = result.cameraState, scope = scope, channel = requestQueue
+                androidCameraState = result.cameraState,
+                scope = scope, channel = requestQueue
             )
         )
     }
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/Camera2Component.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/Camera2Component.kt
index 57d38e5..710b044 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/Camera2Component.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/Camera2Component.kt
@@ -29,6 +29,7 @@
 import androidx.camera.camera2.pipe.compat.Camera2CameraStatusMonitor
 import androidx.camera.camera2.pipe.compat.Camera2CaptureSequenceProcessorFactory
 import androidx.camera.camera2.pipe.compat.Camera2CaptureSessionsModule
+import androidx.camera.camera2.pipe.compat.Camera2ErrorProcessor
 import androidx.camera.camera2.pipe.compat.Camera2MetadataCache
 import androidx.camera.camera2.pipe.compat.Camera2MetadataProvider
 import androidx.camera.camera2.pipe.compat.CameraAvailabilityMonitor
@@ -37,6 +38,7 @@
 import androidx.camera.camera2.pipe.core.Threads
 import androidx.camera.camera2.pipe.graph.GraphListener
 import androidx.camera.camera2.pipe.graph.StreamGraphImpl
+import androidx.camera.camera2.pipe.internal.CameraErrorListener
 import dagger.Binds
 import dagger.Module
 import dagger.Provides
@@ -61,6 +63,11 @@
     ): Camera2MetadataProvider
 
     @Binds
+    abstract fun bindCameraErrorListener(
+        camera2ErrorProcessor: Camera2ErrorProcessor
+    ): CameraErrorListener
+
+    @Binds
     abstract fun bindCameraAvailabilityMonitor(
         camera2CameraAvailabilityMonitor: Camera2CameraAvailabilityMonitor
     ): CameraAvailabilityMonitor
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/graph/GraphProcessor.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/graph/GraphProcessor.kt
index 053e5cb..355643f 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/graph/GraphProcessor.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/graph/GraphProcessor.kt
@@ -179,6 +179,7 @@
     }
 
     override fun onGraphModified(requestProcessor: GraphRequestProcessor) {
+        debug { "$this onGraphModified" }
         synchronized(lock) {
             if (closed) {
                 return
@@ -191,6 +192,7 @@
     }
 
     override fun onGraphError(graphStateError: GraphStateError) {
+        debug { "$this onGraphError($graphStateError)" }
         _graphState.update { graphState ->
             if (graphState is GraphStateStopping || graphState is GraphStateStopped) {
                 GraphStateStopped
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/graph/GraphRequestProcessor.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/graph/GraphRequestProcessor.kt
index bde6051..81d3845 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/graph/GraphRequestProcessor.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/graph/GraphRequestProcessor.kt
@@ -179,7 +179,7 @@
                         Log.warn { "Did not submit $captureSequence, $this was closed!" }
                         return false
                     }
-                    val sequenceNumber = captureSequenceProcessor.submit(captureSequence)
+                    val sequenceNumber = captureSequenceProcessor.submit(captureSequence) ?: -1
                     captureSequence.sequenceNumber = sequenceNumber
                     sequenceNumber
                 }
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/CameraErrorListener.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/CameraErrorListener.kt
new file mode 100644
index 0000000..19b6018
--- /dev/null
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/CameraErrorListener.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.camera2.pipe.internal
+
+import androidx.camera.camera2.pipe.CameraError
+import androidx.camera.camera2.pipe.CameraId
+
+/**
+ * Interface intended to be used to report camera errors. It will ensure only the current
+ * [androidx.camera.camera2.pipe.graph.GraphListener] is notified of the error.
+ */
+interface CameraErrorListener {
+    fun onCameraError(
+        cameraId: CameraId,
+        cameraError: CameraError,
+        willAttemptRetry: Boolean = false
+    )
+}
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/GraphLifecycleManager.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/GraphLifecycleManager.kt
index 1429f76..ee876bf 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/GraphLifecycleManager.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/GraphLifecycleManager.kt
@@ -87,10 +87,14 @@
             cameraBackend.cameraStatus.collect { cameraStatus ->
                 when (cameraStatus) {
                     is CameraStatus.CameraPrioritiesChanged ->
-                        tryRestartCameraController(cameraBackend)
+                        tryRestartCameraController(cameraBackend, cameraStatus)
 
                     is CameraStatus.CameraAvailable ->
-                        tryRestartCameraController(cameraBackend, cameraStatus.cameraId)
+                        tryRestartCameraController(
+                            cameraBackend,
+                            cameraStatus,
+                            cameraStatus.cameraId
+                        )
                 }
             }
         }
@@ -111,6 +115,7 @@
 
     private fun tryRestartCameraController(
         cameraBackend: CameraBackend,
+        cameraStatus: CameraStatus,
         cameraId: CameraId? = null,
     ) = synchronized(lock) {
         // Restart the last CameraController being tracked in each backend. The last
@@ -122,6 +127,6 @@
             } else {
                 true
             }
-        }?.tryRestart()
+        }?.tryRestart(cameraStatus)
     }
 }
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/AndroidCaptureSessionStateCallbackTest.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/AndroidCaptureSessionStateCallbackTest.kt
index 4e1e57f..6b0573a 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/AndroidCaptureSessionStateCallbackTest.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/AndroidCaptureSessionStateCallbackTest.kt
@@ -18,6 +18,7 @@
 
 import android.hardware.camera2.CameraCaptureSession
 import android.os.Build
+import androidx.camera.camera2.pipe.internal.CameraErrorListener
 import androidx.camera.camera2.pipe.testing.RobolectricCameraPipeTestRunner
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -35,11 +36,13 @@
     private val stateCallback: CameraCaptureSessionWrapper.StateCallback = mock()
     private val previousStateCallback: CameraCaptureSessionWrapper.StateCallback = mock()
     private val captureSession: CameraCaptureSession = mock()
+    private val cameraErrorListener: CameraErrorListener = mock()
     private val androidStateCallback =
         AndroidCaptureSessionStateCallback(
             device = camera,
             stateCallback = stateCallback,
             lastStateCallback = previousStateCallback,
+            cameraErrorListener = cameraErrorListener,
         )
 
     @Test
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessorTest.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessorTest.kt
index a5b2acf..93349db 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessorTest.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessorTest.kt
@@ -202,6 +202,7 @@
 
         val result = captureSequenceProcessor.submit(sequence!!)
 
+        assertThat(result).isNotNull()
         assertThat(result).isGreaterThan(0)
         assertThat(fakeCaptureSessionWrapper.lastCapture).hasSize(1)
         assertThat(fakeCaptureSessionWrapper.lastRepeating).isNull()
@@ -231,6 +232,7 @@
         assertThat(captureSequence).isNotNull()
 
         val result = captureSequenceProcessor.submit(captureSequence!!)
+        assertThat(result).isNotNull()
         assertThat(result).isGreaterThan(0)
     }
 
@@ -320,6 +322,7 @@
 
         val result = captureSequenceProcessor.submit(sequence!!)
 
+        assertThat(result).isNotNull()
         assertThat(result).isGreaterThan(0)
         assertThat(fakeCaptureSessionWrapper.lastCapture).hasSize(1)
         assertThat(fakeCaptureSessionWrapper.lastRepeating).isNull()
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 c2bcc17..475d2fb 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
@@ -39,6 +39,7 @@
 import androidx.camera.camera2.pipe.config.ThreadConfigModule
 import androidx.camera.camera2.pipe.core.SystemTimeSource
 import androidx.camera.camera2.pipe.graph.StreamGraphImpl
+import androidx.camera.camera2.pipe.internal.CameraErrorListener
 import androidx.camera.camera2.pipe.testing.FakeCaptureSequence
 import androidx.camera.camera2.pipe.testing.FakeCaptureSequenceProcessor
 import androidx.camera.camera2.pipe.testing.FakeGraphProcessor
@@ -55,6 +56,7 @@
 import org.junit.After
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
 import org.robolectric.Shadows
 import org.robolectric.annotation.Config
 
@@ -66,6 +68,7 @@
     private val mainLooper = Shadows.shadowOf(Looper.getMainLooper())
     private val cameraId = RobolectricCameras.create()
     private val testCamera = RobolectricCameras.open(cameraId)
+    private val cameraErrorListener: CameraErrorListener = mock()
 
     @After
     fun teardown() {
@@ -106,7 +109,10 @@
         val pendingOutputs =
             sessionFactory.create(
                 AndroidCameraDevice(
-                    testCamera.metadata, testCamera.cameraDevice, testCamera.cameraId
+                    testCamera.metadata,
+                    testCamera.cameraDevice,
+                    testCamera.cameraId,
+                    cameraErrorListener
                 ),
                 mapOf(stream1.id to surface),
                 captureSessionState =
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/RetryingCameraStateOpenerTest.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/RetryingCameraStateOpenerTest.kt
index 06d89fc..6e1716c 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/RetryingCameraStateOpenerTest.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/RetryingCameraStateOpenerTest.kt
@@ -24,16 +24,15 @@
 import androidx.camera.camera2.pipe.CameraError.Companion.ERROR_CAMERA_DISCONNECTED
 import androidx.camera.camera2.pipe.CameraError.Companion.ERROR_CAMERA_IN_USE
 import androidx.camera.camera2.pipe.CameraError.Companion.ERROR_CAMERA_LIMIT_EXCEEDED
+import androidx.camera.camera2.pipe.CameraError.Companion.ERROR_DO_NOT_DISTURB_ENABLED
 import androidx.camera.camera2.pipe.CameraError.Companion.ERROR_ILLEGAL_ARGUMENT_EXCEPTION
 import androidx.camera.camera2.pipe.CameraError.Companion.ERROR_SECURITY_EXCEPTION
 import androidx.camera.camera2.pipe.CameraId
 import androidx.camera.camera2.pipe.CameraMetadata
-import androidx.camera.camera2.pipe.GraphState.GraphStateError
 import androidx.camera.camera2.pipe.core.DurationNs
 import androidx.camera.camera2.pipe.core.TimestampNs
 import androidx.camera.camera2.pipe.core.Timestamps
-import androidx.camera.camera2.pipe.graph.GraphListener
-import androidx.camera.camera2.pipe.graph.GraphRequestProcessor
+import androidx.camera.camera2.pipe.internal.CameraErrorListener
 import androidx.camera.camera2.pipe.testing.FakeCameraMetadata
 import androidx.camera.camera2.pipe.testing.FakeTimeSource
 import androidx.camera.camera2.pipe.testing.RobolectricCameraPipeTestRunner
@@ -78,8 +77,28 @@
 
     private val fakeTimeSource = FakeTimeSource()
 
+    // TODO(lnishan): Consider mocking this object when Mockito works well with value classes.
+    private val fakeCameraErrorListener =
+        object : CameraErrorListener {
+            var numberOfErrorCalls = 0
+
+            override fun onCameraError(
+                cameraId: CameraId,
+                cameraError: CameraError,
+                willAttemptRetry: Boolean
+            ) {
+                numberOfErrorCalls++
+            }
+        }
+
     private val cameraStateOpener =
-        CameraStateOpener(cameraOpener, camera2MetadataProvider, fakeTimeSource, null)
+        CameraStateOpener(
+            cameraOpener,
+            camera2MetadataProvider,
+            fakeCameraErrorListener,
+            fakeTimeSource,
+            cameraInteropConfig = null,
+        )
 
     private val cameraAvailabilityMonitor =
         object : CameraAvailabilityMonitor {
@@ -97,25 +116,13 @@
 
     private val retryingCameraStateOpener =
         RetryingCameraStateOpener(
-            cameraStateOpener, cameraAvailabilityMonitor, fakeTimeSource, fakeDevicePolicyManager
+            cameraStateOpener,
+            fakeCameraErrorListener,
+            cameraAvailabilityMonitor,
+            fakeTimeSource,
+            fakeDevicePolicyManager,
         )
 
-    // TODO(lnishan): Consider mocking this object when Mockito works well with value classes.
-    private val fakeGraphListener =
-        object : GraphListener {
-            var numberOfErrorCalls = 0
-
-            override fun onGraphStarted(requestProcessor: GraphRequestProcessor) {}
-
-            override fun onGraphStopped(requestProcessor: GraphRequestProcessor) {}
-
-            override fun onGraphModified(requestProcessor: GraphRequestProcessor) {}
-
-            override fun onGraphError(graphStateError: GraphStateError) {
-                numberOfErrorCalls++
-            }
-        }
-
     @Test
     fun testShouldRetryReturnsTrueWithinTimeout() {
         val firstAttemptTimestamp = TimestampNs(0L)
@@ -123,7 +130,7 @@
 
         assertThat(
             RetryingCameraStateOpener.shouldRetry(
-                CameraError.ERROR_CAMERA_IN_USE,
+                ERROR_CAMERA_IN_USE,
                 1,
                 firstAttemptTimestamp,
                 fakeTimeSource,
@@ -140,7 +147,7 @@
 
         assertThat(
             RetryingCameraStateOpener.shouldRetry(
-                CameraError.ERROR_CAMERA_IN_USE,
+                ERROR_CAMERA_IN_USE,
                 1,
                 firstAttemptTimestamp,
                 fakeTimeSource,
@@ -174,7 +181,7 @@
 
         assertThat(
             RetryingCameraStateOpener.shouldRetry(
-                CameraError.ERROR_CAMERA_IN_USE,
+                ERROR_CAMERA_IN_USE,
                 1,
                 firstAttemptTimestamp,
                 fakeTimeSource,
@@ -186,7 +193,7 @@
         // The second retry attempt should fail if SDK version < S, and succeed otherwise.
         val secondRetry =
             RetryingCameraStateOpener.shouldRetry(
-                CameraError.ERROR_CAMERA_IN_USE, 2, firstAttemptTimestamp, fakeTimeSource, false
+                ERROR_CAMERA_IN_USE, 2, firstAttemptTimestamp, fakeTimeSource, false
             )
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
             assertThat(secondRetry).isFalse()
@@ -202,7 +209,7 @@
 
         assertThat(
             RetryingCameraStateOpener.shouldRetry(
-                CameraError.ERROR_CAMERA_LIMIT_EXCEEDED,
+                ERROR_CAMERA_LIMIT_EXCEEDED,
                 1,
                 firstAttemptTimestamp,
                 fakeTimeSource,
@@ -214,7 +221,7 @@
         // Second attempt should succeed as well.
         assertThat(
             RetryingCameraStateOpener.shouldRetry(
-                CameraError.ERROR_CAMERA_LIMIT_EXCEEDED,
+                ERROR_CAMERA_LIMIT_EXCEEDED,
                 2,
                 firstAttemptTimestamp,
                 fakeTimeSource,
@@ -231,7 +238,7 @@
 
         assertThat(
             RetryingCameraStateOpener.shouldRetry(
-                CameraError.ERROR_CAMERA_DISABLED,
+                ERROR_CAMERA_DISABLED,
                 1,
                 firstAttemptTimestamp,
                 fakeTimeSource,
@@ -243,7 +250,7 @@
         // Second attempt should fail if camera is disabled.
         assertThat(
             RetryingCameraStateOpener.shouldRetry(
-                CameraError.ERROR_CAMERA_DISABLED,
+                ERROR_CAMERA_DISABLED,
                 2,
                 firstAttemptTimestamp,
                 fakeTimeSource,
@@ -260,7 +267,7 @@
 
         assertThat(
             RetryingCameraStateOpener.shouldRetry(
-                CameraError.ERROR_CAMERA_DISABLED,
+                ERROR_CAMERA_DISABLED,
                 1,
                 firstAttemptTimestamp,
                 fakeTimeSource,
@@ -272,7 +279,7 @@
         // Second attempt should success if camera is not disabled.
         assertThat(
             RetryingCameraStateOpener.shouldRetry(
-                CameraError.ERROR_CAMERA_DISABLED,
+                ERROR_CAMERA_DISABLED,
                 2,
                 firstAttemptTimestamp,
                 fakeTimeSource,
@@ -347,7 +354,7 @@
 
         assertThat(
             RetryingCameraStateOpener.shouldRetry(
-                CameraError.ERROR_CAMERA_DISCONNECTED,
+                ERROR_CAMERA_DISCONNECTED,
                 1,
                 firstAttemptTimestamp,
                 fakeTimeSource,
@@ -359,7 +366,7 @@
         // Second attempt should succeed as well.
         assertThat(
             RetryingCameraStateOpener.shouldRetry(
-                CameraError.ERROR_CAMERA_DISCONNECTED,
+                ERROR_CAMERA_DISCONNECTED,
                 2,
                 firstAttemptTimestamp,
                 fakeTimeSource,
@@ -376,7 +383,7 @@
 
         assertThat(
             RetryingCameraStateOpener.shouldRetry(
-                CameraError.ERROR_ILLEGAL_ARGUMENT_EXCEPTION,
+                ERROR_ILLEGAL_ARGUMENT_EXCEPTION,
                 1,
                 firstAttemptTimestamp,
                 fakeTimeSource,
@@ -388,7 +395,7 @@
         // Second attempt should succeed as well.
         assertThat(
             RetryingCameraStateOpener.shouldRetry(
-                CameraError.ERROR_ILLEGAL_ARGUMENT_EXCEPTION,
+                ERROR_ILLEGAL_ARGUMENT_EXCEPTION,
                 2,
                 firstAttemptTimestamp,
                 fakeTimeSource,
@@ -405,7 +412,7 @@
 
         assertThat(
             RetryingCameraStateOpener.shouldRetry(
-                CameraError.ERROR_SECURITY_EXCEPTION,
+                ERROR_SECURITY_EXCEPTION,
                 1,
                 firstAttemptTimestamp,
                 fakeTimeSource,
@@ -417,7 +424,7 @@
         // Second attempt should fail.
         assertThat(
             RetryingCameraStateOpener.shouldRetry(
-                CameraError.ERROR_SECURITY_EXCEPTION,
+                ERROR_SECURITY_EXCEPTION,
                 2,
                 firstAttemptTimestamp,
                 fakeTimeSource,
@@ -428,19 +435,72 @@
     }
 
     @Test
+    fun testShouldNotRetryDoNotDisturbModeEnabled() {
+        val firstAttemptTimestamp = TimestampNs(0L)
+        fakeTimeSource.currentTimestamp = TimestampNs(1_000_000_000L) // 1 second
+
+        assertThat(
+            RetryingCameraStateOpener.shouldRetry(
+                ERROR_DO_NOT_DISTURB_ENABLED,
+                1,
+                firstAttemptTimestamp,
+                fakeTimeSource,
+                false
+            )
+        )
+            .isFalse()
+    }
+
+    @Test
     fun cameraStateOpenerReturnsCorrectError() = runTest {
         cameraOpener.toThrow = CameraAccessException(CameraAccessException.CAMERA_IN_USE)
-        val result = cameraStateOpener.tryOpenCamera(cameraId0, 1, Timestamps.now(fakeTimeSource))
+        val result = cameraStateOpener.tryOpenCamera(
+            cameraId0,
+            1,
+            Timestamps.now(fakeTimeSource),
+        )
 
         assertThat(result.errorCode).isEqualTo(ERROR_CAMERA_IN_USE)
     }
 
     @Test
+    fun cameraStateOpenerReturnsCorrectErrorWhenDoNotDisturbModeEnabledOnApi28() = runTest {
+        val throwable = RuntimeException("Camera is being used after Camera.release() was called")
+        throwable.stackTrace = arrayOf(
+            StackTraceElement(
+                "android.hardware.Camera",
+                "_enableShutterSound",
+                "Native Method",
+                0
+            ),
+            StackTraceElement(
+                "android.hardware.Camera",
+                "updateAppOpsPlayAudio",
+                "Camera.java",
+                1770
+            )
+        )
+        cameraOpener.toThrow = throwable
+
+        try {
+            val result = cameraStateOpener.tryOpenCamera(
+                cameraId0,
+                1,
+                Timestamps.now(fakeTimeSource),
+            )
+            assertThat(result.errorCode).isEqualTo(ERROR_DO_NOT_DISTURB_ENABLED)
+        } catch (throwable: Throwable) {
+            // Only non-28 SDK levels should throw an exception.
+            assertThat(Build.VERSION.SDK_INT).isNotEqualTo(28)
+        }
+    }
+
+    @Test
     fun retryingCameraStateOpenerRetriesCorrectlyOnCameraInUse() = runTest {
         whenever(fakeDevicePolicyManager.camerasDisabled).thenReturn(false)
         cameraOpener.toThrow = CameraAccessException(CameraAccessException.CAMERA_IN_USE)
         val result = async {
-            retryingCameraStateOpener.openCameraWithRetry(cameraId0, fakeGraphListener)
+            retryingCameraStateOpener.openCameraWithRetry(cameraId0)
         }
 
         // Advance virtual clock to move past the retry timeout.
@@ -457,7 +517,9 @@
         }
         // The first retry should be hidden. Therefore the number of onGraphError() calls should be
         // exactly the number of camera opens minus 1.
-        assertThat(fakeGraphListener.numberOfErrorCalls).isEqualTo(cameraOpener.numberOfOpens - 1)
+        assertThat(fakeCameraErrorListener.numberOfErrorCalls).isEqualTo(
+            cameraOpener.numberOfOpens - 1
+        )
     }
 
     @Test
@@ -465,7 +527,7 @@
         whenever(fakeDevicePolicyManager.camerasDisabled).thenReturn(false)
         cameraOpener.toThrow = CameraAccessException(CameraAccessException.MAX_CAMERAS_IN_USE)
         val result = async {
-            retryingCameraStateOpener.openCameraWithRetry(cameraId0, fakeGraphListener)
+            retryingCameraStateOpener.openCameraWithRetry(cameraId0)
         }
 
         // Advance virtual clock to move past the retry timeout.
@@ -478,7 +540,9 @@
         assertThat(cameraOpener.numberOfOpens).isGreaterThan(2)
         // The first retry should be hidden. Therefore the number of onGraphError() calls should be
         // exactly the number of camera opens minus 1.
-        assertThat(fakeGraphListener.numberOfErrorCalls).isEqualTo(cameraOpener.numberOfOpens - 1)
+        assertThat(fakeCameraErrorListener.numberOfErrorCalls).isEqualTo(
+            cameraOpener.numberOfOpens - 1
+        )
     }
 
     @Test
@@ -486,7 +550,7 @@
         whenever(fakeDevicePolicyManager.camerasDisabled).thenReturn(true)
         cameraOpener.toThrow = CameraAccessException(CameraAccessException.CAMERA_DISABLED)
         val result = async {
-            retryingCameraStateOpener.openCameraWithRetry(cameraId0, fakeGraphListener)
+            retryingCameraStateOpener.openCameraWithRetry(cameraId0)
         }
 
         // Advance virtual clock with just enough time for 1 camera retry (we wait 500ms before the
@@ -500,7 +564,7 @@
         assertThat(cameraOpener.numberOfOpens).isEqualTo(2)
         // The first retry should be hidden. Therefore the number of onGraphError() calls should be
         // exactly 1.
-        assertThat(fakeGraphListener.numberOfErrorCalls).isEqualTo(1)
+        assertThat(fakeCameraErrorListener.numberOfErrorCalls).isEqualTo(1)
     }
 
     @Test
@@ -508,7 +572,7 @@
         whenever(fakeDevicePolicyManager.camerasDisabled).thenReturn(false)
         cameraOpener.toThrow = CameraAccessException(CameraAccessException.CAMERA_DISABLED)
         val result = async {
-            retryingCameraStateOpener.openCameraWithRetry(cameraId0, fakeGraphListener)
+            retryingCameraStateOpener.openCameraWithRetry(cameraId0)
         }
 
         // Advance virtual clock to move past the retry timeout.
@@ -521,7 +585,9 @@
         assertThat(cameraOpener.numberOfOpens).isGreaterThan(2)
         // The first retry should be hidden. Therefore the number of onGraphError() calls should be
         // exactly the number of camera opens minus 1.
-        assertThat(fakeGraphListener.numberOfErrorCalls).isEqualTo(cameraOpener.numberOfOpens - 1)
+        assertThat(fakeCameraErrorListener.numberOfErrorCalls).isEqualTo(
+            cameraOpener.numberOfOpens - 1
+        )
     }
 
     @Test
@@ -529,7 +595,7 @@
         whenever(fakeDevicePolicyManager.camerasDisabled).thenReturn(false)
         cameraOpener.toThrow = CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED)
         val result = async {
-            retryingCameraStateOpener.openCameraWithRetry(cameraId0, fakeGraphListener)
+            retryingCameraStateOpener.openCameraWithRetry(cameraId0)
         }
 
         // Advance virtual clock to move past the retry timeout.
@@ -542,7 +608,9 @@
         assertThat(cameraOpener.numberOfOpens).isGreaterThan(2)
         // The first retry should be hidden. Therefore the number of onGraphError() calls should be
         // exactly the number of camera opens minus 1.
-        assertThat(fakeGraphListener.numberOfErrorCalls).isEqualTo(cameraOpener.numberOfOpens - 1)
+        assertThat(fakeCameraErrorListener.numberOfErrorCalls).isEqualTo(
+            cameraOpener.numberOfOpens - 1
+        )
     }
 
     @Test
@@ -550,7 +618,7 @@
         whenever(fakeDevicePolicyManager.camerasDisabled).thenReturn(false)
         cameraOpener.toThrow = IllegalArgumentException()
         val result = async {
-            retryingCameraStateOpener.openCameraWithRetry(cameraId0, fakeGraphListener)
+            retryingCameraStateOpener.openCameraWithRetry(cameraId0)
         }
 
         // Advance virtual clock to move past the retry timeout.
@@ -563,7 +631,9 @@
         assertThat(cameraOpener.numberOfOpens).isGreaterThan(2)
         // The first retry should be hidden. Therefore the number of onGraphError() calls should be
         // exactly the number of camera opens minus 1.
-        assertThat(fakeGraphListener.numberOfErrorCalls).isEqualTo(cameraOpener.numberOfOpens - 1)
+        assertThat(fakeCameraErrorListener.numberOfErrorCalls).isEqualTo(
+            cameraOpener.numberOfOpens - 1
+        )
     }
 
     @Test
@@ -571,7 +641,7 @@
         whenever(fakeDevicePolicyManager.camerasDisabled).thenReturn(false)
         cameraOpener.toThrow = SecurityException()
         val result = async {
-            retryingCameraStateOpener.openCameraWithRetry(cameraId0, fakeGraphListener)
+            retryingCameraStateOpener.openCameraWithRetry(cameraId0)
         }
 
         // Advance virtual clock with just enough time for 1 camera retry (we wait 500ms before the
@@ -585,6 +655,6 @@
         assertThat(cameraOpener.numberOfOpens).isEqualTo(2)
         // The first retry should be hidden. Therefore the number of onGraphError() calls should be
         // exactly 1.
-        assertThat(fakeGraphListener.numberOfErrorCalls).isEqualTo(1)
+        assertThat(fakeCameraErrorListener.numberOfErrorCalls).isEqualTo(1)
     }
 }
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/VirtualCameraTest.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/VirtualCameraTest.kt
index 01c6aac..75a220d 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/VirtualCameraTest.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/VirtualCameraTest.kt
@@ -20,10 +20,13 @@
 import android.os.Build
 import android.os.Looper.getMainLooper
 import androidx.camera.camera2.pipe.CameraError
+import androidx.camera.camera2.pipe.CameraId
 import androidx.camera.camera2.pipe.core.SystemTimeSource
 import androidx.camera.camera2.pipe.core.TimeSource
 import androidx.camera.camera2.pipe.core.Timestamps
 import androidx.camera.camera2.pipe.core.Token
+import androidx.camera.camera2.pipe.graph.GraphListener
+import androidx.camera.camera2.pipe.internal.CameraErrorListener
 import androidx.camera.camera2.pipe.testing.RobolectricCameraPipeTestRunner
 import androidx.camera.camera2.pipe.testing.RobolectricCameras
 import com.google.common.truth.Truth.assertThat
@@ -39,6 +42,7 @@
 import org.junit.After
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
 import org.robolectric.Shadows.shadowOf
 import org.robolectric.annotation.Config
 
@@ -49,6 +53,8 @@
     private val mainLooper = shadowOf(getMainLooper())
     private val cameraId = RobolectricCameras.create()
     private val testCamera = RobolectricCameras.open(cameraId)
+    private val graphListener: GraphListener = mock()
+    private val cameraErrorListener: CameraErrorListener = mock()
 
     @After
     fun teardown() {
@@ -60,7 +66,7 @@
     fun virtualCameraStateCanBeDisconnected() = runTest {
         // This test asserts that the virtual camera starts in an unopened state and is changed to
         // "Closed" when disconnect is invoked on the VirtualCamera.
-        val virtualCamera = VirtualCameraState(cameraId)
+        val virtualCamera = VirtualCameraState(cameraId, graphListener)
         assertThat(virtualCamera.value).isInstanceOf(CameraStateUnopened::class.java)
 
         virtualCamera.disconnect()
@@ -84,12 +90,15 @@
         // This test asserts that when a virtual camera is connected to a flow of CameraState
         // changes that it receives those changes and can be subsequently disconnected, which stops
         // additional events from being passed to the virtual camera instance.
-        val virtualCamera = VirtualCameraState(cameraId)
+        val virtualCamera = VirtualCameraState(cameraId, graphListener)
         val cameraState =
             flowOf(
                 CameraStateOpen(
                     AndroidCameraDevice(
-                        testCamera.metadata, testCamera.cameraDevice, testCamera.cameraId
+                        testCamera.metadata,
+                        testCamera.cameraDevice,
+                        testCamera.cameraId,
+                        cameraErrorListener,
                     )
                 )
             )
@@ -116,12 +125,15 @@
     fun virtualCameraStateRespondsToClose() = runTest {
         // This tests that a listener attached to the virtualCamera.state property will receive all
         // of the events, starting from CameraStateUnopened.
-        val virtualCamera = VirtualCameraState(cameraId)
+        val virtualCamera = VirtualCameraState(cameraId, graphListener)
         val states =
             listOf(
                 CameraStateOpen(
                     AndroidCameraDevice(
-                        testCamera.metadata, testCamera.cameraDevice, testCamera.cameraId
+                        testCamera.metadata,
+                        testCamera.cameraDevice,
+                        testCamera.cameraId,
+                        cameraErrorListener,
                     )
                 ),
                 CameraStateClosing(),
@@ -159,6 +171,19 @@
     private val testCamera = RobolectricCameras.open(cameraId)
     private val timeSource: TimeSource = SystemTimeSource()
     private val now = Timestamps.now(timeSource)
+    private val cameraErrorListener = object : CameraErrorListener {
+        var lastCameraId: CameraId? = null
+        var lastCameraError: CameraError? = null
+
+        override fun onCameraError(
+            cameraId: CameraId,
+            cameraError: CameraError,
+            willAttemptRetry: Boolean
+        ) {
+            lastCameraId = cameraId
+            lastCameraError = cameraError
+        }
+    }
 
     @After
     fun teardown() {
@@ -174,7 +199,8 @@
                 testCamera.metadata,
                 attemptNumber = 1,
                 attemptTimestampNanos = now,
-                timeSource
+                timeSource,
+                cameraErrorListener
             )
 
         assertThat(listener.state.value).isInstanceOf(CameraStateUnopened.javaClass)
@@ -219,7 +245,8 @@
                 testCamera.metadata,
                 attemptNumber = 1,
                 attemptTimestampNanos = now,
-                timeSource
+                timeSource,
+                cameraErrorListener
             )
 
         listener.onDisconnected(testCamera.cameraDevice)
@@ -240,7 +267,8 @@
                 testCamera.metadata,
                 attemptNumber = 1,
                 attemptTimestampNanos = now,
-                timeSource
+                timeSource,
+                cameraErrorListener
             )
 
         listener.close()
@@ -258,7 +286,8 @@
                 testCamera.metadata,
                 attemptNumber = 1,
                 attemptTimestampNanos = now,
-                timeSource
+                timeSource,
+                cameraErrorListener
             )
 
         listener.closeWith(IllegalArgumentException("Test Exception"))
@@ -276,7 +305,8 @@
                 testCamera.metadata,
                 attemptNumber = 1,
                 attemptTimestampNanos = now,
-                timeSource
+                timeSource,
+                cameraErrorListener
             )
 
         listener.onError(testCamera.cameraDevice, CameraDevice.StateCallback.ERROR_CAMERA_SERVICE)
@@ -287,4 +317,44 @@
         assertThat(closedState.cameraErrorCode).isEqualTo(CameraError.ERROR_CAMERA_SERVICE)
         assertThat(closedState.cameraException).isNull()
     }
+
+    @Test
+    fun errorCodesAreReportedToGraphListener() {
+        val listener =
+            AndroidCameraState(
+                testCamera.cameraId,
+                testCamera.metadata,
+                attemptNumber = 1,
+                attemptTimestampNanos = now,
+                timeSource,
+                cameraErrorListener
+            )
+
+        listener.onOpened(testCamera.cameraDevice)
+        listener.onError(testCamera.cameraDevice, CameraDevice.StateCallback.ERROR_CAMERA_SERVICE)
+        mainLooper.idle()
+        assertThat(cameraErrorListener.lastCameraId).isEqualTo(testCamera.cameraId)
+        assertThat(cameraErrorListener.lastCameraError).isEqualTo(CameraError.ERROR_CAMERA_SERVICE)
+    }
+
+    @Test
+    fun errorCodesAreReportedToGraphListenerWhenCameraIsNotOpened() {
+        // Unless this is a camera open exception, all errors should be reported even if camera is
+        // not opened. The main reason is CameraAccessException.CAMERA_ERROR, where under which, we
+        // only know the nature of the error true onError(), and we should and would report that.
+        val listener =
+            AndroidCameraState(
+                testCamera.cameraId,
+                testCamera.metadata,
+                attemptNumber = 1,
+                attemptTimestampNanos = now,
+                timeSource,
+                cameraErrorListener
+            )
+
+        listener.onError(testCamera.cameraDevice, CameraDevice.StateCallback.ERROR_CAMERA_SERVICE)
+        mainLooper.idle()
+        assertThat(cameraErrorListener.lastCameraId).isEqualTo(testCamera.cameraId)
+        assertThat(cameraErrorListener.lastCameraError).isEqualTo(CameraError.ERROR_CAMERA_SERVICE)
+    }
 }
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCameraController.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCameraController.kt
index c49f98a..c8a6aa8 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCameraController.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCameraController.kt
@@ -19,6 +19,7 @@
 import android.view.Surface
 import androidx.camera.camera2.pipe.CameraController
 import androidx.camera.camera2.pipe.CameraId
+import androidx.camera.camera2.pipe.CameraStatusMonitor
 import androidx.camera.camera2.pipe.StreamId
 
 internal class FakeCameraController : CameraController {
@@ -36,7 +37,7 @@
         started = false
     }
 
-    override fun tryRestart() {
+    override fun tryRestart(cameraStatus: CameraStatusMonitor.CameraStatus) {
         stop()
         start()
     }
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCameraDeviceWrapper.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCameraDeviceWrapper.kt
index 33c7946..76333bd 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCameraDeviceWrapper.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCameraDeviceWrapper.kt
@@ -61,12 +61,14 @@
         outputs: List<Surface>,
         stateCallback: CameraCaptureSessionWrapper.StateCallback,
         handler: Handler?
-    ) {
+    ): Boolean {
         createFakeCaptureSession(stateCallback)
+        return true
     }
 
-    override fun createCaptureSession(config: SessionConfigData) {
+    override fun createCaptureSession(config: SessionConfigData): Boolean {
         createFakeCaptureSession(config.stateCallback)
+        return true
     }
 
     override fun createReprocessableCaptureSession(
@@ -74,24 +76,27 @@
         outputs: List<Surface>,
         stateCallback: CameraCaptureSessionWrapper.StateCallback,
         handler: Handler?
-    ) {
+    ): Boolean {
         createFakeCaptureSession(stateCallback)
+        return true
     }
 
     override fun createConstrainedHighSpeedCaptureSession(
         outputs: List<Surface>,
         stateCallback: CameraCaptureSessionWrapper.StateCallback,
         handler: Handler?
-    ) {
+    ): Boolean {
         createFakeCaptureSession(stateCallback)
+        return true
     }
 
     override fun createCaptureSessionByOutputConfigurations(
         outputConfigurations: List<OutputConfigurationWrapper>,
         stateCallback: CameraCaptureSessionWrapper.StateCallback,
         handler: Handler?
-    ) {
+    ): Boolean {
         createFakeCaptureSession(stateCallback)
+        return true
     }
 
     override fun createReprocessableCaptureSessionByConfigurations(
@@ -99,8 +104,9 @@
         outputs: List<OutputConfigurationWrapper>,
         stateCallback: CameraCaptureSessionWrapper.StateCallback,
         handler: Handler?
-    ) {
+    ): Boolean {
         createFakeCaptureSession(stateCallback)
+        return true
     }
 
     override fun onDeviceClosed() {
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCaptureSessionWrapper.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCaptureSessionWrapper.kt
index 9688607e..bc4d75d 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCaptureSessionWrapper.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCaptureSessionWrapper.kt
@@ -43,8 +43,9 @@
 
     val unwrappedClasses = arrayListOf<Any>()
 
-    override fun abortCaptures() {
+    override fun abortCaptures(): Boolean {
         abortCapturesInvoked = true
+        return true
     }
 
     override fun capture(
@@ -95,11 +96,14 @@
         return lastSequenceNumber
     }
 
-    override fun stopRepeating() {
+    override fun stopRepeating(): Boolean {
         stopRepeatingInvoked = true
+        return true
     }
 
-    override fun finalizeOutputConfigurations(outputConfigs: List<OutputConfigurationWrapper>) {
+    override fun finalizeOutputConfigurations(
+        outputConfigs: List<OutputConfigurationWrapper>
+    ): Boolean {
         throw UnsupportedOperationException("finalizeOutputConfigurations is not supported")
     }
 
diff --git a/camera/camera-core/api/current.txt b/camera/camera-core/api/current.txt
index 1f0d922..c0b6511 100644
--- a/camera/camera-core/api/current.txt
+++ b/camera/camera-core/api/current.txt
@@ -322,7 +322,7 @@
   }
 
   public static interface ImageProcessor.Response {
-    method public androidx.camera.core.ImageProxy? getOutputImage();
+    method public androidx.camera.core.ImageProxy getOutputImage();
   }
 
   @RequiresApi(21) public interface ImageProxy extends java.lang.AutoCloseable {
diff --git a/camera/camera-core/api/public_plus_experimental_current.txt b/camera/camera-core/api/public_plus_experimental_current.txt
index 38b65a3..6b1ce03 100644
--- a/camera/camera-core/api/public_plus_experimental_current.txt
+++ b/camera/camera-core/api/public_plus_experimental_current.txt
@@ -338,7 +338,7 @@
   }
 
   public static interface ImageProcessor.Response {
-    method public androidx.camera.core.ImageProxy? getOutputImage();
+    method public androidx.camera.core.ImageProxy getOutputImage();
   }
 
   @RequiresApi(21) public interface ImageProxy extends java.lang.AutoCloseable {
diff --git a/camera/camera-core/api/restricted_current.txt b/camera/camera-core/api/restricted_current.txt
index 1f0d922..c0b6511 100644
--- a/camera/camera-core/api/restricted_current.txt
+++ b/camera/camera-core/api/restricted_current.txt
@@ -322,7 +322,7 @@
   }
 
   public static interface ImageProcessor.Response {
-    method public androidx.camera.core.ImageProxy? getOutputImage();
+    method public androidx.camera.core.ImageProxy getOutputImage();
   }
 
   @RequiresApi(21) public interface ImageProxy extends java.lang.AutoCloseable {
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageProcessor.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageProcessor.java
index edc19bb..75f9cf2 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageProcessor.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageProcessor.java
@@ -20,7 +20,6 @@
 
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 
 import java.lang.annotation.Retention;
@@ -92,7 +91,6 @@
      * Valid output formats.
      *
      * <p>{@link Request#getOutputFormat()} can only return the formats defined by this annotation.
-     *
      */
     @Retention(RetentionPolicy.SOURCE)
     @RestrictTo(RestrictTo.Scope.LIBRARY)
@@ -162,7 +160,7 @@
          *
          * @return the output image.
          */
-        @Nullable
+        @NonNull
         ImageProxy getOutputImage();
     }
 }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageSaver.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageSaver.java
index a43a5e2..e1f0dbc 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageSaver.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageSaver.java
@@ -111,8 +111,11 @@
         try {
             if (isSaveToFile()) {
                 // For saving to file, write to the target folder and rename for better performance.
+                // The file extensions must be the same as app provided to avoid the directory
+                // access problem.
                 tempFile = new File(mOutputFileOptions.getFile().getParent(),
-                        TEMP_FILE_PREFIX + UUID.randomUUID().toString() + TEMP_FILE_SUFFIX);
+                        TEMP_FILE_PREFIX + UUID.randomUUID().toString()
+                                + getFileExtensionWithDot(mOutputFileOptions.getFile()));
             } else {
                 tempFile = File.createTempFile(TEMP_FILE_PREFIX, TEMP_FILE_SUFFIX);
             }
@@ -185,6 +188,16 @@
         return tempFile;
     }
 
+    private static String getFileExtensionWithDot(File file) {
+        String fileName = file.getName();
+        int dotIndex = fileName.lastIndexOf('.');
+        if (dotIndex >= 0) {
+            return fileName.substring(dotIndex);
+        } else {
+            return "";
+        }
+    }
+
     @NonNull
     private byte[] imageToJpegByteArray(@NonNull ImageProxy image, @IntRange(from = 1,
             to = 100) int jpegQuality) throws CodecFailedException {
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/JpegBytes2Disk.java b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/JpegBytes2Disk.java
index 1bdaceb..142985f 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/JpegBytes2Disk.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/JpegBytes2Disk.java
@@ -81,9 +81,11 @@
             File appProvidedFile = options.getFile();
             if (appProvidedFile != null) {
                 // For saving-to-file case, write to the target folder and rename for better
-                // performance.
+                // performance. The file extensions must be the same as app provided to avoid the
+                // directory access problem.
                 return new File(appProvidedFile.getParent(),
-                        TEMP_FILE_PREFIX + UUID.randomUUID().toString() + TEMP_FILE_SUFFIX);
+                        TEMP_FILE_PREFIX + UUID.randomUUID().toString()
+                                + getFileExtensionWithDot(appProvidedFile));
             } else {
                 return File.createTempFile(TEMP_FILE_PREFIX, TEMP_FILE_SUFFIX);
             }
@@ -92,6 +94,16 @@
         }
     }
 
+    private static String getFileExtensionWithDot(File file) {
+        String fileName = file.getName();
+        int dotIndex = fileName.lastIndexOf('.');
+        if (dotIndex >= 0) {
+            return fileName.substring(dotIndex);
+        } else {
+            return "";
+        }
+    }
+
     /**
      * Writes byte array to the given {@link File}.
      */
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 932e71a..17c29ae 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
@@ -21,6 +21,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
+import androidx.camera.core.DynamicRange;
 
 import com.google.auto.value.AutoValue;
 
@@ -45,6 +46,13 @@
     public abstract Size getResolution();
 
     /**
+     * Returns the {@link DynamicRange} for the stream associated with this stream specification.
+     * @return the dynamic range for the stream.
+     */
+    @NonNull
+    public abstract DynamicRange getDynamicRange();
+
+    /**
      * Returns the expected frame rate range for the stream associated with this stream
      * specification.
      * @return the expected frame rate range for the stream.
@@ -57,7 +65,8 @@
     public static Builder builder(@NonNull Size resolution) {
         return new AutoValue_StreamSpec.Builder()
                 .setResolution(resolution)
-                .setExpectedFrameRateRange(FRAME_RATE_RANGE_UNSPECIFIED);
+                .setExpectedFrameRateRange(FRAME_RATE_RANGE_UNSPECIFIED)
+                .setDynamicRange(DynamicRange.SDR);
     }
 
     /** Returns a builder pre-populated with the current specification. */
@@ -76,6 +85,14 @@
         public abstract Builder setResolution(@NonNull Size resolution);
 
         /**
+         * Sets the dynamic range.
+         *
+         * <p>If not set, the default dynamic range is {@link DynamicRange#SDR}.
+         */
+        @NonNull
+        public abstract Builder setDynamicRange(@NonNull DynamicRange dynamicRange);
+
+        /**
          * Sets the expected frame rate range.
          *
          * <p>If not set, the default expected frame rate range is
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/internal/SupportedOutputSizesSorter.java b/camera/camera-core/src/main/java/androidx/camera/core/internal/SupportedOutputSizesSorter.java
index 2a84e43..62baa3e 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/internal/SupportedOutputSizesSorter.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/internal/SupportedOutputSizesSorter.java
@@ -258,6 +258,10 @@
             resolutionCandidateList = mCameraInfoInternal.getSupportedResolutions(imageFormat);
         }
 
+        // CameraInfoInternal.getSupportedResolutions is not guaranteed to return a modifiable list
+        // needed by Collections.sort(), so it is converted to a modifiable list here
+        resolutionCandidateList = new ArrayList<>(resolutionCandidateList);
+
         Collections.sort(resolutionCandidateList, new CompareSizesByArea(true));
 
         return resolutionCandidateList;
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 6142527..fee7f3e 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
@@ -19,6 +19,7 @@
 import android.os.Build
 import android.util.Range
 import android.util.Size
+import androidx.camera.core.DynamicRange
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -38,6 +39,20 @@
         assertThat(streamSpec.resolution).isEqualTo(TEST_RESOLUTION)
     }
 
+    fun defaultDynamicRangeIsSdr() {
+        val streamSpec = StreamSpec.builder(TEST_RESOLUTION).build()
+
+        assertThat(streamSpec.dynamicRange).isEqualTo(DynamicRange.SDR)
+    }
+
+    @Test
+    fun canRetrieveDynamicRange() {
+        val dynamicRange = DynamicRange(DynamicRange.FORMAT_HLG, DynamicRange.BIT_DEPTH_10_BIT)
+        val streamSpec = StreamSpec.builder(TEST_RESOLUTION).setDynamicRange(dynamicRange).build()
+
+        assertThat(streamSpec.dynamicRange).isEqualTo(dynamicRange)
+    }
+
     @Test
     fun defaultExpectedFrameRateRangeIsUnspecified() {
         val streamSpec = StreamSpec.builder(TEST_RESOLUTION).build()
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/internal/SupportedOutputSizesSorterTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/internal/SupportedOutputSizesSorterTest.kt
index 96211ee..ffbbada 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/internal/SupportedOutputSizesSorterTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/internal/SupportedOutputSizesSorterTest.kt
@@ -37,6 +37,7 @@
 import androidx.camera.testing.fakes.FakeUseCaseConfig
 import com.google.common.truth.Truth.assertThat
 import java.util.Collections
+import java.util.Collections.unmodifiableList
 import org.junit.Assert.assertThrows
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -519,6 +520,23 @@
         }
     }
 
+    @Test
+    fun getSortedSupportedOutputSizesReturns_whenCameraInfoProvidesUnmodifiableList() {
+        // Arrange
+        val imageFormat = ImageFormat.JPEG
+        val cameraInfoInternal = FakeCameraInfoInternal().apply {
+            setSupportedResolutions(imageFormat, unmodifiableList(DEFAULT_SUPPORTED_SIZES))
+        }
+        val supportedOutputSizesSorter =
+            SupportedOutputSizesSorter(cameraInfoInternal, LANDSCAPE_ACTIVE_ARRAY_SIZE)
+        // Sets up a no-op useCaseConfig
+        val useCaseConfig =
+            FakeUseCaseConfig.Builder(CaptureType.IMAGE_CAPTURE, imageFormat).useCaseConfig
+
+        // Act & Assert
+        supportedOutputSizesSorter.getSortedSupportedOutputSizes(useCaseConfig)
+    }
+
     private fun verifySupportedOutputSizesWithResolutionSelectorSettings(
         outputSizesSorter: SupportedOutputSizesSorter = supportedOutputSizesSorter,
         captureType: CaptureType = CaptureType.IMAGE_CAPTURE,
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/mocks/MockConsumer.java b/camera/camera-testing/src/main/java/androidx/camera/testing/mocks/MockConsumer.java
index cdd4e39..575215b 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/mocks/MockConsumer.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/mocks/MockConsumer.java
@@ -183,11 +183,11 @@
         mClassTypeToVerify = classType;
         mCallTimes = callTimes;
         mInOrder = inOrder;
-        snapshotVerifyingEventList();
 
         CountDownLatch latch = null;
         boolean isVerified;
         synchronized (mLock) {
+            snapshotVerifyingEventList();
             isVerified = isVerified();
             if (!isVerified && timeoutInMillis != NO_TIMEOUT) {
                 latch = mLatch = new CountDownLatch(1);
diff --git a/camera/camera-video/lint-baseline.xml b/camera/camera-video/lint-baseline.xml
index 29d2664..e8b6b9c 100644
--- a/camera/camera-video/lint-baseline.xml
+++ b/camera/camera-video/lint-baseline.xml
@@ -25,7 +25,7 @@
         errorLine1="                Thread.sleep(TimeUnit.NANOSECONDS.toMillis(requiredBlockTimeNs));"
         errorLine2="                       ~~~~~">
         <location
-            file="src/main/java/androidx/camera/video/internal/SilentAudioStream.java"/>
+            file="src/main/java/androidx/camera/video/internal/audio/SilentAudioStream.java"/>
     </issue>
 
     <issue
diff --git a/camera/camera-video/src/test/java/androidx/camera/video/internal/audio/AudioSourceTest.kt b/camera/camera-video/src/test/java/androidx/camera/video/internal/audio/AudioSourceTest.kt
index abf4d68..72e1075 100644
--- a/camera/camera-video/src/test/java/androidx/camera/video/internal/audio/AudioSourceTest.kt
+++ b/camera/camera-video/src/test/java/androidx/camera/video/internal/audio/AudioSourceTest.kt
@@ -33,14 +33,12 @@
 import java.util.concurrent.Executor
 import java.util.concurrent.TimeUnit.NANOSECONDS
 import org.junit.After
-import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.robolectric.RobolectricTestRunner
 import org.robolectric.annotation.Config
 import org.robolectric.annotation.internal.DoNotInstrument
 
-@Ignore("b/274840083")
 @RunWith(RobolectricTestRunner::class)
 @DoNotInstrument
 @Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
@@ -98,7 +96,6 @@
         audioStream.verifyStopCall(CallTimes(1), COMMON_TIMEOUT_MS)
     }
 
-    @Ignore("b/273963265")
     @Test
     fun release_AudioStreamIsReleased() {
         // Arrange
@@ -153,7 +150,6 @@
         }
     }
 
-    @Ignore("b/274588483")
     @Test
     fun bufferProviderBecomeActive_startSendingAudio() {
         // Arrange.
@@ -202,7 +198,6 @@
         audioStream.verifyStopCall(CallTimes(1), COMMON_TIMEOUT_MS)
     }
 
-    @Ignore // b/273534749
     @Test
     fun canReceiveSilence() {
         // Arrange.
diff --git a/camera/integration-tests/avsynctestapp/lint-baseline.xml b/camera/integration-tests/avsynctestapp/lint-baseline.xml
deleted file mode 100644
index c66a07a..0000000
--- a/camera/integration-tests/avsynctestapp/lint-baseline.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-alpha05" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-alpha05)" variant="all" version="8.0.0-alpha05">
-
-    <issue
-        id="PermissionImpliesUnsupportedChromeOsHardware"
-        message="Permission exists without corresponding hardware `&lt;uses-feature android:name=&quot;android.hardware.camera.autofocus&quot; required=&quot;false&quot;>` tag"
-        errorLine1="    &lt;uses-permission android:name=&quot;android.permission.CAMERA&quot; />"
-        errorLine2="     ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/AndroidManifest.xml"/>
-    </issue>
-
-</issues>
diff --git a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ImageCaptureTest.kt b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ImageCaptureTest.kt
index c8c1d21..d3ce6bf 100644
--- a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ImageCaptureTest.kt
+++ b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ImageCaptureTest.kt
@@ -315,6 +315,17 @@
         canSaveToFile(saveLocation)
     }
 
+    @Test
+    fun saveCanSucceed_toExternalStoragePublicFolderFile() {
+        val pictureFolder = Environment.getExternalStoragePublicDirectory(
+            Environment.DIRECTORY_PICTURES
+        )
+        assumeTrue(pictureFolder.exists())
+        val saveLocation = File(pictureFolder, "test.jpg")
+        canSaveToFile(saveLocation)
+        saveLocation.delete()
+    }
+
     private fun canSaveToFile(saveLocation: File) = runBlocking {
         val useCase = defaultBuilder.build()
         withContext(Dispatchers.Main) {
diff --git a/camera/integration-tests/coretestapp/src/main/AndroidManifest.xml b/camera/integration-tests/coretestapp/src/main/AndroidManifest.xml
index c313041..5e483e9 100644
--- a/camera/integration-tests/coretestapp/src/main/AndroidManifest.xml
+++ b/camera/integration-tests/coretestapp/src/main/AndroidManifest.xml
@@ -14,8 +14,11 @@
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
 
+    <!-- Enable requestLegacyExternalStorage for Android 10 saving to direct media file test
+         This value is ignore after targeting Android 11 -->
     <application
         android:supportsRtl="true"
+        android:requestLegacyExternalStorage="true"
         android:theme="@style/AppTheme">
         <activity
             android:name=".ConcurrentCameraActivity"
diff --git a/camera/integration-tests/diagnosetestapp/lint-baseline.xml b/camera/integration-tests/diagnosetestapp/lint-baseline.xml
deleted file mode 100644
index 715b1e4..0000000
--- a/camera/integration-tests/diagnosetestapp/lint-baseline.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-alpha05" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-alpha05)" variant="all" version="8.0.0-alpha05">
-
-    <issue
-        id="PermissionImpliesUnsupportedChromeOsHardware"
-        message="Permission exists without corresponding hardware `&lt;uses-feature android:name=&quot;android.hardware.camera&quot; required=&quot;false&quot;>` tag"
-        errorLine1="    &lt;uses-permission android:name=&quot;android.permission.CAMERA&quot; />"
-        errorLine2="     ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/AndroidManifest.xml"/>
-    </issue>
-
-</issues>
diff --git a/camera/integration-tests/extensionstestapp/lint-baseline.xml b/camera/integration-tests/extensionstestapp/lint-baseline.xml
deleted file mode 100644
index c66a07a..0000000
--- a/camera/integration-tests/extensionstestapp/lint-baseline.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-alpha05" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-alpha05)" variant="all" version="8.0.0-alpha05">
-
-    <issue
-        id="PermissionImpliesUnsupportedChromeOsHardware"
-        message="Permission exists without corresponding hardware `&lt;uses-feature android:name=&quot;android.hardware.camera.autofocus&quot; required=&quot;false&quot;>` tag"
-        errorLine1="    &lt;uses-permission android:name=&quot;android.permission.CAMERA&quot; />"
-        errorLine2="     ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/AndroidManifest.xml"/>
-    </issue>
-
-</issues>
diff --git a/camera/integration-tests/uiwidgetstestapp/lint-baseline.xml b/camera/integration-tests/uiwidgetstestapp/lint-baseline.xml
deleted file mode 100644
index d2a1aa6..0000000
--- a/camera/integration-tests/uiwidgetstestapp/lint-baseline.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-alpha05" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-alpha05)" variant="all" version="8.0.0-alpha05">
-
-    <issue
-        id="PermissionImpliesUnsupportedChromeOsHardware"
-        message="Permission exists without corresponding hardware `&lt;uses-feature android:name=&quot;android.hardware.camera&quot; required=&quot;false&quot;>` tag"
-        errorLine1="    &lt;uses-permission android:name=&quot;android.permission.CAMERA&quot; />"
-        errorLine2="     ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/AndroidManifest.xml"/>
-    </issue>
-
-    <issue
-        id="PermissionImpliesUnsupportedChromeOsHardware"
-        message="Permission exists without corresponding hardware `&lt;uses-feature android:name=&quot;android.hardware.camera.autofocus&quot; required=&quot;false&quot;>` tag"
-        errorLine1="    &lt;uses-permission android:name=&quot;android.permission.CAMERA&quot; />"
-        errorLine2="     ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/AndroidManifest.xml"/>
-    </issue>
-
-</issues>
diff --git a/camera/integration-tests/viewtestapp/lint-baseline.xml b/camera/integration-tests/viewtestapp/lint-baseline.xml
index d2a1aa6..715b1e4 100644
--- a/camera/integration-tests/viewtestapp/lint-baseline.xml
+++ b/camera/integration-tests/viewtestapp/lint-baseline.xml
@@ -10,13 +10,4 @@
             file="src/main/AndroidManifest.xml"/>
     </issue>
 
-    <issue
-        id="PermissionImpliesUnsupportedChromeOsHardware"
-        message="Permission exists without corresponding hardware `&lt;uses-feature android:name=&quot;android.hardware.camera.autofocus&quot; required=&quot;false&quot;>` tag"
-        errorLine1="    &lt;uses-permission android:name=&quot;android.permission.CAMERA&quot; />"
-        errorLine2="     ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/AndroidManifest.xml"/>
-    </issue>
-
 </issues>
diff --git a/car/app/app-automotive/build.gradle b/car/app/app-automotive/build.gradle
index d2c31fc..df11ac8 100644
--- a/car/app/app-automotive/build.gradle
+++ b/car/app/app-automotive/build.gradle
@@ -34,7 +34,7 @@
     // There is an implicit compile-only dep due to :annotation-experimental
     // Build will complain without this manual declaration.
     api(libs.kotlinStdlib)
-    implementation "androidx.annotation:annotation-experimental:1.2.0"
+    implementation "androidx.annotation:annotation-experimental:1.3.0"
 
     annotationProcessor(libs.nullaway)
     annotationProcessor(libs.autoValue)
diff --git a/car/app/app-automotive/lint-baseline.xml b/car/app/app-automotive/lint-baseline.xml
index 5840334..502b590 100644
--- a/car/app/app-automotive/lint-baseline.xml
+++ b/car/app/app-automotive/lint-baseline.xml
@@ -2,6 +2,114 @@
 <issues format="6" by="lint 7.4.0-alpha08" type="baseline" client="gradle" dependencies="false" name="AGP (7.4.0-alpha08)" variant="all" version="7.4.0-alpha08">
 
     <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                        Collections.singleton(CarZone.CAR_ZONE_GLOBAL)))"
+        errorLine2="                                                      ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/hardware/common/CarPropertyProfile.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                        fanDirectionValues.put(convertAreaIdToCarZones(CarZoneUtils.AreaType.SEAT,"
+        errorLine2="                                               ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/hardware/common/PropertyRequestProcessor.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                        fanDirectionValues.put(convertAreaIdToCarZones(CarZoneUtils.AreaType.SEAT,"
+        errorLine2="                                                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/hardware/common/PropertyRequestProcessor.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                        fanDirectionValues.put(convertAreaIdToCarZones(CarZoneUtils.AreaType.SEAT,"
+        errorLine2="                                                                                             ~~~~">
+        <location
+            file="src/main/java/androidx/car/app/hardware/common/PropertyRequestProcessor.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                            ? CarZoneUtils.AreaType.SEAT : CarZoneUtils.AreaType.NONE;"
+        errorLine2="                                                    ~~~~">
+        <location
+            file="src/main/java/androidx/car/app/hardware/common/PropertyRequestProcessor.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                            ? CarZoneUtils.AreaType.SEAT : CarZoneUtils.AreaType.NONE;"
+        errorLine2="                                                                                 ~~~~">
+        <location
+            file="src/main/java/androidx/car/app/hardware/common/PropertyRequestProcessor.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                            minMaxRange.put(convertAreaIdToCarZones(areaType,"
+        errorLine2="                                            ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/hardware/common/PropertyRequestProcessor.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                            minMaxRange.put(convertAreaIdToCarZones(areaType,"
+        errorLine2="                                                                    ~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/hardware/common/PropertyRequestProcessor.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                        carZones.add(convertAreaIdToCarZones(areaType, areaId));"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/hardware/common/PropertyRequestProcessor.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                        carZones.add(convertAreaIdToCarZones(areaType, areaId));"
+        errorLine2="                                                             ~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/hardware/common/PropertyRequestProcessor.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            append(HVAC_ELECTRIC_DEFROSTER_ON_PROPERTY_ID, CAR_PERMISSION_CLIMATE_CONTROL);"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/hardware/common/PropertyUtils.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            append(HVAC_ELECTRIC_DEFROSTER_ON_PROPERTY_ID, CAR_PERMISSION_CLIMATE_CONTROL);"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/hardware/common/PropertyUtils.java"/>
+    </issue>
+
+    <issue
         id="SupportAnnotationUsage"
         message="This annotation does not apply for type com.google.common.collect.ImmutableMap&lt;java.util.Set&lt;androidx.car.app.hardware.common.CarZone>,java.util.Set&lt;java.lang.Integer>>; expected int"
         errorLine1="    @HvacFanDirection"
diff --git a/car/app/app-samples/navigation/common/build.gradle b/car/app/app-samples/navigation/common/build.gradle
index 9ca8478..b7bb4a0 100644
--- a/car/app/app-samples/navigation/common/build.gradle
+++ b/car/app/app-samples/navigation/common/build.gradle
@@ -33,7 +33,7 @@
     implementation(project(":car:app:app"))
 
     implementation 'androidx.core:core:1.7.0'
-    implementation "androidx.annotation:annotation-experimental:1.2.0"
+    implementation "androidx.annotation:annotation-experimental:1.3.0"
     // There is an implicit compile-only dep due to :annotation-experimental
     // Build will complain without this manual declaration.
     compileOnly libs.kotlinStdlib
diff --git a/car/app/app-samples/showcase/common/build.gradle b/car/app/app-samples/showcase/common/build.gradle
index 4b61c864..fc49490 100644
--- a/car/app/app-samples/showcase/common/build.gradle
+++ b/car/app/app-samples/showcase/common/build.gradle
@@ -33,7 +33,7 @@
     debugImplementation(libs.leakcanary)
 
     implementation("androidx.core:core:1.7.0")
-    implementation "androidx.annotation:annotation-experimental:1.2.0"
+    implementation "androidx.annotation:annotation-experimental:1.3.0"
     // There is an implicit compile-only dep due to :annotation-experimental
     // Build will complain without this manual declaration.
     compileOnly libs.kotlinStdlib
diff --git a/car/app/app-samples/showcase/common/lint-baseline.xml b/car/app/app-samples/showcase/common/lint-baseline.xml
index 0af02f8..9975e85 100644
--- a/car/app/app-samples/showcase/common/lint-baseline.xml
+++ b/car/app/app-samples/showcase/common/lint-baseline.xml
@@ -10,4 +10,643 @@
             file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/listtemplates/DelayedFileProvider.java"/>
     </issue>
 
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            rowBuilder.addAction(action);"
+        errorLine2="                       ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/navigationdemos/MapTemplateWithListDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            rowBuilder.addAction(action);"
+        errorLine2="                       ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/navigationdemos/MapTemplateWithPaneDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                ConstraintManager.class).isAppDrivenRefreshEnabled();"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/navigationdemos/PlaceListNavigationTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                .addAction(action)"
+        errorLine2="                 ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/navigationdemos/RoutePreviewDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                .setNumericDecoration(numericDecoration)"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/listtemplates/SecondaryActionsAndDecorationDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                .addAction(action)"
+        errorLine2="                 ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/listtemplates/SecondaryActionsAndDecorationDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                .setNumericDecoration(numericDecoration)"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/listtemplates/SecondaryActionsAndDecorationDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                .addAction(action)"
+        errorLine2="                 ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/listtemplates/SecondaryActionsAndDecorationDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="        mTabTemplateBuilder = new TabTemplate.Builder(new TabTemplate.TabCallback() {"
+        errorLine2="                              ^">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="        mTabTemplateBuilder = new TabTemplate.Builder(new TabTemplate.TabCallback() {"
+        errorLine2="                                                      ^">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            public void onTabSelected(@NonNull String tabContentId) {"
+        errorLine2="                        ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="        }).setHeaderAction(APP_ICON);"
+        errorLine2="           ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="        }).setHeaderAction(APP_ICON);"
+        errorLine2="                           ~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            TabContents tabContents = new TabContents.Builder(contentTemplate).build();"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            TabContents tabContents = new TabContents.Builder(contentTemplate).build();"
+        errorLine2="                                                              ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            TabContents tabContents = new TabContents.Builder(contentTemplate).build();"
+        errorLine2="                                                                               ~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            Tab.Builder tabBuilder = new Tab.Builder()"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                    .setTitle(getCarContext().getString(TITLE_RES_IDS[i]))"
+        errorLine2="                     ~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                    .setTitle(getCarContext().getString(TITLE_RES_IDS[i]))"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                    .setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(),"
+        errorLine2="                     ~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                    .setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(),"
+        errorLine2="                             ^">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                    .setContentId(contentId);"
+        errorLine2="                     ~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                    .setContentId(contentId);"
+        errorLine2="                                  ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                tabBuilder.setActive(true);"
+        errorLine2="                           ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                mTabTemplateBuilder.setTabContents(tabContents);"
+        errorLine2="                                    ~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                mTabTemplateBuilder.setTabContents(tabContents);"
+        errorLine2="                                                   ~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                tabBuilder.setActive(true);"
+        errorLine2="                           ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                mTabTemplateBuilder.setTabContents(tabContents);"
+        errorLine2="                                    ~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                mTabTemplateBuilder.setTabContents(tabContents);"
+        errorLine2="                                                   ~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                tabBuilder.setActive(false);"
+        errorLine2="                           ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            Tab tab = tabBuilder.build();"
+        errorLine2="                                 ~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            mTabs.put(tab.getContentId(), tab);"
+        errorLine2="                          ~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            mTabTemplateBuilder.addTab(tab);"
+        errorLine2="                                ~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            mTabTemplateBuilder.addTab(tab);"
+        errorLine2="                                       ~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="        return mTabTemplateBuilder.build();"
+        errorLine2="                                   ~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                .addAction(createFabBackAction())"
+        errorLine2="                 ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                .addAction(createFabBackAction())"
+        errorLine2="                 ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="        mTabTemplateBuilder = new TabTemplate.Builder(new TabTemplate.TabCallback() {"
+        errorLine2="                              ^">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="        mTabTemplateBuilder = new TabTemplate.Builder(new TabTemplate.TabCallback() {"
+        errorLine2="                                                      ^">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            public void onTabSelected(@NonNull String tabContentId) {"
+        errorLine2="                        ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                .setHeaderAction(APP_ICON);"
+        errorLine2="                 ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                .setHeaderAction(APP_ICON);"
+        errorLine2="                                 ~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            Tab.Builder tabBuilder = new Tab.Builder()"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                    .setTitle(getCarContext().getString(sTitleResIds[i]))"
+        errorLine2="                     ~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                    .setTitle(getCarContext().getString(sTitleResIds[i]))"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                    .setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(),"
+        errorLine2="                     ~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                    .setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(),"
+        errorLine2="                             ^">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                    .setContentId(contentId);"
+        errorLine2="                     ~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                    .setContentId(contentId);"
+        errorLine2="                                  ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                tabBuilder.setActive(true);"
+        errorLine2="                           ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                tabBuilder.setActive(true);"
+        errorLine2="                           ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                tabBuilder.setActive(false);"
+        errorLine2="                           ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            Tab tab = tabBuilder.build();"
+        errorLine2="                                 ~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            mTabs.put(tab.getContentId(), tab);"
+        errorLine2="                          ~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            mTabTemplateBuilder.addTab(tab);"
+        errorLine2="                                ~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            mTabTemplateBuilder.addTab(tab);"
+        errorLine2="                                       ~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            if (tab.isActive()) {"
+        errorLine2="                    ~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                    mTabTemplateBuilder.setLoading(true);"
+        errorLine2="                                        ~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                    mTabTemplateBuilder.setTabContents(createSearchTab());"
+        errorLine2="                                        ~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                    mTabTemplateBuilder.setTabContents(createSearchTab());"
+        errorLine2="                                                       ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="        return mTabTemplateBuilder.build();"
+        errorLine2="                                   ~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="        return new TabContents.Builder(searchTemplate).build();"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="        return new TabContents.Builder(searchTemplate).build();"
+        errorLine2="                                       ~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="        return new TabContents.Builder(searchTemplate).build();"
+        errorLine2="                                                       ~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateLoadingDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="        mTabTemplateBuilder = new TabTemplate.Builder(new TabTemplate.TabCallback() {"
+        errorLine2="                              ^">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateNoTabsDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="        mTabTemplateBuilder = new TabTemplate.Builder(new TabTemplate.TabCallback() {"
+        errorLine2="                                                      ^">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateNoTabsDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="            public void onTabSelected(@NonNull String tabContentId) {"
+        errorLine2="                        ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateNoTabsDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                .setHeaderAction(APP_ICON)"
+        errorLine2="                 ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateNoTabsDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                .setHeaderAction(APP_ICON)"
+        errorLine2="                                 ~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateNoTabsDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="                .setLoading(true);"
+        errorLine2="                 ~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateNoTabsDemoScreen.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.car.app.annotations.ExperimentalCarApi` or `@OptIn(markerClass = androidx.car.app.annotations.ExperimentalCarApi.class)`"
+        errorLine1="        return mTabTemplateBuilder.build();"
+        errorLine2="                                   ~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/sample/showcase/common/screens/templatelayouts/tabtemplates/TabTemplateNoTabsDemoScreen.java"/>
+    </issue>
+
 </issues>
diff --git a/car/app/app/lint-baseline.xml b/car/app/app/lint-baseline.xml
index 1c92b5a..a185f3f 100644
--- a/car/app/app/lint-baseline.xml
+++ b/car/app/app/lint-baseline.xml
@@ -327,7 +327,7 @@
 
     <issue
         id="WrongConstant"
-        message="Must be one of: CarAppApiLevels.UNKNOWN, CarAppApiLevels.LEVEL_1, CarAppApiLevels.LEVEL_2, CarAppApiLevels.LEVEL_3, CarAppApiLevels.LEVEL_4, CarAppApiLevels.LEVEL_5, CarAppApiLevels.LEVEL_6"
+        message="Must be one of: CarAppApiLevels.UNKNOWN, CarAppApiLevels.LEVEL_1, CarAppApiLevels.LEVEL_2, CarAppApiLevels.LEVEL_3, CarAppApiLevels.LEVEL_4, CarAppApiLevels.LEVEL_5, CarAppApiLevels.LEVEL_6, CarAppApiLevels.LEVEL_7"
         errorLine1="        mCarAppApiLevel = handshakeInfo.getHostCarAppApiLevel();"
         errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -371,6 +371,15 @@
     </issue>
 
     <issue
+        id="PrivateConstructorForUtilityClass"
+        message="Utility class is missing private constructor"
+        errorLine1="class PersonsEqualityHelper {"
+        errorLine2="      ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/car/app/messaging/model/PersonsEqualityHelper.java"/>
+    </issue>
+
+    <issue
         id="SupportAnnotationUsage"
         message="This annotation does not apply for type java.util.List&lt;androidx.car.app.hardware.climate.CarClimateFeature>; expected int"
         errorLine1="    @ClimateProfileRequest.ClimateProfileFeature"
diff --git a/compose/compiler/compiler-hosted/lint-baseline.xml b/compose/compiler/compiler-hosted/lint-baseline.xml
index d3c6ed5..bf73059 100644
--- a/compose/compiler/compiler-hosted/lint-baseline.xml
+++ b/compose/compiler/compiler-hosted/lint-baseline.xml
@@ -2,12 +2,10 @@
 <issues format="6" by="lint 8.0.0-alpha05" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-alpha05)" variant="all" version="8.0.0-alpha05">
 
     <issue
-        id="ExperimentalPropertyAnnotation"
-        message="This property does not have all required annotations to correctly mark it as experimental."
-        errorLine1="    @ObsoleteDescriptorBasedAPI"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        id="LintError"
+        message="Unexpected failure during lint analysis (this is a bug in lint or one of the libraries it depends on)&#xA;&#xA;Message: Could not read file: /media/workspace/android/androidx-main/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin-compiler/1.8.10/kotlin-compiler-1.8.10.jar!/org/jetbrains/kotlin/ir/expressions/impl/IrSetFieldImpl.class; size in bytes: 5423; file type: CLASS&#xA;Stack: `IllegalStateException:VirtualFileKotlinClass$Factory.logFileReadingErrorMessage(VirtualFileKotlinClass.kt:77)←VirtualFileKotlinClass$Factory.access$logFileReadingErrorMessage(VirtualFileKotlinClass.kt:46)←VirtualFileKotlinClass$Factory$create$1.invoke(VirtualFileKotlinClass.kt:68)←VirtualFileKotlinClass$Factory$create$1.invoke(VirtualFileKotlinClass.kt:51)←PerformanceCounter.time(PerformanceCounter.kt:90)←VirtualFileKotlinClass$Factory.create$frontend_common_jvm(VirtualFileKotlinClass.kt:51)←KotlinBinaryClassCache$Companion.getKotlinBinaryClassOrClassFileContent$lambda$0(KotlinBinaryClassCache.kt:90)←MockApplication.runReadAction(MockApplication.java:193)←KotlinBinaryClassCache$Companion.getKotlinBinaryClassOrClassFileContent(KotlinBinaryClassCache.kt:89)←KotlinBinaryClassCache$Companion.getKotlinBinaryClassOrClassFileContent$default(KotlinBinaryClassCache.kt:73)←VirtualFileFinder.findKotlinClassOrContent(VirtualFileFinder.kt:37)←LazyJavaPackageScope$classes$1.invoke(LazyJavaPackageScope.kt:67)←LazyJavaPackageScope$classes$1.invoke(LazyJavaPackageScope.kt:59)←LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:578)←LazyJavaPackageScope.findClassifier(LazyJavaPackageScope.kt:146)←LazyJavaPackageScope.getContributedClassifier(LazyJavaPackageScope.kt:136)←JvmPackageScope.getContributedClassifier(JvmPackageScope.kt:55)←ChainedMemberScope.getContributedClassifier(ChainedMemberScope.kt:35)←AbstractScopeAdapter.getContributedClassifier(AbstractScopeAdapter.kt:44)←FindClassInModuleKt.findClassifierAcrossModuleDependencies(findClassInModule.kt:26)←TypeDeserializer.computeClassifierDescriptor(TypeDeserializer.kt:268)←TypeDeserializer.access$computeClassifierDescriptor(TypeDeserializer.kt:28)←TypeDeserializer$classifierDescriptors$1.invoke(TypeDeserializer.kt:37)←TypeDeserializer$classifierDescriptors$1.invoke(TypeDeserializer.kt:36)←LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:578)←TypeDeserializer.typeConstructor(TypeDeserializer.kt:161)←TypeDeserializer.simpleType(TypeDeserializer.kt:91)←TypeDeserializer.type(TypeDeserializer.kt:68)←MemberDeserializer.loadFunction(MemberDeserializer.kt:218)←DeserializedMemberScope$OptimizedImplementation.computeFunctions(DeserializedMemberScope.kt:276)←DeserializedMemberScope$OptimizedImplementation.access$computeFunctions(DeserializedMemberScope.kt:228)←DeserializedMemberScope$OptimizedImplementation$functions$1.invoke(DeserializedMemberScope.kt:251)←DeserializedMemberScope$OptimizedImplementation$functions$1.invoke(DeserializedMemberScope.kt:251)←LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:578)←LockBasedStorageManager$MapBasedMemoizedFunctionToNotNull.invoke(LockBasedStorageManager.java:651)←DeserializedMemberScope$OptimizedImplementation.getContributedFunctions(DeserializedMemberScope.kt:329)←DeserializedMemberScope.getContributedFunctions(DeserializedMemberScope.kt:82)←JvmPackageScope.getContributedFunctions(JvmPackageScope.kt:68)←ChainedMemberScope.getContributedFunctions(ChainedMemberScope.kt:41)←AbstractScopeAdapter.getContributedFunctions(AbstractScopeAdapter.kt:40)←LazyExplicitImportScope$getContributedFunctions$1.invoke(LazyExplicitImportScope.kt:54)←LazyExplicitImportScope$getContributedFunctions$1.invoke(LazyExplicitImportScope.kt:54)←LazyExplicitImportScope.collectCallableMemberDescriptors(LazyExplicitImportScope.kt:131)←LazyExplicitImportScope.getContributedFunctions(LazyExplicitImportScope.kt:54)←LazyImportScope$getContributedFunctions$1.invoke(LazyImportScope.kt:326)←LazyImportScope$getContributedFunctions$1.invoke(LazyImportScope.kt:326)←LazyImportResolver$collectFromImports$1.invoke(LazyImportScope.kt:121)←LazyImportResolver$collectFromImports$1.invoke(LazyImportScope.kt:118)←LockBasedStorageManager.compute(LockBasedStorageManager.java:290)←LazyImportResolver.collectFromImports(LazyImportScope.kt:118)←LazyImportScope.getContributedFunctions(LazyImportScope.kt:326)←TowerLevelsKt.getContributedFunctionsAndConstructors(TowerLevels.kt:474)←TowerLevelsKt.access$getContributedFunctionsAndConstructors(TowerLevels.kt:1)←ScopeBasedTowerLevel.getFunctions(TowerLevels.kt:361)←ScopeTowerProcessorsKt$createSimpleFunctionProcessor$1.invoke(ScopeTowerProcessors.kt:304)←ScopeTowerProcessorsKt$createSimpleFunctionProcessor$1.invoke(ScopeTowerProcessors.kt:304)←NoExplicitReceiverScopeTowerProcessor.simpleProcess(ScopeTowerProcessors.kt:201)←SimpleScopeTowerProcessor.process(ScopeTowerProcessors.kt:109)←PrioritizedCompositeScopeTowerProcessor.process(ScopeTowerProcessors.kt:41)←TowerResolver.processTowerData(TowerResolver.kt:383)←TowerResolver.access$processTowerData(TowerResolver.kt:95)←TowerResolver$Task.process(TowerResolver.kt:207)←TowerResolver$Task.processImplicitReceiver(TowerResolver.kt:342)←TowerResolver$Task.run$processLexicalScope(TowerResolver.kt:250)←TowerResolver$Task.run$processScopes(TowerResolver.kt:280)←TowerResolver$Task.run(TowerResolver.kt:305)←TowerResolver.run(TowerResolver.kt:114)←TowerResolver.runResolve(TowerResolver.kt:101)←KotlinCallResolver.resolveCall(KotlinCallResolver.kt:184)←KotlinCallResolver.resolveAndCompleteCall(KotlinCallResolver.kt:41)←PSICallResolver.runResolutionAndInference(PSICallResolver.kt:114)←CallResolver.doResolveCallOrGetCachedResults(CallResolver.java:602)←CallResolver.lambda$computeTasksAndResolveCall$0(CallResolver.java:213)←PerformanceCounter.time(PerformanceCounter.kt:90)←CallResolver.computeTasksAndResolveCall(CallResolver.java:211)←CallResolver.computeTasksAndResolveCall(CallResolver.java:199)←CallResolver.resolveFunctionCall(CallResolver.java:329)←CallExpressionResolver.getResolvedCallForFunction(CallExpressionResolver.kt:86)←CallExpressionResolver.getCallExpressionTypeInfoWithoutFinalTypeCheck(CallExpressionResolver.kt:208)←CallExpressionResolver.getCallExpressionTypeInfo(CallExpressionResolver.kt:185)←BasicExpressionTypingVisitor.visitCallExpression(BasicExpressionTypingVisitor.java:731)←ExpressionTypingVisitorDispatcher.visitCallExpression(ExpressionTypingVisitorDispatcher.java:396)←ExpressionTypingVisitorDispatcher$ForBlock.visitCallExpression(ExpressionTypingVisitorDispatcher.java:60)←KtCallExpression.accept(KtCallExpression.java:35)←ExpressionTypingVisitorDispatcher.lambda$getTypeInfo$0(ExpressionTypingVisitorDispatcher.java:176)←PerformanceCounter.time(PerformanceCounter.kt:90)←ExpressionTypingVisitorDispatcher.getTypeInfo(ExpressionTypingVisitorDispatcher.java:165)←ExpressionTypingVisitorDispatcher.getTypeInfo(ExpressionTypingVisitorDispatcher.java:135)←ExpressionTypingVisitorDispatcher.safeGetTypeInfo(ExpressionTypingVisitorDispatcher.java:123)←BasicExpressionTypingVisitor.visitUnaryExpression(BasicExpressionTypingVisitor.java:754)←ExpressionTypingVisitorDispatcher.visitUnaryExpression(ExpressionTypingVisitorDispatcher.java:401)←ExpressionTypingVisitorDispatcher$ForBlock.visitUnaryExpression(ExpressionTypingVisitorDispatcher.java:60)←KtVisitor.visitPrefixExpression(KtVisitor.java:210)←KtPrefixExpression.accept(KtPrefixExpression.java:31)←ExpressionTypingVisitorDispatcher.lambda$getTypeInfo$0(ExpressionTypingVisitorDispatcher.java:176)←PerformanceCounter.time(PerformanceCounter.kt:90)←ExpressionTypingVisitorDispatcher.getTypeInfo(ExpressionTypingVisitorDispatcher.java:165)←ExpressionTypingVisitorDispatcher.getTypeInfo(ExpressionTypingVisitorDispatcher.java:135)←ExpressionTypingVisitorForStatements.visitExpression(ExpressionTypingVisitorForStatements.java:543)←ExpressionTypingVisitorForStatements.visitExpression(ExpressionTypingVisitorForStatements.java:73)`&#xA;&#xA;You can run with --stacktrace or set environment variable `LINT_PRINT_STACKTRACE=true` to dump a full stacktrace to stdout.">
         <location
-            file="src/main/java/androidx/compose/compiler/plugins/kotlin/lower/AbstractComposeLowering.kt"/>
+            file="compiler-hosted"/>
     </issue>
 
 </issues>
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/VersionChecker.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/VersionChecker.kt
index 49ba87ca..1896f67 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/VersionChecker.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/VersionChecker.kt
@@ -110,6 +110,7 @@
             9700 to "1.4.0-rc01",
             9701 to "1.4.0-rc02",
             9701 to "1.5.0-alpha01",
+            9801 to "1.5.0-alpha02",
         )
 
         /**
@@ -122,7 +123,7 @@
          * The maven version string of this compiler. This string should be updated before/after every
          * release.
          */
-        const val compilerVersion: String = "1.4.4"
+        const val compilerVersion: String = "1.5.0-alpha02"
         private val minimumRuntimeVersion: String
             get() = runtimeVersionToMavenVersionTable[minimumRuntimeVersionInt] ?: "unknown"
     }
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 db95093..741ffe0 100644
--- a/compose/foundation/foundation-layout/api/public_plus_experimental_current.txt
+++ b/compose/foundation/foundation-layout/api/public_plus_experimental_current.txt
@@ -115,8 +115,8 @@
   }
 
   public final class FlowLayoutKt {
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable public static void FlowColumn(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, 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 void FlowRow(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional androidx.compose.ui.Alignment.Vertical verticalAlignment, 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 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 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);
   }
 
   public final class IntrinsicKt {
diff --git a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/FlowColumnSample.kt b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/FlowColumnSample.kt
index 83a2135..94be47c 100644
--- a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/FlowColumnSample.kt
+++ b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/FlowColumnSample.kt
@@ -48,14 +48,15 @@
             .wrapContentHeight(align = Alignment.Top)
             .requiredHeight(200.dp)
             .border(BorderStroke(2.dp, Color.Gray)),
-        horizontalAlignment = Alignment.CenterHorizontally,
+        horizontalArrangement = Arrangement.spacedBy(10.dp),
         verticalArrangement = Arrangement.Center,
         maxItemsInEachColumn = 3
     ) {
-        repeat(9) { index ->
+        repeat(10) { index ->
             Box(
                 Modifier
-                    .padding(10.dp)
+                    .align(Alignment.CenterHorizontally)
+                    .padding(top = 10.dp)
                     .width(50.dp)
                     .height(50.dp)
                     .background(color = Color.Green)
@@ -76,17 +77,18 @@
             .wrapContentHeight(align = Alignment.Top)
             .requiredHeight(200.dp)
             .border(BorderStroke(2.dp, Color.Gray)),
-        horizontalAlignment = Alignment.CenterHorizontally,
-        verticalArrangement = Arrangement.Top,
+        horizontalArrangement = Arrangement.spacedBy(10.dp),
+        verticalArrangement = Arrangement.Center,
         maxItemsInEachColumn = 3
     ) {
         repeat(10) { index ->
             Box(
                 Modifier
-                    .padding(10.dp)
+                    .align(Alignment.CenterHorizontally)
+                    .padding(top = 10.dp)
                     .width(50.dp)
                     .height(50.dp)
-                    .weight(if (index % 3 == 0) 1f else 2f, fill = true)
+                    .weight(if (index % 2 == 0) 1f else 2f, fill = true)
                     .background(color = Color.Green)
             )
         }
diff --git a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/FlowRowSample.kt b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/FlowRowSample.kt
index a3e87b9..9bc950c 100644
--- a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/FlowRowSample.kt
+++ b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/FlowRowSample.kt
@@ -17,12 +17,9 @@
 package androidx.compose.foundation.layout.samples
 
 import androidx.annotation.Sampled
-import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.background
-import androidx.compose.foundation.border
 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.fillMaxWidth
@@ -42,26 +39,23 @@
 @Sampled
 @Composable
 fun SimpleFlowRow() {
-    Column() {
-        FlowRow(
-            Modifier
-                .fillMaxWidth(1f)
-                .wrapContentHeight(align = Alignment.Top)
-                .border(BorderStroke(2.dp, Color.Gray)),
-            verticalAlignment = Alignment.CenterVertically,
-            horizontalArrangement = Arrangement.Start,
-            maxItemsInEachRow = 3
-        ) {
-            repeat(10) {
-                Box(
-                    Modifier
-                        .padding(10.dp)
-                        .width(50.dp)
-                        .height(50.dp)
-                        .background(Color.Green)
-                ) {
-                    Text(text = it.toString(), fontSize = 18.sp, modifier = Modifier.padding(3.dp))
-                }
+    FlowRow(
+        Modifier
+            .fillMaxWidth(1f)
+            .wrapContentHeight(align = Alignment.Top),
+        horizontalArrangement = Arrangement.spacedBy(10.dp),
+        verticalArrangement = Arrangement.spacedBy(20.dp),
+        maxItemsInEachRow = 3
+    ) {
+        repeat(10) {
+            Box(
+                Modifier
+                    .align(Alignment.CenterVertically)
+                    .width(50.dp)
+                    .height(50.dp)
+                    .background(Color.Green)
+            ) {
+                Text(text = it.toString(), fontSize = 18.sp, modifier = Modifier.padding(3.dp))
             }
         }
     }
@@ -71,25 +65,23 @@
 @Sampled
 @Composable
 fun SimpleFlowRowWithWeights() {
-    Column() {
-        FlowRow(
-            Modifier
-                .wrapContentHeight()
-                .fillMaxWidth(1f),
-            horizontalArrangement = Arrangement.Start,
-            verticalAlignment = Alignment.CenterVertically,
-            maxItemsInEachRow = 3
-        ) {
-            repeat(6) { index ->
-                Box(
-                    Modifier
-                        .padding(10.dp)
-                        .width(50.dp)
-                        .height(50.dp)
-                        .background(Color.Green)
-                        .weight(if (index % 3 == 0) 1f else 2f, fill = true)
-                )
-            }
+    FlowRow(
+        Modifier
+            .wrapContentHeight()
+            .fillMaxWidth(1f),
+        horizontalArrangement = Arrangement.spacedBy(10.dp),
+        verticalArrangement = Arrangement.spacedBy(20.dp),
+        maxItemsInEachRow = 3
+    ) {
+        repeat(6) { index ->
+            Box(
+                Modifier
+                    .align(Alignment.CenterVertically)
+                    .width(50.dp)
+                    .height(50.dp)
+                    .background(Color.Green)
+                    .weight(if (index % 2 == 0) 1f else 2f, fill = true)
+            )
         }
     }
 }
\ No newline at end of file
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 01f1756..39c2067 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
@@ -26,6 +26,7 @@
 import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth
@@ -51,7 +52,6 @@
                 Box(Modifier.size(100.toDp())) {
                     FlowRow(
                         Modifier
-                            .wrapContentHeight()
                             .onSizeChanged {
                                 height = it.height
                             }) {
@@ -76,7 +76,6 @@
                 Box(Modifier.size(100.toDp())) {
                     FlowColumn(
                         Modifier
-                            .wrapContentHeight()
                             .onSizeChanged {
                                 width = it.width
                             }) {
@@ -101,7 +100,6 @@
                 Box(Modifier.size(100.toDp())) {
                     FlowRow(
                         Modifier
-                            .wrapContentHeight()
                             .onSizeChanged {
                                 height = it.height
                             }) {
@@ -126,7 +124,6 @@
                 Box(Modifier.size(100.toDp())) {
                     FlowColumn(
                         Modifier
-                            .wrapContentHeight()
                             .onSizeChanged {
                                 width = it.width
                             }) {
@@ -151,7 +148,6 @@
                 Box(Modifier.size(60.toDp())) {
                     FlowRow(
                         Modifier
-                            .wrapContentHeight()
                             .onSizeChanged {
                                 height = it.height
                             }) {
@@ -176,7 +172,6 @@
                 Box(Modifier.size(60.toDp())) {
                     FlowColumn(
                         Modifier
-                            .wrapContentHeight()
                             .onSizeChanged {
                                 width = it.width
                             }) {
@@ -201,10 +196,10 @@
                 Box(Modifier.size(60.toDp())) {
                     FlowRow(
                         Modifier
-                            .wrapContentHeight()
                             .onSizeChanged {
                                 height = it.height
-                            }, maxItemsInEachRow = 2) {
+                            }, maxItemsInEachRow = 2
+                    ) {
                         repeat(6) {
                             Box(Modifier.size(20.toDp()))
                         }
@@ -226,10 +221,10 @@
                 Box(Modifier.size(60.toDp())) {
                     FlowColumn(
                         Modifier
-                            .wrapContentHeight()
                             .onSizeChanged {
                                 width = it.width
-                            }, maxItemsInEachColumn = 2) {
+                            }, maxItemsInEachColumn = 2
+                    ) {
                         repeat(6) {
                             Box(Modifier.size(20.toDp()))
                         }
@@ -251,15 +246,16 @@
                 Box(Modifier.size(60.toDp())) {
                     FlowRow(
                         Modifier
-                            .wrapContentHeight()
                             .onSizeChanged {
                                 height = it.height
-                            }, maxItemsInEachRow = 2) {
+                            }, maxItemsInEachRow = 2
+                    ) {
                         repeat(6) {
                             Box(
                                 Modifier
                                     .size(20.toDp())
-                                    .weight(1f, true))
+                                    .weight(1f, true)
+                            )
                         }
                     }
                 }
@@ -279,15 +275,16 @@
                 Box(Modifier.size(60.toDp())) {
                     FlowColumn(
                         Modifier
-                            .wrapContentHeight()
                             .onSizeChanged {
                                 width = it.width
-                            }, maxItemsInEachColumn = 2) {
+                            }, maxItemsInEachColumn = 2
+                    ) {
                         repeat(6) {
                             Box(
                                 Modifier
                                     .size(20.toDp())
-                                    .weight(1f, true))
+                                    .weight(1f, true)
+                            )
                         }
                     }
                 }
@@ -307,7 +304,6 @@
                 Box(Modifier.size(50.toDp())) {
                     FlowRow(
                         Modifier
-                            .wrapContentHeight()
                             .onSizeChanged {
                                 height = it.height
                             }) {
@@ -332,7 +328,6 @@
                 Box(Modifier.size(50.toDp())) {
                     FlowColumn(
                         Modifier
-                            .wrapContentHeight()
                             .onSizeChanged {
                                 width = it.width
                             }) {
@@ -357,7 +352,6 @@
                 Box(Modifier.size(50.toDp())) {
                     FlowRow(
                         Modifier
-                            .wrapContentHeight()
                             .onSizeChanged {
                                 height = it.height
                             }) {
@@ -382,7 +376,6 @@
                 Box(Modifier.size(50.toDp())) {
                     FlowColumn(
                         Modifier
-                            .wrapContentHeight()
                             .onSizeChanged {
                                 width = it.width
                             }) {
@@ -399,18 +392,60 @@
     }
 
     @Test
-    fun testFlowRow_centerVertically() {
+    fun testFlowRow_empty() {
+        var height = 0
+        var width = 0
+
+        rule.setContent {
+            Box(Modifier.size(100.dp)) {
+                FlowRow(
+                    Modifier
+                        .onSizeChanged {
+                            height = it.height
+                            width = it.width
+                        }) {
+                }
+            }
+        }
+
+        rule.waitForIdle()
+        Truth.assertThat(height).isEqualTo(0)
+        Truth.assertThat(width).isEqualTo(0)
+    }
+
+    @Test
+    fun testFlowColumn_empty() {
+        var height = 0
+        var width = 0
+
+        rule.setContent {
+            Box(Modifier.size(100.dp)) {
+                FlowColumn(
+                    Modifier
+                        .onSizeChanged {
+                            height = it.height
+                            width = it.width
+                        }) {
+                }
+            }
+        }
+
+        rule.waitForIdle()
+        Truth.assertThat(height).isEqualTo(0)
+        Truth.assertThat(width).isEqualTo(0)
+    }
+
+    @Test
+    fun testFlowRow_alignItemsDefaultsToLeft() {
 
         val totalRowHeight = 20
         val shorterHeight = 10
-        val expectedResult = (totalRowHeight - shorterHeight) / 2
+        val expectedResult = 0f
         var positionInParentY = 0f
         rule.setContent {
             with(LocalDensity.current) {
                 Box(Modifier.size(200.toDp())) {
-                    FlowRow(
-                        Modifier.wrapContentHeight(),
-                        verticalAlignment = Alignment.CenterVertically) {
+                    FlowRow() {
                         repeat(5) { index ->
                             Box(
                                 Modifier
@@ -439,7 +474,83 @@
     }
 
     @Test
-    fun testFlowColumn_centerHorizontally() {
+    fun testFlowRow_alignItemsCenterVertically() {
+
+        val totalRowHeight = 20
+        val shorterHeight = 10
+        val expectedResult = (totalRowHeight - shorterHeight) / 2
+        var positionInParentY = 0f
+        rule.setContent {
+            with(LocalDensity.current) {
+                Box(Modifier.size(200.toDp())) {
+                    FlowRow() {
+                        repeat(5) { index ->
+                            Box(
+                                Modifier
+                                    .align(Alignment.CenterVertically)
+                                    .size(
+                                        20.toDp(),
+                                        if (index == 4) {
+                                            shorterHeight.toDp()
+                                        } else {
+                                            totalRowHeight.toDp()
+                                        }
+                                    )
+                                    .onPlaced {
+                                        if (index == 4) {
+                                            val positionInParent = it.positionInParent()
+                                            positionInParentY = positionInParent.y
+                                        }
+                                    })
+                        }
+                    }
+                }
+            }
+        }
+
+        rule.waitForIdle()
+        Truth.assertThat(positionInParentY).isEqualTo(expectedResult)
+    }
+
+    @Test
+    fun testFlowColumn_alignItemsDefaultsToTop() {
+        val totalColumnWidth = 20
+        val shorterWidth = 10
+        val expectedResult = 0f
+        var positionInParentX = 0f
+        rule.setContent {
+            with(LocalDensity.current) {
+                Box(Modifier.size(200.toDp())) {
+                    FlowColumn() {
+                        repeat(5) { index ->
+                            Box(
+                                Modifier
+                                    .size(
+                                        if (index == 4) {
+                                            shorterWidth.toDp()
+                                        } else {
+                                            totalColumnWidth.toDp()
+                                        },
+                                        20.toDp()
+                                    )
+                                    .onPlaced {
+                                        if (index == 4) {
+                                            val positionInParent = it.positionInParent()
+                                            positionInParentX = positionInParent.x
+                                        }
+                                    })
+                        }
+                    }
+                }
+            }
+        }
+
+        rule.waitForIdle()
+        Truth.assertThat(positionInParentX).isEqualTo(expectedResult)
+    }
+
+    @Test
+    fun testFlowColumn_alignItemsCenterHorizontally() {
 
         val totalColumnWidth = 20
         val shorterWidth = 10
@@ -448,12 +559,11 @@
         rule.setContent {
             with(LocalDensity.current) {
                 Box(Modifier.size(200.toDp())) {
-                    FlowColumn(
-                        Modifier.wrapContentHeight(),
-                        horizontalAlignment = Alignment.CenterHorizontally) {
+                    FlowColumn() {
                         repeat(5) { index ->
                             Box(
                                 Modifier
+                                    .align(Alignment.CenterHorizontally)
                                     .size(
                                         if (index == 4) {
                                             shorterWidth.toDp()
@@ -494,8 +604,11 @@
         rule.setContent {
             with(LocalDensity.current) {
                 Box(Modifier.size(200.toDp())) {
-                    FlowRow(Modifier.wrapContentHeight().fillMaxWidth(1f),
-                        horizontalArrangement = Arrangement.SpaceAround) {
+                    FlowRow(
+                        Modifier
+                            .fillMaxWidth(1f),
+                        horizontalArrangement = Arrangement.SpaceAround
+                    ) {
                         repeat(5) { index ->
                             Box(
                                 Modifier
@@ -538,8 +651,11 @@
         rule.setContent {
             with(LocalDensity.current) {
                 Box(Modifier.size(200.toDp())) {
-                    FlowColumn(Modifier.wrapContentWidth().fillMaxHeight(1f),
-                        verticalArrangement = Arrangement.SpaceAround) {
+                    FlowColumn(
+                        Modifier
+                            .fillMaxHeight(1f),
+                        verticalArrangement = Arrangement.SpaceAround
+                    ) {
                         repeat(5) { index ->
                             Box(
                                 Modifier
@@ -585,7 +701,9 @@
         rule.setContent {
             with(LocalDensity.current) {
                 Box(Modifier.size(200.toDp())) {
-                    FlowRow(Modifier.wrapContentHeight().fillMaxWidth(1f),
+                    FlowRow(
+                        Modifier
+                            .fillMaxWidth(1f),
                         horizontalArrangement = Arrangement.SpaceAround,
                         maxItemsInEachRow = 5
                     ) {
@@ -633,7 +751,9 @@
         rule.setContent {
             with(LocalDensity.current) {
                 Box(Modifier.size(200.toDp())) {
-                    FlowColumn(Modifier.wrapContentWidth().fillMaxHeight(1f),
+                    FlowColumn(
+                        Modifier
+                            .fillMaxHeight(1f),
                         verticalArrangement = Arrangement.SpaceAround,
                         maxItemsInEachColumn = 5
                     ) {
@@ -675,13 +795,15 @@
         val eachSize = 20
         val spaceAvailable = size - (noOfItemsPerRow * eachSize) // 100
         val gapSize = spaceAvailable.roundToInt()
-       //  * Visually: ####123
+        //  * Visually: ####123
 
         val xPositions = FloatArray(10)
         rule.setContent {
             with(LocalDensity.current) {
                 Box(Modifier.size(200.toDp())) {
-                    FlowRow(Modifier.wrapContentHeight().fillMaxWidth(1f),
+                    FlowRow(
+                        Modifier
+                            .fillMaxWidth(1f),
                         horizontalArrangement = Arrangement.End,
                         maxItemsInEachRow = 5
                     ) {
@@ -726,7 +848,9 @@
         rule.setContent {
             with(LocalDensity.current) {
                 Box(Modifier.size(200.toDp())) {
-                    FlowColumn(Modifier.fillMaxHeight(1f).wrapContentWidth(),
+                    FlowColumn(
+                        Modifier
+                            .fillMaxHeight(1f),
                         verticalArrangement = Arrangement.Bottom,
                         maxItemsInEachColumn = 5
                     ) {
@@ -758,6 +882,7 @@
             expectedYPosition += eachSize
         }
     }
+
     @Test
     fun testFlowRow_horizontalArrangementStart() {
         val eachSize = 20
@@ -768,7 +893,7 @@
         rule.setContent {
             with(LocalDensity.current) {
                 Box(Modifier.size(200.toDp())) {
-                    FlowRow(Modifier.wrapContentHeight(),
+                    FlowRow(
                         horizontalArrangement = Arrangement.Start,
                         maxItemsInEachRow = maxItemsInMainAxis
                     ) {
@@ -812,7 +937,7 @@
         rule.setContent {
             with(LocalDensity.current) {
                 Box(Modifier.size(200.toDp())) {
-                    FlowRow(Modifier.wrapContentHeight(),
+                    FlowRow(
                         horizontalArrangement = Arrangement.spacedBy(spaceAligned.toDp()),
                         maxItemsInEachRow = maxItemsInMainAxis
                     ) {
@@ -848,6 +973,117 @@
         }
     }
 
+    /**
+     * Should space something like this:
+     * 1 2 3
+     * # SpaceAligned
+     * 4 5 6
+     * No Space here
+     */
+    @Test
+    fun testFlowRow_crossAxisSpacedBy() {
+        val eachSize = 20
+        val spaceAligned = 20
+        val noOfItems = 3
+        val expectedHeight = 100
+        var heightResult = 0
+
+        val yPositions = FloatArray(noOfItems)
+        rule.setContent {
+            with(LocalDensity.current) {
+                Box(Modifier.size(200.toDp())) {
+                    FlowRow(
+                        Modifier
+                            .onSizeChanged {
+                                heightResult = it.height
+                            },
+                        verticalArrangement = Arrangement.spacedBy(spaceAligned.toDp()),
+                        maxItemsInEachRow = 1
+                    ) {
+                        repeat(noOfItems) { index ->
+                            Box(
+                                Modifier
+                                    .size(eachSize.toDp())
+                                    .onPlaced {
+                                        val positionInParent = it.positionInParent()
+                                        val yPosition = positionInParent.y
+                                        yPositions[index] = yPosition
+                                    }
+                            )
+                        }
+                    }
+                }
+            }
+        }
+
+        rule.waitForIdle()
+        Truth
+            .assertThat(heightResult)
+            .isEqualTo(expectedHeight)
+        var expectedYPosition = 0
+        yPositions.forEachIndexed { index, position ->
+            Truth
+                .assertThat(position)
+                .isEqualTo(expectedYPosition)
+            expectedYPosition += eachSize
+            if (index < (noOfItems - 1)) {
+                expectedYPosition += spaceAligned
+            }
+        }
+    }
+
+    @Test
+    fun testFlowColumn_crossAxisSpacedBy() {
+        val eachSize = 20
+        val spaceAligned = 20
+        val noOfItems = 3
+        val expectedWidth = 100
+        var widthResult = 0
+
+        val xPositions = FloatArray(noOfItems)
+        rule.setContent {
+            with(LocalDensity.current) {
+                Box(Modifier.size(200.toDp())) {
+                    FlowColumn(
+                        Modifier
+                            .onSizeChanged {
+                                widthResult = it.width
+                            },
+                        horizontalArrangement = Arrangement.spacedBy(spaceAligned.toDp()),
+                        maxItemsInEachColumn = 1
+                    ) {
+                        repeat(noOfItems) { index ->
+                            Box(
+                                Modifier
+                                    .size(eachSize.toDp())
+                                    .onPlaced {
+                                        val positionInParent = it.positionInParent()
+                                        val xPosition = positionInParent.x
+                                        xPositions[index] = xPosition
+                                    }
+                            )
+                        }
+                    }
+                }
+            }
+        }
+
+        rule.waitForIdle()
+        var expectedXPosition = 0
+        Truth
+            .assertThat(widthResult)
+            .isEqualTo(expectedWidth)
+        xPositions.forEachIndexed { index, position ->
+            Truth
+                .assertThat(position)
+                .isEqualTo(expectedXPosition)
+            expectedXPosition += eachSize
+            if (index < (noOfItems - 1)) {
+                expectedXPosition += spaceAligned
+            }
+        }
+    }
+
     @Test
     fun testFlowColumn_SpaceAligned() {
         val eachSize = 10
@@ -858,7 +1094,7 @@
         rule.setContent {
             with(LocalDensity.current) {
                 Box(Modifier.size(200.toDp())) {
-                    FlowColumn(Modifier.wrapContentHeight(),
+                    FlowColumn(
                         verticalArrangement = Arrangement.spacedBy(spaceAligned.toDp()),
                         maxItemsInEachColumn = maxItemsInMainAxis
                     ) {
@@ -906,10 +1142,15 @@
         val xPositions = FloatArray(10)
         rule.setContent {
             with(LocalDensity.current) {
-                Box(Modifier.wrapContentHeight().widthIn(30.toDp(), 40.toDp())) {
-                    FlowRow(Modifier.wrapContentHeight().onSizeChanged {
-                           width = it.width
-                    },
+                Box(
+                    Modifier
+                        .widthIn(30.toDp(), 40.toDp())
+                ) {
+                    FlowRow(
+                        Modifier
+                            .onSizeChanged {
+                                width = it.width
+                            },
                         horizontalArrangement = Arrangement.spacedBy(spaceAligned.toDp()),
                         maxItemsInEachRow = maxItemsInMainAxis
                     ) {
@@ -958,10 +1199,16 @@
         val yPositions = FloatArray(10)
         rule.setContent {
             with(LocalDensity.current) {
-                Box(Modifier.heightIn(30.toDp(), 40.toDp()).wrapContentWidth()) {
-                    FlowColumn(Modifier.wrapContentHeight().onSizeChanged {
-                        height = it.height
-                    },
+                Box(
+                    Modifier
+                        .heightIn(30.toDp(), 40.toDp())
+
+                ) {
+                    FlowColumn(
+                        Modifier
+                            .onSizeChanged {
+                                height = it.height
+                            },
                         verticalArrangement = Arrangement.spacedBy(spaceAligned.toDp()),
                         maxItemsInEachColumn = maxItemsInMainAxis
                     ) {
@@ -1008,7 +1255,9 @@
         rule.setContent {
             with(LocalDensity.current) {
                 Box(Modifier.size(size.toDp())) {
-                    FlowColumn(Modifier.fillMaxHeight(1f).wrapContentWidth(),
+                    FlowColumn(
+                        Modifier
+                            .fillMaxHeight(1f),
                         verticalArrangement = Arrangement.Top,
                         maxItemsInEachColumn = maxItemsInMainAxis
                     ) {
@@ -1052,12 +1301,14 @@
 
         val xPositions = FloatArray(6)
         rule.setContent {
-            CompositionLocalProvider(values = arrayOf(
-                LocalLayoutDirection provides LayoutDirection.Rtl,
-            )) {
+            CompositionLocalProvider(
+                LocalLayoutDirection provides LayoutDirection.Rtl
+            ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(size.toDp())) {
-                        FlowRow(Modifier.wrapContentHeight().fillMaxWidth(1f),
+                        FlowRow(
+                            Modifier
+                                .fillMaxWidth(1f),
                             horizontalArrangement = Arrangement.Start,
                             maxItemsInEachRow = maxItemsInMainAxis
                         ) {
@@ -1098,14 +1349,17 @@
         val eachSize = 20
         val maxItemsInMainAxis = 5
 
-        val xYPositions = Array<Pair<Float, Float>>(10) { Pair(0f, 0f) }
+        val xYPositions = Array(10) { Pair(0f, 0f) }
         rule.setContent {
-            CompositionLocalProvider(values = arrayOf(
-                LocalLayoutDirection provides LayoutDirection.Rtl,
-            )) {
+            CompositionLocalProvider(
+                LocalLayoutDirection provides LayoutDirection.Rtl
+            ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(size.toDp())) {
-                        FlowColumn(Modifier.fillMaxHeight(1f).fillMaxWidth(1f),
+                        FlowColumn(
+                            Modifier
+                                .fillMaxHeight(1f)
+                                .fillMaxWidth(1f),
                             verticalArrangement = Arrangement.Top,
                             maxItemsInEachColumn = maxItemsInMainAxis
                         ) {
@@ -1158,18 +1412,20 @@
 
         var itemsThatCanFit = 0
         var width = 0
-        val xYPositions = Array<Pair<Float, Float>>(10) { Pair(0f, 0f) }
+        val xYPositions = Array(10) { Pair(0f, 0f) }
         rule.setContent {
-            CompositionLocalProvider(values = arrayOf(
-                LocalLayoutDirection provides LayoutDirection.Rtl,
-            )) {
+            CompositionLocalProvider(
+                LocalLayoutDirection provides LayoutDirection.Rtl
+            ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(size.toDp())) {
-                        FlowColumn(Modifier.fillMaxHeight(1f).wrapContentWidth()
-                            .onSizeChanged {
-                                width = it.width
-                                itemsThatCanFit = it.height / eachSize
-                        },
+                        FlowColumn(
+                            Modifier
+                                .fillMaxHeight(1f)
+                                .onSizeChanged {
+                                    width = it.width
+                                    itemsThatCanFit = it.height / eachSize
+                                },
                             verticalArrangement = Arrangement.Top,
                             maxItemsInEachColumn = maxItemsInMainAxis
                         ) {
@@ -1200,7 +1456,8 @@
             val xPosition = pair.first
             val yPosition = pair.second
             if (index % maxItemsInMainAxis == 0 ||
-                fittedItems == itemsThatCanFit) {
+                fittedItems == itemsThatCanFit
+            ) {
                 expectedYPosition = 0
                 expectedXPosition -= eachSize
                 fittedItems = 0
@@ -1228,14 +1485,11 @@
         val xPositions = FloatArray(6)
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowRow(
-                            Modifier.wrapContentHeight().wrapContentWidth(),
                             horizontalArrangement = Arrangement.Start,
                             maxItemsInEachRow = 5
                         ) {
@@ -1274,16 +1528,16 @@
         var width = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowRow(
-                            Modifier.width(IntrinsicSize.Min).wrapContentHeight().onSizeChanged {
-                                   width = it.width
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    width = it.width
+                                },
                             horizontalArrangement = Arrangement.Start,
                             maxItemsInEachRow = 5
                         ) {
@@ -1307,16 +1561,16 @@
         var width = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowColumn(
-                            Modifier.width(IntrinsicSize.Min).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    width = it.width
+                                },
                             maxItemsInEachColumn = 6
                         ) {
                             repeat(6) {
@@ -1339,16 +1593,16 @@
         var width = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowColumn(
-                            Modifier.width(IntrinsicSize.Min).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    width = it.width
+                                },
                             maxItemsInEachColumn = 5
                         ) {
                             repeat(6) {
@@ -1371,16 +1625,16 @@
         var width = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowRow(
-                            Modifier.width(IntrinsicSize.Max).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Max)
+                                .onSizeChanged {
+                                    width = it.width
+                                },
                             horizontalArrangement = Arrangement.Start,
                         ) {
                             repeat(6) {
@@ -1403,16 +1657,16 @@
         var width = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowColumn(
-                            Modifier.width(IntrinsicSize.Max).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Max)
+                                .onSizeChanged {
+                                    width = it.width
+                                },
                         ) {
                             repeat(6) {
                                 Box(
@@ -1434,16 +1688,16 @@
         var width = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowRow(
-                            Modifier.width(IntrinsicSize.Min).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    width = it.width
+                                },
                             horizontalArrangement = Arrangement.spacedBy(20.toDp()),
                             maxItemsInEachRow = 5
                         ) {
@@ -1467,16 +1721,16 @@
         var width = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(80.toDp())) {
                         FlowColumn(
-                            Modifier.width(IntrinsicSize.Min).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    width = it.width
+                                },
                             verticalArrangement = Arrangement.spacedBy(20.toDp()),
                         ) {
                             repeat(6) {
@@ -1495,20 +1749,86 @@
     }
 
     @Test
+    fun testFlowColumn_minIntrinsicWidth_horizontalArrangement_withSpaceBy_MultipleRows() {
+        var width = 0
+        rule.setContent {
+            CompositionLocalProvider(
+                LocalLayoutDirection provides LayoutDirection.Rtl
+            ) {
+                with(LocalDensity.current) {
+                    Box(Modifier.size(200.toDp())) {
+                        FlowColumn(
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    width = it.width
+                                },
+                            horizontalArrangement = Arrangement.spacedBy(20.toDp()),
+                            maxItemsInEachColumn = 5
+                        ) {
+                            repeat(6) {
+                                Box(
+                                    Modifier
+                                        .size(20.toDp())
+                                )
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        rule.waitForIdle()
+        Truth.assertThat(width).isEqualTo(60)
+    }
+
+    @Test
+    fun testFlowColumn_minIntrinsicWidth_horizontalArrangement_withSpaceBy() {
+        var width = 0
+        rule.setContent {
+            CompositionLocalProvider(
+                LocalLayoutDirection provides LayoutDirection.Rtl
+            ) {
+                with(LocalDensity.current) {
+                    Box(Modifier.size(200.toDp())) {
+                        FlowColumn(
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    width = it.width
+                                },
+                            horizontalArrangement = Arrangement.spacedBy(20.toDp()),
+                            maxItemsInEachColumn = 5
+                        ) {
+                            repeat(5) {
+                                Box(
+                                    Modifier
+                                        .size(20.toDp())
+                                )
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        rule.waitForIdle()
+        Truth.assertThat(width).isEqualTo(20)
+    }
+
+    @Test
     fun testFlowRow_maxIntrinsicWidth_withSpaceBy() {
         var width = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowRow(
-                            Modifier.width(IntrinsicSize.Max).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Max)
+                                .onSizeChanged {
+                                    width = it.width
+                                },
                             horizontalArrangement = Arrangement.spacedBy(10.toDp()),
                         ) {
                             repeat(6) {
@@ -1523,7 +1843,7 @@
             }
         }
         rule.waitForIdle()
-        Truth.assertThat(width).isEqualTo(180)
+        Truth.assertThat(width).isEqualTo(170)
     }
 
     @Test
@@ -1531,16 +1851,16 @@
         var width = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowColumn(
-                            Modifier.width(IntrinsicSize.Max).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Max)
+                                .onSizeChanged {
+                                    width = it.width
+                                },
                             verticalArrangement = Arrangement.spacedBy(20.toDp()),
                         ) {
                             repeat(6) {
@@ -1564,17 +1884,17 @@
         var height = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowRow(
-                            Modifier.width(IntrinsicSize.Min).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                                height = it.height
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    width = it.width
+                                    height = it.height
+                                },
                             maxItemsInEachRow = 5
                         ) {
                             repeat(6) { index ->
@@ -1600,17 +1920,17 @@
         var height = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowColumn(
-                            Modifier.width(IntrinsicSize.Min).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                                height = it.height
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    width = it.width
+                                    height = it.height
+                                },
                             maxItemsInEachColumn = 5
                         ) {
                             repeat(6) { index ->
@@ -1636,17 +1956,17 @@
         var height = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowRow(
-                            Modifier.width(IntrinsicSize.Min).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                                height = it.height
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    width = it.width
+                                    height = it.height
+                                },
                             horizontalArrangement = Arrangement.spacedBy(10.toDp()),
                             maxItemsInEachRow = 5
                         ) {
@@ -1673,17 +1993,17 @@
         var height = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowColumn(
-                            Modifier.width(IntrinsicSize.Min).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                                height = it.height
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    width = it.width
+                                    height = it.height
+                                },
                             verticalArrangement = Arrangement.spacedBy(10.toDp()),
                             maxItemsInEachColumn = 5
                         ) {
@@ -1709,16 +2029,16 @@
         var width = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowRow(
-                            Modifier.width(IntrinsicSize.Min).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    width = it.width
+                                },
                             maxItemsInEachRow = 2
                         ) {
                             repeat(6) {
@@ -1741,16 +2061,16 @@
         var width = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowRow(
-                            Modifier.width(IntrinsicSize.Min).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    width = it.width
+                                },
                             maxItemsInEachRow = 2
                         ) {
                             repeat(6) {
@@ -1773,16 +2093,16 @@
         var width = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowRow(
-                            Modifier.width(IntrinsicSize.Max).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Max)
+                                .onSizeChanged {
+                                    width = it.width
+                                },
                             maxItemsInEachRow = 2
                         ) {
                             repeat(6) {
@@ -1805,16 +2125,16 @@
         var width = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowColumn(
-                            Modifier.width(IntrinsicSize.Max).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Max)
+                                .onSizeChanged {
+                                    width = it.width
+                                },
                             maxItemsInEachColumn = 2
                         ) {
                             repeat(6) {
@@ -1838,17 +2158,17 @@
         var height = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowRow(
-                            Modifier.width(IntrinsicSize.Min).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                                height = it.height
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    width = it.width
+                                    height = it.height
+                                },
                             maxItemsInEachRow = 2
                         ) {
                             repeat(10) { index ->
@@ -1874,17 +2194,17 @@
         var height = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowColumn(
-                            Modifier.width(IntrinsicSize.Min).wrapContentHeight().onSizeChanged {
-                                width = it.width
-                                height = it.height
-                            },
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    width = it.width
+                                    height = it.height
+                                },
                             maxItemsInEachColumn = 2
                         ) {
                             repeat(10) { index ->
@@ -1909,16 +2229,16 @@
         var height = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowRow(
-                            Modifier.height(IntrinsicSize.Min).wrapContentWidth().onSizeChanged {
-                                height = it.height
-                            },
+                            Modifier
+                                .height(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    height = it.height
+                                },
                         ) {
                             repeat(6) {
                                 Box(
@@ -1936,20 +2256,150 @@
     }
 
     @Test
+    fun testFlowRow_maxIntrinsicHeight() {
+        var height = 0
+        rule.setContent {
+            CompositionLocalProvider(
+                LocalLayoutDirection provides LayoutDirection.Rtl
+            ) {
+                with(LocalDensity.current) {
+                    Box(Modifier.size(200.toDp())) {
+                        FlowRow(
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .height(IntrinsicSize.Max)
+                                .onSizeChanged {
+                                    height = it.height
+                                },
+                        ) {
+                            repeat(5) {
+                                Box(
+                                    Modifier
+                                        .size(20.toDp())
+                                )
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        rule.waitForIdle()
+        Truth.assertThat(height).isEqualTo(100)
+    }
+
+    @Test
+    fun testFlowRow_maxIntrinsicHeight_withSpacedBy() {
+        var height = 0
+        rule.setContent {
+            CompositionLocalProvider(
+                LocalLayoutDirection provides LayoutDirection.Rtl
+            ) {
+                with(LocalDensity.current) {
+                    Box(Modifier.size(200.toDp())) {
+                        FlowRow(
+                            Modifier
+                                .width(IntrinsicSize.Min)
+                                .height(IntrinsicSize.Max)
+                                .onSizeChanged {
+                                    height = it.height
+                                },
+                            verticalArrangement = Arrangement.spacedBy(20.toDp()),
+                        ) {
+                            repeat(5) {
+                                Box(
+                                    Modifier
+                                        .size(20.toDp())
+                                )
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        rule.waitForIdle()
+        Truth.assertThat(height).isEqualTo(180)
+    }
+
+    @Test
+    fun testFlowRow_minIntrinsicHeight_withSpaceBy_MultipleRows() {
+        var height = 0
+        rule.setContent {
+            CompositionLocalProvider(
+                LocalLayoutDirection provides LayoutDirection.Rtl
+            ) {
+                with(LocalDensity.current) {
+                    Box(Modifier.size(200.toDp())) {
+                        FlowRow(
+                            Modifier
+                                .height(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    height = it.height
+                                },
+                            verticalArrangement = Arrangement.spacedBy(20.toDp()),
+                            maxItemsInEachRow = 1
+                        ) {
+                            repeat(2) {
+                                Box(
+                                    Modifier
+                                        .size(20.toDp())
+                                )
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        rule.waitForIdle()
+        Truth.assertThat(height).isEqualTo(60)
+    }
+
+    @Test
+    fun testFlowRow_minIntrinsicHeight_withSpaceBy() {
+        var height = 0
+        rule.setContent {
+            CompositionLocalProvider(
+                LocalLayoutDirection provides LayoutDirection.Rtl
+            ) {
+                with(LocalDensity.current) {
+                    Box(Modifier.size(200.toDp())) {
+                        FlowRow(
+                            Modifier
+                                .height(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    height = it.height
+                                },
+                            verticalArrangement = Arrangement.spacedBy(20.toDp()),
+                        ) {
+                            repeat(2) {
+                                Box(
+                                    Modifier
+                                        .size(20.toDp())
+                                )
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        rule.waitForIdle()
+        Truth.assertThat(height).isEqualTo(20)
+    }
+
+    @Test
     fun testFlowColumn_minIntrinsicHeight() {
         var height = 0
         rule.setContent {
             CompositionLocalProvider(
-                values = arrayOf(
-                    LocalLayoutDirection provides LayoutDirection.Rtl,
-                )
+                LocalLayoutDirection provides LayoutDirection.Rtl
             ) {
                 with(LocalDensity.current) {
                     Box(Modifier.size(200.toDp())) {
                         FlowColumn(
-                            Modifier.height(IntrinsicSize.Min).wrapContentWidth().onSizeChanged {
-                                height = it.height
-                            },
+                            Modifier
+                                .height(IntrinsicSize.Min)
+                                .onSizeChanged {
+                                    height = it.height
+                                },
                             maxItemsInEachColumn = 5
                         ) {
                             repeat(6) {
@@ -1966,4 +2416,70 @@
         rule.waitForIdle()
         Truth.assertThat(height).isEqualTo(20)
     }
+
+    @Test
+    fun testFlowColumn_maxIntrinsicHeight() {
+        var height = 0
+        rule.setContent {
+            CompositionLocalProvider(
+                LocalLayoutDirection provides LayoutDirection.Rtl
+            ) {
+                with(LocalDensity.current) {
+                    Box(Modifier.size(200.toDp())) {
+                        FlowColumn(
+                            Modifier
+                                .height(IntrinsicSize.Max)
+                                .onSizeChanged {
+                                    height = it.height
+                                },
+                            maxItemsInEachColumn = 5,
+                            horizontalArrangement = Arrangement.spacedBy(20.toDp()),
+                        ) {
+                            repeat(5) {
+                                Box(
+                                    Modifier
+                                        .size(20.toDp())
+                                )
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        rule.waitForIdle()
+        Truth.assertThat(height).isEqualTo(100)
+    }
+
+    @Test
+    fun testFlowColumn_maxIntrinsicHeight_withSpacedByOnMainAxis() {
+        var height = 0
+        rule.setContent {
+            CompositionLocalProvider(
+                LocalLayoutDirection provides LayoutDirection.Rtl
+            ) {
+                with(LocalDensity.current) {
+                    Box(Modifier.size(200.toDp())) {
+                        FlowColumn(
+                            Modifier
+                                .height(IntrinsicSize.Max)
+                                .onSizeChanged {
+                                    height = it.height
+                                },
+                            maxItemsInEachColumn = 5,
+                            verticalArrangement = Arrangement.spacedBy(20.toDp()),
+                        ) {
+                            repeat(5) {
+                                Box(
+                                    Modifier
+                                        .size(20.toDp())
+                                )
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        rule.waitForIdle()
+        Truth.assertThat(height).isEqualTo(180)
+    }
 }
\ 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 7703c5b..ded1da7 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
@@ -42,7 +42,7 @@
  *
  * @param modifier The modifier to be applied to the Row.
  * @param horizontalArrangement The horizontal arrangement of the layout's children.
- * @param verticalAlignment The vertical alignment of the layout's children.
+ * @param verticalArrangement The vertical arrangement of the layout's virtual rows.
  * @param maxItemsInEachRow The maximum number of items per row
  * @param content The content as a [RowScope]
  *
@@ -54,13 +54,13 @@
 fun FlowRow(
     modifier: Modifier = Modifier,
     horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
-    verticalAlignment: Alignment.Vertical = Alignment.Top,
+    verticalArrangement: Arrangement.Vertical = Arrangement.Top,
     maxItemsInEachRow: Int = Int.MAX_VALUE,
     content: @Composable RowScope.() -> Unit
 ) {
     val measurePolicy = rowMeasurementHelper(
         horizontalArrangement,
-        verticalAlignment,
+        verticalArrangement,
         maxItemsInEachRow
     )
     Layout(
@@ -92,7 +92,7 @@
  *
  * @param modifier The modifier to be applied to the Row.
  * @param verticalArrangement The vertical arrangement of the layout's children.
- * @param horizontalAlignment The horizontal alignment of the layout's children.
+ * @param horizontalArrangement The horizontal arrangement of the layout's virtual columns
  * @param maxItemsInEachColumn The maximum number of items per column
  * @param content The content as a [ColumnScope]
  *
@@ -104,13 +104,13 @@
 fun FlowColumn(
     modifier: Modifier = Modifier,
     verticalArrangement: Arrangement.Vertical = Arrangement.Top,
-    horizontalAlignment: Alignment.Horizontal = Alignment.Start,
+    horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
     maxItemsInEachColumn: Int = Int.MAX_VALUE,
     content: @Composable ColumnScope.() -> Unit
 ) {
     val measurePolicy = columnMeasurementHelper(
         verticalArrangement,
-        horizontalAlignment,
+        horizontalArrangement,
         maxItemsInEachColumn
     )
     Layout(
@@ -120,83 +120,58 @@
     )
 }
 
-@Composable
-private fun mainAxisRowArrangement(horizontalArrangement: Arrangement.Horizontal):
+private fun getVerticalArrangement(verticalArrangement: Arrangement.Vertical):
         (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit =
-    remember(horizontalArrangement) {
-        { totalSize, size, layoutDirection, density, outPosition ->
-            with(horizontalArrangement) {
-                density.arrange(totalSize, size, layoutDirection, outPosition)
-            }
+    { totalSize: Int, size: IntArray, _, density: Density, outPosition: IntArray ->
+        with(verticalArrangement) {
+            density.arrange(totalSize, size, outPosition)
         }
     }
 
-@Composable
-private fun mainAxisColumnArrangement(verticalArrangement: Arrangement.Vertical):
-        (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit =
-    remember(verticalArrangement) {
-        { totalSize, size, _, density, outPosition ->
-            with(verticalArrangement) {
-                density.arrange(totalSize, size, outPosition)
-            }
+private fun getHorizontalArrangement(horizontalArrangement: Arrangement.Horizontal) =
+    { totalSize: Int, size: IntArray, layoutDirection: LayoutDirection,
+        density: Density, outPosition: IntArray ->
+        with(horizontalArrangement) {
+            density.arrange(totalSize, size, layoutDirection, outPosition)
         }
     }
 
-private val crossAxisRowArrangement = { totalSize: Int, size: IntArray,
-    measureScope: MeasureScope,
-    outPosition: IntArray ->
-    with(Arrangement.Top) { measureScope.arrange(totalSize, size, outPosition) }
-}
-
-private val crossAxisColumnArrangement = { totalSize: Int,
-    size: IntArray, measureScope: MeasureScope, outPosition: IntArray ->
-    with(Arrangement.Start) {
-        measureScope.arrange(totalSize, size, measureScope.layoutDirection, outPosition)
-    }
-}
-
 @Composable
 private fun rowMeasurementHelper(
-    horizontalArrangement: Arrangement.Horizontal = Arrangement.End,
-    verticalAlignment: Alignment.Vertical = Alignment.Top,
+    horizontalArrangement: Arrangement.Horizontal,
+    verticalArrangement: Arrangement.Vertical,
     maxItemsInMainAxis: Int,
 ): MeasurePolicy {
-    val mainAxisArrangement = mainAxisRowArrangement(horizontalArrangement)
-    val crossAxisAlignment = remember(verticalAlignment) {
-        CrossAxisAlignment.vertical(verticalAlignment)
-    }
-    return remember(horizontalArrangement, verticalAlignment, maxItemsInMainAxis) {
+    return remember(horizontalArrangement, verticalArrangement, maxItemsInMainAxis) {
         flowMeasurePolicy(
             orientation = LayoutOrientation.Horizontal,
-            mainAxisArrangement = mainAxisArrangement,
-            arrangementSpacing = horizontalArrangement.spacing,
-            crossAxisAlignment = crossAxisAlignment,
+            mainAxisArrangement = getHorizontalArrangement(horizontalArrangement),
+            mainAxisArrangementSpacing = horizontalArrangement.spacing,
             crossAxisSize = SizeMode.Wrap,
-            crossAxisArrangement = crossAxisRowArrangement,
-            maxItemsInMainAxis = maxItemsInMainAxis,
+            crossAxisAlignment = CROSS_AXIS_ALIGNMENT_TOP,
+            crossAxisArrangement = getVerticalArrangement(verticalArrangement),
+            crossAxisArrangementSpacing = verticalArrangement.spacing,
+            maxItemsInMainAxis = maxItemsInMainAxis
         )
     }
 }
 
 @Composable
 private fun columnMeasurementHelper(
-    verticalArrangement: Arrangement.Vertical = Arrangement.Top,
-    horizontalAlignment: Alignment.Horizontal = Alignment.Start,
+    verticalArrangement: Arrangement.Vertical,
+    horizontalArrangement: Arrangement.Horizontal,
     maxItemsInMainAxis: Int,
 ): MeasurePolicy {
-    val mainAxisArrangement = mainAxisColumnArrangement(verticalArrangement)
-    val crossAxisAlignment = remember(horizontalAlignment) {
-        CrossAxisAlignment.horizontal(horizontalAlignment)
-    }
-    return remember(verticalArrangement, horizontalAlignment, maxItemsInMainAxis) {
+    return remember(verticalArrangement, horizontalArrangement, maxItemsInMainAxis) {
         flowMeasurePolicy(
             orientation = LayoutOrientation.Vertical,
-            mainAxisArrangement = mainAxisArrangement,
-            arrangementSpacing = verticalArrangement.spacing,
-            crossAxisAlignment = crossAxisAlignment,
-            crossAxisArrangement = crossAxisColumnArrangement,
+            mainAxisArrangement = getVerticalArrangement(verticalArrangement),
+            mainAxisArrangementSpacing = verticalArrangement.spacing,
+            crossAxisSize = SizeMode.Wrap,
+            crossAxisAlignment = CROSS_AXIS_ALIGNMENT_START,
+            crossAxisArrangement = getHorizontalArrangement(horizontalArrangement),
+            crossAxisArrangementSpacing = horizontalArrangement.spacing,
             maxItemsInMainAxis = maxItemsInMainAxis,
-            crossAxisSize = SizeMode.Wrap
         )
     }
 }
@@ -207,10 +182,11 @@
 private fun flowMeasurePolicy(
     orientation: LayoutOrientation,
     mainAxisArrangement: (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit,
-    arrangementSpacing: Dp,
+    mainAxisArrangementSpacing: Dp,
     crossAxisSize: SizeMode,
     crossAxisAlignment: CrossAxisAlignment,
-    crossAxisArrangement: (Int, IntArray, MeasureScope, IntArray) -> Unit,
+    crossAxisArrangement: (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit,
+    crossAxisArrangementSpacing: Dp,
     maxItemsInMainAxis: Int,
 ): MeasurePolicy {
 
@@ -220,11 +196,12 @@
             measurables: List<Measurable>,
             constraints: Constraints
         ): MeasureResult {
+            if (measurables.isEmpty()) { return layout(0, 0) {} }
             val placeables: Array<Placeable?> = arrayOfNulls(measurables.size)
             val measureHelper = RowColumnMeasurementHelper(
                 orientation,
                 mainAxisArrangement,
-                arrangementSpacing,
+                mainAxisArrangementSpacing,
                 crossAxisSize,
                 crossAxisAlignment,
                 measurables,
@@ -238,24 +215,31 @@
                 orientationIndependentConstraints,
                 maxItemsInMainAxis,
             )
-            val totalCrossAxisSize = flowResult.crossAxisTotalSize
             val items = flowResult.items
             val crossAxisSizes = IntArray(items.size) { index ->
                 items[index].crossAxisSize
             }
+            // space in between children, except for the last child
             val outPosition = IntArray(crossAxisSizes.size)
+            var totalCrossAxisSize = flowResult.crossAxisTotalSize
+            val totalCrossAxisSpacing =
+                crossAxisArrangementSpacing.roundToPx() * (items.size - 1)
+            totalCrossAxisSize += totalCrossAxisSpacing
             crossAxisArrangement(
                 totalCrossAxisSize,
-                crossAxisSizes, this@measure, outPosition
+                crossAxisSizes,
+                layoutDirection,
+                this@measure,
+                outPosition
             )
 
             var layoutWidth: Int
             var layoutHeight: Int
             if (orientation == LayoutOrientation.Horizontal) {
                 layoutWidth = flowResult.mainAxisTotalSize
-                layoutHeight = flowResult.crossAxisTotalSize
+                layoutHeight = totalCrossAxisSize
             } else {
-                layoutWidth = flowResult.crossAxisTotalSize
+                layoutWidth = totalCrossAxisSize
                 layoutHeight = flowResult.mainAxisTotalSize
             }
             layoutWidth = constraints.constrainWidth(layoutWidth)
@@ -281,13 +265,15 @@
             minIntrinsicMainAxisSize(
                 measurables,
                 height,
-                arrangementSpacing.roundToPx(),
+                mainAxisArrangementSpacing.roundToPx(),
+                crossAxisArrangementSpacing.roundToPx()
             )
         } else {
             intrinsicCrossAxisSize(
                 measurables,
                 height,
-                arrangementSpacing.roundToPx(),
+                mainAxisArrangementSpacing.roundToPx(),
+                crossAxisArrangementSpacing.roundToPx()
             )
         }
 
@@ -298,13 +284,15 @@
             intrinsicCrossAxisSize(
                 measurables,
                 width,
-                arrangementSpacing.roundToPx(),
+                mainAxisArrangementSpacing.roundToPx(),
+                crossAxisArrangementSpacing.roundToPx()
             )
         } else {
             minIntrinsicMainAxisSize(
                 measurables,
                 width,
-                arrangementSpacing.roundToPx(),
+                mainAxisArrangementSpacing.roundToPx(),
+                crossAxisArrangementSpacing.roundToPx(),
             )
         }
 
@@ -315,13 +303,14 @@
             intrinsicCrossAxisSize(
                 measurables,
                 width,
-                arrangementSpacing.roundToPx(),
+                mainAxisArrangementSpacing.roundToPx(),
+                crossAxisArrangementSpacing.roundToPx()
             )
         } else {
             maxIntrinsicMainAxisSize(
                 measurables,
                 width,
-                arrangementSpacing.roundToPx(),
+                mainAxisArrangementSpacing.roundToPx(),
             )
         }
 
@@ -332,26 +321,29 @@
             maxIntrinsicMainAxisSize(
                 measurables,
                 height,
-                arrangementSpacing.roundToPx(),
+                mainAxisArrangementSpacing.roundToPx(),
             )
         } else {
             intrinsicCrossAxisSize(
                 measurables,
                 height,
-                arrangementSpacing.roundToPx(),
+                mainAxisArrangementSpacing.roundToPx(),
+                crossAxisArrangementSpacing.roundToPx()
             )
         }
 
         fun minIntrinsicMainAxisSize(
             measurables: List<IntrinsicMeasurable>,
             crossAxisAvailable: Int,
-            arrangementSpacing: Int
+            mainAxisSpacing: Int,
+            crossAxisSpacing: Int,
         ) = minIntrinsicMainAxisSize(
             measurables,
             mainAxisSize = minMainAxisIntrinsicItemSize,
             crossAxisSize = minCrossAxisIntrinsicItemSize,
             crossAxisAvailable,
-            arrangementSpacing,
+            mainAxisSpacing,
+            crossAxisSpacing,
             maxItemsInMainAxis
         )
 
@@ -370,13 +362,15 @@
         fun intrinsicCrossAxisSize(
             measurables: List<IntrinsicMeasurable>,
             mainAxisAvailable: Int,
-            arrangementSpacing: Int
+            mainAxisSpacing: Int,
+            crossAxisSpacing: Int
         ) = intrinsicCrossAxisSize(
             measurables,
             mainAxisSize = minMainAxisIntrinsicItemSize,
             crossAxisSize = minCrossAxisIntrinsicItemSize,
             mainAxisAvailable,
-            arrangementSpacing,
+            mainAxisSpacing,
+            crossAxisSpacing,
             maxItemsInMainAxis
         )
 
@@ -429,6 +423,7 @@
         if (index + 1 - lastBreak == maxItemsInMainAxis || index + 1 == children.size) {
             lastBreak = index
             currentFixedSpace += size
+            currentFixedSpace -= mainAxisSpacing // no mainAxisSpacing for last item in main axis
             fixedSpace = max(fixedSpace, currentFixedSpace)
             currentFixedSpace = 0
         } else {
@@ -448,6 +443,7 @@
     crossAxisSize: IntrinsicMeasurable.(Int, Int) -> Int,
     crossAxisAvailable: Int,
     mainAxisSpacing: Int,
+    crossAxisSpacing: Int,
     maxItemsInMainAxis: Int
 ): Int {
     val mainAxisSizes = IntArray(children.size) { 0 }
@@ -479,6 +475,7 @@
             crossAxisSizes,
             mainAxisUsed,
             mainAxisSpacing,
+            crossAxisSpacing,
             maxItemsInMainAxis
         )
 
@@ -504,6 +501,7 @@
     crossAxisSizes: IntArray,
     mainAxisAvailable: Int,
     mainAxisSpacing: Int,
+    crossAxisSpacing: Int,
     maxItemsInMainAxis: Int
 ): Int {
     return intrinsicCrossAxisSize(
@@ -512,6 +510,7 @@
         { index, _ -> crossAxisSizes[index] },
         mainAxisAvailable,
         mainAxisSpacing,
+        crossAxisSpacing,
         maxItemsInMainAxis
     )
 }
@@ -525,6 +524,7 @@
     crossAxisSize: IntrinsicMeasurable.(Int, Int) -> Int,
     mainAxisAvailable: Int,
     mainAxisSpacing: Int,
+    crossAxisSpacing: Int,
     maxItemsInMainAxis: Int
 ): Int {
     if (children.isEmpty()) {
@@ -556,13 +556,15 @@
             (index + 1) - lastBreak == maxItemsInMainAxis ||
             remaining - nextMainAxisSize < 0
         ) {
-            totalCrossAxisSize += currentCrossAxisSize
+            totalCrossAxisSize += currentCrossAxisSize + crossAxisSpacing
             currentCrossAxisSize = 0
             remaining = mainAxisAvailable
             lastBreak = index + 1
             nextMainAxisSize -= mainAxisSpacing
         }
     }
+    // remove the last spacing for the last row or column
+    totalCrossAxisSize -= crossAxisSpacing
     return totalCrossAxisSize
 }
 
@@ -685,6 +687,9 @@
 internal fun Placeable.crossAxisSize(orientation: LayoutOrientation) =
     if (orientation == LayoutOrientation.Horizontal) height else width
 
+private val CROSS_AXIS_ALIGNMENT_TOP = CrossAxisAlignment.vertical(Alignment.Top)
+private val CROSS_AXIS_ALIGNMENT_START = CrossAxisAlignment.horizontal(Alignment.Start)
+
 // We measure and cache to improve performance dramatically, instead of using intrinsics
 // This only works so far for fixed size items.
 // For weighted items, we continue to use their intrinsic widths.
diff --git a/compose/foundation/foundation/api/public_plus_experimental_current.txt b/compose/foundation/foundation/api/public_plus_experimental_current.txt
index df15145..776cd4d 100644
--- a/compose/foundation/foundation/api/public_plus_experimental_current.txt
+++ b/compose/foundation/foundation/api/public_plus_experimental_current.txt
@@ -614,6 +614,11 @@
     method public java.util.List<java.lang.Integer> calculateCrossAxisCellSizes(androidx.compose.ui.unit.Density, int availableSize, int spacing);
   }
 
+  @androidx.compose.foundation.ExperimentalFoundationApi public static final class GridCells.FixedSize implements androidx.compose.foundation.lazy.grid.GridCells {
+    ctor public GridCells.FixedSize(float size);
+    method public java.util.List<java.lang.Integer> calculateCrossAxisCellSizes(androidx.compose.ui.unit.Density, int availableSize, int spacing);
+  }
+
   @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class GridItemSpan {
     method public int getCurrentLineSpan();
     property @androidx.compose.foundation.ExperimentalFoundationApi public final int currentLineSpan;
diff --git a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/text/lazyhosted/TextLazyReuse.kt b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/text/lazyhosted/TextLazyReuse.kt
new file mode 100644
index 0000000..74ae0fc
--- /dev/null
+++ b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/text/lazyhosted/TextLazyReuse.kt
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalComposeUiApi::class)
+
+package androidx.compose.foundation.benchmark.text.lazyhosted
+
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.ReusableContent
+import androidx.compose.runtime.ReusableContentHost
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.testutils.LayeredComposeTestCase
+import androidx.compose.testutils.ToggleableTestCase
+import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
+import androidx.compose.testutils.benchmark.toggleStateBenchmarkComposeMeasureLayout
+import androidx.compose.testutils.benchmark.toggleStateBenchmarkDraw
+import androidx.compose.testutils.benchmark.toggleStateBenchmarkRecompose
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontFamily
+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
+
+class TextLazyReuse(
+    private val changeText: Boolean
+) : LayeredComposeTestCase(), ToggleableTestCase {
+    private var flipper = false
+    private var toggleText = mutableStateOf("")
+    private var active = mutableStateOf(true)
+    private var reuseKey = mutableStateOf(0)
+
+    private val style = TextStyle.Default.copy(fontFamily = FontFamily.Monospace)
+
+    @Composable
+    override fun MeasuredContent() {
+        ReusableContentHost(active.value) {
+            ReusableContent(reuseKey.value) {
+                Text(
+                    toggleText.value,
+                    style = style,
+                    modifier = Modifier.fillMaxWidth()
+                )
+            }
+        }
+    }
+
+    override fun toggleState() {
+        flipper = !flipper
+        if (flipper) {
+            active.value = false
+        } else {
+            active.value = true
+            reuseKey.value = reuseKey.value++
+            if (changeText) {
+                toggleText.value = "reuse ${reuseKey.value}"
+            }
+        }
+    }
+}
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+class TextLazyReuseSameText {
+
+    @get:Rule
+    val benchmarkRule = ComposeBenchmarkRule()
+
+    val caseFactory = { TextLazyReuse(false) }
+
+    @Test
+    fun recomposeOnly() {
+        benchmarkRule.toggleStateBenchmarkRecompose(caseFactory)
+    }
+
+    @Test
+    fun recomposeMeasureLayout() {
+        benchmarkRule.toggleStateBenchmarkComposeMeasureLayout(caseFactory)
+    }
+
+    @Test
+    fun draw() {
+        benchmarkRule.toggleStateBenchmarkDraw(caseFactory)
+    }
+}
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+class TextLazyReuseChangedText {
+
+    @get:Rule
+    val benchmarkRule = ComposeBenchmarkRule()
+
+    val caseFactory = { TextLazyReuse(true) }
+
+    @Test
+    fun recomposeOnly() {
+        benchmarkRule.toggleStateBenchmarkRecompose(caseFactory)
+    }
+
+    @Test
+    fun recomposeMeasureLayout() {
+        benchmarkRule.toggleStateBenchmarkComposeMeasureLayout(caseFactory)
+    }
+
+    @Test
+    fun draw() {
+        benchmarkRule.toggleStateBenchmarkDraw(caseFactory)
+    }
+}
\ No newline at end of file
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 cd800a7..f4f50f1 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
@@ -689,11 +689,14 @@
     }
 }
 
+@OptIn(ExperimentalFoundationApi::class)
+@Preview
 @Composable
 private fun LazyGridWithSpacingDemo() {
     val columnModes = listOf(
         GridCells.Fixed(3),
         GridCells.Adaptive(minSize = 60.dp),
+        GridCells.FixedSize(50.dp),
         object : GridCells {
             // columns widths have ratio 1:1:2:3
             override fun Density.calculateCrossAxisCellSizes(
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/MemoryAllocs.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/MemoryAllocs.kt
index b191349a..65eb312 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/MemoryAllocs.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/MemoryAllocs.kt
@@ -23,6 +23,8 @@
 import androidx.compose.material.Divider
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.ReusableContent
+import androidx.compose.runtime.ReusableContentHost
 import androidx.compose.runtime.State
 import androidx.compose.runtime.produceState
 import androidx.compose.runtime.withFrameMillis
@@ -73,6 +75,18 @@
 }
 
 @Composable
+fun MemoryAllocsLazyList() {
+    val states = produceLazyListReuseDriver()
+    Column {
+        Preamble(sourceCode = """
+                item { Text("Some static text") }
+            """.trimIndent()
+        )
+        LazyListReuse(states)
+    }
+}
+
+@Composable
 fun Preamble(sourceCode: String) {
     Text("Run in memory profiler to emulate text behavior during observable loads")
     Text(text = sourceCode,
@@ -98,6 +112,19 @@
 }
 
 @Composable
+fun LazyListReuse(active: State<Pair<Boolean, Int>>) {
+    // this emulates what a LazyList does during reuse
+    ReusableContentHost(active.value.first) {
+        ReusableContent(active.value.second) {
+            Text(
+                "Some static text",
+                modifier = Modifier.fillMaxWidth()
+            )
+        }
+    }
+}
+
+@Composable
 private fun SetText(text: State<String>) {
     Text(text.value)
 }
@@ -114,3 +141,17 @@
         }
     }
 }
+
+@Composable
+fun produceLazyListReuseDriver(): State<Pair<Boolean, Int>> = produceState(false to 0) {
+    while (true) {
+        withFrameMillis {
+            val (oldToggle, oldCount) = value
+            value = if (oldToggle) {
+                false to oldCount
+            } else {
+                true to oldCount + 1
+            }
+        }
+    }
+}
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextDemos.kt
index 1702e47..e68d579 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextDemos.kt
@@ -143,7 +143,8 @@
             "\uD83D\uDD75️️️ Memory allocs",
             listOf(
                 ComposableDemo("\uD83D\uDD75️ SetText") { MemoryAllocsSetText() },
-                ComposableDemo("\uD83D\uDD75️ IfNotEmptyText") { MemoryAllocsIfNotEmptyText() }
+                ComposableDemo("\uD83D\uDD75️ IfNotEmptyText") { MemoryAllocsIfNotEmptyText() },
+                ComposableDemo("\uD83E\uDDA5 LazyList reuse") { MemoryAllocsLazyList() }
             )
         )
     )
diff --git a/compose/foundation/foundation/lint-baseline.xml b/compose/foundation/foundation/lint-baseline.xml
index c0e9e05..82be5f8 100644
--- a/compose/foundation/foundation/lint-baseline.xml
+++ b/compose/foundation/foundation/lint-baseline.xml
@@ -46,4 +46,13 @@
             file="src/androidMain/kotlin/androidx/compose/foundation/Magnifier.kt"/>
     </issue>
 
+    <issue
+        id="IllegalExperimentalApiUsage"
+        message="`Experimental` and `RequiresOptIn` APIs may only be used within the same-version group where they were defined."
+        errorLine1="    @OptIn(ExperimentalTextApi::class)"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/TextStringSimpleNode.kt"/>
+    </issue>
+
 </issues>
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyArrangementsTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyArrangementsTest.kt
index 7dd6e46..89e6b70 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyArrangementsTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyArrangementsTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.compose.foundation.lazy.grid
 
+import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.scrollBy
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
@@ -31,6 +32,7 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.platform.testTag
@@ -50,6 +52,7 @@
 import org.junit.Rule
 import org.junit.Test
 
+@OptIn(ExperimentalFoundationApi::class)
 class LazyArrangementsTest {
 
     private val ContainerTag = "ContainerTag"
@@ -667,6 +670,106 @@
         }
     }
 
+    @Test
+    fun horizontal_nonDefaultCrossAxisArrangement() {
+        val state = LazyGridState()
+        rule.setContent {
+            LazyHorizontalGrid(
+                rows = GridCells.FixedSize(itemSize * 2),
+                modifier = Modifier.requiredSize(width = itemSize * 5, height = itemSize * 5),
+                verticalArrangement = Arrangement.Center,
+                state = state
+            ) {
+                items(100) { index ->
+                    Box(Modifier.size(itemSize).testTag(index.toString()))
+                }
+            }
+        }
+
+        rule.onNodeWithTag("0")
+            .assertTopPositionInRootIsEqualTo(itemSize * 0.5f)
+            .assertHeightIsEqualTo(itemSize * 2f)
+
+        rule.onNodeWithTag("1")
+            .assertTopPositionInRootIsEqualTo(itemSize * 2.5f)
+            .assertHeightIsEqualTo(itemSize * 2f)
+    }
+
+    @Test
+    fun vertical_nonDefaultCrossAxisArrangement() {
+        val state = LazyGridState()
+        rule.setContent {
+            LazyVerticalGrid(
+                columns = GridCells.FixedSize(itemSize * 2),
+                modifier = Modifier.requiredSize(width = itemSize * 5, height = itemSize * 5),
+                horizontalArrangement = Arrangement.Center,
+                state = state
+            ) {
+                items(100) { index ->
+                    Box(Modifier.size(itemSize).testTag(index.toString()))
+                }
+            }
+        }
+
+        rule.onNodeWithTag("0")
+            .assertLeftPositionInRootIsEqualTo(itemSize * 0.5f)
+            .assertWidthIsEqualTo(itemSize * 2f)
+
+        rule.onNodeWithTag("1")
+            .assertLeftPositionInRootIsEqualTo(itemSize * 2.5f)
+            .assertWidthIsEqualTo(itemSize * 2f)
+    }
+
+    @Test
+    fun horizontal_crossAxisArrangement_withAlignment() {
+        val state = LazyGridState()
+        rule.setContent {
+            LazyHorizontalGrid(
+                rows = GridCells.FixedSize(itemSize * 2),
+                modifier = Modifier.requiredSize(width = itemSize * 5, height = itemSize * 5),
+                verticalArrangement = Arrangement.spacedBy(itemSize * 0.5f, Alignment.Bottom),
+                state = state
+            ) {
+                items(100) { index ->
+                    Box(Modifier.size(itemSize).testTag(index.toString()))
+                }
+            }
+        }
+
+        rule.onNodeWithTag("0")
+            .assertTopPositionInRootIsEqualTo(itemSize * 0.5f)
+            .assertHeightIsEqualTo(itemSize * 2f)
+
+        rule.onNodeWithTag("1")
+            .assertTopPositionInRootIsEqualTo(itemSize * 3f)
+            .assertHeightIsEqualTo(itemSize * 2f)
+    }
+
+    @Test
+    fun vertical_crossAxisArrangement_withAlignment() {
+        val state = LazyGridState()
+        rule.setContent {
+            LazyVerticalGrid(
+                columns = GridCells.FixedSize(itemSize * 2),
+                modifier = Modifier.requiredSize(width = itemSize * 5, height = itemSize * 5),
+                horizontalArrangement = Arrangement.spacedBy(itemSize * 0.5f, Alignment.End),
+                state = state
+            ) {
+                items(100) { index ->
+                    Box(Modifier.size(itemSize).testTag(index.toString()))
+                }
+            }
+        }
+
+        rule.onNodeWithTag("0")
+            .assertLeftPositionInRootIsEqualTo(itemSize * 0.5f)
+            .assertWidthIsEqualTo(itemSize * 2f)
+
+        rule.onNodeWithTag("1")
+            .assertLeftPositionInRootIsEqualTo(itemSize * 3f)
+            .assertWidthIsEqualTo(itemSize * 2f)
+    }
+
     fun composeVerticalGridWith(arrangement: Arrangement.Vertical) {
         rule.setContent {
             LazyVerticalGrid(
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridTest.kt
index 24d20dd..b26ab18 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridTest.kt
@@ -18,6 +18,7 @@
 
 import android.os.Build
 import androidx.compose.foundation.AutoTestFrameClock
+import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.background
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.gestures.scrollBy
@@ -86,6 +87,7 @@
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
 
+@OptIn(ExperimentalFoundationApi::class)
 @MediumTest
 @RunWith(Parameterized::class)
 class LazyGridTest(
@@ -878,7 +880,8 @@
             .assertCrossAxisStartPositionInRootIsEqualTo(gridCrossAxisSizeDp * 2 / 3)
         rule.onNodeWithTag(tags[1])
             .assertCrossAxisStartPositionInRootIsEqualTo(gridCrossAxisSizeDp / 3)
-        rule.onNodeWithTag(tags[2]).assertCrossAxisStartPositionInRootIsEqualTo(0.dp)
+        rule.onNodeWithTag(tags[2])
+            .assertCrossAxisStartPositionInRootIsEqualTo(0.dp)
     }
 
     @Test
@@ -1464,6 +1467,54 @@
         expanded = true
         rule.waitForIdle()
     }
+
+    @Test
+    fun fixedSizeCell_forcesFixedSize() {
+        val state = LazyGridState()
+        val itemSizeDp = with(rule.density) { 100.toDp() }
+        rule.setContent {
+            LazyGrid(
+                cells = GridCells.FixedSize(itemSizeDp * 2),
+                modifier = Modifier.axisSize(crossAxis = itemSizeDp * 5, mainAxis = itemSizeDp * 5),
+                state = state
+            ) {
+                items(10) { index ->
+                    Box(Modifier.size(itemSizeDp).testTag(index.toString()))
+                }
+            }
+        }
+
+        rule.onNodeWithTag("0")
+            .assertCrossAxisStartPositionInRootIsEqualTo(0.dp)
+            .assertCrossAxisSizeIsEqualTo(itemSizeDp * 2)
+        rule.onNodeWithTag("1")
+            .assertCrossAxisStartPositionInRootIsEqualTo(itemSizeDp * 2f)
+            .assertCrossAxisSizeIsEqualTo(itemSizeDp * 2)
+    }
+
+    @Test
+    fun fixedSizeCell_smallContainer_matchesContainer() {
+        val state = LazyGridState()
+        val itemSizeDp = with(rule.density) { 100.toDp() }
+        rule.setContent {
+            LazyGrid(
+                cells = GridCells.FixedSize(itemSizeDp * 2),
+                modifier = Modifier.axisSize(crossAxis = itemSizeDp, mainAxis = itemSizeDp * 5),
+                state = state
+            ) {
+                items(10) { index ->
+                    Box(Modifier.size(itemSizeDp).testTag(index.toString()))
+                }
+            }
+        }
+
+        rule.onNodeWithTag("0")
+            .assertCrossAxisStartPositionInRootIsEqualTo(0.dp)
+            .assertCrossAxisSizeIsEqualTo(itemSizeDp)
+        rule.onNodeWithTag("1")
+            .assertCrossAxisStartPositionInRootIsEqualTo(0.dp)
+            .assertCrossAxisSizeIsEqualTo(itemSizeDp)
+    }
 }
 
 internal fun IntegerSubject.isEqualTo(expected: Int, tolerance: Int) {
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/ClickableTextTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/ClickableTextTest.kt
index 8bba29a2..b23e468 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/ClickableTextTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/ClickableTextTest.kt
@@ -29,13 +29,13 @@
 import androidx.compose.ui.text.AnnotatedString
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.argWhere
-import com.nhaarman.mockitokotlin2.inOrder
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
-import com.nhaarman.mockitokotlin2.verifyZeroInteractions
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argWhere
+import org.mockito.kotlin.inOrder
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.verifyNoMoreInteractions
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -119,7 +119,9 @@
                 verify().invoke(argWhere { it > 0 }) // move to different character
                 verifyNoMoreInteractions()
             }
-            verifyZeroInteractions(onClick)
+            // Using `verifyZeroInteractions` here inexplicably results in a build failure, but
+            // `verifyNoMoreInteractions` builds and is literally calling the same API.
+            verifyNoMoreInteractions(onClick)
         }
     }
 }
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextInlineContentTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextInlineContentTest.kt
index 38f29ed..0226267 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextInlineContentTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextInlineContentTest.kt
@@ -43,8 +43,8 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/MultiWidgetSelectionDelegateTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/MultiWidgetSelectionDelegateTest.kt
index 15d8b01..05fbc24 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/MultiWidgetSelectionDelegateTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/MultiWidgetSelectionDelegateTest.kt
@@ -40,8 +40,8 @@
 import androidx.test.filters.SdkSuppress
 import androidx.test.platform.app.InstrumentationRegistry
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.whenever
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionContainerFocusTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionContainerFocusTest.kt
index 0fe45bd..4abc2b5 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionContainerFocusTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionContainerFocusTest.kt
@@ -57,9 +57,9 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
 import java.util.concurrent.CountDownLatch
 import org.junit.Rule
 import org.junit.Test
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionContainerTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionContainerTest.kt
index 8842c04..54927cb 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionContainerTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionContainerTest.kt
@@ -79,9 +79,9 @@
 import androidx.test.filters.LargeTest
 import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
 import java.util.concurrent.CountDownLatch
 import kotlin.math.max
 import kotlin.math.sign
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text2/BasicTextField2SemanticsTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text2/BasicTextField2SemanticsTest.kt
index 2cc0f2a..53558f7 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text2/BasicTextField2SemanticsTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text2/BasicTextField2SemanticsTest.kt
@@ -3,9 +3,7 @@
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.text.BasicText
-import androidx.compose.foundation.text.InternalFoundationTextApi
 import androidx.compose.foundation.text.KeyboardOptions
-import androidx.compose.foundation.text.TextDelegate
 import androidx.compose.foundation.text.selection.fetchTextLayoutResult
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
@@ -16,6 +14,7 @@
 import androidx.compose.ui.semantics.SemanticsActions
 import androidx.compose.ui.semantics.SemanticsProperties
 import androidx.compose.ui.semantics.getOrNull
+import androidx.compose.ui.test.ExperimentalTestApi
 import androidx.compose.ui.test.SemanticsMatcher
 import androidx.compose.ui.test.SemanticsNodeInteraction
 import androidx.compose.ui.test.assert
@@ -23,23 +22,21 @@
 import androidx.compose.ui.test.assertTextEquals
 import androidx.compose.ui.test.hasImeAction
 import androidx.compose.ui.test.hasSetTextAction
+import androidx.compose.ui.test.isEnabled
 import androidx.compose.ui.test.isFocused
+import androidx.compose.ui.test.isNotEnabled
 import androidx.compose.ui.test.isNotFocused
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performSemanticsAction
 import androidx.compose.ui.test.performTextInput
-import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.test.performTextInputSelection
 import androidx.compose.ui.text.TextLayoutResult
 import androidx.compose.ui.text.TextRange
-import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.text.font.createFontFamilyResolver
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.TextFieldValue
-import androidx.compose.ui.unit.Density
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
-import androidx.test.platform.app.InstrumentationRegistry
 import com.google.common.truth.Truth.assertThat
 import org.junit.Rule
 import org.junit.Test
@@ -54,20 +51,6 @@
 
     private val Tag = "TextField"
 
-    private var defaultDensity = Density(1f)
-    private val context = InstrumentationRegistry.getInstrumentation().context
-    private val defaultFontFamilyResolver = createFontFamilyResolver(context)
-
-    @OptIn(InternalFoundationTextApi::class)
-    private var textLayoutState = TextLayoutState(
-        TextDelegate(
-            AnnotatedString(""),
-            TextStyle.Default,
-            fontFamilyResolver = defaultFontFamilyResolver,
-            density = defaultDensity
-        )
-    )
-
     @Test
     fun defaultSemantics() {
         rule.setContent {
@@ -108,6 +91,28 @@
     }
 
     @Test
+    fun semantics_enabledStatus() {
+        var enabled by mutableStateOf(true)
+        rule.setContent {
+            val state = remember { TextFieldState() }
+            BasicTextField2(
+                state = state,
+                modifier = Modifier.testTag(Tag),
+                enabled = enabled
+            )
+        }
+
+        rule.onNodeWithTag(Tag)
+            .assert(isEnabled())
+
+        enabled = false
+        rule.waitForIdle()
+
+        rule.onNodeWithTag(Tag)
+            .assert(isNotEnabled())
+    }
+
+    @Test
     fun semantics_clickAction() {
         rule.setContent {
             val state = remember { TextFieldState() }
@@ -207,6 +212,24 @@
         }
     }
 
+    @OptIn(ExperimentalTestApi::class)
+    @Test
+    fun inputSelection_changesSelectionState() {
+        val state = TextFieldState(TextFieldValue("hello"))
+        rule.setContent {
+            BasicTextField2(
+                state = state,
+                modifier = Modifier.testTag(Tag)
+            )
+        }
+
+        rule.onNodeWithTag(Tag).performTextInputSelection(TextRange(2))
+
+        rule.runOnIdle {
+            assertThat(state.value.selection).isEqualTo(TextRange(2))
+        }
+    }
+
     @Test
     fun textLayoutResultSemanticsAreSet_inTheFirstComposition() {
         val state = TextFieldState(TextFieldValue("hello"))
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text2/TextFieldCursorTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text2/TextFieldCursorTest.kt
index 7f0c58a..121f684 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text2/TextFieldCursorTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text2/TextFieldCursorTest.kt
@@ -21,12 +21,15 @@
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.text.BasicTextField
+import androidx.compose.foundation.text.TEST_FONT_FAMILY
+import androidx.compose.foundation.text.selection.LocalTextSelectionColors
+import androidx.compose.foundation.text.selection.TextSelectionColors
+import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
 import androidx.compose.runtime.snapshots.Snapshot
+import androidx.compose.testutils.assertDoesNotContainColor
 import androidx.compose.testutils.assertPixelColor
 import androidx.compose.testutils.assertPixels
 import androidx.compose.testutils.assertShape
@@ -47,7 +50,8 @@
 import androidx.compose.ui.test.hasSetTextAction
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.performClick
-import androidx.compose.ui.test.performTextReplacement
+import androidx.compose.ui.test.performTextInput
+import androidx.compose.ui.test.performTextInputSelection
 import androidx.compose.ui.text.TextLayoutResult
 import androidx.compose.ui.text.TextRange
 import androidx.compose.ui.text.TextStyle
@@ -66,7 +70,7 @@
 import org.junit.Rule
 import org.junit.Test
 
-@OptIn(ExperimentalFoundationApi::class)
+@OptIn(ExperimentalFoundationApi::class, ExperimentalTestApi::class)
 @LargeTest
 class TextFieldCursorTest {
 
@@ -80,38 +84,41 @@
         it.mainClock.autoAdvance = false
     }
 
-    private val boxPadding = 10.dp
+    private lateinit var state: TextFieldState
+
+    private val boxPadding = 8.dp
+    // Both TextField background and font color should be the same to make sure that only
+    // cursor is visible
+    private val contentColor = Color.White
     private val cursorColor = Color.Red
     private val textStyle = TextStyle(
-        color = Color.White,
-        background = Color.White,
-        fontSize = 10.sp
+        color = contentColor,
+        background = contentColor,
+        fontSize = 10.sp,
+        fontFamily = TEST_FONT_FAMILY
     )
 
-    private val textFieldWidth = 10.dp
-    private val textFieldHeight = 20.dp
-    private val textFieldBgColor = Color.White
     private var isFocused = false
-    private var cursorRect = Rect.Zero
+    private var textLayoutResult: TextLayoutResult? = null
+    private val cursorRect: Rect
+        // assume selection is collapsed
+        get() = textLayoutResult?.getCursorRect(state.value.selection.start) ?: Rect.Zero
 
-    private val bgModifier = Modifier.background(textFieldBgColor)
+    private val backgroundModifier = Modifier.background(contentColor)
     private val focusModifier = Modifier.onFocusChanged { if (it.isFocused) isFocused = true }
-    private val sizeModifier = Modifier.size(textFieldWidth, textFieldHeight)
 
     // default TextFieldModifier
-    private val textFieldModifier = sizeModifier
-        .then(bgModifier)
+    private val textFieldModifier = Modifier
+        .then(backgroundModifier)
         .then(focusModifier)
 
     // default onTextLayout to capture cursor boundaries.
-    private val onTextLayout: Density.(TextLayoutResult) -> Unit = {
-        cursorRect = it.getCursorRect(0)
-    }
+    private val onTextLayout: Density.(TextLayoutResult) -> Unit = { textLayoutResult = it }
 
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
-    fun textFieldFocused_cursorRendered() = with(rule.density) {
-        val state = TextFieldState()
+    fun textFieldFocused_cursorRendered() {
+        state = TextFieldState()
         rule.setContent {
             Box(Modifier.padding(boxPadding)) {
                 BasicTextField2(
@@ -128,29 +135,26 @@
 
         rule.mainClock.advanceTimeBy(100)
 
-        with(rule.density) {
-            rule.onNode(hasSetTextAction())
-                .captureToImage()
-                .assertCursor(2.dp, this, cursorRect)
-        }
+        rule.onNode(hasSetTextAction())
+            .captureToImage()
+            .assertCursor(2.dp, cursorRect)
     }
 
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
-    fun textFieldFocused_cursorWithBrush() = with(rule.density) {
-        val state = TextFieldState()
+    fun textFieldFocused_cursorWithBrush() {
+        state = TextFieldState()
         rule.setContent {
             Box(Modifier.padding(boxPadding)) {
                 BasicTextField2(
                     state = state,
                     textStyle = textStyle.copy(fontSize = textStyle.fontSize * 2),
                     modifier = Modifier
-                        .size(textFieldWidth, textFieldHeight * 2)
-                        .then(bgModifier)
+                        .then(backgroundModifier)
                         .then(focusModifier),
                     cursorBrush = Brush.verticalGradient(
-                        // make a brush double/triple color at the beginning and end so we have stable
-                        // colors at the ends.
+                        // make a brush double/triple color at the beginning and end so we have
+                        // stable colors at the ends.
                         // Without triple bottom, the bottom color never hits to the provided color.
                         listOf(
                             Color.Blue,
@@ -181,8 +185,8 @@
 
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
-    fun cursorBlinkingAnimation() = with(rule.density) {
-        val state = TextFieldState()
+    fun cursorBlinkingAnimation() {
+        state = TextFieldState()
         rule.setContent {
             // The padding helps if the test is run accidentally in landscape. Landscape makes
             // the cursor to be next to the navigation bar which affects the red color to be a bit
@@ -205,7 +209,7 @@
         with(rule.density) {
             rule.onNode(hasSetTextAction())
                 .captureToImage()
-                .assertCursor(2.dp, this, cursorRect)
+                .assertCursor(2.dp, cursorRect)
         }
 
         // cursor invisible during next 500 ms
@@ -215,8 +219,8 @@
             .assertShape(
                 density = rule.density,
                 shape = RectangleShape,
-                shapeColor = Color.White,
-                backgroundColor = Color.White,
+                shapeColor = contentColor,
+                backgroundColor = contentColor,
                 shapeOverlapPixelCount = 0.0f
             )
     }
@@ -225,9 +229,9 @@
     @OptIn(ExperimentalTestApi::class)
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
-    fun cursorBlinkingAnimation_whenSystemDisablesAnimations() = with(rule.density) {
+    fun cursorBlinkingAnimation_whenSystemDisablesAnimations() {
         motionDurationScale.scaleFactor = 0f
-        val state = TextFieldState()
+        state = TextFieldState()
 
         rule.setContent {
             // The padding helps if the test is run accidentally in landscape. Landscape makes
@@ -251,7 +255,7 @@
         with(rule.density) {
             rule.onNode(hasSetTextAction())
                 .captureToImage()
-                .assertCursor(2.dp, this, cursorRect)
+                .assertCursor(2.dp, cursorRect)
         }
 
         // cursor invisible during next 500 ms
@@ -261,23 +265,23 @@
             .assertShape(
                 density = rule.density,
                 shape = RectangleShape,
-                shapeColor = Color.White,
-                backgroundColor = Color.White,
+                shapeColor = contentColor,
+                backgroundColor = contentColor,
                 shapeOverlapPixelCount = 0.0f
             )
     }
 
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
-    fun cursorUnsetColor_noCursor() = with(rule.density) {
+    fun cursorUnsetColor_noCursor() {
+        state = TextFieldState(TextFieldValue("hello", selection = TextRange(2)))
         rule.setContent {
             // The padding helps if the test is run accidentally in landscape. Landscape makes
             // the cursor to be next to the navigation bar which affects the red color to be a bit
             // different - possibly anti-aliasing.
             Box(Modifier.padding(boxPadding)) {
-                BasicTextField(
-                    value = "",
-                    onValueChange = {},
+                BasicTextField2(
+                    state = state,
                     textStyle = textStyle,
                     modifier = textFieldModifier,
                     cursorBrush = SolidColor(Color.Unspecified)
@@ -293,8 +297,8 @@
             .assertShape(
                 density = rule.density,
                 shape = RectangleShape,
-                shapeColor = Color.White,
-                backgroundColor = Color.White,
+                shapeColor = contentColor,
+                backgroundColor = contentColor,
                 shapeOverlapPixelCount = 0.0f
             )
 
@@ -305,16 +309,16 @@
             .assertShape(
                 density = rule.density,
                 shape = RectangleShape,
-                shapeColor = Color.White,
-                backgroundColor = Color.White,
+                shapeColor = contentColor,
+                backgroundColor = contentColor,
                 shapeOverlapPixelCount = 0.0f
             )
     }
 
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
-    fun cursorNotBlinking_whileTyping() = with(rule.density) {
-        val state = TextFieldState(TextFieldValue("test"))
+    fun cursorNotBlinking_whileTyping() {
+        state = TextFieldState(TextFieldValue("test", selection = TextRange(4)))
         rule.setContent {
             // The padding helps if the test is run accidentally in landscape. Landscape makes
             // the cursor to be next to the navigation bar which affects the red color to be a bit
@@ -339,23 +343,20 @@
 
         // change text field value
         rule.onNode(hasSetTextAction())
-            .performTextReplacement("")
+            .performTextInput("s")
 
         // cursor would have been invisible during next 500 ms if cursor blinks while typing.
         // To prevent blinking while typing we restart animation when new symbol is typed.
-        rule.mainClock.advanceTimeBy(400)
-        with(rule.density) {
-            rule.onNode(hasSetTextAction())
-                .captureToImage()
-                .assertCursor(2.dp, this, cursorRect)
-        }
+        rule.mainClock.advanceTimeBy(300)
+        rule.onNode(hasSetTextAction())
+            .captureToImage()
+            .assertCursor(2.dp, cursorRect)
     }
 
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
-    fun selectionChanges_cursorNotBlinking() = with(rule.density) {
-        rule.mainClock.autoAdvance = false
-        val state = TextFieldState(TextFieldValue("test", selection = TextRange(2)))
+    fun selectionChanges_cursorNotBlinking() {
+        state = TextFieldState(TextFieldValue("test", selection = TextRange(2)))
         rule.setContent {
             // The padding helps if the test is run accidentally in landscape. Landscape makes
             // the cursor to be next to the navigation bar which affects the red color to be a bit
@@ -380,25 +381,22 @@
         // TODO(b/170298051) check here that cursor is visible when we have a way to control
         //  cursor position when sending a text
 
-        rule.runOnIdle {
-            state.editProcessor.reset(state.value.copy(selection = TextRange(0)))
-        }
+        rule.onNode(hasSetTextAction())
+            .performTextInputSelection(TextRange(0))
 
         // necessary for animation to start (shows cursor again)
         rule.mainClock.advanceTimeByFrame()
 
-        with(rule.density) {
-            rule.onNode(hasSetTextAction())
-                .captureToImage()
-                .assertCursor(2.dp, this, cursorRect)
-        }
+        rule.onNode(hasSetTextAction())
+            .captureToImage()
+            .assertCursor(2.dp, cursorRect)
     }
 
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     fun brushChanged_doesntResetTimer() {
         var cursorBrush by mutableStateOf(SolidColor(cursorColor))
-        val state = TextFieldState()
+        state = TextFieldState()
         rule.setContent {
             Box(Modifier.padding(boxPadding)) {
                 BasicTextField2(
@@ -422,21 +420,59 @@
             .assertShape(
                 density = rule.density,
                 shape = RectangleShape,
-                shapeColor = Color.White,
-                backgroundColor = Color.White,
+                shapeColor = contentColor,
+                backgroundColor = contentColor,
                 shapeOverlapPixelCount = 0.0f
             )
     }
 
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    fun selectionNotCollapsed_cursorNotDrawn() {
+        state = TextFieldState(TextFieldValue("test", selection = TextRange(2, 3)))
+        rule.setContent {
+            // The padding helps if the test is run accidentally in landscape. Landscape makes
+            // the cursor to be next to the navigation bar which affects the red color to be a bit
+            // different - possibly anti-aliasing.
+            Box(Modifier.padding(boxPadding)) {
+                // set selection highlight to a known color
+                CompositionLocalProvider(
+                    LocalTextSelectionColors provides TextSelectionColors(Color.Blue, Color.Blue)
+                ) {
+                    BasicTextField2(
+                        state = state,
+                        // make sure that background is not obstructing selection
+                        textStyle = textStyle.copy(
+                            background = Color.Unspecified
+                        ),
+                        modifier = textFieldModifier,
+                        cursorBrush = SolidColor(cursorColor),
+                        onTextLayout = onTextLayout
+                    )
+                }
+            }
+        }
+
+        focusAndWait()
+
+        // cursor should still be visible if there wasn't a selection
+        rule.mainClock.advanceTimeBy(300)
+        rule.mainClock.advanceTimeByFrame()
+
+        rule.onNode(hasSetTextAction())
+            .captureToImage()
+            .assertDoesNotContainColor(cursorColor)
+    }
+
     private fun focusAndWait() {
         rule.onNode(hasSetTextAction()).performClick()
         rule.mainClock.advanceTimeUntil { isFocused }
     }
 
-    private fun ImageBitmap.assertCursor(cursorWidth: Dp, density: Density, cursorRect: Rect) {
+    private fun ImageBitmap.assertCursor(cursorWidth: Dp, cursorRect: Rect) {
         assertThat(cursorRect.height).isNotEqualTo(0f)
         assertThat(cursorRect).isNotEqualTo(Rect.Zero)
-        val cursorWidthPx = (with(density) { cursorWidth.roundToPx() })
+        val cursorWidthPx = (with(rule.density) { cursorWidth.roundToPx() })
 
         // assert cursor width is greater than 2 since we will shrink the check area by 1 on each
         // side
@@ -471,14 +507,14 @@
                 null
             } else {
                 // text field background
-                textFieldBgColor
+                contentColor
             }
         }
     }
 
     @Test
     fun textFieldCursor_alwaysReadLatestState_duringDraw() {
-        val state = TextFieldState(TextFieldValue("hello world", TextRange(5)))
+        state = TextFieldState(TextFieldValue("hello world", TextRange(5)))
         rule.setContent {
             Box(Modifier.padding(boxPadding)) {
                 BasicTextField2(
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text2/TextFieldKeyEventTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text2/TextFieldKeyEventTest.kt
index 9b6d1b6..5deba74 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text2/TextFieldKeyEventTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text2/TextFieldKeyEventTest.kt
@@ -46,7 +46,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth
-import com.nhaarman.mockitokotlin2.mock
+import org.mockito.kotlin.mock
 import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/HardwareKeyboardTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/HardwareKeyboardTest.kt
index 5981847..f251e67 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/HardwareKeyboardTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/HardwareKeyboardTest.kt
@@ -49,7 +49,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.mock
+import org.mockito.kotlin.mock
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldOnValueChangeTextFieldValueTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldOnValueChangeTextFieldValueTest.kt
index 4f3caef..adda314 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldOnValueChangeTextFieldValueTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldOnValueChangeTextFieldValueTest.kt
@@ -41,13 +41,13 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.argumentCaptor
-import com.nhaarman.mockitokotlin2.clearInvocations
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldTest.kt
index ef5913b..990b749 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldTest.kt
@@ -150,12 +150,12 @@
 import androidx.testutils.fonts.R
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.argumentCaptor
-import com.nhaarman.mockitokotlin2.atLeastOnce
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
 import kotlin.test.assertFailsWith
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldUndoTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldUndoTest.kt
index 684d448..3ad3067 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldUndoTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldUndoTest.kt
@@ -36,7 +36,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.mock
+import org.mockito.kotlin.mock
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.android.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.android.kt
index 19a823d..4da7839 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.android.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.android.kt
@@ -17,32 +17,21 @@
 package androidx.compose.foundation.relocation
 
 import android.graphics.Rect as AndroidRect
-import android.view.View
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
 import androidx.compose.ui.geometry.Rect
-import androidx.compose.ui.layout.LayoutCoordinates
 import androidx.compose.ui.layout.positionInRoot
+import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
+import androidx.compose.ui.node.currentValueOf
 import androidx.compose.ui.platform.LocalView
 
-@Composable
-internal actual fun rememberDefaultBringIntoViewParent(): BringIntoViewParent {
-    val view = LocalView.current
-    return remember(view) { AndroidBringIntoViewParent(view) }
-}
-
-/**
- * A [BringIntoViewParent] that delegates to the [View] hosting the composition.
- */
-private class AndroidBringIntoViewParent(private val view: View) : BringIntoViewParent {
-    override suspend fun bringChildIntoView(
-        childCoordinates: LayoutCoordinates,
-        boundsProvider: () -> Rect?
-    ) {
+internal actual fun CompositionLocalConsumerModifierNode.defaultBringIntoViewParent():
+    BringIntoViewParent =
+    BringIntoViewParent { childCoordinates, boundsProvider ->
+        val view = currentValueOf(LocalView)
         val childOffset = childCoordinates.positionInRoot()
-        val rootRect = boundsProvider()?.translate(childOffset) ?: return
-        view.requestRectangleOnScreen(rootRect.toRect(), false)
+        val rootRect = boundsProvider()?.translate(childOffset)
+        if (rootRect != null) {
+            view.requestRectangleOnScreen(rootRect.toRect(), false)
+        }
     }
-}
 
 private fun Rect.toRect() = AndroidRect(left.toInt(), top.toInt(), right.toInt(), bottom.toInt())
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/BasicTextField2.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/BasicTextField2.kt
index 021f5e2..c51dd6e 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/BasicTextField2.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/BasicTextField2.kt
@@ -27,18 +27,15 @@
 import androidx.compose.foundation.text.KeyboardOptions
 import androidx.compose.foundation.text.TextDelegate
 import androidx.compose.foundation.text.heightInLines
-import androidx.compose.foundation.text.selection.LocalTextSelectionColors
 import androidx.compose.foundation.text.selection.SimpleLayout
 import androidx.compose.foundation.text.textFieldMinSize
 import androidx.compose.foundation.text2.service.AndroidTextInputPlugin
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.drawBehind
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.SolidColor
-import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
 import androidx.compose.ui.layout.FirstBaseline
 import androidx.compose.ui.layout.LastBaseline
 import androidx.compose.ui.layout.Layout
@@ -47,7 +44,6 @@
 import androidx.compose.ui.platform.LocalFontFamilyResolver
 import androidx.compose.ui.platform.LocalPlatformTextInputPluginRegistry
 import androidx.compose.ui.text.TextLayoutResult
-import androidx.compose.ui.text.TextPainter
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.KeyboardType
@@ -115,7 +111,6 @@
 
     val fontFamilyResolver = LocalFontFamilyResolver.current
     val density = LocalDensity.current
-    val selectionBackgroundColor = LocalTextSelectionColors.current.backgroundColor
     val singleLine = minLines == 1 && maxLines == 1
     // We're using this to communicate focus state to cursor for now.
     @Suppress("NAME_SHADOWING")
@@ -134,33 +129,6 @@
         )
     }
 
-    val drawModifier = Modifier.drawBehind {
-        textLayoutState.layoutResult?.let { layoutResult ->
-            // draw selection
-            val value = state.value
-            if (!value.selection.collapsed) {
-                val start = value.selection.min
-                val end = value.selection.max
-                if (start != end) {
-                    val selectionPath = layoutResult.getPathForRange(start, end)
-                    drawPath(selectionPath, color = selectionBackgroundColor)
-                }
-            }
-            // draw text
-            drawIntoCanvas { canvas ->
-                TextPainter.paint(canvas, layoutResult)
-            }
-        }
-    }
-
-    val cursorModifier = Modifier.cursor(
-        textLayoutState = textLayoutState,
-        isFocused = interactionSource.collectIsFocusedAsState().value,
-        state = state,
-        cursorBrush = cursorBrush,
-        enabled = enabled && !readOnly
-    )
-
     val decorationModifiers = modifier
         .then(
             // semantics + some focus + input session + touch to focus
@@ -184,9 +152,14 @@
                     minLines = minLines,
                     maxLines = maxLines
                 )
-                .then(drawModifier)
                 .textFieldMinSize(textStyle)
-                .then(cursorModifier)
+                .then(TextFieldCoreModifierElement(
+                    isFocused = interactionSource.collectIsFocusedAsState().value,
+                    textLayoutState = textLayoutState,
+                    textFieldState = state,
+                    cursorBrush = cursorBrush,
+                    writeable = enabled && !readOnly
+                ))
                 .onGloballyPositioned {
                     textLayoutState.proxy?.innerTextFieldCoordinates = it
                 }
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/TextFieldCoreModifier.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/TextFieldCoreModifier.kt
new file mode 100644
index 0000000..f2e0235
--- /dev/null
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/TextFieldCoreModifier.kt
@@ -0,0 +1,249 @@
+/*
+ * 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.compose.foundation.text2
+
+import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.AnimationSpec
+import androidx.compose.animation.core.infiniteRepeatable
+import androidx.compose.animation.core.keyframes
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.text.selection.LocalTextSelectionColors
+import androidx.compose.runtime.snapshotFlow
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.MotionDurationScale
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Brush
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.graphics.drawscope.ContentDrawScope
+import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
+import androidx.compose.ui.graphics.isUnspecified
+import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
+import androidx.compose.ui.node.DrawModifierNode
+import androidx.compose.ui.node.ModifierNodeElement
+import androidx.compose.ui.node.currentValueOf
+import androidx.compose.ui.platform.InspectorInfo
+import androidx.compose.ui.text.TextLayoutResult
+import androidx.compose.ui.text.TextPainter
+import androidx.compose.ui.text.TextRange
+import androidx.compose.ui.unit.dp
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+/**
+ * Modifier element for the core functionality of [BasicTextField2] that is passed as inner
+ * TextField to the decoration box. This is only half the actual modifiers for the field, the other
+ * half are only attached to the decorated text field.
+ *
+ * This modifier mostly handles layout and draw.
+ */
+@OptIn(ExperimentalFoundationApi::class)
+internal data class TextFieldCoreModifierElement(
+    private val isFocused: Boolean,
+    private val textLayoutState: TextLayoutState,
+    private val textFieldState: TextFieldState,
+    private val cursorBrush: Brush,
+    private val writeable: Boolean
+) : ModifierNodeElement<TextFieldCoreModifierNode>() {
+
+    override fun create(): TextFieldCoreModifierNode = TextFieldCoreModifierNode(
+        isFocused = isFocused,
+        textLayoutState = textLayoutState,
+        textFieldState = textFieldState,
+        cursorBrush = cursorBrush,
+        writable = writeable
+    )
+
+    override fun update(node: TextFieldCoreModifierNode): TextFieldCoreModifierNode {
+        node.updateNode(
+            isFocused = isFocused,
+            textLayoutState = textLayoutState,
+            textFieldState = textFieldState,
+            cursorBrush = cursorBrush,
+            writeable = writeable
+        )
+        return node
+    }
+
+    override fun InspectorInfo.inspectableProperties() {
+        // no inspector info
+    }
+}
+
+/** Modifier node for [TextFieldCoreModifierElement]. */
+@OptIn(ExperimentalFoundationApi::class)
+internal class TextFieldCoreModifierNode(
+    private var isFocused: Boolean,
+    private var textLayoutState: TextLayoutState,
+    private var textFieldState: TextFieldState,
+    private var cursorBrush: Brush,
+    private var writable: Boolean
+) : Modifier.Node(),
+    DrawModifierNode,
+    CompositionLocalConsumerModifierNode {
+
+    /**
+     * Animatable object for cursor's alpha value. Cursor is always drawn, only its alpha gets
+     * animated.
+     */
+    private val cursorAlpha = Animatable(1f)
+
+    /**
+     * Whether to show cursor at all when TextField has focus. This depends on enabled, read only,
+     * and brush at a given time.
+     */
+    private val showCursor: Boolean
+        get() = writable && isFocused && cursorBrush.isSpecified
+
+    /**
+     * Observes the [textFieldState] for any changes to content or selection. If a change happens,
+     * cursor blink animation gets reset.
+     */
+    private var changeObserverJob: Job? = null
+
+    /**
+     * Updates all the related properties and invalidates internal state based on the changes.
+     */
+    fun updateNode(
+        isFocused: Boolean,
+        textLayoutState: TextLayoutState,
+        textFieldState: TextFieldState,
+        cursorBrush: Brush,
+        writeable: Boolean
+    ) {
+        val wasFocused = this.isFocused
+        val previousTextFieldState = this.textFieldState
+
+        this.isFocused = isFocused
+        this.textLayoutState = textLayoutState
+        this.textFieldState = textFieldState
+        this.cursorBrush = cursorBrush
+        this.writable = writeable
+
+        if (!showCursor) {
+            changeObserverJob?.cancel()
+            changeObserverJob = null
+        } else if (!wasFocused || previousTextFieldState != textFieldState) {
+            // this node is writeable, focused and gained that focus just now.
+            // start the state value observation
+            changeObserverJob = coroutineScope.launch {
+                // Animate the cursor even when animations are disabled by the system.
+                withContext(FixedMotionDurationScale) {
+                    snapshotFlow { textFieldState.value }
+                        .collectLatest {
+                            // ensure that the value is always 1f _this_ frame by calling snapTo
+                            cursorAlpha.snapTo(1f)
+                            // then start the cursor blinking on animation clock (500ms on to start)
+                            cursorAlpha.animateTo(0f, cursorAnimationSpec)
+                        }
+                }
+            }
+        }
+    }
+
+    override fun ContentDrawScope.draw() {
+        drawContent()
+        val value = textFieldState.value
+        val textLayoutResult = textLayoutState.layoutResult ?: return
+
+        if (value.selection.collapsed) {
+            drawText(textLayoutResult)
+            drawCursor(value.selection, textLayoutResult)
+        } else {
+            drawSelection(value.selection, textLayoutResult)
+            drawText(textLayoutResult)
+        }
+    }
+
+    /**
+     * Draws the selection highlight.
+     */
+    private fun ContentDrawScope.drawSelection(
+        selection: TextRange,
+        textLayoutResult: TextLayoutResult
+    ) {
+        val start = selection.min
+        val end = selection.max
+        if (start != end) {
+            val selectionBackgroundColor = currentValueOf(LocalTextSelectionColors)
+                .backgroundColor
+            val selectionPath = textLayoutResult.getPathForRange(start, end)
+            drawPath(selectionPath, color = selectionBackgroundColor)
+        }
+    }
+
+    /**
+     * Draws the text content.
+     */
+    private fun ContentDrawScope.drawText(textLayoutResult: TextLayoutResult) {
+        drawIntoCanvas { canvas ->
+            TextPainter.paint(canvas, textLayoutResult)
+        }
+    }
+
+    /**
+     * Draws the cursor indicator. Do not confuse it with cursor handle which is a popup that
+     * carries the cursor movement gestures.
+     */
+    private fun ContentDrawScope.drawCursor(
+        selection: TextRange,
+        textLayoutResult: TextLayoutResult
+    ) {
+        if (!showCursor) return
+
+        val cursorAlphaValue = cursorAlpha.value.coerceIn(0f, 1f)
+        if (cursorAlphaValue == 0f) return
+
+        val cursorRect = textLayoutResult.getCursorRect(selection.start)
+        val cursorWidth = DefaultCursorThickness.toPx()
+        val cursorX = (cursorRect.left + cursorWidth / 2)
+            .coerceAtMost(size.width - cursorWidth / 2)
+
+        drawLine(
+            cursorBrush,
+            Offset(cursorX, cursorRect.top),
+            Offset(cursorX, cursorRect.bottom),
+            alpha = cursorAlphaValue,
+            strokeWidth = cursorWidth
+        )
+    }
+}
+
+private val cursorAnimationSpec: AnimationSpec<Float> = infiniteRepeatable(
+    animation = keyframes {
+        durationMillis = 1000
+        1f at 0
+        1f at 499
+        0f at 500
+        0f at 999
+    }
+)
+
+private val DefaultCursorThickness = 2.dp
+
+/**
+ * If brush has a specified color. It's possible that [SolidColor] contains [Color.Unspecified].
+ */
+private val Brush.isSpecified: Boolean
+    get() = !(this is SolidColor && this.value.isUnspecified)
+
+private object FixedMotionDurationScale : MotionDurationScale {
+    override val scaleFactor: Float
+        get() = 1f
+}
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/TextFieldCursor.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/TextFieldCursor.kt
deleted file mode 100644
index bcdd029..0000000
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/TextFieldCursor.kt
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.foundation.text2
-
-import androidx.compose.animation.core.Animatable
-import androidx.compose.animation.core.AnimationSpec
-import androidx.compose.animation.core.infiniteRepeatable
-import androidx.compose.animation.core.keyframes
-import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.snapshots.Snapshot
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.MotionDurationScale
-import androidx.compose.ui.composed
-import androidx.compose.ui.draw.drawWithContent
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.geometry.Rect
-import androidx.compose.ui.graphics.Brush
-import androidx.compose.ui.graphics.SolidColor
-import androidx.compose.ui.graphics.isUnspecified
-import androidx.compose.ui.unit.dp
-import kotlinx.coroutines.withContext
-
-@OptIn(ExperimentalFoundationApi::class)
-internal fun Modifier.cursor(
-    textLayoutState: TextLayoutState,
-    isFocused: Boolean,
-    state: TextFieldState,
-    cursorBrush: Brush,
-    enabled: Boolean
-) = if (enabled) composed {
-    val cursorAlpha = remember { Animatable(1f) }
-    val isBrushSpecified = !(cursorBrush is SolidColor && cursorBrush.value.isUnspecified)
-    val value = state.value
-    if (isFocused && value.selection.collapsed && isBrushSpecified) {
-        LaunchedEffect(value.annotatedString, value.selection) {
-            // Animate the cursor even when animations are disabled by the system.
-            withContext(FixedMotionDurationScale) {
-                // ensure that the value is always 1f _this_ frame by calling snapTo
-                cursorAlpha.snapTo(1f)
-                // then start the cursor blinking on animation clock (500ms on to start)
-                cursorAlpha.animateTo(0f, cursorAnimationSpec)
-            }
-        }
-        drawWithContent {
-            this.drawContent()
-            // re-read from state value to make sure that we have the latest snapshot state that
-            // should be in line with the layout in textLayoutState
-            val selectionStart = Snapshot.withoutReadObservation { state.value.selection.start }
-            val cursorAlphaValue = cursorAlpha.value.coerceIn(0f, 1f)
-            if (cursorAlphaValue != 0f) {
-                val cursorRect = textLayoutState.layoutResult?.getCursorRect(selectionStart)
-                    ?: Rect(0f, 0f, 0f, 0f)
-                val cursorWidth = DefaultCursorThickness.toPx()
-                val cursorX = (cursorRect.left + cursorWidth / 2)
-                    .coerceAtMost(size.width - cursorWidth / 2)
-
-                drawLine(
-                    cursorBrush,
-                    Offset(cursorX, cursorRect.top),
-                    Offset(cursorX, cursorRect.bottom),
-                    alpha = cursorAlphaValue,
-                    strokeWidth = cursorWidth
-                )
-            }
-        }
-    } else {
-        Modifier
-    }
-} else this
-
-private val cursorAnimationSpec: AnimationSpec<Float> = infiniteRepeatable(
-    animation = keyframes {
-        durationMillis = 1000
-        1f at 0
-        1f at 499
-        0f at 500
-        0f at 999
-    }
-)
-
-internal val DefaultCursorThickness = 2.dp
-
-private object FixedMotionDurationScale : MotionDurationScale {
-    override val scaleFactor: Float
-        get() = 1f
-}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/TextFieldDecoratorModifier.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/TextFieldDecoratorModifier.kt
index 86a7087..7d1bd87 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/TextFieldDecoratorModifier.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/TextFieldDecoratorModifier.kt
@@ -46,10 +46,12 @@
 import androidx.compose.ui.semantics.imeAction
 import androidx.compose.ui.semantics.insertTextAtCursor
 import androidx.compose.ui.semantics.onClick
+import androidx.compose.ui.semantics.setSelection
 import androidx.compose.ui.semantics.setText
 import androidx.compose.ui.semantics.textSelectionRange
 import androidx.compose.ui.text.AnnotatedString
 import androidx.compose.ui.text.TextRange
+import androidx.compose.ui.text.input.TextFieldValue
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.util.fastAny
 
@@ -116,8 +118,11 @@
     PointerInputModifierNode,
     KeyInputModifierNode {
 
+    // semantics properties that require semantics invalidation
     private var lastText: AnnotatedString? = null
     private var lastSelection: TextRange? = null
+    private var lastEnabled: Boolean = enabled
+
     private var isFocused: Boolean = false
     private var semanticsConfigurationCache: SemanticsConfiguration? = null
     private var textInputSession: TextInputSession? = null
@@ -183,7 +188,8 @@
             // selection might change without triggering a modifier update.
             if (localSemantics == null ||
                 lastText != value.annotatedString ||
-                lastSelection != value.selection
+                lastSelection != value.selection ||
+                lastEnabled != enabled
             ) {
                 localSemantics = generateSemantics(value.annotatedString, value.selection)
             }
@@ -255,6 +261,7 @@
     ): SemanticsConfiguration {
         lastText = text
         lastSelection = selection
+        lastEnabled = enabled
         return SemanticsConfiguration().apply {
             this.isMergingSemanticsOfDescendants = true
             getTextLayoutResult {
@@ -274,6 +281,30 @@
                 )
                 true
             }
+            setSelection { start, end, _ ->
+                // BasicTextField2 doesn't have VisualTransformation for the time being and
+                // probably won't have something that uses offsetMapping design. We can safely
+                // skip relativeToOriginalText flag. Assume it's always true.
+
+                if (!enabled) {
+                    false
+                } else if (start == selection.start && end == selection.end) {
+                    false
+                } else if (start.coerceAtMost(end) >= 0 &&
+                    start.coerceAtLeast(end) <= text.length
+                ) {
+                    // reset is required to make sure IME gets the update.
+                    textFieldState.editProcessor.reset(
+                        TextFieldValue(
+                            annotatedString = text,
+                            selection = TextRange(start, end)
+                        )
+                    )
+                    true
+                } else {
+                    false
+                }
+            }
             insertTextAtCursor { text ->
                 textFieldState.editProcessor.update(
                     listOf(
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/TextFieldKeyEventHandler.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/TextFieldKeyEventHandler.kt
index 158a2d4..629b60a 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/TextFieldKeyEventHandler.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/TextFieldKeyEventHandler.kt
@@ -28,7 +28,6 @@
 import androidx.compose.foundation.text2.input.DeleteSurroundingTextCommand
 import androidx.compose.foundation.text2.input.EditCommand
 import androidx.compose.foundation.text2.input.FinishComposingTextCommand
-import androidx.compose.foundation.text2.input.SetSelectionCommand
 import androidx.compose.ui.input.key.KeyEvent
 import androidx.compose.ui.input.key.KeyEventType
 import androidx.compose.ui.input.key.type
@@ -216,11 +215,9 @@
         preparedSelection.block()
         if (preparedSelection.selection != preparedSelection.initialValue.selection) {
             // update the editProcessor with the latest selection state.
-            state.editProcessor.update(
-                listOf(SetSelectionCommand(
-                    preparedSelection.selection.start,
-                    preparedSelection.selection.end
-                ))
+            // this has to be a reset because EditCommands do not inform IME.
+            state.editProcessor.reset(
+                preparedSelection.initialValue.copy(selection = preparedSelection.selection)
             )
         }
     }
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 b379cad..704d6ef 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
@@ -55,7 +55,7 @@
     /** State controlling the scroll position */
     state: LazyGridState,
     /** Prefix sums of cross axis sizes of slots per line, e.g. the columns for vertical grid. */
-    slotSizesSums: Density.(Constraints) -> List<Int>,
+    slots: Density.(Constraints) -> LazyGridSlots,
     /** The inner padding to be added for the whole content (not for each individual item) */
     contentPadding: PaddingValues = PaddingValues(0.dp),
     /** reverse the direction of scrolling and layout */
@@ -88,7 +88,7 @@
     val measurePolicy = rememberLazyGridMeasurePolicy(
         itemProvider,
         state,
-        slotSizesSums,
+        slots,
         contentPadding,
         reverseLayout,
         isVertical,
@@ -146,6 +146,12 @@
     }
 }
 
+/** lazy grid slots configuration */
+internal class LazyGridSlots(
+    val sizes: IntArray,
+    val positions: IntArray
+)
+
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
 private fun rememberLazyGridMeasurePolicy(
@@ -154,7 +160,7 @@
     /** The state of the list. */
     state: LazyGridState,
     /** Prefix sums of cross axis sizes of slots of the grid. */
-    slotSizesSums: Density.(Constraints) -> List<Int>,
+    slots: Density.(Constraints) -> LazyGridSlots,
     /** The inner padding to be added for the whole content(nor for each individual item) */
     contentPadding: PaddingValues,
     /** reverse the direction of scrolling and layout */
@@ -169,7 +175,7 @@
     placementAnimator: LazyGridItemPlacementAnimator
 ) = remember<LazyLayoutMeasureScope.(Constraints) -> MeasureResult>(
     state,
-    slotSizesSums,
+    slots,
     contentPadding,
     reverseLayout,
     isVertical,
@@ -217,12 +223,13 @@
         state.updateScrollPositionIfTheFirstItemWasMoved(itemProvider)
 
         val spanLayoutProvider = itemProvider.spanLayoutProvider
-        val resolvedSlotSizesSums = slotSizesSums(containerConstraints)
-        spanLayoutProvider.slotsPerLine = resolvedSlotSizesSums.size
+        val resolvedSlots = slots(containerConstraints)
+        val slotsPerLine = resolvedSlots.sizes.size
+        spanLayoutProvider.slotsPerLine = slotsPerLine
 
         // Update the state's cached Density and slotsPerLine
         state.density = this
-        state.slotsPerLine = resolvedSlotSizesSums.size
+        state.slotsPerLine = slotsPerLine
 
         val spaceBetweenLinesDp = if (isVertical) {
             requireNotNull(verticalArrangement).spacing
@@ -230,13 +237,6 @@
             requireNotNull(horizontalArrangement).spacing
         }
         val spaceBetweenLines = spaceBetweenLinesDp.roundToPx()
-        val spaceBetweenSlotsDp = if (isVertical) {
-            horizontalArrangement?.spacing ?: 0.dp
-        } else {
-            verticalArrangement?.spacing ?: 0.dp
-        }
-        val spaceBetweenSlots = spaceBetweenSlotsDp.roundToPx()
-
         val itemsCount = itemProvider.itemCount
 
         // can be negative if the content padding is larger than the max size from constraints
@@ -278,23 +278,22 @@
             )
         }
         val measuredLineProvider = LazyGridMeasuredLineProvider(
-            isVertical,
-            resolvedSlotSizesSums,
-            spaceBetweenSlots,
-            itemsCount,
-            spaceBetweenLines,
-            measuredItemProvider,
-            spanLayoutProvider
+            isVertical = isVertical,
+            slots = resolvedSlots,
+            gridItemsCount = itemsCount,
+            spaceBetweenLines = spaceBetweenLines,
+            measuredItemProvider = measuredItemProvider,
+            spanLayoutProvider = spanLayoutProvider
         ) { index, items, spans, mainAxisSpacing ->
             LazyGridMeasuredLine(
                 index = index,
                 items = items,
                 spans = spans,
+                slots = resolvedSlots,
                 isVertical = isVertical,
-                slotsPerLine = resolvedSlotSizesSums.size,
+                slotsPerLine = slotsPerLine,
                 layoutDirection = layoutDirection,
                 mainAxisSpacing = mainAxisSpacing,
-                crossAxisSpacing = spaceBetweenSlots
             )
         }
         state.prefetchInfoRetriever = { line ->
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt
index 1ddb480..5492a12 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt
@@ -73,9 +73,8 @@
     userScrollEnabled: Boolean = true,
     content: LazyGridScope.() -> Unit
 ) {
-    val slotSizesSums = rememberColumnWidthSums(columns, horizontalArrangement, contentPadding)
     LazyGrid(
-        slotSizesSums = slotSizesSums,
+        slots = rememberColumnWidthSums(columns, horizontalArrangement, contentPadding),
         modifier = modifier,
         state = state,
         contentPadding = contentPadding,
@@ -127,9 +126,8 @@
     userScrollEnabled: Boolean = true,
     content: LazyGridScope.() -> Unit
 ) {
-    val slotSizesSums = rememberRowHeightSums(rows, verticalArrangement, contentPadding)
     LazyGrid(
-        slotSizesSums = slotSizesSums,
+        slots = rememberRowHeightSums(rows, verticalArrangement, contentPadding),
         modifier = modifier,
         state = state,
         contentPadding = contentPadding,
@@ -144,18 +142,17 @@
 }
 
 /** Returns prefix sums of column widths. */
-@OptIn(ExperimentalFoundationApi::class)
 @Composable
 private fun rememberColumnWidthSums(
     columns: GridCells,
     horizontalArrangement: Arrangement.Horizontal,
     contentPadding: PaddingValues
-) = remember<Density.(Constraints) -> List<Int>>(
+) = remember<Density.(Constraints) -> LazyGridSlots>(
     columns,
     horizontalArrangement,
     contentPadding,
 ) {
-    { constraints ->
+    GridSlotCache { constraints ->
         require(constraints.maxWidth != Constraints.Infinity) {
             "LazyVerticalGrid's width should be bound by parent."
         }
@@ -166,28 +163,29 @@
             calculateCrossAxisCellSizes(
                 gridWidth,
                 horizontalArrangement.spacing.roundToPx()
-            ).toMutableList().apply {
-                for (i in 1 until size) {
-                    this[i] += this[i - 1]
+            ).toIntArray().let { sizes ->
+                val positions = IntArray(sizes.size)
+                with(horizontalArrangement) {
+                    arrange(gridWidth, sizes, LayoutDirection.Ltr, positions)
                 }
+                LazyGridSlots(sizes, positions)
             }
         }
     }
 }
 
 /** Returns prefix sums of row heights. */
-@OptIn(ExperimentalFoundationApi::class)
 @Composable
 private fun rememberRowHeightSums(
     rows: GridCells,
     verticalArrangement: Arrangement.Vertical,
     contentPadding: PaddingValues
-) = remember<Density.(Constraints) -> List<Int>>(
+) = remember<Density.(Constraints) -> LazyGridSlots>(
     rows,
     verticalArrangement,
     contentPadding,
 ) {
-    { constraints ->
+    GridSlotCache { constraints ->
         require(constraints.maxHeight != Constraints.Infinity) {
             "LazyHorizontalGrid's height should be bound by parent."
         }
@@ -198,10 +196,39 @@
             calculateCrossAxisCellSizes(
                 gridHeight,
                 verticalArrangement.spacing.roundToPx()
-            ).toMutableList().apply {
-                for (i in 1 until size) {
-                    this[i] += this[i - 1]
+            ).toIntArray().let { sizes ->
+                val positions = IntArray(sizes.size)
+                with(verticalArrangement) {
+                    arrange(gridHeight, sizes, positions)
                 }
+                LazyGridSlots(sizes, positions)
+            }
+        }
+    }
+}
+
+/** measurement cache to avoid recalculating row/column sizes on each scroll. */
+private class GridSlotCache(
+    private val calculation: Density.(Constraints) -> LazyGridSlots
+) : (Density, Constraints) -> LazyGridSlots {
+    private var cachedConstraints = Constraints()
+    private var cachedDensity: Float = 0f
+    private var cachedSizes: LazyGridSlots? = null
+
+    override fun invoke(density: Density, constraints: Constraints): LazyGridSlots {
+        with(density) {
+            if (
+                cachedSizes != null &&
+                cachedConstraints == constraints &&
+                cachedDensity == this.density
+            ) {
+                return cachedSizes!!
+            }
+
+            cachedConstraints = constraints
+            cachedDensity = this.density
+            return calculation(constraints).also {
+                cachedSizes = it
             }
         }
     }
@@ -239,7 +266,7 @@
      */
     class Fixed(private val count: Int) : GridCells {
         init {
-            require(count > 0)
+            require(count > 0) { "Provided count $count should be larger than zero" }
         }
 
         override fun Density.calculateCrossAxisCellSizes(
@@ -269,7 +296,7 @@
      */
     class Adaptive(private val minSize: Dp) : GridCells {
         init {
-            require(minSize > 0.dp)
+            require(minSize > 0.dp) { "Provided min size $minSize should be larger than zero." }
         }
 
         override fun Density.calculateCrossAxisCellSizes(
@@ -288,6 +315,45 @@
             return other is Adaptive && minSize == other.minSize
         }
     }
+
+    /**
+     * Defines a grid with as many rows or columns as possible on the condition that
+     * every cell takes exactly [size] space. The remaining space will be arranged through
+     * [LazyGrid] arrangements on corresponding axis. If [size] is larger than
+     * container size, the cell will be size to match the container.
+     *
+     * For example, for the vertical [LazyGrid] FixedSize(20.dp) would mean that
+     * there will be as many columns as possible and every column will be exactly 20.dp.
+     * If the screen is 88.dp wide tne there will be 4 columns 20.dp each with remaining 8.dp
+     * distributed through [Arrangement.Horizontal].
+     */
+    @ExperimentalFoundationApi
+    class FixedSize(private val size: Dp) : GridCells {
+        init {
+            require(size > 0.dp) { "Provided size $size should be larger than zero." }
+        }
+
+        override fun Density.calculateCrossAxisCellSizes(
+            availableSize: Int,
+            spacing: Int
+        ): List<Int> {
+            val cellSize = size.roundToPx()
+            return if (cellSize + spacing < availableSize + spacing) {
+                val cellCount = (availableSize + spacing) / (cellSize + spacing)
+                List(cellCount) { cellSize }
+            } else {
+                List(1) { availableSize }
+            }
+        }
+
+        override fun hashCode(): Int {
+            return size.hashCode()
+        }
+
+        override fun equals(other: Any?): Boolean {
+            return other is FixedSize && size == other.size
+        }
+    }
 }
 
 private fun calculateCellsCrossAxisSizeImpl(
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLine.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLine.kt
index efc095e..b70f8bf 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLine.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLine.kt
@@ -27,6 +27,7 @@
 internal class LazyGridMeasuredLine constructor(
     val index: LineIndex,
     val items: Array<LazyGridMeasuredItem>,
+    private val slots: LazyGridSlots,
     private val spans: List<GridItemSpan>,
     private val isVertical: Boolean,
     private val slotsPerLine: Int,
@@ -35,7 +36,6 @@
      * Spacing to be added after [mainAxisSize], in the main axis direction.
      */
     private val mainAxisSpacing: Int,
-    private val crossAxisSpacing: Int
 ) {
     /**
      * Main axis size of the line - the max main axis size of the items on the line.
@@ -70,25 +70,19 @@
         layoutWidth: Int,
         layoutHeight: Int
     ): List<LazyGridPositionedItem> {
-        var usedCrossAxis = 0
         var usedSpan = 0
         return items.mapIndexed { itemIndex, item ->
             val span = spans[itemIndex].currentLineSpan
-            val startSlot = if (layoutDirection == LayoutDirection.Rtl) {
-                slotsPerLine - usedSpan - span
-            } else {
-                usedSpan
-            }
+            val startSlot = usedSpan
 
             item.position(
                 mainAxisOffset = offset,
-                crossAxisOffset = usedCrossAxis,
+                crossAxisOffset = slots.positions[startSlot],
                 layoutWidth = layoutWidth,
                 layoutHeight = layoutHeight,
                 row = if (isVertical) index.value else startSlot,
                 column = if (isVertical) startSlot else index.value
             ).also {
-                usedCrossAxis += item.crossAxisSize + crossAxisSpacing
                 usedSpan += span
             }
         }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLineProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLineProvider.kt
index 1645d29..f0d8250 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLineProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLineProvider.kt
@@ -26,8 +26,7 @@
 @OptIn(ExperimentalFoundationApi::class)
 internal class LazyGridMeasuredLineProvider(
     private val isVertical: Boolean,
-    private val slotSizesSums: List<Int>,
-    private val crossAxisSpacing: Int,
+    private val slots: LazyGridSlots,
     private val gridItemsCount: Int,
     private val spaceBetweenLines: Int,
     private val measuredItemProvider: LazyGridMeasuredItemProvider,
@@ -36,10 +35,12 @@
 ) {
     // The constraints for cross axis size. The main axis is not restricted.
     internal fun childConstraints(startSlot: Int, span: Int): Constraints {
-        val lastSlotSum = slotSizesSums[startSlot + span - 1]
-        val prevSlotSum = if (startSlot == 0) 0 else slotSizesSums[startSlot - 1]
-        val slotsSize = lastSlotSum - prevSlotSum
-        val crossAxisSize = (slotsSize + crossAxisSpacing * (span - 1)).coerceAtLeast(0)
+        val crossAxisSize = if (span == 1) {
+            slots.sizes[startSlot]
+        } else {
+            val endSlot = startSlot + span - 1
+            slots.positions[endSlot] + slots.sizes[endSlot] - slots.positions[startSlot]
+        }.coerceAtLeast(0)
         return if (isVertical) {
             Constraints.fixedWidth(crossAxisSize)
         } else {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridCells.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridCells.kt
index a783690..a71cf51 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridCells.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridCells.kt
@@ -123,8 +123,8 @@
             spacing: Int
         ): IntArray {
             val cellSize = size.roundToPx()
-            return if (cellSize + spacing < availableSize) {
-                val cellCount = availableSize / (cellSize + spacing)
+            return if (cellSize + spacing < availableSize + spacing) {
+                val cellCount = (availableSize + spacing) / (cellSize + spacing)
                 IntArray(cellCount) { cellSize }
             } else {
                 IntArray(1) { availableSize }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoView.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoView.kt
index 7e5402e..4c532f3 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoView.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoView.kt
@@ -15,28 +15,25 @@
  */
 package androidx.compose.foundation.relocation
 
-import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.layout.LayoutCoordinates
-import androidx.compose.ui.layout.OnPlacedModifier
-import androidx.compose.ui.modifier.ModifierLocalConsumer
-import androidx.compose.ui.modifier.ModifierLocalReadScope
+import androidx.compose.ui.modifier.ModifierLocalNode
 import androidx.compose.ui.modifier.modifierLocalOf
+import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
+import androidx.compose.ui.node.LayoutAwareModifierNode
 
 /**
  * The Key for the ModifierLocal that can be used to access the [BringIntoViewParent].
  */
-@OptIn(ExperimentalFoundationApi::class)
 internal val ModifierLocalBringIntoViewParent = modifierLocalOf<BringIntoViewParent?> { null }
 
 /**
  * Platform-specific "root" of the [BringIntoViewParent] chain to call into when there are no
- * [ModifierLocalBringIntoViewParent]s above a [BringIntoViewChildModifier]. The value returned by
- * this function should be passed to the [BringIntoViewChildModifier] constructor.
+ * [ModifierLocalBringIntoViewParent]s above a [BringIntoViewChildNode].
  */
-@Composable
-internal expect fun rememberDefaultBringIntoViewParent(): BringIntoViewParent
+internal expect fun CompositionLocalConsumerModifierNode.defaultBringIntoViewParent():
+    BringIntoViewParent
 
 /**
  * A node that can respond to [bringChildIntoView] requests from its children by scrolling its
@@ -67,16 +64,15 @@
  * [BringIntoViewParent]: either one read from the [ModifierLocalBringIntoViewParent], or if no
  * modifier local is specified then the [defaultParent].
  *
- * @param defaultParent The [BringIntoViewParent] to use if there is no
+ * @property defaultParent The [BringIntoViewParent] to use if there is no
  * [ModifierLocalBringIntoViewParent] available to read. This parent should always be obtained by
- * calling [rememberDefaultBringIntoViewParent] to support platform-specific integration.
+ * calling [defaultBringIntoViewParent] to support platform-specific integration.
  */
-internal abstract class BringIntoViewChildModifier(
-    private val defaultParent: BringIntoViewParent
-) : ModifierLocalConsumer,
-    OnPlacedModifier {
+internal abstract class BringIntoViewChildNode : Modifier.Node(),
+    ModifierLocalNode, LayoutAwareModifierNode, CompositionLocalConsumerModifierNode {
+    private val defaultParent = defaultBringIntoViewParent()
 
-    private var localParent: BringIntoViewParent? = null
+    private val localParent: BringIntoViewParent? get() = ModifierLocalBringIntoViewParent.current
 
     /** The [LayoutCoordinates] of this modifier, if attached. */
     protected var layoutCoordinates: LayoutCoordinates? = null
@@ -86,12 +82,6 @@
     protected val parent: BringIntoViewParent
         get() = localParent ?: defaultParent
 
-    override fun onModifierLocalsUpdated(scope: ModifierLocalReadScope) {
-        with(scope) {
-            localParent = ModifierLocalBringIntoViewParent.current
-        }
-    }
-
     override fun onPlaced(coordinates: LayoutCoordinates) {
         layoutCoordinates = coordinates
     }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewRequester.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewRequester.kt
index 0636f8c..290860c 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewRequester.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewRequester.kt
@@ -17,14 +17,12 @@
 package androidx.compose.foundation.relocation
 
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.collection.mutableVectorOf
-import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.composed
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.geometry.toRect
-import androidx.compose.ui.platform.debugInspectorInfo
+import androidx.compose.ui.node.ModifierNodeElement
+import androidx.compose.ui.platform.InspectorInfo
 import androidx.compose.ui.unit.toSize
 
 /**
@@ -97,29 +95,15 @@
  *     [bringIntoView][BringIntoViewRequester.bringIntoView] requests to parents
  *     of the current composable.
  */
+@Suppress("ModifierInspectorInfo")
 @ExperimentalFoundationApi
 fun Modifier.bringIntoViewRequester(
     bringIntoViewRequester: BringIntoViewRequester
-): Modifier = composed(debugInspectorInfo {
-    name = "bringIntoViewRequester"
-    properties["bringIntoViewRequester"] = bringIntoViewRequester
-}) {
-    val defaultResponder = rememberDefaultBringIntoViewParent()
-    val modifier = remember(defaultResponder) {
-        BringIntoViewRequesterModifier(defaultResponder)
-    }
-    if (bringIntoViewRequester is BringIntoViewRequesterImpl) {
-        DisposableEffect(bringIntoViewRequester) {
-            bringIntoViewRequester.modifiers += modifier
-            onDispose { bringIntoViewRequester.modifiers -= modifier }
-        }
-    }
-    return@composed modifier
-}
+): Modifier = this.then(BringIntoViewRequesterElement(bringIntoViewRequester))
 
 @ExperimentalFoundationApi
 private class BringIntoViewRequesterImpl : BringIntoViewRequester {
-    val modifiers = mutableVectorOf<BringIntoViewRequesterModifier>()
+    val modifiers = mutableVectorOf<BringIntoViewRequesterNode>()
 
     override suspend fun bringIntoView(rect: Rect?) {
         modifiers.forEach {
@@ -128,15 +112,64 @@
     }
 }
 
+@ExperimentalFoundationApi
+private class BringIntoViewRequesterElement(
+    private val requester: BringIntoViewRequester
+) : ModifierNodeElement<BringIntoViewRequesterNode>() {
+    override fun create(): BringIntoViewRequesterNode {
+        return BringIntoViewRequesterNode(requester)
+    }
+
+    override fun update(node: BringIntoViewRequesterNode): BringIntoViewRequesterNode =
+        node.also {
+            it.updateRequester(requester)
+        }
+
+    override fun InspectorInfo.inspectableProperties() {
+        name = "bringIntoViewRequester"
+        properties["bringIntoViewRequester"] = requester
+    }
+
+    override fun equals(other: Any?): Boolean {
+        return (this === other) ||
+            (other is BringIntoViewRequesterElement) && (requester == other.requester)
+    }
+
+    override fun hashCode(): Int {
+        return requester.hashCode()
+    }
+}
+
 /**
  * A modifier that holds state and modifier implementations for [bringIntoViewRequester]. It has
- * access to the next [BringIntoViewParent] via [BringIntoViewChildModifier], and uses that parent
+ * access to the next [BringIntoViewParent] via [BringIntoViewChildNode], and uses that parent
  * to respond to requests to [bringIntoView].
  */
 @ExperimentalFoundationApi
-private class BringIntoViewRequesterModifier(
-    defaultParent: BringIntoViewParent
-) : BringIntoViewChildModifier(defaultParent) {
+internal class BringIntoViewRequesterNode(
+    private var requester: BringIntoViewRequester
+) : BringIntoViewChildNode() {
+    init {
+        updateRequester(requester)
+    }
+
+    fun updateRequester(requester: BringIntoViewRequester) {
+        disposeRequester()
+        if (requester is BringIntoViewRequesterImpl) {
+            requester.modifiers += this
+        }
+        this.requester = requester
+    }
+
+    private fun disposeRequester() {
+        if (requester is BringIntoViewRequesterImpl) {
+            (requester as BringIntoViewRequesterImpl).modifiers -= this
+        }
+    }
+
+    override fun onDetach() {
+        disposeRequester()
+    }
 
     /**
      * Requests that [rect] (if non-null) or the entire bounds of this modifier's node (if [rect]
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.kt
index 3d95cca..9e31be2 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.kt
@@ -17,14 +17,12 @@
 package androidx.compose.foundation.relocation
 
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.composed
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.layout.LayoutCoordinates
-import androidx.compose.ui.modifier.ModifierLocalProvider
-import androidx.compose.ui.modifier.ProvidableModifierLocal
-import androidx.compose.ui.platform.debugInspectorInfo
+import androidx.compose.ui.modifier.modifierLocalMapOf
+import androidx.compose.ui.node.ModifierNodeElement
+import androidx.compose.ui.platform.InspectorInfo
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.launch
 
@@ -96,40 +94,48 @@
  *
  * @see BringIntoViewRequester
  */
+@Suppress("ModifierInspectorInfo")
 @ExperimentalFoundationApi
 fun Modifier.bringIntoViewResponder(
     responder: BringIntoViewResponder
-): Modifier = composed(debugInspectorInfo {
-    name = "bringIntoViewResponder"
-    properties["responder"] = responder
-}) {
-    val defaultParent = rememberDefaultBringIntoViewParent()
-    val modifier = remember(defaultParent) {
-        BringIntoViewResponderModifier(defaultParent)
+): Modifier = this.then(BringIntoViewResponderElement(responder))
+
+@ExperimentalFoundationApi
+private class BringIntoViewResponderElement(
+    private val responder: BringIntoViewResponder
+) : ModifierNodeElement<BringIntoViewResponderNode>() {
+    override fun create(): BringIntoViewResponderNode = BringIntoViewResponderNode(responder)
+
+    override fun update(node: BringIntoViewResponderNode) = node.also {
+        it.responder = responder
     }
-    modifier.responder = responder
-    return@composed modifier
+    override fun equals(other: Any?): Boolean {
+        return (this === other) ||
+            (other is BringIntoViewResponderElement) && (responder == other.responder)
+    }
+
+    override fun hashCode(): Int {
+        return responder.hashCode()
+    }
+
+    override fun InspectorInfo.inspectableProperties() {
+        name = "bringIntoViewResponder"
+        properties["responder"] = responder
+    }
 }
 
 /**
  * A modifier that holds state and modifier implementations for [bringIntoViewResponder]. It has
- * access to the next [BringIntoViewParent] via [BringIntoViewChildModifier] and additionally
+ * access to the next [BringIntoViewParent] via [BringIntoViewChildNode] and additionally
  * provides itself as the [BringIntoViewParent] for subsequent modifiers. This class is responsible
  * for recursively propagating requests up the responder chain.
  */
 @OptIn(ExperimentalFoundationApi::class)
-private class BringIntoViewResponderModifier(
-    defaultParent: BringIntoViewParent
-) : BringIntoViewChildModifier(defaultParent),
-    ModifierLocalProvider<BringIntoViewParent?>,
-    BringIntoViewParent {
+private class BringIntoViewResponderNode(
+    var responder: BringIntoViewResponder
+) : BringIntoViewChildNode(), BringIntoViewParent {
 
-    lateinit var responder: BringIntoViewResponder
-
-    override val key: ProvidableModifierLocal<BringIntoViewParent?>
-        get() = ModifierLocalBringIntoViewParent
-    override val value: BringIntoViewParent
-        get() = this
+    override val providedValues = modifierLocalMapOf(ModifierLocalBringIntoViewParent to this)
 
     /**
      * Responds to a child's request by first converting [boundsProvider] into this node's [LayoutCoordinates]
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.desktop.kt
index ea02955..736956c 100644
--- a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.desktop.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.desktop.kt
@@ -16,17 +16,14 @@
 
 package androidx.compose.foundation.relocation
 
-import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.runtime.Composable
+import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
 
 /**
  * Platform specific internal API to bring a rectangle into view.
  */
-@OptIn(ExperimentalFoundationApi::class)
-@Composable
-internal actual fun rememberDefaultBringIntoViewParent(): BringIntoViewParent {
-    return BringIntoViewParent { _, _ ->
+internal actual fun CompositionLocalConsumerModifierNode.defaultBringIntoViewParent():
+    BringIntoViewParent =
+     BringIntoViewParent { _, _ ->
         // TODO(b/203204124): Implement this if desktop has a
         //  concept similar to Android's View.requestRectangleOnScreen.
-    }
-}
\ No newline at end of file
+    }
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/text/selection/DesktopTextFieldSelectionManagerTest.kt b/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/text/selection/DesktopTextFieldSelectionManagerTest.kt
index 5872d27..f4df453 100644
--- a/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/text/selection/DesktopTextFieldSelectionManagerTest.kt
+++ b/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/text/selection/DesktopTextFieldSelectionManagerTest.kt
@@ -38,11 +38,11 @@
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.LayoutDirection
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
-import com.nhaarman.mockitokotlin2.whenever
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
 import org.junit.Before
 import org.junit.Ignore
 import org.junit.Test
diff --git a/compose/material/material-icons-core/lint-baseline.xml b/compose/material/material-icons-core/lint-baseline.xml
new file mode 100644
index 0000000..c800509
--- /dev/null
+++ b/compose/material/material-icons-core/lint-baseline.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
+
+    <issue
+        id="LintError"
+        message="Unexpected failure during lint analysis (this is a bug in lint or one of the libraries it depends on)&#xA;&#xA;Message: Java heap space&#xA;Stack: `OutOfMemoryError:OpenAddressLinearProbingHashTable.rehash(OpenAddressLinearProbingHashTable.kt:93)←OpenAddressLinearProbingHashTable.put(OpenAddressLinearProbingHashTable.kt:83)←SlicedMapImpl.put(SlicedMapImpl.java:79)←BindingTraceContext.record(BindingTraceContext.java:137)←CliBindingTraceForLint.record(Fe10UastEnvironment.kt:388)←QualifiedExpressionResolver.storeResult(QualifiedExpressionResolver.kt:750)←QualifiedExpressionResolver.access$storeResult(QualifiedExpressionResolver.kt:53)←QualifiedExpressionResolver$processSingleImport$1.invoke(QualifiedExpressionResolver.kt:346)←QualifiedExpressionResolver$processSingleImport$1.invoke(QualifiedExpressionResolver.kt:344)←CallOnceFunction.invoke(CallOnceFunction.kt:13)←LazyExplicitImportScope.storeReferencesToDescriptors$frontend(LazyExplicitImportScope.kt:120)←LazyImportResolverForKtImportDirective$forceResolveImportDirective$1.invoke(LazyImportScope.kt:172)←LazyImportResolverForKtImportDirective$forceResolveImportDirective$1.invoke(LazyImportScope.kt:169)←LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:578)←LockBasedStorageManager$MapBasedMemoizedFunctionToNotNull.invoke(LockBasedStorageManager.java:651)←LazyImportResolverForKtImportDirective.forceResolveImport(LazyImportScope.kt:231)←LazyImportResolverForKtImportDirective$forceResolveNonDefaultImportsTask$1.invoke(LazyImportScope.kt:184)←LazyImportResolverForKtImportDirective$forceResolveNonDefaultImportsTask$1.invoke(LazyImportScope.kt:181)←LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408)←LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:527)←LazyImportResolverForKtImportDirective.forceResolveNonDefaultImports(LazyImportScope.kt:214)←FileScopeFactory$FilesScopesBuilder$importResolver$1.forceResolveNonDefaultImports(FileScopeFactory.kt:170)←LazyTopDownAnalyzer.resolveImportsInFile(LazyTopDownAnalyzer.kt:252)←LazyTopDownAnalyzer.resolveImportsInAllFiles(LazyTopDownAnalyzer.kt:247)←LazyTopDownAnalyzer.analyzeDeclarations(LazyTopDownAnalyzer.kt:229)←LazyTopDownAnalyzer.analyzeDeclarations$default(LazyTopDownAnalyzer.kt:58)←TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:130)←TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:99)←Fe10UastEnvironment.analyzeFiles(Fe10UastEnvironment.kt:170)←LintCliClient$LintCliUastParser.prepare(LintCliClient.kt:1850)←UastParser.prepare$default(UastParser.kt:59)←LintDriver.prepareUast(LintDriver.kt:2107)`&#xA;&#xA;You can run with --stacktrace or set environment variable `LINT_PRINT_STACKTRACE=true` to dump a full stacktrace to stdout.">
+        <location
+            file="material-icons-core"/>
+    </issue>
+
+</issues>
diff --git a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/ChipSamples.kt b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/ChipSamples.kt
index 14a45d5..5d84255 100644
--- a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/ChipSamples.kt
+++ b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/ChipSamples.kt
@@ -166,12 +166,13 @@
             Modifier
                 .fillMaxWidth(1f)
                 .wrapContentHeight(align = Alignment.Top),
-            verticalAlignment = Alignment.CenterVertically,
             horizontalArrangement = Arrangement.Start,
         ) {
             repeat(10) { index ->
                 Chip(
-                    modifier = Modifier.padding(horizontal = 4.dp),
+                    modifier = Modifier
+                        .padding(horizontal = 4.dp)
+                        .align(alignment = Alignment.CenterVertically),
                     onClick = { /* do something*/ }) {
                     Text("Chip $index")
                 }
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SnackbarHostTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SnackbarHostTest.kt
index cc683a3..5feb341 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SnackbarHostTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SnackbarHostTest.kt
@@ -34,10 +34,10 @@
 import androidx.test.filters.LargeTest
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.doReturn
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.SupervisorJob
 import kotlinx.coroutines.delay
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/OutlinedTextFieldTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/OutlinedTextFieldTest.kt
index 84340e8..b791476 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/OutlinedTextFieldTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/OutlinedTextFieldTest.kt
@@ -100,11 +100,11 @@
 import androidx.test.filters.MediumTest
 import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.atLeastOnce
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
 import kotlin.math.max
 import kotlin.math.roundToInt
 import org.junit.Rule
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/TextFieldTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/TextFieldTest.kt
index b52e8ea..63a61ef 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/TextFieldTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/TextFieldTest.kt
@@ -116,11 +116,11 @@
 import androidx.test.filters.MediumTest
 import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.atLeastOnce
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.launch
diff --git a/compose/material3/material3-window-size-class/api/1.1.0-beta02.txt b/compose/material3/material3-window-size-class/api/1.1.0-beta02.txt
new file mode 100644
index 0000000..cc66d9f
--- /dev/null
+++ b/compose/material3/material3-window-size-class/api/1.1.0-beta02.txt
@@ -0,0 +1,44 @@
+// Signature format: 4.0
+package androidx.compose.material3.windowsizeclass {
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class WindowHeightSizeClass implements java.lang.Comparable<androidx.compose.material3.windowsizeclass.WindowHeightSizeClass> {
+    method public operator int compareTo(int other);
+    field public static final androidx.compose.material3.windowsizeclass.WindowHeightSizeClass.Companion Companion;
+  }
+
+  public static final class WindowHeightSizeClass.Companion {
+    method public int getCompact();
+    method public int getExpanded();
+    method public int getMedium();
+    property public final int Compact;
+    property public final int Expanded;
+    property public final int Medium;
+  }
+
+  @androidx.compose.runtime.Immutable public final class WindowSizeClass {
+    method public int getHeightSizeClass();
+    method public int getWidthSizeClass();
+    property public final int heightSizeClass;
+    property public final int widthSizeClass;
+    field public static final androidx.compose.material3.windowsizeclass.WindowSizeClass.Companion Companion;
+  }
+
+  public static final class WindowSizeClass.Companion {
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class WindowWidthSizeClass implements java.lang.Comparable<androidx.compose.material3.windowsizeclass.WindowWidthSizeClass> {
+    method public operator int compareTo(int other);
+    field public static final androidx.compose.material3.windowsizeclass.WindowWidthSizeClass.Companion Companion;
+  }
+
+  public static final class WindowWidthSizeClass.Companion {
+    method public int getCompact();
+    method public int getExpanded();
+    method public int getMedium();
+    property public final int Compact;
+    property public final int Expanded;
+    property public final int Medium;
+  }
+
+}
+
diff --git a/compose/material3/material3-window-size-class/api/public_plus_experimental_1.1.0-beta02.txt b/compose/material3/material3-window-size-class/api/public_plus_experimental_1.1.0-beta02.txt
new file mode 100644
index 0000000..88ceafc
--- /dev/null
+++ b/compose/material3/material3-window-size-class/api/public_plus_experimental_1.1.0-beta02.txt
@@ -0,0 +1,52 @@
+// Signature format: 4.0
+package androidx.compose.material3.windowsizeclass {
+
+  public final class AndroidWindowSizeClass_androidKt {
+    method @androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi @androidx.compose.runtime.Composable public static androidx.compose.material3.windowsizeclass.WindowSizeClass calculateWindowSizeClass(android.app.Activity activity);
+  }
+
+  @kotlin.RequiresOptIn(message="This material3-window-size-class API is experimental and is likely to change or to " + "be removed in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalMaterial3WindowSizeClassApi {
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class WindowHeightSizeClass implements java.lang.Comparable<androidx.compose.material3.windowsizeclass.WindowHeightSizeClass> {
+    method public operator int compareTo(int other);
+    field public static final androidx.compose.material3.windowsizeclass.WindowHeightSizeClass.Companion Companion;
+  }
+
+  public static final class WindowHeightSizeClass.Companion {
+    method public int getCompact();
+    method public int getExpanded();
+    method public int getMedium();
+    property public final int Compact;
+    property public final int Expanded;
+    property public final int Medium;
+  }
+
+  @androidx.compose.runtime.Immutable public final class WindowSizeClass {
+    method public int getHeightSizeClass();
+    method public int getWidthSizeClass();
+    property public final int heightSizeClass;
+    property public final int widthSizeClass;
+    field public static final androidx.compose.material3.windowsizeclass.WindowSizeClass.Companion Companion;
+  }
+
+  public static final class WindowSizeClass.Companion {
+    method @androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi @org.jetbrains.annotations.TestOnly public androidx.compose.material3.windowsizeclass.WindowSizeClass calculateFromSize(long size);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class WindowWidthSizeClass implements java.lang.Comparable<androidx.compose.material3.windowsizeclass.WindowWidthSizeClass> {
+    method public operator int compareTo(int other);
+    field public static final androidx.compose.material3.windowsizeclass.WindowWidthSizeClass.Companion Companion;
+  }
+
+  public static final class WindowWidthSizeClass.Companion {
+    method public int getCompact();
+    method public int getExpanded();
+    method public int getMedium();
+    property public final int Compact;
+    property public final int Expanded;
+    property public final int Medium;
+  }
+
+}
+
diff --git a/compose/material3/material3-window-size-class/api/res-1.1.0-beta02.txt b/compose/material3/material3-window-size-class/api/res-1.1.0-beta02.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/compose/material3/material3-window-size-class/api/res-1.1.0-beta02.txt
diff --git a/compose/material3/material3-window-size-class/api/restricted_1.1.0-beta02.txt b/compose/material3/material3-window-size-class/api/restricted_1.1.0-beta02.txt
new file mode 100644
index 0000000..cc66d9f
--- /dev/null
+++ b/compose/material3/material3-window-size-class/api/restricted_1.1.0-beta02.txt
@@ -0,0 +1,44 @@
+// Signature format: 4.0
+package androidx.compose.material3.windowsizeclass {
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class WindowHeightSizeClass implements java.lang.Comparable<androidx.compose.material3.windowsizeclass.WindowHeightSizeClass> {
+    method public operator int compareTo(int other);
+    field public static final androidx.compose.material3.windowsizeclass.WindowHeightSizeClass.Companion Companion;
+  }
+
+  public static final class WindowHeightSizeClass.Companion {
+    method public int getCompact();
+    method public int getExpanded();
+    method public int getMedium();
+    property public final int Compact;
+    property public final int Expanded;
+    property public final int Medium;
+  }
+
+  @androidx.compose.runtime.Immutable public final class WindowSizeClass {
+    method public int getHeightSizeClass();
+    method public int getWidthSizeClass();
+    property public final int heightSizeClass;
+    property public final int widthSizeClass;
+    field public static final androidx.compose.material3.windowsizeclass.WindowSizeClass.Companion Companion;
+  }
+
+  public static final class WindowSizeClass.Companion {
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class WindowWidthSizeClass implements java.lang.Comparable<androidx.compose.material3.windowsizeclass.WindowWidthSizeClass> {
+    method public operator int compareTo(int other);
+    field public static final androidx.compose.material3.windowsizeclass.WindowWidthSizeClass.Companion Companion;
+  }
+
+  public static final class WindowWidthSizeClass.Companion {
+    method public int getCompact();
+    method public int getExpanded();
+    method public int getMedium();
+    property public final int Compact;
+    property public final int Expanded;
+    property public final int Medium;
+  }
+
+}
+
diff --git a/compose/material3/material3/api/1.1.0-beta02.txt b/compose/material3/material3/api/1.1.0-beta02.txt
new file mode 100644
index 0000000..7e2de6f
--- /dev/null
+++ b/compose/material3/material3/api/1.1.0-beta02.txt
@@ -0,0 +1,856 @@
+// Signature format: 4.0
+package androidx.compose.material3 {
+
+  public final class AlertDialogDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public long getIconContentColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public long getTextContentColor();
+    method @androidx.compose.runtime.Composable public long getTitleContentColor();
+    method public float getTonalElevation();
+    property public final float TonalElevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final long iconContentColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final long textContentColor;
+    property @androidx.compose.runtime.Composable public final long titleContentColor;
+    field public static final androidx.compose.material3.AlertDialogDefaults INSTANCE;
+  }
+
+  public final class AndroidAlertDialog_androidKt {
+    method @androidx.compose.runtime.Composable public static void AlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, kotlin.jvm.functions.Function0<kotlin.Unit> confirmButton, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dismissButton, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long iconContentColor, optional long titleContentColor, optional long textContentColor, optional float tonalElevation, optional androidx.compose.ui.window.DialogProperties properties);
+  }
+
+  public final class AndroidMenu_androidKt {
+    method @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean enabled, optional androidx.compose.material3.MenuItemColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  public final class AppBarKt {
+    method @androidx.compose.runtime.Composable public static void BottomAppBar(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? floatingActionButton, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.WindowInsets windowInsets);
+    method @androidx.compose.runtime.Composable public static void BottomAppBar(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+  }
+
+  public final class AssistChipDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipBorder assistChipBorder(optional long borderColor, optional long disabledBorderColor, optional float borderWidth);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors assistChipColors(optional long containerColor, optional long labelColor, optional long leadingIconContentColor, optional long trailingIconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconContentColor, optional long disabledTrailingIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation assistChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors elevatedAssistChipColors(optional long containerColor, optional long labelColor, optional long leadingIconContentColor, optional long trailingIconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconContentColor, optional long disabledTrailingIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation elevatedAssistChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method public float getHeight();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    property public final float Height;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.AssistChipDefaults INSTANCE;
+  }
+
+  public final class BottomAppBarDefaults {
+    method @androidx.compose.runtime.Composable public long getBottomAppBarFabColor();
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getContainerElevation();
+    method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property public final float ContainerElevation;
+    property public final androidx.compose.foundation.layout.PaddingValues ContentPadding;
+    property @androidx.compose.runtime.Composable public final long bottomAppBarFabColor;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.BottomAppBarDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class ButtonColors {
+  }
+
+  public final class ButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors buttonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonElevation buttonElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors elevatedButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonElevation elevatedButtonElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors filledTonalButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonElevation filledTonalButtonElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float disabledElevation);
+    method public androidx.compose.foundation.layout.PaddingValues getButtonWithIconContentPadding();
+    method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getElevatedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFilledTonalShape();
+    method public float getIconSize();
+    method public float getIconSpacing();
+    method public float getMinHeight();
+    method public float getMinWidth();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke getOutlinedButtonBorder();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method public androidx.compose.foundation.layout.PaddingValues getTextButtonContentPadding();
+    method public androidx.compose.foundation.layout.PaddingValues getTextButtonWithIconContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getTextShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors outlinedButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors textButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    property public final androidx.compose.foundation.layout.PaddingValues ButtonWithIconContentPadding;
+    property public final androidx.compose.foundation.layout.PaddingValues ContentPadding;
+    property public final float IconSize;
+    property public final float IconSpacing;
+    property public final float MinHeight;
+    property public final float MinWidth;
+    property public final androidx.compose.foundation.layout.PaddingValues TextButtonContentPadding;
+    property public final androidx.compose.foundation.layout.PaddingValues TextButtonWithIconContentPadding;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape elevatedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape filledTonalShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.BorderStroke outlinedButtonBorder;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape textShape;
+    field public static final androidx.compose.material3.ButtonDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class ButtonElevation {
+  }
+
+  public final class ButtonKt {
+    method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ElevatedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class CardColors {
+  }
+
+  public final class CardDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardColors cardColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardElevation cardElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardColors elevatedCardColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardElevation elevatedCardElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getElevatedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke outlinedCardBorder(optional boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardColors outlinedCardColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardElevation outlinedCardElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape elevatedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.CardDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class CardElevation {
+  }
+
+  public final class CardKt {
+    method @androidx.compose.runtime.Composable public static void Card(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ElevatedCard(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedCard(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class CheckboxColors {
+  }
+
+  public final class CheckboxDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.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.compose.material3.CheckboxDefaults INSTANCE;
+  }
+
+  public final class CheckboxKt {
+    method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Immutable public final class ChipBorder {
+  }
+
+  @androidx.compose.runtime.Immutable public final class ChipColors {
+  }
+
+  @androidx.compose.runtime.Immutable public final class ChipElevation {
+  }
+
+  public final class ChipKt {
+    method @androidx.compose.runtime.Composable public static void AssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedAssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedSuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void SuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Stable public final class ColorScheme {
+    ctor public ColorScheme(long primary, long onPrimary, long primaryContainer, long onPrimaryContainer, long inversePrimary, long secondary, long onSecondary, long secondaryContainer, long onSecondaryContainer, long tertiary, long onTertiary, long tertiaryContainer, long onTertiaryContainer, long background, long onBackground, long surface, long onSurface, long surfaceVariant, long onSurfaceVariant, long surfaceTint, long inverseSurface, long inverseOnSurface, long error, long onError, long errorContainer, long onErrorContainer, long outline, long outlineVariant, long scrim);
+    method public androidx.compose.material3.ColorScheme copy(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim);
+    method public long getBackground();
+    method public long getError();
+    method public long getErrorContainer();
+    method public long getInverseOnSurface();
+    method public long getInversePrimary();
+    method public long getInverseSurface();
+    method public long getOnBackground();
+    method public long getOnError();
+    method public long getOnErrorContainer();
+    method public long getOnPrimary();
+    method public long getOnPrimaryContainer();
+    method public long getOnSecondary();
+    method public long getOnSecondaryContainer();
+    method public long getOnSurface();
+    method public long getOnSurfaceVariant();
+    method public long getOnTertiary();
+    method public long getOnTertiaryContainer();
+    method public long getOutline();
+    method public long getOutlineVariant();
+    method public long getPrimary();
+    method public long getPrimaryContainer();
+    method public long getScrim();
+    method public long getSecondary();
+    method public long getSecondaryContainer();
+    method public long getSurface();
+    method public long getSurfaceTint();
+    method public long getSurfaceVariant();
+    method public long getTertiary();
+    method public long getTertiaryContainer();
+    property public final long background;
+    property public final long error;
+    property public final long errorContainer;
+    property public final long inverseOnSurface;
+    property public final long inversePrimary;
+    property public final long inverseSurface;
+    property public final long onBackground;
+    property public final long onError;
+    property public final long onErrorContainer;
+    property public final long onPrimary;
+    property public final long onPrimaryContainer;
+    property public final long onSecondary;
+    property public final long onSecondaryContainer;
+    property public final long onSurface;
+    property public final long onSurfaceVariant;
+    property public final long onTertiary;
+    property public final long onTertiaryContainer;
+    property public final long outline;
+    property public final long outlineVariant;
+    property public final long primary;
+    property public final long primaryContainer;
+    property public final long scrim;
+    property public final long secondary;
+    property public final long secondaryContainer;
+    property public final long surface;
+    property public final long surfaceTint;
+    property public final long surfaceVariant;
+    property public final long tertiary;
+    property public final long tertiaryContainer;
+  }
+
+  public final class ColorSchemeKt {
+    method public static long contentColorFor(androidx.compose.material3.ColorScheme, long backgroundColor);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static long contentColorFor(long backgroundColor);
+    method public static androidx.compose.material3.ColorScheme darkColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim);
+    method public static androidx.compose.material3.ColorScheme lightColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim);
+    method public static long surfaceColorAtElevation(androidx.compose.material3.ColorScheme, float elevation);
+  }
+
+  public final class ContentColorKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.graphics.Color> getLocalContentColor();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.graphics.Color> LocalContentColor;
+  }
+
+  public final class DividerDefaults {
+    method @androidx.compose.runtime.Composable public long getColor();
+    method public float getThickness();
+    property public final float Thickness;
+    property @androidx.compose.runtime.Composable public final long color;
+    field public static final androidx.compose.material3.DividerDefaults INSTANCE;
+  }
+
+  public final class DividerKt {
+    method @androidx.compose.runtime.Composable public static void Divider(optional androidx.compose.ui.Modifier modifier, optional float thickness, optional long color);
+  }
+
+  public final class DrawerDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getDismissibleDrawerElevation();
+    method public float getMaximumDrawerWidth();
+    method public float getModalDrawerElevation();
+    method public float getPermanentDrawerElevation();
+    method @androidx.compose.runtime.Composable public long getScrimColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property public final float DismissibleDrawerElevation;
+    property public final float MaximumDrawerWidth;
+    property public final float ModalDrawerElevation;
+    property public final float PermanentDrawerElevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final long scrimColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.DrawerDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class DrawerState {
+    ctor public DrawerState(androidx.compose.material3.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
+    method public suspend Object? animateTo(androidx.compose.material3.DrawerValue targetValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.material3.DrawerValue getCurrentValue();
+    method public androidx.compose.runtime.State<java.lang.Float> getOffset();
+    method public androidx.compose.material3.DrawerValue getTargetValue();
+    method public boolean isAnimationRunning();
+    method public boolean isClosed();
+    method public boolean isOpen();
+    method public suspend Object? open(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? snapTo(androidx.compose.material3.DrawerValue targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final androidx.compose.material3.DrawerValue currentValue;
+    property public final boolean isAnimationRunning;
+    property public final boolean isClosed;
+    property public final boolean isOpen;
+    property public final androidx.compose.runtime.State<java.lang.Float> offset;
+    property public final androidx.compose.material3.DrawerValue targetValue;
+    field public static final androidx.compose.material3.DrawerState.Companion Companion;
+  }
+
+  public static final class DrawerState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.DrawerState,androidx.compose.material3.DrawerValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
+  }
+
+  public enum DrawerValue {
+    method public static androidx.compose.material3.DrawerValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.DrawerValue[] values();
+    enum_constant public static final androidx.compose.material3.DrawerValue Closed;
+    enum_constant public static final androidx.compose.material3.DrawerValue Open;
+  }
+
+  public final class DynamicTonalPaletteKt {
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public static androidx.compose.material3.ColorScheme dynamicDarkColorScheme(android.content.Context context);
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public static androidx.compose.material3.ColorScheme dynamicLightColorScheme(android.content.Context context);
+  }
+
+  @kotlin.jvm.JvmInline public final value class FabPosition {
+    field public static final androidx.compose.material3.FabPosition.Companion Companion;
+  }
+
+  public static final class FabPosition.Companion {
+    method public int getCenter();
+    method public int getEnd();
+    property public final int Center;
+    property public final int End;
+  }
+
+  public final class FloatingActionButtonDefaults {
+    method public androidx.compose.material3.FloatingActionButtonElevation bottomAppBarFabElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.FloatingActionButtonElevation elevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getExtendedFabShape();
+    method public float getLargeIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getLargeShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getSmallShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.FloatingActionButtonElevation loweredElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
+    property public final float LargeIconSize;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape extendedFabShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape largeShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape smallShape;
+    field public static final androidx.compose.material3.FloatingActionButtonDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public class FloatingActionButtonElevation {
+  }
+
+  public final class FloatingActionButtonKt {
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean expanded, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void LargeFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void SmallFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class IconButtonColors {
+  }
+
+  public final class IconButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors filledIconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors filledIconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors filledTonalIconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors filledTonalIconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFilledShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors iconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors iconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke outlinedIconButtonBorder(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors outlinedIconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke? outlinedIconToggleButtonBorder(boolean enabled, boolean checked);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors outlinedIconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape filledShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    field public static final androidx.compose.material3.IconButtonDefaults INSTANCE;
+  }
+
+  public final class IconButtonKt {
+    method @androidx.compose.runtime.Composable public static void FilledIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class IconKt {
+    method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.vector.ImageVector imageVector, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+    method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.ImageBitmap bitmap, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+    method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.painter.Painter painter, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+  }
+
+  @androidx.compose.runtime.Immutable public final class IconToggleButtonColors {
+  }
+
+  public final class InteractiveComponentSizeKt {
+    method public static androidx.compose.ui.Modifier minimumInteractiveComponentSize(androidx.compose.ui.Modifier);
+  }
+
+  @androidx.compose.runtime.Immutable public final class ListItemColors {
+  }
+
+  public final class ListItemDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ListItemColors colors(optional long containerColor, optional long headlineColor, optional long leadingIconColor, optional long overlineColor, optional long supportingColor, optional long trailingIconColor, optional long disabledHeadlineColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public long getContainerColor();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public long getContentColor();
+    method public float getElevation();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.ui.graphics.Shape getShape();
+    property public final float Elevation;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final long containerColor;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final long contentColor;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.ListItemDefaults INSTANCE;
+  }
+
+  public final class ListItemKt {
+    method @androidx.compose.runtime.Composable public static void ListItem(kotlin.jvm.functions.Function0<kotlin.Unit> headlineContent, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? overlineContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingContent, optional androidx.compose.material3.ListItemColors colors, optional float tonalElevation, optional float shadowElevation);
+  }
+
+  public final class MaterialTheme {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.ColorScheme getColorScheme();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.Shapes getShapes();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.Typography getTypography();
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.ColorScheme colorScheme;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.Shapes shapes;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.Typography typography;
+    field public static final androidx.compose.material3.MaterialTheme INSTANCE;
+  }
+
+  public final class MaterialThemeKt {
+    method @androidx.compose.runtime.Composable public static void MaterialTheme(optional androidx.compose.material3.ColorScheme colorScheme, optional androidx.compose.material3.Shapes shapes, optional androidx.compose.material3.Typography typography, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class MenuDefaults {
+    method public androidx.compose.foundation.layout.PaddingValues getDropdownMenuItemContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.MenuItemColors itemColors(optional long textColor, optional long leadingIconColor, optional long trailingIconColor, optional long disabledTextColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor);
+    property public final androidx.compose.foundation.layout.PaddingValues DropdownMenuItemContentPadding;
+    field public static final androidx.compose.material3.MenuDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class MenuItemColors {
+  }
+
+  public final class NavigationBarDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getElevation();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property public final float Elevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.NavigationBarDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class NavigationBarItemColors {
+  }
+
+  public final class NavigationBarItemDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationBarItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor, optional long disabledIconColor, optional long disabledTextColor);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationBarItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor);
+    field public static final androidx.compose.material3.NavigationBarItemDefaults INSTANCE;
+  }
+
+  public final class NavigationBarKt {
+    method @androidx.compose.runtime.Composable public static void NavigationBar(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void NavigationBarItem(androidx.compose.foundation.layout.RowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationBarItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Stable public interface NavigationDrawerItemColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> badgeColor(boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> iconColor(boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean selected);
+  }
+
+  public final class NavigationDrawerItemDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationDrawerItemColors colors(optional long selectedContainerColor, optional long unselectedContainerColor, optional long selectedIconColor, optional long unselectedIconColor, optional long selectedTextColor, optional long unselectedTextColor, optional long selectedBadgeColor, optional long unselectedBadgeColor);
+    method public androidx.compose.foundation.layout.PaddingValues getItemPadding();
+    property public final androidx.compose.foundation.layout.PaddingValues ItemPadding;
+    field public static final androidx.compose.material3.NavigationDrawerItemDefaults INSTANCE;
+  }
+
+  public final class NavigationDrawerKt {
+    method @androidx.compose.runtime.Composable public static void DismissibleDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void DismissibleNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DrawerState drawerState, optional boolean gesturesEnabled, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ModalDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ModalNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DrawerState drawerState, optional boolean gesturesEnabled, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void NavigationDrawerItem(kotlin.jvm.functions.Function0<kotlin.Unit> label, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? badge, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.NavigationDrawerItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void PermanentDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void PermanentNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static androidx.compose.material3.DrawerState rememberDrawerState(androidx.compose.material3.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
+  }
+
+  public final class NavigationRailDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property @androidx.compose.runtime.Composable public final long ContainerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.NavigationRailDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class NavigationRailItemColors {
+  }
+
+  public final class NavigationRailItemDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationRailItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor, optional long disabledIconColor, optional long disabledTextColor);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationRailItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor);
+    field public static final androidx.compose.material3.NavigationRailItemDefaults INSTANCE;
+  }
+
+  public final class NavigationRailKt {
+    method @androidx.compose.runtime.Composable public static void NavigationRail(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? header, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void NavigationRailItem(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationRailItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  public final class OutlinedTextFieldKt {
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+  }
+
+  public final class ProgressIndicatorDefaults {
+    method @androidx.compose.runtime.Composable public long getCircularColor();
+    method public int getCircularDeterminateStrokeCap();
+    method public int getCircularIndeterminateStrokeCap();
+    method public float getCircularStrokeWidth();
+    method @androidx.compose.runtime.Composable public long getCircularTrackColor();
+    method @androidx.compose.runtime.Composable public long getLinearColor();
+    method public int getLinearStrokeCap();
+    method @androidx.compose.runtime.Composable public long getLinearTrackColor();
+    method public androidx.compose.animation.core.SpringSpec<java.lang.Float> getProgressAnimationSpec();
+    property public final int CircularDeterminateStrokeCap;
+    property public final int CircularIndeterminateStrokeCap;
+    property public final float CircularStrokeWidth;
+    property public final int LinearStrokeCap;
+    property public final androidx.compose.animation.core.SpringSpec<java.lang.Float> ProgressAnimationSpec;
+    property @androidx.compose.runtime.Composable public final long circularColor;
+    property @androidx.compose.runtime.Composable public final long circularTrackColor;
+    property @androidx.compose.runtime.Composable public final long linearColor;
+    property @androidx.compose.runtime.Composable public final long linearTrackColor;
+    field public static final androidx.compose.material3.ProgressIndicatorDefaults INSTANCE;
+  }
+
+  public final class ProgressIndicatorKt {
+    method @androidx.compose.runtime.Composable public static void CircularProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth, optional long trackColor, optional int strokeCap);
+    method @androidx.compose.runtime.Composable public static void CircularProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth, optional long trackColor, optional int strokeCap);
+    method @Deprecated @androidx.compose.runtime.Composable public static void CircularProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth);
+    method @Deprecated @androidx.compose.runtime.Composable public static void CircularProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth);
+    method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor, optional int strokeCap);
+    method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor, optional int strokeCap);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LinearProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor);
+  }
+
+  @androidx.compose.runtime.Immutable public final class RadioButtonColors {
+  }
+
+  public final class RadioButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.RadioButtonColors colors(optional long selectedColor, optional long unselectedColor, optional long disabledSelectedColor, optional long disabledUnselectedColor);
+    field public static final androidx.compose.material3.RadioButtonDefaults INSTANCE;
+  }
+
+  public final class RadioButtonKt {
+    method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.RadioButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  public final class ScaffoldDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getContentWindowInsets();
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets contentWindowInsets;
+    field public static final androidx.compose.material3.ScaffoldDefaults INSTANCE;
+  }
+
+  public final class ScaffoldKt {
+    method @androidx.compose.runtime.Composable public static void Scaffold(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional int floatingActionButtonPosition, optional long containerColor, optional long contentColor, optional androidx.compose.foundation.layout.WindowInsets contentWindowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+  }
+
+  public final class ShapeDefaults {
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraSmall();
+    method public androidx.compose.foundation.shape.CornerBasedShape getLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getMedium();
+    method public androidx.compose.foundation.shape.CornerBasedShape getSmall();
+    property public final androidx.compose.foundation.shape.CornerBasedShape ExtraLarge;
+    property public final androidx.compose.foundation.shape.CornerBasedShape ExtraSmall;
+    property public final androidx.compose.foundation.shape.CornerBasedShape Large;
+    property public final androidx.compose.foundation.shape.CornerBasedShape Medium;
+    property public final androidx.compose.foundation.shape.CornerBasedShape Small;
+    field public static final androidx.compose.material3.ShapeDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class Shapes {
+    ctor public Shapes(optional androidx.compose.foundation.shape.CornerBasedShape extraSmall, optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large, optional androidx.compose.foundation.shape.CornerBasedShape extraLarge);
+    method public androidx.compose.material3.Shapes copy(optional androidx.compose.foundation.shape.CornerBasedShape extraSmall, optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large, optional androidx.compose.foundation.shape.CornerBasedShape extraLarge);
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraSmall();
+    method public androidx.compose.foundation.shape.CornerBasedShape getLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getMedium();
+    method public androidx.compose.foundation.shape.CornerBasedShape getSmall();
+    property public final androidx.compose.foundation.shape.CornerBasedShape extraLarge;
+    property public final androidx.compose.foundation.shape.CornerBasedShape extraSmall;
+    property public final androidx.compose.foundation.shape.CornerBasedShape large;
+    property public final androidx.compose.foundation.shape.CornerBasedShape medium;
+    property public final androidx.compose.foundation.shape.CornerBasedShape small;
+  }
+
+  @androidx.compose.runtime.Immutable public final class SliderColors {
+  }
+
+  @androidx.compose.runtime.Stable public final class SliderDefaults {
+    method @androidx.compose.runtime.Composable public void Thumb(androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled, optional long thumbSize);
+    method @androidx.compose.runtime.Composable public void Track(androidx.compose.material3.SliderPositions sliderPositions, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SliderColors colors(optional long thumbColor, optional long activeTrackColor, optional long activeTickColor, optional long inactiveTrackColor, optional long inactiveTickColor, optional long disabledThumbColor, optional long disabledActiveTrackColor, optional long disabledActiveTickColor, optional long disabledInactiveTrackColor, optional long disabledInactiveTickColor);
+    field public static final androidx.compose.material3.SliderDefaults INSTANCE;
+  }
+
+  public final class SliderKt {
+    method @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors);
+    method @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Stable public final class SliderPositions {
+    ctor public SliderPositions(optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> initialActiveRange, optional float[] initialTickFractions);
+    method public kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> getActiveRange();
+    method public float[] getTickFractions();
+    property public final kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> activeRange;
+    property public final float[] tickFractions;
+  }
+
+  @androidx.compose.runtime.Stable public interface SnackbarData {
+    method public void dismiss();
+    method public androidx.compose.material3.SnackbarVisuals getVisuals();
+    method public void performAction();
+    property public abstract androidx.compose.material3.SnackbarVisuals visuals;
+  }
+
+  public final class SnackbarDefaults {
+    method @androidx.compose.runtime.Composable public long getActionColor();
+    method @androidx.compose.runtime.Composable public long getActionContentColor();
+    method @androidx.compose.runtime.Composable public long getColor();
+    method @androidx.compose.runtime.Composable public long getContentColor();
+    method @androidx.compose.runtime.Composable public long getDismissActionContentColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    property @androidx.compose.runtime.Composable public final long actionColor;
+    property @androidx.compose.runtime.Composable public final long actionContentColor;
+    property @androidx.compose.runtime.Composable public final long color;
+    property @androidx.compose.runtime.Composable public final long contentColor;
+    property @androidx.compose.runtime.Composable public final long dismissActionContentColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.SnackbarDefaults INSTANCE;
+  }
+
+  public enum SnackbarDuration {
+    method public static androidx.compose.material3.SnackbarDuration valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SnackbarDuration[] values();
+    enum_constant public static final androidx.compose.material3.SnackbarDuration Indefinite;
+    enum_constant public static final androidx.compose.material3.SnackbarDuration Long;
+    enum_constant public static final androidx.compose.material3.SnackbarDuration Short;
+  }
+
+  public final class SnackbarHostKt {
+    method @androidx.compose.runtime.Composable public static void SnackbarHost(androidx.compose.material3.SnackbarHostState hostState, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SnackbarData,kotlin.Unit> snackbar);
+  }
+
+  @androidx.compose.runtime.Stable public final class SnackbarHostState {
+    ctor public SnackbarHostState();
+    method public androidx.compose.material3.SnackbarData? getCurrentSnackbarData();
+    method public suspend Object? showSnackbar(String message, optional String? actionLabel, optional boolean withDismissAction, optional androidx.compose.material3.SnackbarDuration duration, optional kotlin.coroutines.Continuation<? super androidx.compose.material3.SnackbarResult>);
+    method public suspend Object? showSnackbar(androidx.compose.material3.SnackbarVisuals visuals, kotlin.coroutines.Continuation<? super androidx.compose.material3.SnackbarResult>);
+    property public final androidx.compose.material3.SnackbarData? currentSnackbarData;
+  }
+
+  public final class SnackbarKt {
+    method @androidx.compose.runtime.Composable public static void Snackbar(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dismissAction, optional boolean actionOnNewLine, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional long actionContentColor, optional long dismissActionContentColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Snackbar(androidx.compose.material3.SnackbarData snackbarData, optional androidx.compose.ui.Modifier modifier, optional boolean actionOnNewLine, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional long actionColor, optional long actionContentColor, optional long dismissActionContentColor);
+  }
+
+  public enum SnackbarResult {
+    method public static androidx.compose.material3.SnackbarResult valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SnackbarResult[] values();
+    enum_constant public static final androidx.compose.material3.SnackbarResult ActionPerformed;
+    enum_constant public static final androidx.compose.material3.SnackbarResult Dismissed;
+  }
+
+  @androidx.compose.runtime.Stable public interface SnackbarVisuals {
+    method public String? getActionLabel();
+    method public androidx.compose.material3.SnackbarDuration getDuration();
+    method public String getMessage();
+    method public boolean getWithDismissAction();
+    property public abstract String? actionLabel;
+    property public abstract androidx.compose.material3.SnackbarDuration duration;
+    property public abstract String message;
+    property public abstract boolean withDismissAction;
+  }
+
+  public final class SuggestionChipDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors elevatedSuggestionChipColors(optional long containerColor, optional long labelColor, optional long iconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation elevatedSuggestionChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method public float getHeight();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipBorder suggestionChipBorder(optional long borderColor, optional long disabledBorderColor, optional float borderWidth);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors suggestionChipColors(optional long containerColor, optional long labelColor, optional long iconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation suggestionChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    property public final float Height;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.SuggestionChipDefaults INSTANCE;
+  }
+
+  public final class SurfaceKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> getLocalAbsoluteTonalElevation();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> LocalAbsoluteTonalElevation;
+  }
+
+  @androidx.compose.runtime.Immutable public final class SwitchColors {
+  }
+
+  public final class SwitchDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SwitchColors colors(optional long checkedThumbColor, optional long checkedTrackColor, optional long checkedBorderColor, optional long checkedIconColor, optional long uncheckedThumbColor, optional long uncheckedTrackColor, optional long uncheckedBorderColor, optional long uncheckedIconColor, optional long disabledCheckedThumbColor, optional long disabledCheckedTrackColor, optional long disabledCheckedBorderColor, optional long disabledCheckedIconColor, optional long disabledUncheckedThumbColor, optional long disabledUncheckedTrackColor, optional long disabledUncheckedBorderColor, optional long disabledUncheckedIconColor);
+    method public float getIconSize();
+    property public final float IconSize;
+    field public static final androidx.compose.material3.SwitchDefaults INSTANCE;
+  }
+
+  public final class SwitchKt {
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? thumbContent, optional boolean enabled, optional androidx.compose.material3.SwitchColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  public final class TabKt {
+    method @androidx.compose.runtime.Composable public static void LeadingIconTab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TabPosition {
+    method public float getLeft();
+    method public float getRight();
+    method public float getWidth();
+    property public final float left;
+    property public final float right;
+    property public final float width;
+  }
+
+  public final class TabRowDefaults {
+    method @androidx.compose.runtime.Composable public void Indicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public long getContentColor();
+    method public androidx.compose.ui.Modifier tabIndicatorOffset(androidx.compose.ui.Modifier, androidx.compose.material3.TabPosition currentTabPosition);
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final long contentColor;
+    field public static final androidx.compose.material3.TabRowDefaults INSTANCE;
+  }
+
+  public final class TabRowKt {
+    method @androidx.compose.runtime.Composable public static void ScrollableTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float edgePadding, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @androidx.compose.runtime.Composable public static void TabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextFieldColors {
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextFieldDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFilledShape();
+    method public float getFocusedBorderThickness();
+    method public float getMinHeight();
+    method public float getMinWidth();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method public float getUnfocusedBorderThickness();
+    method public androidx.compose.foundation.layout.PaddingValues outlinedTextFieldPadding(optional float start, optional float top, optional float end, optional float bottom);
+    method public androidx.compose.foundation.layout.PaddingValues textFieldWithLabelPadding(optional float start, optional float end, optional float top, optional float bottom);
+    method public androidx.compose.foundation.layout.PaddingValues textFieldWithoutLabelPadding(optional float start, optional float top, optional float end, optional float bottom);
+    property public final float FocusedBorderThickness;
+    property public final float MinHeight;
+    property public final float MinWidth;
+    property public final float UnfocusedBorderThickness;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape filledShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    field public static final androidx.compose.material3.TextFieldDefaults INSTANCE;
+  }
+
+  public final class TextFieldKt {
+    method @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+  }
+
+  public final class TextKt {
+    method @androidx.compose.runtime.Composable public static void ProvideTextStyle(androidx.compose.ui.text.TextStyle value, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Text(String text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional int minLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @androidx.compose.runtime.Composable public static void Text(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional int minLines, optional java.util.Map<java.lang.String,androidx.compose.foundation.text.InlineTextContent> inlineContent, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @Deprecated @androidx.compose.runtime.Composable public static void Text(String text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,? extends kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @Deprecated @androidx.compose.runtime.Composable public static void Text(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional java.util.Map<java.lang.String,? extends androidx.compose.foundation.text.InlineTextContent> inlineContent, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,? extends kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.TextStyle> getLocalTextStyle();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.TextStyle> LocalTextStyle;
+  }
+
+  @androidx.compose.runtime.Stable public final class TimePickerState {
+    ctor public TimePickerState(int initialHour, int initialMinute, boolean is24Hour);
+    method public int getHour();
+    method public int getMinute();
+    method public boolean is24hour();
+    method public suspend Object? settle(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final int hour;
+    property public final boolean is24hour;
+    property public final int minute;
+    field public static final androidx.compose.material3.TimePickerState.Companion Companion;
+  }
+
+  public static final class TimePickerState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TimePickerState,?> Saver();
+  }
+
+  @androidx.compose.runtime.Immutable public final class Typography {
+    ctor public Typography(optional androidx.compose.ui.text.TextStyle displayLarge, optional androidx.compose.ui.text.TextStyle displayMedium, optional androidx.compose.ui.text.TextStyle displaySmall, optional androidx.compose.ui.text.TextStyle headlineLarge, optional androidx.compose.ui.text.TextStyle headlineMedium, optional androidx.compose.ui.text.TextStyle headlineSmall, optional androidx.compose.ui.text.TextStyle titleLarge, optional androidx.compose.ui.text.TextStyle titleMedium, optional androidx.compose.ui.text.TextStyle titleSmall, optional androidx.compose.ui.text.TextStyle bodyLarge, optional androidx.compose.ui.text.TextStyle bodyMedium, optional androidx.compose.ui.text.TextStyle bodySmall, optional androidx.compose.ui.text.TextStyle labelLarge, optional androidx.compose.ui.text.TextStyle labelMedium, optional androidx.compose.ui.text.TextStyle labelSmall);
+    method public androidx.compose.material3.Typography copy(optional androidx.compose.ui.text.TextStyle displayLarge, optional androidx.compose.ui.text.TextStyle displayMedium, optional androidx.compose.ui.text.TextStyle displaySmall, optional androidx.compose.ui.text.TextStyle headlineLarge, optional androidx.compose.ui.text.TextStyle headlineMedium, optional androidx.compose.ui.text.TextStyle headlineSmall, optional androidx.compose.ui.text.TextStyle titleLarge, optional androidx.compose.ui.text.TextStyle titleMedium, optional androidx.compose.ui.text.TextStyle titleSmall, optional androidx.compose.ui.text.TextStyle bodyLarge, optional androidx.compose.ui.text.TextStyle bodyMedium, optional androidx.compose.ui.text.TextStyle bodySmall, optional androidx.compose.ui.text.TextStyle labelLarge, optional androidx.compose.ui.text.TextStyle labelMedium, optional androidx.compose.ui.text.TextStyle labelSmall);
+    method public androidx.compose.ui.text.TextStyle getBodyLarge();
+    method public androidx.compose.ui.text.TextStyle getBodyMedium();
+    method public androidx.compose.ui.text.TextStyle getBodySmall();
+    method public androidx.compose.ui.text.TextStyle getDisplayLarge();
+    method public androidx.compose.ui.text.TextStyle getDisplayMedium();
+    method public androidx.compose.ui.text.TextStyle getDisplaySmall();
+    method public androidx.compose.ui.text.TextStyle getHeadlineLarge();
+    method public androidx.compose.ui.text.TextStyle getHeadlineMedium();
+    method public androidx.compose.ui.text.TextStyle getHeadlineSmall();
+    method public androidx.compose.ui.text.TextStyle getLabelLarge();
+    method public androidx.compose.ui.text.TextStyle getLabelMedium();
+    method public androidx.compose.ui.text.TextStyle getLabelSmall();
+    method public androidx.compose.ui.text.TextStyle getTitleLarge();
+    method public androidx.compose.ui.text.TextStyle getTitleMedium();
+    method public androidx.compose.ui.text.TextStyle getTitleSmall();
+    property public final androidx.compose.ui.text.TextStyle bodyLarge;
+    property public final androidx.compose.ui.text.TextStyle bodyMedium;
+    property public final androidx.compose.ui.text.TextStyle bodySmall;
+    property public final androidx.compose.ui.text.TextStyle displayLarge;
+    property public final androidx.compose.ui.text.TextStyle displayMedium;
+    property public final androidx.compose.ui.text.TextStyle displaySmall;
+    property public final androidx.compose.ui.text.TextStyle headlineLarge;
+    property public final androidx.compose.ui.text.TextStyle headlineMedium;
+    property public final androidx.compose.ui.text.TextStyle headlineSmall;
+    property public final androidx.compose.ui.text.TextStyle labelLarge;
+    property public final androidx.compose.ui.text.TextStyle labelMedium;
+    property public final androidx.compose.ui.text.TextStyle labelSmall;
+    property public final androidx.compose.ui.text.TextStyle titleLarge;
+    property public final androidx.compose.ui.text.TextStyle titleMedium;
+    property public final androidx.compose.ui.text.TextStyle titleSmall;
+  }
+
+}
+
diff --git a/compose/material3/material3/api/public_plus_experimental_1.1.0-beta02.txt b/compose/material3/material3/api/public_plus_experimental_1.1.0-beta02.txt
new file mode 100644
index 0000000..0b261b3
--- /dev/null
+++ b/compose/material3/material3/api/public_plus_experimental_1.1.0-beta02.txt
@@ -0,0 +1,1328 @@
+// Signature format: 4.0
+package androidx.compose.material3 {
+
+  public final class AlertDialogDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public long getIconContentColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public long getTextContentColor();
+    method @androidx.compose.runtime.Composable public long getTitleContentColor();
+    method public float getTonalElevation();
+    property public final float TonalElevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final long iconContentColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final long textContentColor;
+    property @androidx.compose.runtime.Composable public final long titleContentColor;
+    field public static final androidx.compose.material3.AlertDialogDefaults INSTANCE;
+  }
+
+  public final class AndroidAlertDialog_androidKt {
+    method @androidx.compose.runtime.Composable public static void AlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, kotlin.jvm.functions.Function0<kotlin.Unit> confirmButton, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dismissButton, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long iconContentColor, optional long titleContentColor, optional long textContentColor, optional float tonalElevation, optional androidx.compose.ui.window.DialogProperties properties);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void AlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.window.DialogProperties properties, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class AndroidMenu_androidKt {
+    method @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean enabled, optional androidx.compose.material3.MenuItemColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  public final class AppBarKt {
+    method @androidx.compose.runtime.Composable public static void BottomAppBar(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? floatingActionButton, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.WindowInsets windowInsets);
+    method @androidx.compose.runtime.Composable public static void BottomAppBar(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void CenterAlignedTopAppBar(kotlin.jvm.functions.Function0<kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> navigationIcon, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.TopAppBarColors colors, optional androidx.compose.material3.TopAppBarScrollBehavior? scrollBehavior);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void LargeTopAppBar(kotlin.jvm.functions.Function0<kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> navigationIcon, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.TopAppBarColors colors, optional androidx.compose.material3.TopAppBarScrollBehavior? scrollBehavior);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void MediumTopAppBar(kotlin.jvm.functions.Function0<kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> navigationIcon, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.TopAppBarColors colors, optional androidx.compose.material3.TopAppBarScrollBehavior? scrollBehavior);
+    method @Deprecated @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SmallTopAppBar(kotlin.jvm.functions.Function0<kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> navigationIcon, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.TopAppBarColors colors, optional androidx.compose.material3.TopAppBarScrollBehavior? scrollBehavior);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TopAppBar(kotlin.jvm.functions.Function0<kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> navigationIcon, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.TopAppBarColors colors, optional androidx.compose.material3.TopAppBarScrollBehavior? scrollBehavior);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.TopAppBarState rememberTopAppBarState(optional float initialHeightOffsetLimit, optional float initialHeightOffset, optional float initialContentOffset);
+  }
+
+  public final class AssistChipDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipBorder assistChipBorder(optional long borderColor, optional long disabledBorderColor, optional float borderWidth);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors assistChipColors(optional long containerColor, optional long labelColor, optional long leadingIconContentColor, optional long trailingIconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconContentColor, optional long disabledTrailingIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation assistChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors elevatedAssistChipColors(optional long containerColor, optional long labelColor, optional long leadingIconContentColor, optional long trailingIconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconContentColor, optional long disabledTrailingIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation elevatedAssistChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method public float getHeight();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    property public final float Height;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.AssistChipDefaults INSTANCE;
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api public final class BadgeDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    field public static final androidx.compose.material3.BadgeDefaults INSTANCE;
+  }
+
+  public final class BadgeKt {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Badge(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? content);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void BadgedBox(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> badge, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
+  }
+
+  public final class BottomAppBarDefaults {
+    method @androidx.compose.runtime.Composable public long getBottomAppBarFabColor();
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getContainerElevation();
+    method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property public final float ContainerElevation;
+    property public final androidx.compose.foundation.layout.PaddingValues ContentPadding;
+    property @androidx.compose.runtime.Composable public final long bottomAppBarFabColor;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.BottomAppBarDefaults INSTANCE;
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class BottomSheetDefaults {
+    method @androidx.compose.runtime.Composable public void DragHandle(optional androidx.compose.ui.Modifier modifier, optional float width, optional float height, optional androidx.compose.ui.graphics.Shape shape, optional long color);
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getElevation();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getExpandedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getHiddenShape();
+    method @androidx.compose.runtime.Composable public long getScrimColor();
+    method public float getSheetPeekHeight();
+    property @androidx.compose.runtime.Composable public final long ContainerColor;
+    property public final float Elevation;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape ExpandedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape HiddenShape;
+    property @androidx.compose.runtime.Composable public final long ScrimColor;
+    property public final float SheetPeekHeight;
+    field public static final androidx.compose.material3.BottomSheetDefaults INSTANCE;
+  }
+
+  public final class BottomSheetScaffoldKt {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @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.material3.BottomSheetScaffoldState scaffoldState, optional float sheetPeekHeight, optional androidx.compose.ui.graphics.Shape sheetShape, optional long sheetContainerColor, optional long sheetContentColor, optional float sheetTonalElevation, optional float sheetShadowElevation, optional kotlin.jvm.functions.Function0<kotlin.Unit>? sheetDragHandle, optional boolean sheetSwipeEnabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? topBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SnackbarHostState,kotlin.Unit> snackbarHost, optional long containerColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.BottomSheetScaffoldState rememberBottomSheetScaffoldState(optional androidx.compose.material3.SheetState bottomSheetState, optional androidx.compose.material3.SnackbarHostState snackbarHostState);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SheetState rememberStandardBottomSheetState(optional androidx.compose.material3.SheetValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SheetValue,java.lang.Boolean> confirmValueChange, optional boolean skipHiddenState);
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class BottomSheetScaffoldState {
+    ctor public BottomSheetScaffoldState(androidx.compose.material3.SheetState bottomSheetState, androidx.compose.material3.SnackbarHostState snackbarHostState);
+    method public androidx.compose.material3.SheetState getBottomSheetState();
+    method public androidx.compose.material3.SnackbarHostState getSnackbarHostState();
+    property public final androidx.compose.material3.SheetState bottomSheetState;
+    property public final androidx.compose.material3.SnackbarHostState snackbarHostState;
+  }
+
+  @androidx.compose.runtime.Immutable public final class ButtonColors {
+  }
+
+  public final class ButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors buttonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonElevation buttonElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors elevatedButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonElevation elevatedButtonElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors filledTonalButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonElevation filledTonalButtonElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float disabledElevation);
+    method public androidx.compose.foundation.layout.PaddingValues getButtonWithIconContentPadding();
+    method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getElevatedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFilledTonalShape();
+    method public float getIconSize();
+    method public float getIconSpacing();
+    method public float getMinHeight();
+    method public float getMinWidth();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke getOutlinedButtonBorder();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method public androidx.compose.foundation.layout.PaddingValues getTextButtonContentPadding();
+    method public androidx.compose.foundation.layout.PaddingValues getTextButtonWithIconContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getTextShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors outlinedButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors textButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    property public final androidx.compose.foundation.layout.PaddingValues ButtonWithIconContentPadding;
+    property public final androidx.compose.foundation.layout.PaddingValues ContentPadding;
+    property public final float IconSize;
+    property public final float IconSpacing;
+    property public final float MinHeight;
+    property public final float MinWidth;
+    property public final androidx.compose.foundation.layout.PaddingValues TextButtonContentPadding;
+    property public final androidx.compose.foundation.layout.PaddingValues TextButtonWithIconContentPadding;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape elevatedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape filledTonalShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.BorderStroke outlinedButtonBorder;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape textShape;
+    field public static final androidx.compose.material3.ButtonDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class ButtonElevation {
+  }
+
+  public final class ButtonKt {
+    method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ElevatedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class CardColors {
+  }
+
+  public final class CardDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardColors cardColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardElevation cardElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardColors elevatedCardColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardElevation elevatedCardElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getElevatedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke outlinedCardBorder(optional boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardColors outlinedCardColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardElevation outlinedCardElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape elevatedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.CardDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class CardElevation {
+  }
+
+  public final class CardKt {
+    method @androidx.compose.runtime.Composable public static void Card(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Card(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ElevatedCard(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void ElevatedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedCard(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void OutlinedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class CheckboxColors {
+  }
+
+  public final class CheckboxDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.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.compose.material3.CheckboxDefaults INSTANCE;
+  }
+
+  public final class CheckboxKt {
+    method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Immutable public final class ChipBorder {
+  }
+
+  @androidx.compose.runtime.Immutable public final class ChipColors {
+  }
+
+  @androidx.compose.runtime.Immutable public final class ChipElevation {
+  }
+
+  public final class ChipKt {
+    method @androidx.compose.runtime.Composable public static void AssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedAssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void ElevatedFilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.material3.SelectableChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedSuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void FilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.material3.SelectableChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void InputChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? avatar, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.material3.SelectableChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void SuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Stable public final class ColorScheme {
+    ctor public ColorScheme(long primary, long onPrimary, long primaryContainer, long onPrimaryContainer, long inversePrimary, long secondary, long onSecondary, long secondaryContainer, long onSecondaryContainer, long tertiary, long onTertiary, long tertiaryContainer, long onTertiaryContainer, long background, long onBackground, long surface, long onSurface, long surfaceVariant, long onSurfaceVariant, long surfaceTint, long inverseSurface, long inverseOnSurface, long error, long onError, long errorContainer, long onErrorContainer, long outline, long outlineVariant, long scrim);
+    method public androidx.compose.material3.ColorScheme copy(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim);
+    method public long getBackground();
+    method public long getError();
+    method public long getErrorContainer();
+    method public long getInverseOnSurface();
+    method public long getInversePrimary();
+    method public long getInverseSurface();
+    method public long getOnBackground();
+    method public long getOnError();
+    method public long getOnErrorContainer();
+    method public long getOnPrimary();
+    method public long getOnPrimaryContainer();
+    method public long getOnSecondary();
+    method public long getOnSecondaryContainer();
+    method public long getOnSurface();
+    method public long getOnSurfaceVariant();
+    method public long getOnTertiary();
+    method public long getOnTertiaryContainer();
+    method public long getOutline();
+    method public long getOutlineVariant();
+    method public long getPrimary();
+    method public long getPrimaryContainer();
+    method public long getScrim();
+    method public long getSecondary();
+    method public long getSecondaryContainer();
+    method public long getSurface();
+    method public long getSurfaceTint();
+    method public long getSurfaceVariant();
+    method public long getTertiary();
+    method public long getTertiaryContainer();
+    property public final long background;
+    property public final long error;
+    property public final long errorContainer;
+    property public final long inverseOnSurface;
+    property public final long inversePrimary;
+    property public final long inverseSurface;
+    property public final long onBackground;
+    property public final long onError;
+    property public final long onErrorContainer;
+    property public final long onPrimary;
+    property public final long onPrimaryContainer;
+    property public final long onSecondary;
+    property public final long onSecondaryContainer;
+    property public final long onSurface;
+    property public final long onSurfaceVariant;
+    property public final long onTertiary;
+    property public final long onTertiaryContainer;
+    property public final long outline;
+    property public final long outlineVariant;
+    property public final long primary;
+    property public final long primaryContainer;
+    property public final long scrim;
+    property public final long secondary;
+    property public final long secondaryContainer;
+    property public final long surface;
+    property public final long surfaceTint;
+    property public final long surfaceVariant;
+    property public final long tertiary;
+    property public final long tertiaryContainer;
+  }
+
+  public final class ColorSchemeKt {
+    method public static long contentColorFor(androidx.compose.material3.ColorScheme, long backgroundColor);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static long contentColorFor(long backgroundColor);
+    method public static androidx.compose.material3.ColorScheme darkColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim);
+    method public static androidx.compose.material3.ColorScheme lightColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim);
+    method public static long surfaceColorAtElevation(androidx.compose.material3.ColorScheme, float elevation);
+  }
+
+  public final class ContentColorKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.graphics.Color> getLocalContentColor();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.graphics.Color> LocalContentColor;
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class DatePickerColors {
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class DatePickerDefaults {
+    method @androidx.compose.runtime.Composable public void DatePickerHeadline(androidx.compose.material3.DatePickerState state, androidx.compose.material3.DatePickerFormatter dateFormatter, optional androidx.compose.ui.Modifier modifier);
+    method @androidx.compose.runtime.Composable public void DatePickerTitle(androidx.compose.material3.DatePickerState state, optional androidx.compose.ui.Modifier modifier);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.DatePickerColors colors(optional long containerColor, optional long titleContentColor, optional long headlineContentColor, optional long weekdayContentColor, optional long subheadContentColor, optional long yearContentColor, optional long currentYearContentColor, optional long selectedYearContentColor, optional long selectedYearContainerColor, optional long dayContentColor, optional long disabledDayContentColor, optional long selectedDayContentColor, optional long disabledSelectedDayContentColor, optional long selectedDayContainerColor, optional long disabledSelectedDayContainerColor, optional long todayContentColor, optional long todayDateBorderColor, optional long dayInSelectionRangeContentColor, optional long dayInSelectionRangeContainerColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method public float getTonalElevation();
+    method public kotlin.ranges.IntRange getYearRange();
+    property public final float TonalElevation;
+    property public final kotlin.ranges.IntRange YearRange;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.DatePickerDefaults INSTANCE;
+    field public static final String YearAbbrMonthDaySkeleton = "yMMMd";
+    field public static final String YearMonthSkeleton = "yMMMM";
+    field public static final String YearMonthWeekdayDaySkeleton = "yMMMMEEEEd";
+  }
+
+  public final class DatePickerDialog_androidKt {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DatePickerDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, kotlin.jvm.functions.Function0<kotlin.Unit> confirmButton, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dismissButton, optional androidx.compose.ui.graphics.Shape shape, optional float tonalElevation, optional androidx.compose.material3.DatePickerColors colors, optional androidx.compose.ui.window.DialogProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class DatePickerFormatter {
+    ctor public DatePickerFormatter(optional String yearSelectionSkeleton, optional String selectedDateSkeleton, optional String selectedDateDescriptionSkeleton);
+  }
+
+  public final class DatePickerKt {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DatePicker(androidx.compose.material3.DatePickerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DatePickerFormatter dateFormatter, optional kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> dateValidator, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? headline, optional boolean showModeToggle, optional androidx.compose.material3.DatePickerColors colors);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.DatePickerState rememberDatePickerState(optional Long? initialSelectedDateMillis, optional Long? initialDisplayedMonthMillis, optional kotlin.ranges.IntRange yearRange, optional int initialDisplayMode);
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class DatePickerState {
+    ctor public DatePickerState(Long? initialSelectedDateMillis, Long? initialDisplayedMonthMillis, kotlin.ranges.IntRange yearRange, int initialDisplayMode);
+    method public int getDisplayMode();
+    method public Long? getSelectedDateMillis();
+    method public void setDisplayMode(int);
+    method public void setSelection(Long? dateMillis);
+    property public final int displayMode;
+    property public final Long? selectedDateMillis;
+    field public static final androidx.compose.material3.DatePickerState.Companion Companion;
+  }
+
+  public static final class DatePickerState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.DatePickerState,?> Saver();
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class DateRangePickerDefaults {
+    method @androidx.compose.runtime.Composable public void DateRangePickerHeadline(androidx.compose.material3.DateRangePickerState state, androidx.compose.material3.DatePickerFormatter dateFormatter, optional androidx.compose.ui.Modifier modifier);
+    method @androidx.compose.runtime.Composable public void DateRangePickerTitle(androidx.compose.material3.DateRangePickerState state, optional androidx.compose.ui.Modifier modifier);
+    field public static final androidx.compose.material3.DateRangePickerDefaults INSTANCE;
+  }
+
+  public final class DateRangePickerKt {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DateRangePicker(androidx.compose.material3.DateRangePickerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DatePickerFormatter dateFormatter, optional kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> dateValidator, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? headline, optional boolean showModeToggle, optional androidx.compose.material3.DatePickerColors colors);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.DateRangePickerState rememberDateRangePickerState(optional Long? initialSelectedStartDateMillis, optional Long? initialSelectedEndDateMillis, optional Long? initialDisplayedMonthMillis, optional kotlin.ranges.IntRange yearRange, optional int initialDisplayMode);
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class DateRangePickerState {
+    ctor public DateRangePickerState(Long? initialSelectedStartDateMillis, Long? initialSelectedEndDateMillis, Long? initialDisplayedMonthMillis, kotlin.ranges.IntRange yearRange, int initialDisplayMode);
+    method public int getDisplayMode();
+    method public Long? getSelectedEndDateMillis();
+    method public Long? getSelectedStartDateMillis();
+    method public void setDisplayMode(int);
+    method public void setSelection(Long? startDateMillis, Long? endDateMillis);
+    property public final int displayMode;
+    property public final Long? selectedEndDateMillis;
+    property public final Long? selectedStartDateMillis;
+    field public static final androidx.compose.material3.DateRangePickerState.Companion Companion;
+  }
+
+  public static final class DateRangePickerState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.DateRangePickerState,?> Saver();
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissDirection {
+    method public static androidx.compose.material3.DismissDirection valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.DismissDirection[] values();
+    enum_constant public static final androidx.compose.material3.DismissDirection EndToStart;
+    enum_constant public static final androidx.compose.material3.DismissDirection StartToEnd;
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api public final class DismissState {
+    ctor public DismissState(androidx.compose.material3.DismissValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DismissValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function2<? super androidx.compose.ui.unit.Density,? super java.lang.Float,java.lang.Float> positionalThreshold);
+    method public suspend Object? dismiss(androidx.compose.material3.DismissDirection direction, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.material3.DismissValue getCurrentValue();
+    method public androidx.compose.material3.DismissDirection? getDismissDirection();
+    method public float getProgress();
+    method public androidx.compose.material3.DismissValue getTargetValue();
+    method public boolean isDismissed(androidx.compose.material3.DismissDirection direction);
+    method public float requireOffset();
+    method public suspend Object? reset(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? snapTo(androidx.compose.material3.DismissValue targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final androidx.compose.material3.DismissValue currentValue;
+    property public final androidx.compose.material3.DismissDirection? dismissDirection;
+    property public final float progress;
+    property public final androidx.compose.material3.DismissValue targetValue;
+    field public static final androidx.compose.material3.DismissState.Companion Companion;
+  }
+
+  public static final class DismissState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.DismissState,androidx.compose.material3.DismissValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material3.DismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function2<? super androidx.compose.ui.unit.Density,? super java.lang.Float,java.lang.Float> positionalThreshold);
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissValue {
+    method public static androidx.compose.material3.DismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.DismissValue[] values();
+    enum_constant public static final androidx.compose.material3.DismissValue Default;
+    enum_constant public static final androidx.compose.material3.DismissValue DismissedToEnd;
+    enum_constant public static final androidx.compose.material3.DismissValue DismissedToStart;
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class DisplayMode {
+    field public static final androidx.compose.material3.DisplayMode.Companion Companion;
+  }
+
+  public static final class DisplayMode.Companion {
+    method public int getInput();
+    method public int getPicker();
+    property public final int Input;
+    property public final int Picker;
+  }
+
+  public final class DividerDefaults {
+    method @androidx.compose.runtime.Composable public long getColor();
+    method public float getThickness();
+    property public final float Thickness;
+    property @androidx.compose.runtime.Composable public final long color;
+    field public static final androidx.compose.material3.DividerDefaults INSTANCE;
+  }
+
+  public final class DividerKt {
+    method @androidx.compose.runtime.Composable public static void Divider(optional androidx.compose.ui.Modifier modifier, optional float thickness, optional long color);
+  }
+
+  public final class DrawerDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getDismissibleDrawerElevation();
+    method public float getMaximumDrawerWidth();
+    method public float getModalDrawerElevation();
+    method public float getPermanentDrawerElevation();
+    method @androidx.compose.runtime.Composable public long getScrimColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property public final float DismissibleDrawerElevation;
+    property public final float MaximumDrawerWidth;
+    property public final float ModalDrawerElevation;
+    property public final float PermanentDrawerElevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final long scrimColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.DrawerDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class DrawerState {
+    ctor public DrawerState(androidx.compose.material3.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
+    method public suspend Object? animateTo(androidx.compose.material3.DrawerValue targetValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.material3.DrawerValue getCurrentValue();
+    method public androidx.compose.runtime.State<java.lang.Float> getOffset();
+    method public androidx.compose.material3.DrawerValue getTargetValue();
+    method public boolean isAnimationRunning();
+    method public boolean isClosed();
+    method public boolean isOpen();
+    method public suspend Object? open(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? snapTo(androidx.compose.material3.DrawerValue targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final androidx.compose.material3.DrawerValue currentValue;
+    property public final boolean isAnimationRunning;
+    property public final boolean isClosed;
+    property public final boolean isOpen;
+    property public final androidx.compose.runtime.State<java.lang.Float> offset;
+    property public final androidx.compose.material3.DrawerValue targetValue;
+    field public static final androidx.compose.material3.DrawerState.Companion Companion;
+  }
+
+  public static final class DrawerState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.DrawerState,androidx.compose.material3.DrawerValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
+  }
+
+  public enum DrawerValue {
+    method public static androidx.compose.material3.DrawerValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.DrawerValue[] values();
+    enum_constant public static final androidx.compose.material3.DrawerValue Closed;
+    enum_constant public static final androidx.compose.material3.DrawerValue Open;
+  }
+
+  public final class DynamicTonalPaletteKt {
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public static androidx.compose.material3.ColorScheme dynamicDarkColorScheme(android.content.Context context);
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public static androidx.compose.material3.ColorScheme dynamicLightColorScheme(android.content.Context context);
+  }
+
+  @kotlin.RequiresOptIn(message="This material API is experimental and is likely to change or to be removed in" + " the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalMaterial3Api {
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api public interface ExposedDropdownMenuBoxScope {
+    method @androidx.compose.runtime.Composable public default void ExposedDropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method public androidx.compose.ui.Modifier exposedDropdownSize(androidx.compose.ui.Modifier, optional boolean matchTextFieldWidth);
+    method public androidx.compose.ui.Modifier menuAnchor(androidx.compose.ui.Modifier);
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api public final class ExposedDropdownMenuDefaults {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void TrailingIcon(boolean expanded);
+    method public androidx.compose.foundation.layout.PaddingValues getItemContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors outlinedTextFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long containerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors outlinedTextFieldColors(optional long textColor, optional long disabledTextColor, optional long containerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors textFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long containerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors textFieldColors(optional long textColor, optional long disabledTextColor, optional long containerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    property public final androidx.compose.foundation.layout.PaddingValues ItemContentPadding;
+    field public static final androidx.compose.material3.ExposedDropdownMenuDefaults INSTANCE;
+  }
+
+  public final class ExposedDropdownMenuKt {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void ExposedDropdownMenuBox(boolean expanded, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onExpandedChange, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.material3.ExposedDropdownMenuBoxScope,kotlin.Unit> content);
+  }
+
+  @kotlin.jvm.JvmInline public final value class FabPosition {
+    field public static final androidx.compose.material3.FabPosition.Companion Companion;
+  }
+
+  public static final class FabPosition.Companion {
+    method public int getCenter();
+    method public int getEnd();
+    property public final int Center;
+    property public final int End;
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api public final class FilterChipDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipColors elevatedFilterChipColors(optional long containerColor, optional long labelColor, optional long iconColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor, optional long selectedContainerColor, optional long disabledSelectedContainerColor, optional long selectedLabelColor, optional long selectedLeadingIconColor, optional long selectedTrailingIconColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipElevation elevatedFilterChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipBorder filterChipBorder(optional long borderColor, optional long selectedBorderColor, optional long disabledBorderColor, optional long disabledSelectedBorderColor, optional float borderWidth, optional float selectedBorderWidth);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipColors filterChipColors(optional long containerColor, optional long labelColor, optional long iconColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor, optional long selectedContainerColor, optional long disabledSelectedContainerColor, optional long selectedLabelColor, optional long selectedLeadingIconColor, optional long selectedTrailingIconColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipElevation filterChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method public float getHeight();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    property public final float Height;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.FilterChipDefaults INSTANCE;
+  }
+
+  public final class FloatingActionButtonDefaults {
+    method public androidx.compose.material3.FloatingActionButtonElevation bottomAppBarFabElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.FloatingActionButtonElevation elevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getExtendedFabShape();
+    method public float getLargeIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getLargeShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getSmallShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.FloatingActionButtonElevation loweredElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
+    property public final float LargeIconSize;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape extendedFabShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape largeShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape smallShape;
+    field public static final androidx.compose.material3.FloatingActionButtonDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public class FloatingActionButtonElevation {
+  }
+
+  public final class FloatingActionButtonKt {
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean expanded, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void LargeFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void SmallFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class IconButtonColors {
+  }
+
+  public final class IconButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors filledIconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors filledIconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors filledTonalIconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors filledTonalIconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFilledShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors iconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors iconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke outlinedIconButtonBorder(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors outlinedIconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke? outlinedIconToggleButtonBorder(boolean enabled, boolean checked);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors outlinedIconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape filledShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    field public static final androidx.compose.material3.IconButtonDefaults INSTANCE;
+  }
+
+  public final class IconButtonKt {
+    method @androidx.compose.runtime.Composable public static void FilledIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class IconKt {
+    method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.vector.ImageVector imageVector, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+    method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.ImageBitmap bitmap, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+    method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.painter.Painter painter, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+  }
+
+  @androidx.compose.runtime.Immutable public final class IconToggleButtonColors {
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api public final class InputChipDefaults {
+    method public float getAvatarSize();
+    method public float getHeight();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipBorder inputChipBorder(optional long borderColor, optional long selectedBorderColor, optional long disabledBorderColor, optional long disabledSelectedBorderColor, optional float borderWidth, optional float selectedBorderWidth);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipColors inputChipColors(optional long containerColor, optional long labelColor, optional long leadingIconColor, optional long trailingIconColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor, optional long selectedContainerColor, optional long disabledSelectedContainerColor, optional long selectedLabelColor, optional long selectedLeadingIconColor, optional long selectedTrailingIconColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipElevation inputChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    property public final float AvatarSize;
+    property public final float Height;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.InputChipDefaults INSTANCE;
+  }
+
+  public final class InteractiveComponentSizeKt {
+    method @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumInteractiveComponentEnforcement();
+    method @Deprecated @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumTouchTargetEnforcement();
+    method public static androidx.compose.ui.Modifier minimumInteractiveComponentSize(androidx.compose.ui.Modifier);
+    property @androidx.compose.material3.ExperimentalMaterial3Api public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumInteractiveComponentEnforcement;
+    property @Deprecated @androidx.compose.material3.ExperimentalMaterial3Api public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumTouchTargetEnforcement;
+  }
+
+  @androidx.compose.runtime.Immutable public final class ListItemColors {
+  }
+
+  public final class ListItemDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ListItemColors colors(optional long containerColor, optional long headlineColor, optional long leadingIconColor, optional long overlineColor, optional long supportingColor, optional long trailingIconColor, optional long disabledHeadlineColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public long getContainerColor();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public long getContentColor();
+    method public float getElevation();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.ui.graphics.Shape getShape();
+    property public final float Elevation;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final long containerColor;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final long contentColor;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.ListItemDefaults INSTANCE;
+  }
+
+  public final class ListItemKt {
+    method @androidx.compose.runtime.Composable public static void ListItem(kotlin.jvm.functions.Function0<kotlin.Unit> headlineContent, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? overlineContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingContent, optional androidx.compose.material3.ListItemColors colors, optional float tonalElevation, optional float shadowElevation);
+  }
+
+  public final class MaterialTheme {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.ColorScheme getColorScheme();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.Shapes getShapes();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.Typography getTypography();
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.ColorScheme colorScheme;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.Shapes shapes;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.Typography typography;
+    field public static final androidx.compose.material3.MaterialTheme INSTANCE;
+  }
+
+  public final class MaterialThemeKt {
+    method @androidx.compose.runtime.Composable public static void MaterialTheme(optional androidx.compose.material3.ColorScheme colorScheme, optional androidx.compose.material3.Shapes shapes, optional androidx.compose.material3.Typography typography, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class MenuDefaults {
+    method public androidx.compose.foundation.layout.PaddingValues getDropdownMenuItemContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.MenuItemColors itemColors(optional long textColor, optional long leadingIconColor, optional long trailingIconColor, optional long disabledTextColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor);
+    property public final androidx.compose.foundation.layout.PaddingValues DropdownMenuItemContentPadding;
+    field public static final androidx.compose.material3.MenuDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class MenuItemColors {
+  }
+
+  public final class ModalBottomSheetKt {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void ModalBottomSheet(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SheetState sheetState, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional float tonalElevation, optional long scrimColor, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dragHandle, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SheetState rememberModalBottomSheetState(optional boolean skipPartiallyExpanded, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SheetValue,java.lang.Boolean> confirmValueChange);
+  }
+
+  public final class NavigationBarDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getElevation();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property public final float Elevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.NavigationBarDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class NavigationBarItemColors {
+  }
+
+  public final class NavigationBarItemDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationBarItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor, optional long disabledIconColor, optional long disabledTextColor);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationBarItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor);
+    field public static final androidx.compose.material3.NavigationBarItemDefaults INSTANCE;
+  }
+
+  public final class NavigationBarKt {
+    method @androidx.compose.runtime.Composable public static void NavigationBar(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void NavigationBarItem(androidx.compose.foundation.layout.RowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationBarItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Stable public interface NavigationDrawerItemColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> badgeColor(boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> iconColor(boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean selected);
+  }
+
+  public final class NavigationDrawerItemDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationDrawerItemColors colors(optional long selectedContainerColor, optional long unselectedContainerColor, optional long selectedIconColor, optional long unselectedIconColor, optional long selectedTextColor, optional long unselectedTextColor, optional long selectedBadgeColor, optional long unselectedBadgeColor);
+    method public androidx.compose.foundation.layout.PaddingValues getItemPadding();
+    property public final androidx.compose.foundation.layout.PaddingValues ItemPadding;
+    field public static final androidx.compose.material3.NavigationDrawerItemDefaults INSTANCE;
+  }
+
+  public final class NavigationDrawerKt {
+    method @androidx.compose.runtime.Composable public static void DismissibleDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void DismissibleNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DrawerState drawerState, optional boolean gesturesEnabled, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ModalDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ModalNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DrawerState drawerState, optional boolean gesturesEnabled, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void NavigationDrawerItem(kotlin.jvm.functions.Function0<kotlin.Unit> label, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? badge, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.NavigationDrawerItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void PermanentDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void PermanentNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static androidx.compose.material3.DrawerState rememberDrawerState(androidx.compose.material3.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
+  }
+
+  public final class NavigationRailDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property @androidx.compose.runtime.Composable public final long ContainerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.NavigationRailDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class NavigationRailItemColors {
+  }
+
+  public final class NavigationRailItemDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationRailItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor, optional long disabledIconColor, optional long disabledTextColor);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationRailItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor);
+    field public static final androidx.compose.material3.NavigationRailItemDefaults INSTANCE;
+  }
+
+  public final class NavigationRailKt {
+    method @androidx.compose.runtime.Composable public static void NavigationRail(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? header, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void NavigationRailItem(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationRailItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  public final class OutlinedTextFieldKt {
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @Deprecated @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,? extends kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @Deprecated @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,? extends kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class PlainTooltipState {
+    ctor public PlainTooltipState();
+    method public suspend Object? dismiss(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public boolean isVisible();
+    method public suspend Object? show(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public boolean isVisible;
+  }
+
+  public final class ProgressIndicatorDefaults {
+    method @androidx.compose.runtime.Composable public long getCircularColor();
+    method public int getCircularDeterminateStrokeCap();
+    method public int getCircularIndeterminateStrokeCap();
+    method public float getCircularStrokeWidth();
+    method @androidx.compose.runtime.Composable public long getCircularTrackColor();
+    method @androidx.compose.runtime.Composable public long getLinearColor();
+    method public int getLinearStrokeCap();
+    method @androidx.compose.runtime.Composable public long getLinearTrackColor();
+    method public androidx.compose.animation.core.SpringSpec<java.lang.Float> getProgressAnimationSpec();
+    property public final int CircularDeterminateStrokeCap;
+    property public final int CircularIndeterminateStrokeCap;
+    property public final float CircularStrokeWidth;
+    property public final int LinearStrokeCap;
+    property public final androidx.compose.animation.core.SpringSpec<java.lang.Float> ProgressAnimationSpec;
+    property @androidx.compose.runtime.Composable public final long circularColor;
+    property @androidx.compose.runtime.Composable public final long circularTrackColor;
+    property @androidx.compose.runtime.Composable public final long linearColor;
+    property @androidx.compose.runtime.Composable public final long linearTrackColor;
+    field public static final androidx.compose.material3.ProgressIndicatorDefaults INSTANCE;
+  }
+
+  public final class ProgressIndicatorKt {
+    method @androidx.compose.runtime.Composable public static void CircularProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth, optional long trackColor, optional int strokeCap);
+    method @androidx.compose.runtime.Composable public static void CircularProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth, optional long trackColor, optional int strokeCap);
+    method @Deprecated @androidx.compose.runtime.Composable public static void CircularProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth);
+    method @Deprecated @androidx.compose.runtime.Composable public static void CircularProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth);
+    method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor, optional int strokeCap);
+    method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor, optional int strokeCap);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LinearProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor);
+  }
+
+  @androidx.compose.runtime.Immutable public final class RadioButtonColors {
+  }
+
+  public final class RadioButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.RadioButtonColors colors(optional long selectedColor, optional long unselectedColor, optional long disabledSelectedColor, optional long disabledUnselectedColor);
+    field public static final androidx.compose.material3.RadioButtonDefaults INSTANCE;
+  }
+
+  public final class RadioButtonKt {
+    method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.RadioButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable @androidx.compose.runtime.Stable public final class RichTooltipColors {
+    ctor public RichTooltipColors(long containerColor, long contentColor, long titleContentColor, long actionContentColor);
+    method public long getActionContentColor();
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getTitleContentColor();
+    property public final long actionContentColor;
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long titleContentColor;
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class RichTooltipState {
+    ctor public RichTooltipState();
+    method public suspend Object? dismiss(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public boolean isVisible();
+    method public suspend Object? show(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public boolean isVisible;
+  }
+
+  public final class ScaffoldDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getContentWindowInsets();
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets contentWindowInsets;
+    field public static final androidx.compose.material3.ScaffoldDefaults INSTANCE;
+  }
+
+  public final class ScaffoldKt {
+    method @androidx.compose.runtime.Composable public static void Scaffold(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional int floatingActionButtonPosition, optional long containerColor, optional long contentColor, optional androidx.compose.foundation.layout.WindowInsets contentWindowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SearchBarColors {
+    method public long getContainerColor();
+    method public long getDividerColor();
+    method public androidx.compose.material3.TextFieldColors getInputFieldColors();
+    property public final long containerColor;
+    property public final long dividerColor;
+    property public final androidx.compose.material3.TextFieldColors inputFieldColors;
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api public final class SearchBarDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SearchBarColors colors(optional long containerColor, optional long dividerColor, optional androidx.compose.material3.TextFieldColors inputFieldColors);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getDockedShape();
+    method public float getElevation();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFullScreenShape();
+    method public float getInputFieldHeight();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getInputFieldShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors inputFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long cursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors! inputFieldColors(optional long textColor, optional long disabledTextColor, optional long cursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    property public final float Elevation;
+    property public final float InputFieldHeight;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape dockedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape fullScreenShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape inputFieldShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.SearchBarDefaults INSTANCE;
+  }
+
+  public final class SearchBarKt {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DockedSearchBar(String query, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onQueryChange, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onSearch, boolean active, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onActiveChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SearchBarColors colors, optional float tonalElevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SearchBar(String query, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onQueryChange, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onSearch, boolean active, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onActiveChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SearchBarColors colors, optional float tonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SelectableChipBorder {
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SelectableChipColors {
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SelectableChipElevation {
+  }
+
+  public final class ShapeDefaults {
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraSmall();
+    method public androidx.compose.foundation.shape.CornerBasedShape getLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getMedium();
+    method public androidx.compose.foundation.shape.CornerBasedShape getSmall();
+    property public final androidx.compose.foundation.shape.CornerBasedShape ExtraLarge;
+    property public final androidx.compose.foundation.shape.CornerBasedShape ExtraSmall;
+    property public final androidx.compose.foundation.shape.CornerBasedShape Large;
+    property public final androidx.compose.foundation.shape.CornerBasedShape Medium;
+    property public final androidx.compose.foundation.shape.CornerBasedShape Small;
+    field public static final androidx.compose.material3.ShapeDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class Shapes {
+    ctor public Shapes(optional androidx.compose.foundation.shape.CornerBasedShape extraSmall, optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large, optional androidx.compose.foundation.shape.CornerBasedShape extraLarge);
+    method public androidx.compose.material3.Shapes copy(optional androidx.compose.foundation.shape.CornerBasedShape extraSmall, optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large, optional androidx.compose.foundation.shape.CornerBasedShape extraLarge);
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraSmall();
+    method public androidx.compose.foundation.shape.CornerBasedShape getLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getMedium();
+    method public androidx.compose.foundation.shape.CornerBasedShape getSmall();
+    property public final androidx.compose.foundation.shape.CornerBasedShape extraLarge;
+    property public final androidx.compose.foundation.shape.CornerBasedShape extraSmall;
+    property public final androidx.compose.foundation.shape.CornerBasedShape large;
+    property public final androidx.compose.foundation.shape.CornerBasedShape medium;
+    property public final androidx.compose.foundation.shape.CornerBasedShape small;
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class SheetState {
+    ctor public SheetState(boolean skipPartiallyExpanded, optional androidx.compose.material3.SheetValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SheetValue,java.lang.Boolean> confirmValueChange, optional boolean skipHiddenState);
+    method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.material3.SheetValue getCurrentValue();
+    method public boolean getHasExpandedState();
+    method public boolean getHasPartiallyExpandedState();
+    method public androidx.compose.material3.SheetValue getTargetValue();
+    method public suspend Object? hide(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public boolean isVisible();
+    method public suspend Object? partialExpand(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public float requireOffset();
+    method public suspend Object? show(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final androidx.compose.material3.SheetValue currentValue;
+    property public final boolean hasExpandedState;
+    property public final boolean hasPartiallyExpandedState;
+    property public final boolean isVisible;
+    property public final androidx.compose.material3.SheetValue targetValue;
+    field public static final androidx.compose.material3.SheetState.Companion Companion;
+  }
+
+  public static final class SheetState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.SheetState,androidx.compose.material3.SheetValue> Saver(boolean skipPartiallyExpanded, kotlin.jvm.functions.Function1<? super androidx.compose.material3.SheetValue,java.lang.Boolean> confirmValueChange);
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api public enum SheetValue {
+    method public static androidx.compose.material3.SheetValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SheetValue[] values();
+    enum_constant public static final androidx.compose.material3.SheetValue Expanded;
+    enum_constant public static final androidx.compose.material3.SheetValue Hidden;
+    enum_constant public static final androidx.compose.material3.SheetValue PartiallyExpanded;
+  }
+
+  @androidx.compose.runtime.Immutable public final class SliderColors {
+  }
+
+  @androidx.compose.runtime.Stable public final class SliderDefaults {
+    method @androidx.compose.runtime.Composable public void Thumb(androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled, optional long thumbSize);
+    method @androidx.compose.runtime.Composable public void Track(androidx.compose.material3.SliderPositions sliderPositions, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SliderColors colors(optional long thumbColor, optional long activeTrackColor, optional long activeTickColor, optional long inactiveTrackColor, optional long inactiveTickColor, optional long disabledThumbColor, optional long disabledActiveTrackColor, optional long disabledActiveTickColor, optional long disabledInactiveTrackColor, optional long disabledInactiveTickColor);
+    field public static final androidx.compose.material3.SliderDefaults INSTANCE;
+  }
+
+  public final class SliderKt {
+    method @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource startInteractionSource, optional androidx.compose.foundation.interaction.MutableInteractionSource endInteractionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderPositions,kotlin.Unit> startThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderPositions,kotlin.Unit> endThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderPositions,kotlin.Unit> track, optional int steps);
+    method @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderPositions,kotlin.Unit> thumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderPositions,kotlin.Unit> track, optional int steps);
+  }
+
+  @androidx.compose.runtime.Stable public final class SliderPositions {
+    ctor public SliderPositions(optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> initialActiveRange, optional float[] initialTickFractions);
+    method public kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> getActiveRange();
+    method public float[] getTickFractions();
+    property public final kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> activeRange;
+    property public final float[] tickFractions;
+  }
+
+  @androidx.compose.runtime.Stable public interface SnackbarData {
+    method public void dismiss();
+    method public androidx.compose.material3.SnackbarVisuals getVisuals();
+    method public void performAction();
+    property public abstract androidx.compose.material3.SnackbarVisuals visuals;
+  }
+
+  public final class SnackbarDefaults {
+    method @androidx.compose.runtime.Composable public long getActionColor();
+    method @androidx.compose.runtime.Composable public long getActionContentColor();
+    method @androidx.compose.runtime.Composable public long getColor();
+    method @androidx.compose.runtime.Composable public long getContentColor();
+    method @androidx.compose.runtime.Composable public long getDismissActionContentColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    property @androidx.compose.runtime.Composable public final long actionColor;
+    property @androidx.compose.runtime.Composable public final long actionContentColor;
+    property @androidx.compose.runtime.Composable public final long color;
+    property @androidx.compose.runtime.Composable public final long contentColor;
+    property @androidx.compose.runtime.Composable public final long dismissActionContentColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.SnackbarDefaults INSTANCE;
+  }
+
+  public enum SnackbarDuration {
+    method public static androidx.compose.material3.SnackbarDuration valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SnackbarDuration[] values();
+    enum_constant public static final androidx.compose.material3.SnackbarDuration Indefinite;
+    enum_constant public static final androidx.compose.material3.SnackbarDuration Long;
+    enum_constant public static final androidx.compose.material3.SnackbarDuration Short;
+  }
+
+  public final class SnackbarHostKt {
+    method @androidx.compose.runtime.Composable public static void SnackbarHost(androidx.compose.material3.SnackbarHostState hostState, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SnackbarData,kotlin.Unit> snackbar);
+  }
+
+  @androidx.compose.runtime.Stable public final class SnackbarHostState {
+    ctor public SnackbarHostState();
+    method public androidx.compose.material3.SnackbarData? getCurrentSnackbarData();
+    method public suspend Object? showSnackbar(String message, optional String? actionLabel, optional boolean withDismissAction, optional androidx.compose.material3.SnackbarDuration duration, optional kotlin.coroutines.Continuation<? super androidx.compose.material3.SnackbarResult>);
+    method public suspend Object? showSnackbar(androidx.compose.material3.SnackbarVisuals visuals, kotlin.coroutines.Continuation<? super androidx.compose.material3.SnackbarResult>);
+    property public final androidx.compose.material3.SnackbarData? currentSnackbarData;
+  }
+
+  public final class SnackbarKt {
+    method @androidx.compose.runtime.Composable public static void Snackbar(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dismissAction, optional boolean actionOnNewLine, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional long actionContentColor, optional long dismissActionContentColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Snackbar(androidx.compose.material3.SnackbarData snackbarData, optional androidx.compose.ui.Modifier modifier, optional boolean actionOnNewLine, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional long actionColor, optional long actionContentColor, optional long dismissActionContentColor);
+  }
+
+  public enum SnackbarResult {
+    method public static androidx.compose.material3.SnackbarResult valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SnackbarResult[] values();
+    enum_constant public static final androidx.compose.material3.SnackbarResult ActionPerformed;
+    enum_constant public static final androidx.compose.material3.SnackbarResult Dismissed;
+  }
+
+  @androidx.compose.runtime.Stable public interface SnackbarVisuals {
+    method public String? getActionLabel();
+    method public androidx.compose.material3.SnackbarDuration getDuration();
+    method public String getMessage();
+    method public boolean getWithDismissAction();
+    property public abstract String? actionLabel;
+    property public abstract androidx.compose.material3.SnackbarDuration duration;
+    property public abstract String message;
+    property public abstract boolean withDismissAction;
+  }
+
+  public final class SuggestionChipDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors elevatedSuggestionChipColors(optional long containerColor, optional long labelColor, optional long iconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation elevatedSuggestionChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method public float getHeight();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipBorder suggestionChipBorder(optional long borderColor, optional long disabledBorderColor, optional float borderWidth);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors suggestionChipColors(optional long containerColor, optional long labelColor, optional long iconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation suggestionChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    property public final float Height;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.SuggestionChipDefaults INSTANCE;
+  }
+
+  public final class SurfaceKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> getLocalAbsoluteTonalElevation();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> LocalAbsoluteTonalElevation;
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissDefaults {
+    method public kotlin.jvm.functions.Function2<androidx.compose.ui.unit.Density,java.lang.Float,java.lang.Float> getFixedPositionalThreshold();
+    property public final kotlin.jvm.functions.Function2<androidx.compose.ui.unit.Density,java.lang.Float,java.lang.Float> FixedPositionalThreshold;
+    field public static final androidx.compose.material3.SwipeToDismissDefaults INSTANCE;
+  }
+
+  public final class SwipeToDismissKt {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.DismissState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set<? extends androidx.compose.material3.DismissDirection> directions);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.DismissState rememberDismissState(optional androidx.compose.material3.DismissValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DismissValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function2<? super androidx.compose.ui.unit.Density,? super java.lang.Float,java.lang.Float> positionalThreshold);
+  }
+
+  @androidx.compose.runtime.Immutable public final class SwitchColors {
+  }
+
+  public final class SwitchDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SwitchColors colors(optional long checkedThumbColor, optional long checkedTrackColor, optional long checkedBorderColor, optional long checkedIconColor, optional long uncheckedThumbColor, optional long uncheckedTrackColor, optional long uncheckedBorderColor, optional long uncheckedIconColor, optional long disabledCheckedThumbColor, optional long disabledCheckedTrackColor, optional long disabledCheckedBorderColor, optional long disabledCheckedIconColor, optional long disabledUncheckedThumbColor, optional long disabledUncheckedTrackColor, optional long disabledUncheckedBorderColor, optional long disabledUncheckedIconColor);
+    method public float getIconSize();
+    property public final float IconSize;
+    field public static final androidx.compose.material3.SwitchDefaults INSTANCE;
+  }
+
+  public final class SwitchKt {
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? thumbContent, optional boolean enabled, optional androidx.compose.material3.SwitchColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  public final class TabKt {
+    method @androidx.compose.runtime.Composable public static void LeadingIconTab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TabPosition {
+    method public float getLeft();
+    method public float getRight();
+    method public float getWidth();
+    property public final float left;
+    property public final float right;
+    property public final float width;
+  }
+
+  public final class TabRowDefaults {
+    method @androidx.compose.runtime.Composable public void Indicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public long getContentColor();
+    method public androidx.compose.ui.Modifier tabIndicatorOffset(androidx.compose.ui.Modifier, androidx.compose.material3.TabPosition currentTabPosition);
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final long contentColor;
+    field public static final androidx.compose.material3.TabRowDefaults INSTANCE;
+  }
+
+  public final class TabRowKt {
+    method @androidx.compose.runtime.Composable public static void ScrollableTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float edgePadding, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @androidx.compose.runtime.Composable public static void TabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextFieldColors {
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextFieldDefaults {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void FilledContainerBox(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material3.TextFieldColors colors, optional androidx.compose.ui.graphics.Shape shape);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void OutlinedBorderContainerBox(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material3.TextFieldColors colors, optional androidx.compose.ui.graphics.Shape shape, optional float focusedBorderThickness, optional float unfocusedBorderThickness);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void OutlinedTextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional androidx.compose.material3.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> container);
+    method @Deprecated @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void OutlinedTextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<? extends kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? supportingText, optional androidx.compose.material3.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit> container);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void TextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> container);
+    method @Deprecated @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void TextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<? extends kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? supportingText, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit> container);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFilledShape();
+    method public float getFocusedBorderThickness();
+    method public float getMinHeight();
+    method public float getMinWidth();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method public float getUnfocusedBorderThickness();
+    method @androidx.compose.material3.ExperimentalMaterial3Api public androidx.compose.ui.Modifier indicatorLine(androidx.compose.ui.Modifier, boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material3.TextFieldColors colors, optional float focusedIndicatorLineThickness, optional float unfocusedIndicatorLineThickness);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors outlinedTextFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long containerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedSupportingTextColor, optional long unfocusedSupportingTextColor, optional long disabledSupportingTextColor, optional long errorSupportingTextColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @Deprecated @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors outlinedTextFieldColors(optional long textColor, optional long disabledTextColor, optional long containerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor, optional long focusedSupportingTextColor, optional long unfocusedSupportingTextColor, optional long disabledSupportingTextColor, optional long errorSupportingTextColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method public androidx.compose.foundation.layout.PaddingValues outlinedTextFieldPadding(optional float start, optional float top, optional float end, optional float bottom);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors textFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long containerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedSupportingTextColor, optional long unfocusedSupportingTextColor, optional long disabledSupportingTextColor, optional long errorSupportingTextColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @Deprecated @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors textFieldColors(optional long textColor, optional long disabledTextColor, optional long containerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor, optional long focusedSupportingTextColor, optional long unfocusedSupportingTextColor, optional long disabledSupportingTextColor, optional long errorSupportingTextColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method public androidx.compose.foundation.layout.PaddingValues textFieldWithLabelPadding(optional float start, optional float end, optional float top, optional float bottom);
+    method public androidx.compose.foundation.layout.PaddingValues textFieldWithoutLabelPadding(optional float start, optional float top, optional float end, optional float bottom);
+    property public final float FocusedBorderThickness;
+    property public final float MinHeight;
+    property public final float MinWidth;
+    property public final float UnfocusedBorderThickness;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape filledShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    field public static final androidx.compose.material3.TextFieldDefaults INSTANCE;
+  }
+
+  public final class TextFieldKt {
+    method @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @Deprecated @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,? extends kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @Deprecated @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,? extends kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<? extends kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+  }
+
+  public final class TextKt {
+    method @androidx.compose.runtime.Composable public static void ProvideTextStyle(androidx.compose.ui.text.TextStyle value, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Text(String text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional int minLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @androidx.compose.runtime.Composable public static void Text(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional int minLines, optional java.util.Map<java.lang.String,androidx.compose.foundation.text.InlineTextContent> inlineContent, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @Deprecated @androidx.compose.runtime.Composable public static void Text(String text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,? extends kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @Deprecated @androidx.compose.runtime.Composable public static void Text(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional java.util.Map<java.lang.String,? extends androidx.compose.foundation.text.InlineTextContent> inlineContent, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,? extends kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.TextStyle> getLocalTextStyle();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.TextStyle> LocalTextStyle;
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class TimePickerColors {
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TimePickerDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TimePickerColors colors(optional long clockDialColor, optional long clockDialSelectedContentColor, optional long clockDialUnselectedContentColor, optional long selectorColor, optional long containerColor, optional long periodSelectorBorderColor, optional long periodSelectorSelectedContainerColor, optional long periodSelectorUnselectedContainerColor, optional long periodSelectorSelectedContentColor, optional long periodSelectorUnselectedContentColor, optional long timeSelectorSelectedContainerColor, optional long timeSelectorUnselectedContainerColor, optional long timeSelectorSelectedContentColor, optional long timeSelectorUnselectedContentColor);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public int layoutType();
+    field public static final androidx.compose.material3.TimePickerDefaults INSTANCE;
+  }
+
+  public final class TimePickerKt {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TimeInput(androidx.compose.material3.TimePickerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.TimePickerColors colors);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TimePicker(androidx.compose.material3.TimePickerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.TimePickerColors colors, optional int layoutType);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.TimePickerState rememberTimePickerState(optional int initialHour, optional int initialMinute, optional boolean is24Hour);
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class TimePickerLayoutType {
+    field public static final androidx.compose.material3.TimePickerLayoutType.Companion Companion;
+  }
+
+  public static final class TimePickerLayoutType.Companion {
+    method public int getHorizontal();
+    method public int getVertical();
+    property public final int Horizontal;
+    property public final int Vertical;
+  }
+
+  @androidx.compose.runtime.Stable public final class TimePickerState {
+    ctor public TimePickerState(int initialHour, int initialMinute, boolean is24Hour);
+    method public int getHour();
+    method public int getMinute();
+    method public boolean is24hour();
+    method public suspend Object? settle(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final int hour;
+    property public final boolean is24hour;
+    property public final int minute;
+    field public static final androidx.compose.material3.TimePickerState.Companion Companion;
+  }
+
+  public static final class TimePickerState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TimePickerState,?> Saver();
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api public interface TooltipBoxScope {
+    method public androidx.compose.ui.Modifier tooltipAnchor(androidx.compose.ui.Modifier);
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api public final class TooltipDefaults {
+    method @androidx.compose.runtime.Composable public long getPlainTooltipContainerColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getPlainTooltipContainerShape();
+    method @androidx.compose.runtime.Composable public long getPlainTooltipContentColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getRichTooltipContainerShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.RichTooltipColors richTooltipColors(optional long containerColor, optional long contentColor, optional long titleContentColor, optional long actionContentColor);
+    property @androidx.compose.runtime.Composable public final long plainTooltipContainerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape plainTooltipContainerShape;
+    property @androidx.compose.runtime.Composable public final long plainTooltipContentColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape richTooltipContainerShape;
+    field public static final androidx.compose.material3.TooltipDefaults INSTANCE;
+  }
+
+  public final class TooltipKt {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PlainTooltipBox(kotlin.jvm.functions.Function0<kotlin.Unit> tooltip, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.PlainTooltipState tooltipState, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.material3.TooltipBoxScope,kotlin.Unit> content);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RichTooltipBox(kotlin.jvm.functions.Function0<kotlin.Unit> text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.RichTooltipState tooltipState, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.RichTooltipColors colors, kotlin.jvm.functions.Function1<? super androidx.compose.material3.TooltipBoxScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TopAppBarColors {
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api public final class TopAppBarDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarColors centerAlignedTopAppBarColors(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarScrollBehavior enterAlwaysScrollBehavior(optional androidx.compose.material3.TopAppBarState state, optional kotlin.jvm.functions.Function0<java.lang.Boolean> canScroll, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float>? snapAnimationSpec, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? flingAnimationSpec);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarScrollBehavior exitUntilCollapsedScrollBehavior(optional androidx.compose.material3.TopAppBarState state, optional kotlin.jvm.functions.Function0<java.lang.Boolean> canScroll, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float>? snapAnimationSpec, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? flingAnimationSpec);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarColors largeTopAppBarColors(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarColors mediumTopAppBarColors(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarScrollBehavior pinnedScrollBehavior(optional androidx.compose.material3.TopAppBarState state, optional kotlin.jvm.functions.Function0<java.lang.Boolean> canScroll);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarColors smallTopAppBarColors(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarColors topAppBarColors(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.TopAppBarDefaults INSTANCE;
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface TopAppBarScrollBehavior {
+    method public androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? getFlingAnimationSpec();
+    method public androidx.compose.ui.input.nestedscroll.NestedScrollConnection getNestedScrollConnection();
+    method public androidx.compose.animation.core.AnimationSpec<java.lang.Float>? getSnapAnimationSpec();
+    method public androidx.compose.material3.TopAppBarState getState();
+    method public boolean isPinned();
+    property public abstract androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? flingAnimationSpec;
+    property public abstract boolean isPinned;
+    property public abstract androidx.compose.ui.input.nestedscroll.NestedScrollConnection nestedScrollConnection;
+    property public abstract androidx.compose.animation.core.AnimationSpec<java.lang.Float>? snapAnimationSpec;
+    property public abstract androidx.compose.material3.TopAppBarState state;
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TopAppBarState {
+    ctor public TopAppBarState(float initialHeightOffsetLimit, float initialHeightOffset, float initialContentOffset);
+    method public float getCollapsedFraction();
+    method public float getContentOffset();
+    method public float getHeightOffset();
+    method public float getHeightOffsetLimit();
+    method public float getOverlappedFraction();
+    method public void setContentOffset(float);
+    method public void setHeightOffset(float);
+    method public void setHeightOffsetLimit(float);
+    property public final float collapsedFraction;
+    property public final float contentOffset;
+    property public final float heightOffset;
+    property public final float heightOffsetLimit;
+    property public final float overlappedFraction;
+    field public static final androidx.compose.material3.TopAppBarState.Companion Companion;
+  }
+
+  public static final class TopAppBarState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,?> Saver;
+  }
+
+  @androidx.compose.runtime.Immutable public final class Typography {
+    ctor public Typography(optional androidx.compose.ui.text.TextStyle displayLarge, optional androidx.compose.ui.text.TextStyle displayMedium, optional androidx.compose.ui.text.TextStyle displaySmall, optional androidx.compose.ui.text.TextStyle headlineLarge, optional androidx.compose.ui.text.TextStyle headlineMedium, optional androidx.compose.ui.text.TextStyle headlineSmall, optional androidx.compose.ui.text.TextStyle titleLarge, optional androidx.compose.ui.text.TextStyle titleMedium, optional androidx.compose.ui.text.TextStyle titleSmall, optional androidx.compose.ui.text.TextStyle bodyLarge, optional androidx.compose.ui.text.TextStyle bodyMedium, optional androidx.compose.ui.text.TextStyle bodySmall, optional androidx.compose.ui.text.TextStyle labelLarge, optional androidx.compose.ui.text.TextStyle labelMedium, optional androidx.compose.ui.text.TextStyle labelSmall);
+    method public androidx.compose.material3.Typography copy(optional androidx.compose.ui.text.TextStyle displayLarge, optional androidx.compose.ui.text.TextStyle displayMedium, optional androidx.compose.ui.text.TextStyle displaySmall, optional androidx.compose.ui.text.TextStyle headlineLarge, optional androidx.compose.ui.text.TextStyle headlineMedium, optional androidx.compose.ui.text.TextStyle headlineSmall, optional androidx.compose.ui.text.TextStyle titleLarge, optional androidx.compose.ui.text.TextStyle titleMedium, optional androidx.compose.ui.text.TextStyle titleSmall, optional androidx.compose.ui.text.TextStyle bodyLarge, optional androidx.compose.ui.text.TextStyle bodyMedium, optional androidx.compose.ui.text.TextStyle bodySmall, optional androidx.compose.ui.text.TextStyle labelLarge, optional androidx.compose.ui.text.TextStyle labelMedium, optional androidx.compose.ui.text.TextStyle labelSmall);
+    method public androidx.compose.ui.text.TextStyle getBodyLarge();
+    method public androidx.compose.ui.text.TextStyle getBodyMedium();
+    method public androidx.compose.ui.text.TextStyle getBodySmall();
+    method public androidx.compose.ui.text.TextStyle getDisplayLarge();
+    method public androidx.compose.ui.text.TextStyle getDisplayMedium();
+    method public androidx.compose.ui.text.TextStyle getDisplaySmall();
+    method public androidx.compose.ui.text.TextStyle getHeadlineLarge();
+    method public androidx.compose.ui.text.TextStyle getHeadlineMedium();
+    method public androidx.compose.ui.text.TextStyle getHeadlineSmall();
+    method public androidx.compose.ui.text.TextStyle getLabelLarge();
+    method public androidx.compose.ui.text.TextStyle getLabelMedium();
+    method public androidx.compose.ui.text.TextStyle getLabelSmall();
+    method public androidx.compose.ui.text.TextStyle getTitleLarge();
+    method public androidx.compose.ui.text.TextStyle getTitleMedium();
+    method public androidx.compose.ui.text.TextStyle getTitleSmall();
+    property public final androidx.compose.ui.text.TextStyle bodyLarge;
+    property public final androidx.compose.ui.text.TextStyle bodyMedium;
+    property public final androidx.compose.ui.text.TextStyle bodySmall;
+    property public final androidx.compose.ui.text.TextStyle displayLarge;
+    property public final androidx.compose.ui.text.TextStyle displayMedium;
+    property public final androidx.compose.ui.text.TextStyle displaySmall;
+    property public final androidx.compose.ui.text.TextStyle headlineLarge;
+    property public final androidx.compose.ui.text.TextStyle headlineMedium;
+    property public final androidx.compose.ui.text.TextStyle headlineSmall;
+    property public final androidx.compose.ui.text.TextStyle labelLarge;
+    property public final androidx.compose.ui.text.TextStyle labelMedium;
+    property public final androidx.compose.ui.text.TextStyle labelSmall;
+    property public final androidx.compose.ui.text.TextStyle titleLarge;
+    property public final androidx.compose.ui.text.TextStyle titleMedium;
+    property public final androidx.compose.ui.text.TextStyle titleSmall;
+  }
+
+}
+
diff --git a/compose/material3/material3/api/res-1.1.0-beta02.txt b/compose/material3/material3/api/res-1.1.0-beta02.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/compose/material3/material3/api/res-1.1.0-beta02.txt
diff --git a/compose/material3/material3/api/restricted_1.1.0-beta02.txt b/compose/material3/material3/api/restricted_1.1.0-beta02.txt
new file mode 100644
index 0000000..7e2de6f
--- /dev/null
+++ b/compose/material3/material3/api/restricted_1.1.0-beta02.txt
@@ -0,0 +1,856 @@
+// Signature format: 4.0
+package androidx.compose.material3 {
+
+  public final class AlertDialogDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public long getIconContentColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public long getTextContentColor();
+    method @androidx.compose.runtime.Composable public long getTitleContentColor();
+    method public float getTonalElevation();
+    property public final float TonalElevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final long iconContentColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final long textContentColor;
+    property @androidx.compose.runtime.Composable public final long titleContentColor;
+    field public static final androidx.compose.material3.AlertDialogDefaults INSTANCE;
+  }
+
+  public final class AndroidAlertDialog_androidKt {
+    method @androidx.compose.runtime.Composable public static void AlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, kotlin.jvm.functions.Function0<kotlin.Unit> confirmButton, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dismissButton, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long iconContentColor, optional long titleContentColor, optional long textContentColor, optional float tonalElevation, optional androidx.compose.ui.window.DialogProperties properties);
+  }
+
+  public final class AndroidMenu_androidKt {
+    method @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean enabled, optional androidx.compose.material3.MenuItemColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  public final class AppBarKt {
+    method @androidx.compose.runtime.Composable public static void BottomAppBar(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? floatingActionButton, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.WindowInsets windowInsets);
+    method @androidx.compose.runtime.Composable public static void BottomAppBar(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+  }
+
+  public final class AssistChipDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipBorder assistChipBorder(optional long borderColor, optional long disabledBorderColor, optional float borderWidth);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors assistChipColors(optional long containerColor, optional long labelColor, optional long leadingIconContentColor, optional long trailingIconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconContentColor, optional long disabledTrailingIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation assistChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors elevatedAssistChipColors(optional long containerColor, optional long labelColor, optional long leadingIconContentColor, optional long trailingIconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconContentColor, optional long disabledTrailingIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation elevatedAssistChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method public float getHeight();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    property public final float Height;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.AssistChipDefaults INSTANCE;
+  }
+
+  public final class BottomAppBarDefaults {
+    method @androidx.compose.runtime.Composable public long getBottomAppBarFabColor();
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getContainerElevation();
+    method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property public final float ContainerElevation;
+    property public final androidx.compose.foundation.layout.PaddingValues ContentPadding;
+    property @androidx.compose.runtime.Composable public final long bottomAppBarFabColor;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.BottomAppBarDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class ButtonColors {
+  }
+
+  public final class ButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors buttonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonElevation buttonElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors elevatedButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonElevation elevatedButtonElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors filledTonalButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonElevation filledTonalButtonElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float disabledElevation);
+    method public androidx.compose.foundation.layout.PaddingValues getButtonWithIconContentPadding();
+    method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getElevatedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFilledTonalShape();
+    method public float getIconSize();
+    method public float getIconSpacing();
+    method public float getMinHeight();
+    method public float getMinWidth();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke getOutlinedButtonBorder();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method public androidx.compose.foundation.layout.PaddingValues getTextButtonContentPadding();
+    method public androidx.compose.foundation.layout.PaddingValues getTextButtonWithIconContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getTextShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors outlinedButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors textButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    property public final androidx.compose.foundation.layout.PaddingValues ButtonWithIconContentPadding;
+    property public final androidx.compose.foundation.layout.PaddingValues ContentPadding;
+    property public final float IconSize;
+    property public final float IconSpacing;
+    property public final float MinHeight;
+    property public final float MinWidth;
+    property public final androidx.compose.foundation.layout.PaddingValues TextButtonContentPadding;
+    property public final androidx.compose.foundation.layout.PaddingValues TextButtonWithIconContentPadding;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape elevatedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape filledTonalShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.BorderStroke outlinedButtonBorder;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape textShape;
+    field public static final androidx.compose.material3.ButtonDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class ButtonElevation {
+  }
+
+  public final class ButtonKt {
+    method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ElevatedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class CardColors {
+  }
+
+  public final class CardDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardColors cardColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardElevation cardElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardColors elevatedCardColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardElevation elevatedCardElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getElevatedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke outlinedCardBorder(optional boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardColors outlinedCardColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardElevation outlinedCardElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape elevatedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.CardDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class CardElevation {
+  }
+
+  public final class CardKt {
+    method @androidx.compose.runtime.Composable public static void Card(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ElevatedCard(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedCard(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class CheckboxColors {
+  }
+
+  public final class CheckboxDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.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.compose.material3.CheckboxDefaults INSTANCE;
+  }
+
+  public final class CheckboxKt {
+    method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Immutable public final class ChipBorder {
+  }
+
+  @androidx.compose.runtime.Immutable public final class ChipColors {
+  }
+
+  @androidx.compose.runtime.Immutable public final class ChipElevation {
+  }
+
+  public final class ChipKt {
+    method @androidx.compose.runtime.Composable public static void AssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedAssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedSuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void SuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Stable public final class ColorScheme {
+    ctor public ColorScheme(long primary, long onPrimary, long primaryContainer, long onPrimaryContainer, long inversePrimary, long secondary, long onSecondary, long secondaryContainer, long onSecondaryContainer, long tertiary, long onTertiary, long tertiaryContainer, long onTertiaryContainer, long background, long onBackground, long surface, long onSurface, long surfaceVariant, long onSurfaceVariant, long surfaceTint, long inverseSurface, long inverseOnSurface, long error, long onError, long errorContainer, long onErrorContainer, long outline, long outlineVariant, long scrim);
+    method public androidx.compose.material3.ColorScheme copy(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim);
+    method public long getBackground();
+    method public long getError();
+    method public long getErrorContainer();
+    method public long getInverseOnSurface();
+    method public long getInversePrimary();
+    method public long getInverseSurface();
+    method public long getOnBackground();
+    method public long getOnError();
+    method public long getOnErrorContainer();
+    method public long getOnPrimary();
+    method public long getOnPrimaryContainer();
+    method public long getOnSecondary();
+    method public long getOnSecondaryContainer();
+    method public long getOnSurface();
+    method public long getOnSurfaceVariant();
+    method public long getOnTertiary();
+    method public long getOnTertiaryContainer();
+    method public long getOutline();
+    method public long getOutlineVariant();
+    method public long getPrimary();
+    method public long getPrimaryContainer();
+    method public long getScrim();
+    method public long getSecondary();
+    method public long getSecondaryContainer();
+    method public long getSurface();
+    method public long getSurfaceTint();
+    method public long getSurfaceVariant();
+    method public long getTertiary();
+    method public long getTertiaryContainer();
+    property public final long background;
+    property public final long error;
+    property public final long errorContainer;
+    property public final long inverseOnSurface;
+    property public final long inversePrimary;
+    property public final long inverseSurface;
+    property public final long onBackground;
+    property public final long onError;
+    property public final long onErrorContainer;
+    property public final long onPrimary;
+    property public final long onPrimaryContainer;
+    property public final long onSecondary;
+    property public final long onSecondaryContainer;
+    property public final long onSurface;
+    property public final long onSurfaceVariant;
+    property public final long onTertiary;
+    property public final long onTertiaryContainer;
+    property public final long outline;
+    property public final long outlineVariant;
+    property public final long primary;
+    property public final long primaryContainer;
+    property public final long scrim;
+    property public final long secondary;
+    property public final long secondaryContainer;
+    property public final long surface;
+    property public final long surfaceTint;
+    property public final long surfaceVariant;
+    property public final long tertiary;
+    property public final long tertiaryContainer;
+  }
+
+  public final class ColorSchemeKt {
+    method public static long contentColorFor(androidx.compose.material3.ColorScheme, long backgroundColor);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static long contentColorFor(long backgroundColor);
+    method public static androidx.compose.material3.ColorScheme darkColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim);
+    method public static androidx.compose.material3.ColorScheme lightColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim);
+    method public static long surfaceColorAtElevation(androidx.compose.material3.ColorScheme, float elevation);
+  }
+
+  public final class ContentColorKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.graphics.Color> getLocalContentColor();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.graphics.Color> LocalContentColor;
+  }
+
+  public final class DividerDefaults {
+    method @androidx.compose.runtime.Composable public long getColor();
+    method public float getThickness();
+    property public final float Thickness;
+    property @androidx.compose.runtime.Composable public final long color;
+    field public static final androidx.compose.material3.DividerDefaults INSTANCE;
+  }
+
+  public final class DividerKt {
+    method @androidx.compose.runtime.Composable public static void Divider(optional androidx.compose.ui.Modifier modifier, optional float thickness, optional long color);
+  }
+
+  public final class DrawerDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getDismissibleDrawerElevation();
+    method public float getMaximumDrawerWidth();
+    method public float getModalDrawerElevation();
+    method public float getPermanentDrawerElevation();
+    method @androidx.compose.runtime.Composable public long getScrimColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property public final float DismissibleDrawerElevation;
+    property public final float MaximumDrawerWidth;
+    property public final float ModalDrawerElevation;
+    property public final float PermanentDrawerElevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final long scrimColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.DrawerDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class DrawerState {
+    ctor public DrawerState(androidx.compose.material3.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
+    method public suspend Object? animateTo(androidx.compose.material3.DrawerValue targetValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.material3.DrawerValue getCurrentValue();
+    method public androidx.compose.runtime.State<java.lang.Float> getOffset();
+    method public androidx.compose.material3.DrawerValue getTargetValue();
+    method public boolean isAnimationRunning();
+    method public boolean isClosed();
+    method public boolean isOpen();
+    method public suspend Object? open(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? snapTo(androidx.compose.material3.DrawerValue targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final androidx.compose.material3.DrawerValue currentValue;
+    property public final boolean isAnimationRunning;
+    property public final boolean isClosed;
+    property public final boolean isOpen;
+    property public final androidx.compose.runtime.State<java.lang.Float> offset;
+    property public final androidx.compose.material3.DrawerValue targetValue;
+    field public static final androidx.compose.material3.DrawerState.Companion Companion;
+  }
+
+  public static final class DrawerState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.DrawerState,androidx.compose.material3.DrawerValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
+  }
+
+  public enum DrawerValue {
+    method public static androidx.compose.material3.DrawerValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.DrawerValue[] values();
+    enum_constant public static final androidx.compose.material3.DrawerValue Closed;
+    enum_constant public static final androidx.compose.material3.DrawerValue Open;
+  }
+
+  public final class DynamicTonalPaletteKt {
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public static androidx.compose.material3.ColorScheme dynamicDarkColorScheme(android.content.Context context);
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public static androidx.compose.material3.ColorScheme dynamicLightColorScheme(android.content.Context context);
+  }
+
+  @kotlin.jvm.JvmInline public final value class FabPosition {
+    field public static final androidx.compose.material3.FabPosition.Companion Companion;
+  }
+
+  public static final class FabPosition.Companion {
+    method public int getCenter();
+    method public int getEnd();
+    property public final int Center;
+    property public final int End;
+  }
+
+  public final class FloatingActionButtonDefaults {
+    method public androidx.compose.material3.FloatingActionButtonElevation bottomAppBarFabElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.FloatingActionButtonElevation elevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getExtendedFabShape();
+    method public float getLargeIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getLargeShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getSmallShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.FloatingActionButtonElevation loweredElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
+    property public final float LargeIconSize;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape extendedFabShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape largeShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape smallShape;
+    field public static final androidx.compose.material3.FloatingActionButtonDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public class FloatingActionButtonElevation {
+  }
+
+  public final class FloatingActionButtonKt {
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean expanded, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void LargeFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void SmallFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class IconButtonColors {
+  }
+
+  public final class IconButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors filledIconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors filledIconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors filledTonalIconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors filledTonalIconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFilledShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors iconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors iconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke outlinedIconButtonBorder(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors outlinedIconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke? outlinedIconToggleButtonBorder(boolean enabled, boolean checked);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors outlinedIconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape filledShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    field public static final androidx.compose.material3.IconButtonDefaults INSTANCE;
+  }
+
+  public final class IconButtonKt {
+    method @androidx.compose.runtime.Composable public static void FilledIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class IconKt {
+    method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.vector.ImageVector imageVector, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+    method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.ImageBitmap bitmap, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+    method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.painter.Painter painter, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+  }
+
+  @androidx.compose.runtime.Immutable public final class IconToggleButtonColors {
+  }
+
+  public final class InteractiveComponentSizeKt {
+    method public static androidx.compose.ui.Modifier minimumInteractiveComponentSize(androidx.compose.ui.Modifier);
+  }
+
+  @androidx.compose.runtime.Immutable public final class ListItemColors {
+  }
+
+  public final class ListItemDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ListItemColors colors(optional long containerColor, optional long headlineColor, optional long leadingIconColor, optional long overlineColor, optional long supportingColor, optional long trailingIconColor, optional long disabledHeadlineColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public long getContainerColor();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public long getContentColor();
+    method public float getElevation();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.ui.graphics.Shape getShape();
+    property public final float Elevation;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final long containerColor;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final long contentColor;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.ListItemDefaults INSTANCE;
+  }
+
+  public final class ListItemKt {
+    method @androidx.compose.runtime.Composable public static void ListItem(kotlin.jvm.functions.Function0<kotlin.Unit> headlineContent, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? overlineContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingContent, optional androidx.compose.material3.ListItemColors colors, optional float tonalElevation, optional float shadowElevation);
+  }
+
+  public final class MaterialTheme {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.ColorScheme getColorScheme();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.Shapes getShapes();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.Typography getTypography();
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.ColorScheme colorScheme;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.Shapes shapes;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.Typography typography;
+    field public static final androidx.compose.material3.MaterialTheme INSTANCE;
+  }
+
+  public final class MaterialThemeKt {
+    method @androidx.compose.runtime.Composable public static void MaterialTheme(optional androidx.compose.material3.ColorScheme colorScheme, optional androidx.compose.material3.Shapes shapes, optional androidx.compose.material3.Typography typography, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class MenuDefaults {
+    method public androidx.compose.foundation.layout.PaddingValues getDropdownMenuItemContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.MenuItemColors itemColors(optional long textColor, optional long leadingIconColor, optional long trailingIconColor, optional long disabledTextColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor);
+    property public final androidx.compose.foundation.layout.PaddingValues DropdownMenuItemContentPadding;
+    field public static final androidx.compose.material3.MenuDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class MenuItemColors {
+  }
+
+  public final class NavigationBarDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getElevation();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property public final float Elevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.NavigationBarDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class NavigationBarItemColors {
+  }
+
+  public final class NavigationBarItemDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationBarItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor, optional long disabledIconColor, optional long disabledTextColor);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationBarItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor);
+    field public static final androidx.compose.material3.NavigationBarItemDefaults INSTANCE;
+  }
+
+  public final class NavigationBarKt {
+    method @androidx.compose.runtime.Composable public static void NavigationBar(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void NavigationBarItem(androidx.compose.foundation.layout.RowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationBarItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Stable public interface NavigationDrawerItemColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> badgeColor(boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> iconColor(boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean selected);
+  }
+
+  public final class NavigationDrawerItemDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationDrawerItemColors colors(optional long selectedContainerColor, optional long unselectedContainerColor, optional long selectedIconColor, optional long unselectedIconColor, optional long selectedTextColor, optional long unselectedTextColor, optional long selectedBadgeColor, optional long unselectedBadgeColor);
+    method public androidx.compose.foundation.layout.PaddingValues getItemPadding();
+    property public final androidx.compose.foundation.layout.PaddingValues ItemPadding;
+    field public static final androidx.compose.material3.NavigationDrawerItemDefaults INSTANCE;
+  }
+
+  public final class NavigationDrawerKt {
+    method @androidx.compose.runtime.Composable public static void DismissibleDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void DismissibleNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DrawerState drawerState, optional boolean gesturesEnabled, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ModalDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ModalNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DrawerState drawerState, optional boolean gesturesEnabled, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void NavigationDrawerItem(kotlin.jvm.functions.Function0<kotlin.Unit> label, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? badge, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.NavigationDrawerItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void PermanentDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void PermanentNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static androidx.compose.material3.DrawerState rememberDrawerState(androidx.compose.material3.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
+  }
+
+  public final class NavigationRailDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property @androidx.compose.runtime.Composable public final long ContainerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.NavigationRailDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class NavigationRailItemColors {
+  }
+
+  public final class NavigationRailItemDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationRailItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor, optional long disabledIconColor, optional long disabledTextColor);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationRailItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor);
+    field public static final androidx.compose.material3.NavigationRailItemDefaults INSTANCE;
+  }
+
+  public final class NavigationRailKt {
+    method @androidx.compose.runtime.Composable public static void NavigationRail(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? header, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void NavigationRailItem(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationRailItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  public final class OutlinedTextFieldKt {
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+  }
+
+  public final class ProgressIndicatorDefaults {
+    method @androidx.compose.runtime.Composable public long getCircularColor();
+    method public int getCircularDeterminateStrokeCap();
+    method public int getCircularIndeterminateStrokeCap();
+    method public float getCircularStrokeWidth();
+    method @androidx.compose.runtime.Composable public long getCircularTrackColor();
+    method @androidx.compose.runtime.Composable public long getLinearColor();
+    method public int getLinearStrokeCap();
+    method @androidx.compose.runtime.Composable public long getLinearTrackColor();
+    method public androidx.compose.animation.core.SpringSpec<java.lang.Float> getProgressAnimationSpec();
+    property public final int CircularDeterminateStrokeCap;
+    property public final int CircularIndeterminateStrokeCap;
+    property public final float CircularStrokeWidth;
+    property public final int LinearStrokeCap;
+    property public final androidx.compose.animation.core.SpringSpec<java.lang.Float> ProgressAnimationSpec;
+    property @androidx.compose.runtime.Composable public final long circularColor;
+    property @androidx.compose.runtime.Composable public final long circularTrackColor;
+    property @androidx.compose.runtime.Composable public final long linearColor;
+    property @androidx.compose.runtime.Composable public final long linearTrackColor;
+    field public static final androidx.compose.material3.ProgressIndicatorDefaults INSTANCE;
+  }
+
+  public final class ProgressIndicatorKt {
+    method @androidx.compose.runtime.Composable public static void CircularProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth, optional long trackColor, optional int strokeCap);
+    method @androidx.compose.runtime.Composable public static void CircularProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth, optional long trackColor, optional int strokeCap);
+    method @Deprecated @androidx.compose.runtime.Composable public static void CircularProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth);
+    method @Deprecated @androidx.compose.runtime.Composable public static void CircularProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth);
+    method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor, optional int strokeCap);
+    method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor, optional int strokeCap);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LinearProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor);
+  }
+
+  @androidx.compose.runtime.Immutable public final class RadioButtonColors {
+  }
+
+  public final class RadioButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.RadioButtonColors colors(optional long selectedColor, optional long unselectedColor, optional long disabledSelectedColor, optional long disabledUnselectedColor);
+    field public static final androidx.compose.material3.RadioButtonDefaults INSTANCE;
+  }
+
+  public final class RadioButtonKt {
+    method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.RadioButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  public final class ScaffoldDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getContentWindowInsets();
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets contentWindowInsets;
+    field public static final androidx.compose.material3.ScaffoldDefaults INSTANCE;
+  }
+
+  public final class ScaffoldKt {
+    method @androidx.compose.runtime.Composable public static void Scaffold(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional int floatingActionButtonPosition, optional long containerColor, optional long contentColor, optional androidx.compose.foundation.layout.WindowInsets contentWindowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+  }
+
+  public final class ShapeDefaults {
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraSmall();
+    method public androidx.compose.foundation.shape.CornerBasedShape getLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getMedium();
+    method public androidx.compose.foundation.shape.CornerBasedShape getSmall();
+    property public final androidx.compose.foundation.shape.CornerBasedShape ExtraLarge;
+    property public final androidx.compose.foundation.shape.CornerBasedShape ExtraSmall;
+    property public final androidx.compose.foundation.shape.CornerBasedShape Large;
+    property public final androidx.compose.foundation.shape.CornerBasedShape Medium;
+    property public final androidx.compose.foundation.shape.CornerBasedShape Small;
+    field public static final androidx.compose.material3.ShapeDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class Shapes {
+    ctor public Shapes(optional androidx.compose.foundation.shape.CornerBasedShape extraSmall, optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large, optional androidx.compose.foundation.shape.CornerBasedShape extraLarge);
+    method public androidx.compose.material3.Shapes copy(optional androidx.compose.foundation.shape.CornerBasedShape extraSmall, optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large, optional androidx.compose.foundation.shape.CornerBasedShape extraLarge);
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraSmall();
+    method public androidx.compose.foundation.shape.CornerBasedShape getLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getMedium();
+    method public androidx.compose.foundation.shape.CornerBasedShape getSmall();
+    property public final androidx.compose.foundation.shape.CornerBasedShape extraLarge;
+    property public final androidx.compose.foundation.shape.CornerBasedShape extraSmall;
+    property public final androidx.compose.foundation.shape.CornerBasedShape large;
+    property public final androidx.compose.foundation.shape.CornerBasedShape medium;
+    property public final androidx.compose.foundation.shape.CornerBasedShape small;
+  }
+
+  @androidx.compose.runtime.Immutable public final class SliderColors {
+  }
+
+  @androidx.compose.runtime.Stable public final class SliderDefaults {
+    method @androidx.compose.runtime.Composable public void Thumb(androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled, optional long thumbSize);
+    method @androidx.compose.runtime.Composable public void Track(androidx.compose.material3.SliderPositions sliderPositions, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SliderColors colors(optional long thumbColor, optional long activeTrackColor, optional long activeTickColor, optional long inactiveTrackColor, optional long inactiveTickColor, optional long disabledThumbColor, optional long disabledActiveTrackColor, optional long disabledActiveTickColor, optional long disabledInactiveTrackColor, optional long disabledInactiveTickColor);
+    field public static final androidx.compose.material3.SliderDefaults INSTANCE;
+  }
+
+  public final class SliderKt {
+    method @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors);
+    method @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Stable public final class SliderPositions {
+    ctor public SliderPositions(optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> initialActiveRange, optional float[] initialTickFractions);
+    method public kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> getActiveRange();
+    method public float[] getTickFractions();
+    property public final kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> activeRange;
+    property public final float[] tickFractions;
+  }
+
+  @androidx.compose.runtime.Stable public interface SnackbarData {
+    method public void dismiss();
+    method public androidx.compose.material3.SnackbarVisuals getVisuals();
+    method public void performAction();
+    property public abstract androidx.compose.material3.SnackbarVisuals visuals;
+  }
+
+  public final class SnackbarDefaults {
+    method @androidx.compose.runtime.Composable public long getActionColor();
+    method @androidx.compose.runtime.Composable public long getActionContentColor();
+    method @androidx.compose.runtime.Composable public long getColor();
+    method @androidx.compose.runtime.Composable public long getContentColor();
+    method @androidx.compose.runtime.Composable public long getDismissActionContentColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    property @androidx.compose.runtime.Composable public final long actionColor;
+    property @androidx.compose.runtime.Composable public final long actionContentColor;
+    property @androidx.compose.runtime.Composable public final long color;
+    property @androidx.compose.runtime.Composable public final long contentColor;
+    property @androidx.compose.runtime.Composable public final long dismissActionContentColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.SnackbarDefaults INSTANCE;
+  }
+
+  public enum SnackbarDuration {
+    method public static androidx.compose.material3.SnackbarDuration valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SnackbarDuration[] values();
+    enum_constant public static final androidx.compose.material3.SnackbarDuration Indefinite;
+    enum_constant public static final androidx.compose.material3.SnackbarDuration Long;
+    enum_constant public static final androidx.compose.material3.SnackbarDuration Short;
+  }
+
+  public final class SnackbarHostKt {
+    method @androidx.compose.runtime.Composable public static void SnackbarHost(androidx.compose.material3.SnackbarHostState hostState, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SnackbarData,kotlin.Unit> snackbar);
+  }
+
+  @androidx.compose.runtime.Stable public final class SnackbarHostState {
+    ctor public SnackbarHostState();
+    method public androidx.compose.material3.SnackbarData? getCurrentSnackbarData();
+    method public suspend Object? showSnackbar(String message, optional String? actionLabel, optional boolean withDismissAction, optional androidx.compose.material3.SnackbarDuration duration, optional kotlin.coroutines.Continuation<? super androidx.compose.material3.SnackbarResult>);
+    method public suspend Object? showSnackbar(androidx.compose.material3.SnackbarVisuals visuals, kotlin.coroutines.Continuation<? super androidx.compose.material3.SnackbarResult>);
+    property public final androidx.compose.material3.SnackbarData? currentSnackbarData;
+  }
+
+  public final class SnackbarKt {
+    method @androidx.compose.runtime.Composable public static void Snackbar(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dismissAction, optional boolean actionOnNewLine, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional long actionContentColor, optional long dismissActionContentColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Snackbar(androidx.compose.material3.SnackbarData snackbarData, optional androidx.compose.ui.Modifier modifier, optional boolean actionOnNewLine, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional long actionColor, optional long actionContentColor, optional long dismissActionContentColor);
+  }
+
+  public enum SnackbarResult {
+    method public static androidx.compose.material3.SnackbarResult valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SnackbarResult[] values();
+    enum_constant public static final androidx.compose.material3.SnackbarResult ActionPerformed;
+    enum_constant public static final androidx.compose.material3.SnackbarResult Dismissed;
+  }
+
+  @androidx.compose.runtime.Stable public interface SnackbarVisuals {
+    method public String? getActionLabel();
+    method public androidx.compose.material3.SnackbarDuration getDuration();
+    method public String getMessage();
+    method public boolean getWithDismissAction();
+    property public abstract String? actionLabel;
+    property public abstract androidx.compose.material3.SnackbarDuration duration;
+    property public abstract String message;
+    property public abstract boolean withDismissAction;
+  }
+
+  public final class SuggestionChipDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors elevatedSuggestionChipColors(optional long containerColor, optional long labelColor, optional long iconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation elevatedSuggestionChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method public float getHeight();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipBorder suggestionChipBorder(optional long borderColor, optional long disabledBorderColor, optional float borderWidth);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors suggestionChipColors(optional long containerColor, optional long labelColor, optional long iconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation suggestionChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    property public final float Height;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.SuggestionChipDefaults INSTANCE;
+  }
+
+  public final class SurfaceKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> getLocalAbsoluteTonalElevation();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> LocalAbsoluteTonalElevation;
+  }
+
+  @androidx.compose.runtime.Immutable public final class SwitchColors {
+  }
+
+  public final class SwitchDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SwitchColors colors(optional long checkedThumbColor, optional long checkedTrackColor, optional long checkedBorderColor, optional long checkedIconColor, optional long uncheckedThumbColor, optional long uncheckedTrackColor, optional long uncheckedBorderColor, optional long uncheckedIconColor, optional long disabledCheckedThumbColor, optional long disabledCheckedTrackColor, optional long disabledCheckedBorderColor, optional long disabledCheckedIconColor, optional long disabledUncheckedThumbColor, optional long disabledUncheckedTrackColor, optional long disabledUncheckedBorderColor, optional long disabledUncheckedIconColor);
+    method public float getIconSize();
+    property public final float IconSize;
+    field public static final androidx.compose.material3.SwitchDefaults INSTANCE;
+  }
+
+  public final class SwitchKt {
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? thumbContent, optional boolean enabled, optional androidx.compose.material3.SwitchColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  public final class TabKt {
+    method @androidx.compose.runtime.Composable public static void LeadingIconTab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TabPosition {
+    method public float getLeft();
+    method public float getRight();
+    method public float getWidth();
+    property public final float left;
+    property public final float right;
+    property public final float width;
+  }
+
+  public final class TabRowDefaults {
+    method @androidx.compose.runtime.Composable public void Indicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public long getContentColor();
+    method public androidx.compose.ui.Modifier tabIndicatorOffset(androidx.compose.ui.Modifier, androidx.compose.material3.TabPosition currentTabPosition);
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final long contentColor;
+    field public static final androidx.compose.material3.TabRowDefaults INSTANCE;
+  }
+
+  public final class TabRowKt {
+    method @androidx.compose.runtime.Composable public static void ScrollableTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float edgePadding, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @androidx.compose.runtime.Composable public static void TabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextFieldColors {
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextFieldDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFilledShape();
+    method public float getFocusedBorderThickness();
+    method public float getMinHeight();
+    method public float getMinWidth();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method public float getUnfocusedBorderThickness();
+    method public androidx.compose.foundation.layout.PaddingValues outlinedTextFieldPadding(optional float start, optional float top, optional float end, optional float bottom);
+    method public androidx.compose.foundation.layout.PaddingValues textFieldWithLabelPadding(optional float start, optional float end, optional float top, optional float bottom);
+    method public androidx.compose.foundation.layout.PaddingValues textFieldWithoutLabelPadding(optional float start, optional float top, optional float end, optional float bottom);
+    property public final float FocusedBorderThickness;
+    property public final float MinHeight;
+    property public final float MinWidth;
+    property public final float UnfocusedBorderThickness;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape filledShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    field public static final androidx.compose.material3.TextFieldDefaults INSTANCE;
+  }
+
+  public final class TextFieldKt {
+    method @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+  }
+
+  public final class TextKt {
+    method @androidx.compose.runtime.Composable public static void ProvideTextStyle(androidx.compose.ui.text.TextStyle value, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Text(String text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional int minLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @androidx.compose.runtime.Composable public static void Text(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional int minLines, optional java.util.Map<java.lang.String,androidx.compose.foundation.text.InlineTextContent> inlineContent, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @Deprecated @androidx.compose.runtime.Composable public static void Text(String text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,? extends kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @Deprecated @androidx.compose.runtime.Composable public static void Text(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional java.util.Map<java.lang.String,? extends androidx.compose.foundation.text.InlineTextContent> inlineContent, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,? extends kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.TextStyle> getLocalTextStyle();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.TextStyle> LocalTextStyle;
+  }
+
+  @androidx.compose.runtime.Stable public final class TimePickerState {
+    ctor public TimePickerState(int initialHour, int initialMinute, boolean is24Hour);
+    method public int getHour();
+    method public int getMinute();
+    method public boolean is24hour();
+    method public suspend Object? settle(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final int hour;
+    property public final boolean is24hour;
+    property public final int minute;
+    field public static final androidx.compose.material3.TimePickerState.Companion Companion;
+  }
+
+  public static final class TimePickerState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TimePickerState,?> Saver();
+  }
+
+  @androidx.compose.runtime.Immutable public final class Typography {
+    ctor public Typography(optional androidx.compose.ui.text.TextStyle displayLarge, optional androidx.compose.ui.text.TextStyle displayMedium, optional androidx.compose.ui.text.TextStyle displaySmall, optional androidx.compose.ui.text.TextStyle headlineLarge, optional androidx.compose.ui.text.TextStyle headlineMedium, optional androidx.compose.ui.text.TextStyle headlineSmall, optional androidx.compose.ui.text.TextStyle titleLarge, optional androidx.compose.ui.text.TextStyle titleMedium, optional androidx.compose.ui.text.TextStyle titleSmall, optional androidx.compose.ui.text.TextStyle bodyLarge, optional androidx.compose.ui.text.TextStyle bodyMedium, optional androidx.compose.ui.text.TextStyle bodySmall, optional androidx.compose.ui.text.TextStyle labelLarge, optional androidx.compose.ui.text.TextStyle labelMedium, optional androidx.compose.ui.text.TextStyle labelSmall);
+    method public androidx.compose.material3.Typography copy(optional androidx.compose.ui.text.TextStyle displayLarge, optional androidx.compose.ui.text.TextStyle displayMedium, optional androidx.compose.ui.text.TextStyle displaySmall, optional androidx.compose.ui.text.TextStyle headlineLarge, optional androidx.compose.ui.text.TextStyle headlineMedium, optional androidx.compose.ui.text.TextStyle headlineSmall, optional androidx.compose.ui.text.TextStyle titleLarge, optional androidx.compose.ui.text.TextStyle titleMedium, optional androidx.compose.ui.text.TextStyle titleSmall, optional androidx.compose.ui.text.TextStyle bodyLarge, optional androidx.compose.ui.text.TextStyle bodyMedium, optional androidx.compose.ui.text.TextStyle bodySmall, optional androidx.compose.ui.text.TextStyle labelLarge, optional androidx.compose.ui.text.TextStyle labelMedium, optional androidx.compose.ui.text.TextStyle labelSmall);
+    method public androidx.compose.ui.text.TextStyle getBodyLarge();
+    method public androidx.compose.ui.text.TextStyle getBodyMedium();
+    method public androidx.compose.ui.text.TextStyle getBodySmall();
+    method public androidx.compose.ui.text.TextStyle getDisplayLarge();
+    method public androidx.compose.ui.text.TextStyle getDisplayMedium();
+    method public androidx.compose.ui.text.TextStyle getDisplaySmall();
+    method public androidx.compose.ui.text.TextStyle getHeadlineLarge();
+    method public androidx.compose.ui.text.TextStyle getHeadlineMedium();
+    method public androidx.compose.ui.text.TextStyle getHeadlineSmall();
+    method public androidx.compose.ui.text.TextStyle getLabelLarge();
+    method public androidx.compose.ui.text.TextStyle getLabelMedium();
+    method public androidx.compose.ui.text.TextStyle getLabelSmall();
+    method public androidx.compose.ui.text.TextStyle getTitleLarge();
+    method public androidx.compose.ui.text.TextStyle getTitleMedium();
+    method public androidx.compose.ui.text.TextStyle getTitleSmall();
+    property public final androidx.compose.ui.text.TextStyle bodyLarge;
+    property public final androidx.compose.ui.text.TextStyle bodyMedium;
+    property public final androidx.compose.ui.text.TextStyle bodySmall;
+    property public final androidx.compose.ui.text.TextStyle displayLarge;
+    property public final androidx.compose.ui.text.TextStyle displayMedium;
+    property public final androidx.compose.ui.text.TextStyle displaySmall;
+    property public final androidx.compose.ui.text.TextStyle headlineLarge;
+    property public final androidx.compose.ui.text.TextStyle headlineMedium;
+    property public final androidx.compose.ui.text.TextStyle headlineSmall;
+    property public final androidx.compose.ui.text.TextStyle labelLarge;
+    property public final androidx.compose.ui.text.TextStyle labelMedium;
+    property public final androidx.compose.ui.text.TextStyle labelSmall;
+    property public final androidx.compose.ui.text.TextStyle titleLarge;
+    property public final androidx.compose.ui.text.TextStyle titleMedium;
+    property public final androidx.compose.ui.text.TextStyle titleSmall;
+  }
+
+}
+
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/OutlinedTextFieldTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/OutlinedTextFieldTest.kt
index fa4a4be..095eb82 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/OutlinedTextFieldTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/OutlinedTextFieldTest.kt
@@ -82,11 +82,11 @@
 import androidx.test.filters.MediumTest
 import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.atLeastOnce
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
 import kotlin.math.roundToInt
 import org.junit.Rule
 import org.junit.Test
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SnackbarHostTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SnackbarHostTest.kt
index 14e22c4..a5d5e9f 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SnackbarHostTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SnackbarHostTest.kt
@@ -36,10 +36,10 @@
 import androidx.test.filters.MediumTest
 import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.doReturn
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.SupervisorJob
 import kotlinx.coroutines.delay
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldTest.kt
index 4b994e6..3942e4a 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldTest.kt
@@ -98,11 +98,11 @@
 import androidx.test.filters.MediumTest
 import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.atLeastOnce
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
 import kotlin.math.roundToInt
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
diff --git a/compose/runtime/runtime-saveable-lint/lint-baseline.xml b/compose/runtime/runtime-saveable-lint/lint-baseline.xml
new file mode 100644
index 0000000..fe5f34e
--- /dev/null
+++ b/compose/runtime/runtime-saveable-lint/lint-baseline.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
+
+    <issue
+        id="LintError"
+        message="Unexpected failure during lint analysis (this is a bug in lint or one of the libraries it depends on)&#xA;&#xA;Message: GC overhead limit exceeded&#xA;Stack: `OutOfMemoryError:`&#xA;&#xA;You can run with --stacktrace or set environment variable `LINT_PRINT_STACKTRACE=true` to dump a full stacktrace to stdout.">
+        <location
+            file="runtime-saveable-lint"/>
+    </issue>
+
+</issues>
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/ComposeVersion.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/ComposeVersion.kt
index 5e658a4..8040bef 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/ComposeVersion.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/ComposeVersion.kt
@@ -28,5 +28,5 @@
      * IMPORTANT: Whenever updating this value, please make sure to also update `versionTable` and
      * `minimumRuntimeVersionInt` in `VersionChecker.kt` of the compiler.
      */
-    const val version: Int = 9701
+    const val version: Int = 9801
 }
diff --git a/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/SynchronizationMethodsTest.kt b/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/SynchronizationMethodsTest.kt
index 59670df..cfce9a0 100644
--- a/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/SynchronizationMethodsTest.kt
+++ b/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/SynchronizationMethodsTest.kt
@@ -25,9 +25,9 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.doReturn
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.whenever
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
diff --git a/compose/ui/ui-text/lint-baseline.xml b/compose/ui/ui-text/lint-baseline.xml
index 2168b87..7cf329d 100644
--- a/compose/ui/ui-text/lint-baseline.xml
+++ b/compose/ui/ui-text/lint-baseline.xml
@@ -31,15 +31,6 @@
     <issue
         id="ListIterator"
         message="Creating an unnecessary Iterator to iterate through a List"
-        errorLine1="        paragraphStyles.sortedBy { it.start }.fastForEach { paragraphStyle ->"
-        errorLine2="                        ~~~~~~~~">
-        <location
-            file="src/commonMain/kotlin/androidx/compose/ui/text/AnnotatedString.kt"/>
-    </issue>
-
-    <issue
-        id="ListIterator"
-        message="Creating an unnecessary Iterator to iterate through a List"
         errorLine1="                        &quot;&apos;$key&apos; must be unique. Actual [ [${value.joinToString()}]&quot;"
         errorLine2="                                                                  ~~~~~~~~~~~~">
         <location
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/DelegatingFontLoaderForDeprecatedUsageTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/DelegatingFontLoaderForDeprecatedUsageTest.kt
index 57dde35..8d69e3a 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/DelegatingFontLoaderForDeprecatedUsageTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/DelegatingFontLoaderForDeprecatedUsageTest.kt
@@ -25,7 +25,7 @@
 import androidx.test.filters.SmallTest
 import androidx.test.platform.app.InstrumentationRegistry
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.mock
+import org.mockito.kotlin.mock
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/SpannableExtensionsTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/SpannableExtensionsTest.kt
index b227132..576b5339 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/SpannableExtensionsTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/SpannableExtensionsTest.kt
@@ -37,14 +37,14 @@
 import androidx.compose.ui.unit.sp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.argThat
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.inOrder
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.never
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argThat
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.inOrder
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.anyInt
diff --git a/compose/ui/ui/api/current.ignore b/compose/ui/ui/api/current.ignore
index 2001639..750e9a7 100644
--- a/compose/ui/ui/api/current.ignore
+++ b/compose/ui/ui/api/current.ignore
@@ -1,3 +1,7 @@
 // Baseline format: 1.0
 RemovedClass: androidx.compose.ui.platform.AndroidComposeView_androidKt:
     Removed class androidx.compose.ui.platform.AndroidComposeView_androidKt
+
+// see b/275084979 for details. API not actually removed, but metalave confused by JvmName + Deprecated
+RemovedMethod: androidx.compose.ui.ComposedModifierKt#materialize(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier):
+    Removed method androidx.compose.ui.ComposedModifierKt.materialize(androidx.compose.runtime.Composer,androidx.compose.ui.Modifier)
diff --git a/compose/ui/ui/api/current.txt b/compose/ui/ui/api/current.txt
index 5a1455d..7d40ab0 100644
--- a/compose/ui/ui/api/current.txt
+++ b/compose/ui/ui/api/current.txt
@@ -113,7 +113,8 @@
 
   public final class ComposedModifierKt {
     method public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
-    method public static androidx.compose.ui.Modifier materialize(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier modifier);
+    method public static androidx.compose.ui.Modifier materializeModifier(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier modifier);
+    method @Deprecated public static androidx.compose.ui.Modifier materializeWithCompositionLocalInjection(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier modifier);
   }
 
   @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface Modifier {
diff --git a/compose/ui/ui/api/public_plus_experimental_current.txt b/compose/ui/ui/api/public_plus_experimental_current.txt
index fa8d56d..ac7252f 100644
--- a/compose/ui/ui/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui/api/public_plus_experimental_current.txt
@@ -117,7 +117,8 @@
     method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, String fullyQualifiedName, Object? key1, Object? key2, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
     method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, String fullyQualifiedName, Object? key1, Object? key2, Object? key3, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
     method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, String fullyQualifiedName, Object![]? keys, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
-    method public static androidx.compose.ui.Modifier materialize(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier modifier);
+    method public static androidx.compose.ui.Modifier materializeModifier(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier modifier);
+    method @Deprecated public static androidx.compose.ui.Modifier materializeWithCompositionLocalInjection(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier modifier);
   }
 
   @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalComposeUiApi {
diff --git a/compose/ui/ui/api/restricted_current.ignore b/compose/ui/ui/api/restricted_current.ignore
index 2001639..ef0ff9c 100644
--- a/compose/ui/ui/api/restricted_current.ignore
+++ b/compose/ui/ui/api/restricted_current.ignore
@@ -1,3 +1,7 @@
 // Baseline format: 1.0
 RemovedClass: androidx.compose.ui.platform.AndroidComposeView_androidKt:
     Removed class androidx.compose.ui.platform.AndroidComposeView_androidKt
+
+
+RemovedMethod: androidx.compose.ui.ComposedModifierKt#materialize(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier):
+    Removed method androidx.compose.ui.ComposedModifierKt.materialize(androidx.compose.runtime.Composer,androidx.compose.ui.Modifier)
diff --git a/compose/ui/ui/api/restricted_current.txt b/compose/ui/ui/api/restricted_current.txt
index c8fa151..60531e4 100644
--- a/compose/ui/ui/api/restricted_current.txt
+++ b/compose/ui/ui/api/restricted_current.txt
@@ -113,7 +113,8 @@
 
   public final class ComposedModifierKt {
     method public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
-    method public static androidx.compose.ui.Modifier materialize(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier modifier);
+    method public static androidx.compose.ui.Modifier materializeModifier(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier modifier);
+    method @Deprecated public static androidx.compose.ui.Modifier materializeWithCompositionLocalInjection(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier modifier);
   }
 
   @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface Modifier {
@@ -1956,7 +1957,8 @@
     method @androidx.compose.runtime.Composable @androidx.compose.ui.UiComposable public static inline void Layout(java.util.List<? extends kotlin.jvm.functions.Function0<kotlin.Unit>> contents, optional androidx.compose.ui.Modifier modifier, androidx.compose.ui.layout.MultiContentMeasurePolicy measurePolicy);
     method @Deprecated @androidx.compose.runtime.Composable @androidx.compose.ui.UiComposable public static void MultiMeasureLayout(optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> content, androidx.compose.ui.layout.MeasurePolicy measurePolicy);
     method @kotlin.PublishedApi internal static kotlin.jvm.functions.Function0<kotlin.Unit> combineAsVirtualLayouts(java.util.List<? extends kotlin.jvm.functions.Function0<kotlin.Unit>> contents);
-    method @kotlin.PublishedApi internal static kotlin.jvm.functions.Function1<androidx.compose.runtime.SkippableUpdater<androidx.compose.ui.node.ComposeUiNode>,kotlin.Unit> materializerOf(androidx.compose.ui.Modifier modifier);
+    method @Deprecated @kotlin.PublishedApi internal static kotlin.jvm.functions.Function1<androidx.compose.runtime.SkippableUpdater<androidx.compose.ui.node.ComposeUiNode>,kotlin.Unit> materializerOf(androidx.compose.ui.Modifier modifier);
+    method @kotlin.PublishedApi internal static kotlin.jvm.functions.Function1<androidx.compose.runtime.SkippableUpdater<androidx.compose.ui.node.ComposeUiNode>,kotlin.Unit> modifierMaterializerOf(androidx.compose.ui.Modifier modifier);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface LayoutModifier extends androidx.compose.ui.Modifier.Element {
diff --git a/compose/ui/ui/lint-baseline.xml b/compose/ui/ui/lint-baseline.xml
index 1fcadc7d..8de11bd 100644
--- a/compose/ui/ui/lint-baseline.xml
+++ b/compose/ui/ui/lint-baseline.xml
@@ -2,6 +2,24 @@
 <issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
 
     <issue
+        id="BanInlineOptIn"
+        message="Inline functions cannot opt into experimental APIs."
+        errorLine1="    internal inline fun fetchCustomEnter("
+        errorLine2="                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/focus/FocusTargetModifierNode.kt"/>
+    </issue>
+
+    <issue
+        id="BanInlineOptIn"
+        message="Inline functions cannot opt into experimental APIs."
+        errorLine1="    internal inline fun fetchCustomExit("
+        errorLine2="                        ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/focus/FocusTargetModifierNode.kt"/>
+    </issue>
+
+    <issue
         id="BanThreadSleep"
         message="Uses Thread.sleep()"
         errorLine1="                Thread.sleep(sleepTime)"
@@ -13,15 +31,6 @@
     <issue
         id="ExperimentalPropertyAnnotation"
         message="This property does not have all required annotations to correctly mark it as experimental."
-        errorLine1="@InternalComposeUiApi // used by testing infra"
-        errorLine2="~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt"/>
-    </issue>
-
-    <issue
-        id="ExperimentalPropertyAnnotation"
-        message="This property does not have all required annotations to correctly mark it as experimental."
         errorLine1="    @InternalComposeUiApi"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~">
         <location
diff --git a/compose/ui/ui/samples/lint-baseline.xml b/compose/ui/ui/samples/lint-baseline.xml
new file mode 100644
index 0000000..cc8feb5
--- /dev/null
+++ b/compose/ui/ui/samples/lint-baseline.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="true" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
+
+    <issue
+        id="ObsoleteSampledAnnotation"
+        message="androidx.compose.ui.samples.AndroidViewWithReleaseSample is annotated with @Sampled, but is not linked to from a @sample tag."
+        errorLine1="fun AndroidViewWithReleaseSample() {"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/ui/samples/AndroidViewSample.kt"/>
+    </issue>
+
+</issues>
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
index adc7989..e4a7369 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
@@ -165,13 +165,13 @@
 import androidx.test.filters.SdkSuppress
 import androidx.test.platform.app.InstrumentationRegistry
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.argThat
-import com.nhaarman.mockitokotlin2.atLeastOnce
-import com.nhaarman.mockitokotlin2.doReturn
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.spy
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.argThat
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
 import org.junit.Assert.assertEquals
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt
index f2e450f..bb893a7 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt
@@ -97,17 +97,17 @@
 import androidx.test.filters.SdkSuppress
 import androidx.test.platform.app.InstrumentationRegistry
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.argThat
-import com.nhaarman.mockitokotlin2.argumentCaptor
-import com.nhaarman.mockitokotlin2.doReturn
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.never
-import com.nhaarman.mockitokotlin2.spy
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
-import com.nhaarman.mockitokotlin2.whenever
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argThat
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
 import java.util.concurrent.Executors
 import kotlinx.coroutines.asCoroutineDispatcher
 import org.junit.Assert.assertEquals
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionTest.kt
index 714865e..9028277 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionTest.kt
@@ -33,12 +33,12 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.argumentCaptor
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.never
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
 import org.junit.Assert.assertTrue
 import org.junit.Before
 import org.junit.Test
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidEmojiTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidEmojiTest.kt
index 336f579..0aff99c 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidEmojiTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidEmojiTest.kt
@@ -29,9 +29,9 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import androidx.test.platform.app.InstrumentationRegistry
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
 import org.junit.After
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidOnStateUpdateTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidOnStateUpdateTest.kt
index ecb1f4e..73c44e6 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidOnStateUpdateTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidOnStateUpdateTest.kt
@@ -31,13 +31,13 @@
 import androidx.test.filters.SmallTest
 import androidx.test.platform.app.InstrumentationRegistry
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.never
-import com.nhaarman.mockitokotlin2.reset
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.reset
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/AndroidPointerInputTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/AndroidPointerInputTest.kt
index 3e31665..6470495 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/AndroidPointerInputTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/AndroidPointerInputTest.kt
@@ -80,10 +80,10 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.never
-import com.nhaarman.mockitokotlin2.spy
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.never
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.verify
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInteropFilterAndroidViewOffsetsTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInteropFilterAndroidViewOffsetsTest.kt
index 0e3ba43..849c2b9 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInteropFilterAndroidViewOffsetsTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInteropFilterAndroidViewOffsetsTest.kt
@@ -34,11 +34,11 @@
 import androidx.compose.ui.viewinterop.AndroidView
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
-import com.nhaarman.mockitokotlin2.clearInvocations
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.never
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/modifier/CompositionLocalMapInjectionTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/modifier/CompositionLocalMapInjectionTest.kt
new file mode 100644
index 0000000..3526180
--- /dev/null
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/modifier/CompositionLocalMapInjectionTest.kt
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.modifier
+
+import android.view.View
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Applier
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.ReusableComposeNode
+import androidx.compose.runtime.compositionLocalOf
+import androidx.compose.runtime.currentComposer
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.UiComposable
+import androidx.compose.ui.graphics.drawscope.ContentDrawScope
+import androidx.compose.ui.layout.Measurable
+import androidx.compose.ui.layout.MeasurePolicy
+import androidx.compose.ui.layout.MeasureResult
+import androidx.compose.ui.layout.MeasureScope
+import androidx.compose.ui.layout.materializerOfWithCompositionLocalInjection
+import androidx.compose.ui.materializeWithCompositionLocalInjectionInternal
+import androidx.compose.ui.node.ComposeUiNode
+import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
+import androidx.compose.ui.node.DrawModifierNode
+import androidx.compose.ui.node.LayoutModifierNode
+import androidx.compose.ui.node.ModifierNodeElement
+import androidx.compose.ui.node.ObserverNode
+import androidx.compose.ui.node.currentValueOf
+import androidx.compose.ui.node.observeReads
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.LocalLayoutDirection
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.platform.LocalViewConfiguration
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class CompositionLocalMapInjectionTest {
+
+    @get:Rule
+    val rule = createComposeRule()
+
+    @Test
+    fun consumeInDraw() {
+        // No assertions needed. This not crashing is the test
+        rule.setContent {
+            CompositionLocalProvider(SomeLocal provides 1) {
+                OldBox(modifierOf { ConsumeInDrawNode() }.size(10.dp))
+            }
+        }
+    }
+
+    @Test
+    fun consumeInLayout() {
+        // No assertions needed. This not crashing is the test
+        rule.setContent {
+            CompositionLocalProvider(SomeLocal provides 1) {
+                OldBox(modifierOf { ConsumeInLayoutNode() }.size(10.dp))
+            }
+        }
+    }
+
+    @Test
+    fun consumeInAttach() {
+        // No assertions needed. This not crashing is the test
+        rule.setContent {
+            CompositionLocalProvider(SomeLocal provides 1) {
+                OldBox(modifierOf { ConsumeInAttachNode() }.size(10.dp))
+            }
+        }
+    }
+
+    @Test
+    fun consumeInDrawGetsNotifiedOfChanges() {
+        val node = ConsumeInDrawNode()
+        var state by mutableStateOf(1)
+        rule.setContent {
+            CompositionLocalProvider(SomeLocal provides state) {
+                OldBox(modifierOf { node }.size(10.dp))
+            }
+        }
+        assertThat(node.int).isEqualTo(state)
+        state = 2
+        rule.runOnIdle {
+            assertThat(node.int).isEqualTo(state)
+        }
+    }
+
+    @Test
+    fun consumeInLayoutGetsNotifiedOfChanges() {
+        val node = ConsumeInLayoutNode()
+        var state by mutableStateOf(1)
+        rule.setContent {
+            CompositionLocalProvider(SomeLocal provides state) {
+                OldBox(modifierOf { node }.size(10.dp))
+            }
+        }
+        assertThat(node.int).isEqualTo(state)
+        state = 2
+        rule.runOnIdle {
+            assertThat(node.int).isEqualTo(state)
+        }
+    }
+
+    @Test
+    fun consumeInAttachGetsNotifiedOfChanges() {
+        val node = ConsumeInAttachNode()
+        var state by mutableStateOf(1)
+        rule.setContent {
+            CompositionLocalProvider(SomeLocal provides state) {
+                OldBox(modifierOf { node }.size(10.dp))
+            }
+        }
+        assertThat(node.int).isEqualTo(state)
+        state = 2
+        rule.runOnIdle {
+            assertThat(node.int).isEqualTo(state)
+        }
+    }
+
+    @Test
+    fun consumeInDrawSkippableUpdate() {
+        // No assertions needed. This not crashing is the test
+        rule.setContent {
+            CompositionLocalProvider(SomeLocal provides 1) {
+                OldBoxSkippableUpdate(modifierOf { ConsumeInDrawNode() }.size(10.dp))
+            }
+        }
+    }
+
+    @Test
+    fun consumeInLayoutSkippableUpdate() {
+        // No assertions needed. This not crashing is the test
+        rule.setContent {
+            CompositionLocalProvider(SomeLocal provides 1) {
+                OldBoxSkippableUpdate(modifierOf { ConsumeInLayoutNode() }.size(10.dp))
+            }
+        }
+    }
+
+    @Test
+    fun consumeInAttachSkippableUpdate() {
+        // No assertions needed. This not crashing is the test
+        rule.setContent {
+            CompositionLocalProvider(SomeLocal provides 1) {
+                OldBoxSkippableUpdate(modifierOf { ConsumeInAttachNode() }.size(10.dp))
+            }
+        }
+    }
+
+    @Test
+    fun consumeInDrawGetsNotifiedOfChangesSkippableUpdate() {
+        val node = ConsumeInDrawNode()
+        var state by mutableStateOf(1)
+        rule.setContent {
+            CompositionLocalProvider(SomeLocal provides state) {
+                OldBoxSkippableUpdate(modifierOf { node }.size(10.dp))
+            }
+        }
+        assertThat(node.int).isEqualTo(state)
+        state = 2
+        rule.runOnIdle {
+            assertThat(node.int).isEqualTo(state)
+        }
+    }
+
+    @Test
+    fun consumeInLayoutGetsNotifiedOfChangesSkippableUpdate() {
+        val node = ConsumeInLayoutNode()
+        var state by mutableStateOf(1)
+        rule.setContent {
+            CompositionLocalProvider(SomeLocal provides state) {
+                OldBoxSkippableUpdate(modifierOf { node }.size(10.dp))
+            }
+        }
+        assertThat(node.int).isEqualTo(state)
+        state = 2
+        rule.runOnIdle {
+            assertThat(node.int).isEqualTo(state)
+        }
+    }
+
+    @Test
+    fun consumeInAttachGetsNotifiedOfChangesSkippableUpdate() {
+        val node = ConsumeInAttachNode()
+        var state by mutableStateOf(1)
+        rule.setContent {
+            CompositionLocalProvider(SomeLocal provides state) {
+                OldBoxSkippableUpdate(modifierOf { node }.size(10.dp))
+            }
+        }
+        assertThat(node.int).isEqualTo(state)
+        state = 2
+        rule.runOnIdle {
+            assertThat(node.int).isEqualTo(state)
+        }
+    }
+}
+
+val SomeLocal = compositionLocalOf<Int> { error("unprovided value") }
+
+inline fun <reified T : Modifier.Node> modifierOf(crossinline fn: () -> T) =
+    object : ModifierNodeElement<T>() {
+        override fun create() = fn()
+        override fun hashCode() = System.identityHashCode(this)
+        override fun equals(other: Any?) = other === this
+        override fun update(node: T) = node
+    }
+
+class ConsumeInDrawNode : CompositionLocalConsumerModifierNode, DrawModifierNode, Modifier.Node() {
+    var view: View? = null
+    var int: Int? = null
+    override fun ContentDrawScope.draw() {
+        // Consume Static local
+        view = currentValueOf(LocalView)
+        // Consume Freshly Provided Local
+        int = currentValueOf(SomeLocal)
+    }
+}
+
+class ConsumeInLayoutNode :
+    CompositionLocalConsumerModifierNode,
+    LayoutModifierNode,
+    Modifier.Node() {
+    var view: View? = null
+    var int: Int? = null
+    override fun MeasureScope.measure(
+        measurable: Measurable,
+        constraints: Constraints
+    ): MeasureResult {
+        // Consume Static local
+        view = currentValueOf(LocalView)
+        // Consume Freshly Provided Local
+        int = currentValueOf(SomeLocal)
+        val placeable = measurable.measure(constraints)
+        return layout(constraints.minWidth, constraints.maxWidth) {
+            placeable.place(0, 0)
+        }
+    }
+}
+
+class ConsumeInAttachNode : CompositionLocalConsumerModifierNode, ObserverNode, Modifier.Node() {
+    var view: View? = null
+    var int: Int? = null
+    private fun readLocals() {
+        // Consume Static local
+        view = currentValueOf(LocalView)
+        // Consume Freshly Provided Local
+        int = currentValueOf(SomeLocal)
+    }
+    override fun onAttach() {
+        observeReads { readLocals() }
+    }
+    override fun onObservedReadsChanged() {
+        observeReads { readLocals() }
+    }
+}
+
+// This composable is intentionally written to look like the "old" version of Layout, before
+// aosp/2318839. This function allows us to emulate what a module targeting an older version of
+// compose UI would have inlined into their function body. See b/275067189 for more details.
+@UiComposable
+@Composable
+inline fun OldLayoutSkippableUpdate(
+    content: @Composable @UiComposable () -> Unit,
+    modifier: Modifier = Modifier,
+    measurePolicy: MeasurePolicy
+) {
+    val density = LocalDensity.current
+    val layoutDirection = LocalLayoutDirection.current
+    val viewConfiguration = LocalViewConfiguration.current
+    @Suppress("DEPRECATION")
+    ReusableComposeNode<ComposeUiNode, Applier<Any>>(
+        factory = ComposeUiNode.Constructor,
+        update = {
+            set(measurePolicy, ComposeUiNode.SetMeasurePolicy)
+            set(density, ComposeUiNode.SetDensity)
+            set(layoutDirection, ComposeUiNode.SetLayoutDirection)
+            set(viewConfiguration, ComposeUiNode.SetViewConfiguration)
+        },
+        // The old version of Layout called a function called "materializerOf". The function below
+        // has the same JVM signature as that function used to have, so the code that this source
+        // generates will be essentially identical to what will have been generated in older versions
+        // of UI, despite this name being different now.
+        skippableUpdate = materializerOfWithCompositionLocalInjection(modifier),
+        content = content
+    )
+}
+
+@Suppress("NOTHING_TO_INLINE")
+@Composable
+@UiComposable
+internal inline fun OldLayout(
+    modifier: Modifier = Modifier,
+    measurePolicy: MeasurePolicy
+) {
+    val density = LocalDensity.current
+    val layoutDirection = LocalLayoutDirection.current
+    val viewConfiguration = LocalViewConfiguration.current
+    // The old version of Layout called a function called "materialize". The function below
+    // has the same JVM signature as that function used to have, so the code that this source
+    // generates will be essentially identical to what will have been generated in older versions
+    // of UI, despite this name being different now.
+    val materialized = currentComposer.materializeWithCompositionLocalInjectionInternal(modifier)
+    ReusableComposeNode<ComposeUiNode, Applier<Any>>(
+        factory = ComposeUiNode.Constructor,
+        update = {
+            set(measurePolicy, ComposeUiNode.SetMeasurePolicy)
+            set(density, ComposeUiNode.SetDensity)
+            set(layoutDirection, ComposeUiNode.SetLayoutDirection)
+            set(viewConfiguration, ComposeUiNode.SetViewConfiguration)
+            set(materialized, ComposeUiNode.SetModifier)
+        },
+    )
+}
+private val EmptyBoxMeasurePolicy = MeasurePolicy { _, constraints ->
+    layout(constraints.minWidth, constraints.minHeight) {}
+}
+
+@Composable fun OldBoxSkippableUpdate(modifier: Modifier = Modifier) {
+    OldLayoutSkippableUpdate({ }, modifier, EmptyBoxMeasurePolicy)
+}
+
+@Composable fun OldBox(modifier: Modifier = Modifier) {
+    OldLayout(modifier, EmptyBoxMeasurePolicy)
+}
\ No newline at end of file
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidClipboardManagerTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidClipboardManagerTest.kt
index 23c7652..d9a4bc8 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidClipboardManagerTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidClipboardManagerTest.kt
@@ -37,8 +37,8 @@
 import androidx.test.filters.SmallTest
 import androidx.test.platform.app.InstrumentationRegistry
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.whenever
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/DepthSortedSetTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/DepthSortedSetTest.kt
index 68dd09e..99b94bb 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/DepthSortedSetTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/DepthSortedSetTest.kt
@@ -23,7 +23,7 @@
 import androidx.compose.ui.node.add
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
-import com.nhaarman.mockitokotlin2.spy
+import org.mockito.kotlin.spy
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertTrue
 import org.junit.Test
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/LocalSoftwareKeyboardControllerTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/LocalSoftwareKeyboardControllerTest.kt
index 3a2c291..0b6e22c 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/LocalSoftwareKeyboardControllerTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/LocalSoftwareKeyboardControllerTest.kt
@@ -31,10 +31,10 @@
 import androidx.compose.ui.text.input.TextInputService
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.never
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/ComposedModifier.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/ComposedModifier.kt
index a06b7ea..a1872aa 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/ComposedModifier.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/ComposedModifier.kt
@@ -18,7 +18,10 @@
 
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composer
+import androidx.compose.runtime.CompositionLocalMap
 import androidx.compose.runtime.Stable
+import androidx.compose.ui.node.ModifierNodeElement
+import androidx.compose.ui.node.requireLayoutNode
 import androidx.compose.ui.platform.InspectorInfo
 import androidx.compose.ui.platform.InspectorValueInfo
 import androidx.compose.ui.platform.NoInspectorInfo
@@ -244,6 +247,8 @@
  * You almost certainly do not need to call this function directly.
  */
 @Suppress("ModifierFactoryExtensionFunction")
+// "materialize" JVM name is taken below to solve a backwards-incompatibility
+@JvmName("materializeModifier")
 fun Composer.materialize(modifier: Modifier): Modifier {
     if (modifier.all { it !is ComposedModifier }) {
         return modifier
@@ -273,3 +278,64 @@
     endReplaceableGroup()
     return result
 }
+
+/**
+ * This class is only used for backwards compatibility purposes to inject the CompositionLocalMap
+ * into LayoutNodes that were created by inlined code of older versions of the Layout composable.
+ * More details can be found at https://issuetracker.google.com/275067189
+ */
+internal class CompositionLocalMapInjectionNode(map: CompositionLocalMap) : Modifier.Node() {
+    var map: CompositionLocalMap = map
+        set(value) {
+            field = value
+            requireLayoutNode().compositionLocalMap = value
+        }
+    override fun onAttach() {
+        requireLayoutNode().compositionLocalMap = map
+    }
+}
+
+/**
+ * This class is only used for backwards compatibility purposes to inject the CompositionLocalMap
+ * into LayoutNodes that were created by inlined code of older versions of the Layout composable.
+ * More details can be found at https://issuetracker.google.com/275067189
+ */
+internal class CompositionLocalMapInjectionElement(
+    val map: CompositionLocalMap
+) : ModifierNodeElement<CompositionLocalMapInjectionNode>() {
+    override fun create() = CompositionLocalMapInjectionNode(map)
+    override fun update(node: CompositionLocalMapInjectionNode) = node.also { it.map = map }
+    override fun hashCode(): Int = map.hashCode()
+    override fun equals(other: Any?): Boolean {
+        return other is CompositionLocalMapInjectionElement && other.map == map
+    }
+    override fun InspectorInfo.inspectableProperties() {
+        name = "<Injected CompositionLocalMap>"
+    }
+}
+
+/**
+ * This function exists solely for solving a backwards-incompatibility with older compilations
+ * that used an older version of the `Layout` composable. New code paths should not call this.
+ * More details can be found at https://issuetracker.google.com/275067189
+ */
+@Suppress("ModifierFactoryExtensionFunction")
+@JvmName("materialize")
+@Deprecated(
+    "Kept for backwards compatibility only. If you are recompiling, use materialize.",
+    ReplaceWith("materialize"),
+    DeprecationLevel.HIDDEN
+)
+fun Composer.materializeWithCompositionLocalInjection(modifier: Modifier): Modifier =
+    materializeWithCompositionLocalInjectionInternal(modifier)
+
+// This method is here to be called from tests since the deprecated hidden API cannot be.
+@Suppress("ModifierFactoryExtensionFunction")
+internal fun Composer.materializeWithCompositionLocalInjectionInternal(
+    modifier: Modifier
+): Modifier {
+    return if (modifier === Modifier)
+        modifier
+    else
+        materialize(CompositionLocalMapInjectionElement(currentCompositionLocalMap).then(modifier))
+}
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Layout.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Layout.kt
index 001261d..2b45ead 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Layout.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Layout.kt
@@ -28,6 +28,7 @@
 import androidx.compose.ui.UiComposable
 import androidx.compose.ui.graphics.GraphicsLayerScope
 import androidx.compose.ui.materialize
+import androidx.compose.ui.materializeWithCompositionLocalInjectionInternal
 import androidx.compose.ui.node.ComposeUiNode
 import androidx.compose.ui.node.LayoutNode
 import androidx.compose.ui.unit.Constraints
@@ -173,7 +174,13 @@
     }
 }
 
+/**
+ * This function uses a JVM-Name because the original name now has a different implementation for
+ * backwards compatibility [materializerOfWithCompositionLocalInjection].
+ * More details can be found at https://issuetracker.google.com/275067189
+ */
 @PublishedApi
+@JvmName("modifierMaterializerOf")
 internal fun materializerOf(
     modifier: Modifier
 ): @Composable SkippableUpdater<ComposeUiNode>.() -> Unit = {
@@ -183,6 +190,26 @@
     }
 }
 
+/**
+ * This function exists solely for solving a backwards-incompatibility with older compilations
+ * that used an older version of the `Layout` composable. New code paths should not call this.
+ * More details can be found at https://issuetracker.google.com/275067189
+ */
+@JvmName("materializerOf")
+@Deprecated(
+    "Needed only for backwards compatibility. Do not use.",
+    level = DeprecationLevel.WARNING
+)
+@PublishedApi
+internal fun materializerOfWithCompositionLocalInjection(
+    modifier: Modifier
+): @Composable SkippableUpdater<ComposeUiNode>.() -> Unit = {
+    val materialized = currentComposer.materializeWithCompositionLocalInjectionInternal(modifier)
+    update {
+        set(materialized, ComposeUiNode.SetModifier)
+    }
+}
+
 @Suppress("ComposableLambdaParameterPosition")
 @Composable
 @UiComposable
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/demos/build.gradle b/constraintlayout/constraintlayout-compose/integration-tests/demos/build.gradle
index d552342..b9fcd3c 100644
--- a/constraintlayout/constraintlayout-compose/integration-tests/demos/build.gradle
+++ b/constraintlayout/constraintlayout-compose/integration-tests/demos/build.gradle
@@ -36,4 +36,9 @@
 
 android {
     namespace "androidx.constraintlayout.compose.demos"
-}
\ No newline at end of file
+
+    lint {
+        // ConstraintLayoutDslDetector fails with NoClassDefFoundError in ChainsDemo.kt
+        disable "IncorrectReferencesDeclaration", "IncorrectMatchParentUsage", "IncorrectChainMarginsUsage"
+    }
+}
diff --git a/constraintlayout/constraintlayout-compose/lint-baseline.xml b/constraintlayout/constraintlayout-compose/lint-baseline.xml
index fab4f22..b08ac1e 100644
--- a/constraintlayout/constraintlayout-compose/lint-baseline.xml
+++ b/constraintlayout/constraintlayout-compose/lint-baseline.xml
@@ -73,67 +73,4 @@
             file="src/androidMain/kotlin/androidx/constraintlayout/compose/ConstraintLayout.kt"/>
     </issue>
 
-    <issue
-        id="ComposableNaming"
-        message="Composable functions with a return type should start with a lowercase letter"
-        errorLine1="fun MotionScene("
-        errorLine2="    ~~~~~~~~~~~">
-        <location
-            file="src/androidMain/kotlin/androidx/constraintlayout/compose/MotionSceneScope.kt"/>
-    </issue>
-
-    <issue
-        id="ComposableNaming"
-        message="Composable functions with a return type should start with a lowercase letter"
-        errorLine1="fun Transition("
-        errorLine2="    ~~~~~~~~~~">
-        <location
-            file="src/androidMain/kotlin/androidx/constraintlayout/compose/TransitionScope.kt"/>
-    </issue>
-
-    <issue
-        id="ModifierInspectorInfo"
-        message="Expected name of the modifier: `&quot;name&quot; = &quot;carouselSwipeable&quot;`"
-        errorLine1="        name = &quot;swipeable&quot;"
-        errorLine2="                ~~~~~~~~~">
-        <location
-            file="src/androidMain/kotlin/androidx/constraintlayout/compose/carousel/CarouselSwipeable.kt"/>
-    </issue>
-
-    <issue
-        id="ModifierInspectorInfo"
-        message="Modifier missing inspectorInfo"
-        errorLine1="    ) = this.then(ConstrainAsModifier(ref, constrainBlock))"
-        errorLine2="                  ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/androidMain/kotlin/androidx/constraintlayout/compose/ConstraintLayout.kt"/>
-    </issue>
-
-    <issue
-        id="ModifierInspectorInfo"
-        message="Expected name of the modifier: `&quot;name&quot; = &quot;layoutId&quot;`"
-        errorLine1="                    name = &quot;constraintLayoutId&quot;"
-        errorLine2="                            ~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/androidMain/kotlin/androidx/constraintlayout/compose/ConstraintLayoutTag.kt"/>
-    </issue>
-
-    <issue
-        id="ModifierInspectorInfo"
-        message="Modifier missing inspectorInfo"
-        errorLine1="    ): Modifier = composed {"
-        errorLine2="                  ~~~~~~~~">
-        <location
-            file="src/androidMain/kotlin/androidx/constraintlayout/compose/Motion.kt"/>
-    </issue>
-
-    <issue
-        id="ModifierInspectorInfo"
-        message="These lambda arguments are missing in the InspectorInfo: `motionProgress`"
-        errorLine1="    inspectorInfo = debugInspectorInfo {"
-        errorLine2="                                       ^">
-        <location
-            file="src/androidMain/kotlin/androidx/constraintlayout/compose/MotionDragHandler.kt"/>
-    </issue>
-
 </issues>
diff --git a/constraintlayout/constraintlayout-core/lint-baseline.xml b/constraintlayout/constraintlayout-core/lint-baseline.xml
index 7e51af2..bff62dd 100644
--- a/constraintlayout/constraintlayout-core/lint-baseline.xml
+++ b/constraintlayout/constraintlayout-core/lint-baseline.xml
@@ -3097,132 +3097,6 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    protected HashMap&lt;String ,Float> mMapWeights;"
-        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    protected HashMap&lt;String,Float> mMapPreMargin;"
-        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    protected HashMap&lt;String,Float> mMapPostMargin;"
-        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    protected State.Chain mStyle = State.Chain.SPREAD;"
-        errorLine2="              ~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public ChainReference(State state, State.Helper type) {"
-        errorLine2="                          ~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public ChainReference(State state, State.Helper type) {"
-        errorLine2="                                       ~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public State.Chain getStyle() {"
-        errorLine2="           ~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public ChainReference style(State.Chain style) {"
-        errorLine2="           ~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public ChainReference style(State.Chain style) {"
-        errorLine2="                                ~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public void addChainElement(String id, float weight, float preMargin, float  postMargin ) {"
-        errorLine2="                                ~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="  protected float getWeight(String id) {"
-        errorLine2="                            ~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    protected float getPostMargin(String id) {"
-        errorLine2="                                  ~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    protected float getPreMargin(String id) {"
-        errorLine2="                                 ~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public ChainReference bias(float bias) {"
-        errorLine2="           ~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
         errorLine1="    public ChainRun(ConstraintWidget widget, int orientation) {"
         errorLine2="                    ~~~~~~~~~~~~~~~~">
         <location
@@ -4942,8 +4816,8 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="            LayoutVariables layoutVariables) throws CLParsingException {"
-        errorLine2="            ~~~~~~~~~~~~~~~">
+        errorLine1="                                 LayoutVariables layoutVariables) throws CLParsingException {"
+        errorLine2="                                 ~~~~~~~~~~~~~~~">
         <location
             file="src/main/java/androidx/constraintlayout/core/state/ConstraintSetParser.java"/>
     </issue>
@@ -13006,33 +12880,6 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public static void parse(CLObject json, Transition transition, CorePixelDp dpToPixel)"
-        errorLine2="                             ~~~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/TransitionParser.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public static void parse(CLObject json, Transition transition, CorePixelDp dpToPixel)"
-        errorLine2="                                            ~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/TransitionParser.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public static void parse(CLObject json, Transition transition, CorePixelDp dpToPixel)"
-        errorLine2="                                                                   ~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/core/state/TransitionParser.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
         errorLine1="    public static void parseKeyFrames(CLObject transitionCLObject, Transition transition)"
         errorLine2="                                      ~~~~~~~~">
         <location
diff --git a/constraintlayout/constraintlayout/lint-baseline.xml b/constraintlayout/constraintlayout/lint-baseline.xml
index a9b5204..6f8af38 100644
--- a/constraintlayout/constraintlayout/lint-baseline.xml
+++ b/constraintlayout/constraintlayout/lint-baseline.xml
@@ -5332,15 +5332,6 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    protected void dispatchDraw(Canvas canvas) {"
-        errorLine2="                                ~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/widget/ConstraintLayout.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
         errorLine1="    public void setOnConstraintsChanged(ConstraintsChangedListener constraintsChangedListener) {"
         errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -9256,15 +9247,6 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    protected void dispatchDraw(Canvas canvas) {"
-        errorLine2="                                ~~~~~~">
-        <location
-            file="src/main/java/androidx/constraintlayout/motion/widget/MotionLayout.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
         errorLine1="    public void setScene(MotionScene scene) {"
         errorLine2="                         ~~~~~~~~~~~">
         <location
diff --git a/coordinatorlayout/coordinatorlayout/src/main/java/androidx/coordinatorlayout/widget/CoordinatorLayout.java b/coordinatorlayout/coordinatorlayout/src/main/java/androidx/coordinatorlayout/widget/CoordinatorLayout.java
index 05a23875..70782d1 100644
--- a/coordinatorlayout/coordinatorlayout/src/main/java/androidx/coordinatorlayout/widget/CoordinatorLayout.java
+++ b/coordinatorlayout/coordinatorlayout/src/main/java/androidx/coordinatorlayout/widget/CoordinatorLayout.java
@@ -115,6 +115,8 @@
         NestedScrollingParent3 {
     static final String TAG = "CoordinatorLayout";
     static final String WIDGET_PACKAGE_NAME;
+    // For the UP/DOWN keys, we scroll 1/10th of the screen.
+    private static final float KEY_SCROLL_FRACTION_AMOUNT = 0.1f;
 
     static {
         final Package pkg = CoordinatorLayout.class.getPackage();
@@ -181,6 +183,13 @@
     // This only exist to prevent GC and object instantiation costs that are present before API 21.
     private final int[] mNestedScrollingV2ConsumedCompat = new int[2];
 
+    // Array to be mutated by calls to nested scrolling related methods triggered by key events.
+    // Because these scrolling events rely on lower level methods using mBehaviorConsumed, we need
+    // a separate variable to save memory. As with the above, this only exist to prevent GC and
+    // object instantiation costs that are
+    // present before API 21.
+    private final int[] mKeyTriggeredScrollConsumed = new int[2];
+
     private boolean mDisallowInterceptReset;
 
     private boolean mIsAttachedToWindow;
@@ -1945,47 +1954,46 @@
             if (event.getAction() == KeyEvent.ACTION_DOWN) {
                 switch (event.getKeyCode()) {
                     case KeyEvent.KEYCODE_DPAD_UP:
-                    case KeyEvent.KEYCODE_DPAD_DOWN:
-                    case KeyEvent.KEYCODE_SPACE:
-
-                        int yScrollDelta;
-
-                        if (event.getKeyCode() == KeyEvent.KEYCODE_SPACE) {
-                            if (event.isShiftPressed()) {
-                                // Places the CoordinatorLayout at the top of the available
-                                // content.
-                                // Note: The delta may represent a value that would overshoot the
-                                // top of the screen, but the children only use as much of the
-                                // delta as they can support, so it will always go exactly to the
-                                // top.
-                                yScrollDelta = -getFullContentHeight();
-                            } else {
-                                // Places the CoordinatorLayout at the bottom of the available
-                                // content.
-                                yScrollDelta = getFullContentHeight() - getHeight();
-                            }
-
-                        } else if (event.isAltPressed()) { // For UP and DOWN KeyEvents
-                            // Full page scroll
-                            yScrollDelta = getHeight();
-
+                        if (event.isAltPressed()) {
+                            // Inverse to move up the screen
+                            handled = moveVertically(-pageDelta());
                         } else {
-                            // Regular arrow scroll
-                            yScrollDelta = (int) (getHeight() * 0.1f);
+                            // Inverse to move up the screen
+                            handled = moveVertically(-lineDelta());
                         }
+                        break;
 
-                        View focusedView = findDeepestFocusedChild(this);
-
-                        // Convert delta to negative if the key event is UP.
-                        if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP) {
-                            yScrollDelta = -yScrollDelta;
+                    case KeyEvent.KEYCODE_DPAD_DOWN:
+                        if (event.isAltPressed()) {
+                            handled = moveVertically(pageDelta());
+                        } else {
+                            handled = moveVertically(lineDelta());
                         }
+                        break;
 
-                        handled = manuallyTriggersNestedScrollFromKeyEvent(
-                                focusedView,
-                                yScrollDelta
-                        );
+                    case KeyEvent.KEYCODE_PAGE_UP:
+                        // Inverse to move up the screen
+                        handled = moveVertically(-pageDelta());
+                        break;
 
+                    case KeyEvent.KEYCODE_PAGE_DOWN:
+                        handled = moveVertically(pageDelta());
+                        break;
+
+                    case KeyEvent.KEYCODE_SPACE:
+                        if (event.isShiftPressed()) {
+                            handled = moveVertically(distanceToTop());
+                        } else {
+                            handled = moveVertically(distanceToBottom());
+                        }
+                        break;
+
+                    case KeyEvent.KEYCODE_MOVE_HOME:
+                        handled = moveVertically(distanceToTop());
+                        break;
+
+                    case KeyEvent.KEYCODE_MOVE_END:
+                        handled = moveVertically(distanceToBottom());
                         break;
                 }
             }
@@ -1994,6 +2002,36 @@
         return handled;
     }
 
+    // Distance for moving one arrow key tap.
+    private int lineDelta() {
+        return (int) (getHeight() * KEY_SCROLL_FRACTION_AMOUNT);
+    }
+
+    private int pageDelta() {
+        return getHeight();
+    }
+
+    private int distanceToTop() {
+        // Note: The delta may represent a value that would overshoot the
+        // top of the screen, but the children only use as much of the
+        // delta as they can support, so it will always go exactly to the
+        // top.
+        return -getFullContentHeight();
+    }
+
+    private int distanceToBottom() {
+        return getFullContentHeight() - getHeight();
+    }
+
+    private boolean moveVertically(int yScrollDelta) {
+        View focusedView = findDeepestFocusedChild(this);
+
+        return manuallyTriggersNestedScrollFromKeyEvent(
+                focusedView,
+                yScrollDelta
+        );
+    }
+
     private View findDeepestFocusedChild(View startingParentView) {
         View focusedView = startingParentView;
         while (focusedView != null) {
@@ -2050,6 +2088,10 @@
                 ViewCompat.TYPE_NON_TOUCH
         );
 
+        // Reset consumed values to zero.
+        mKeyTriggeredScrollConsumed[0] = 0;
+        mKeyTriggeredScrollConsumed[1] = 0;
+
         onNestedScroll(
                 focusedView,
                 0,
@@ -2057,12 +2099,12 @@
                 0,
                 yScrollDelta,
                 ViewCompat.TYPE_NON_TOUCH,
-                mBehaviorConsumed
+                mKeyTriggeredScrollConsumed
         );
 
         onStopNestedScroll(focusedView, ViewCompat.TYPE_NON_TOUCH);
 
-        if (mBehaviorConsumed[1] > 0) {
+        if (mKeyTriggeredScrollConsumed[1] > 0) {
             handled = true;
         }
 
diff --git a/core/core-testing/api/current.txt b/core/core-testing/api/current.txt
new file mode 100644
index 0000000..bca6bb8
--- /dev/null
+++ b/core/core-testing/api/current.txt
@@ -0,0 +1,11 @@
+// Signature format: 4.0
+package androidx.core.testing.util {
+
+  public final class TestConsumer<T> implements androidx.core.util.Consumer<T> {
+    ctor public TestConsumer();
+    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
new file mode 100644
index 0000000..bca6bb8
--- /dev/null
+++ b/core/core-testing/api/public_plus_experimental_current.txt
@@ -0,0 +1,11 @@
+// Signature format: 4.0
+package androidx.core.testing.util {
+
+  public final class TestConsumer<T> implements androidx.core.util.Consumer<T> {
+    ctor public TestConsumer();
+    method public void accept(T? t);
+    method public void assertValues(java.util.List<? extends T> values);
+  }
+
+}
+
diff --git a/core/core-testing/api/res-current.txt b/core/core-testing/api/res-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/core/core-testing/api/res-current.txt
diff --git a/core/core-testing/api/restricted_current.txt b/core/core-testing/api/restricted_current.txt
new file mode 100644
index 0000000..bca6bb8
--- /dev/null
+++ b/core/core-testing/api/restricted_current.txt
@@ -0,0 +1,11 @@
+// Signature format: 4.0
+package androidx.core.testing.util {
+
+  public final class TestConsumer<T> implements androidx.core.util.Consumer<T> {
+    ctor public TestConsumer();
+    method public void accept(T? t);
+    method public void assertValues(java.util.List<? extends T> values);
+  }
+
+}
+
diff --git a/core/core-testing/build.gradle b/core/core-testing/build.gradle
new file mode 100644
index 0000000..fdc6f76
--- /dev/null
+++ b/core/core-testing/build.gradle
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import androidx.build.LibraryType
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+    id("org.jetbrains.kotlin.android")
+}
+
+dependencies {
+    // Atomically versioned.
+    constraints {
+        implementation(project(":core:core"))
+    }
+    api(libs.kotlinStdlib)
+    implementation("androidx.annotation:annotation-jvm:1.6.0")
+    api(project(":core:core"))
+
+    testImplementation(libs.testCore)
+    testImplementation(libs.testRunner)
+    testImplementation(libs.junit)
+}
+
+android {
+    namespace "androidx.core.testing"
+}
+
+androidx {
+    name = "androidx.core:core-testing"
+    type = LibraryType.PUBLISHED_LIBRARY
+    mavenVersion = LibraryVersions.CORE
+    inceptionYear = "2023"
+    description = "Write tests using core APIs."
+}
diff --git a/core/core-testing/src/main/java/androidx/core/testing/util/TestConsumer.kt b/core/core-testing/src/main/java/androidx/core/testing/util/TestConsumer.kt
new file mode 100644
index 0000000..14623df
--- /dev/null
+++ b/core/core-testing/src/main/java/androidx/core/testing/util/TestConsumer.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.testing.util
+
+import androidx.annotation.GuardedBy
+import androidx.core.util.Consumer
+import java.util.concurrent.locks.ReentrantLock
+import kotlin.concurrent.withLock
+
+/**
+ * An implementation of [Consumer] to capture values during a test and allows developers to perform
+ * assertions on the values.
+ * @param T the type of the input to the operation
+ */
+class TestConsumer<T> : Consumer<T> {
+
+    private val lock = ReentrantLock()
+
+    @GuardedBy("lock")
+    private val values = mutableListOf<T>()
+
+    /**
+     * Records the value in the order it was received.
+     * @param t the input argument.
+     */
+    override fun accept(t: T) {
+        lock.withLock {
+            values.add(t)
+        }
+    }
+
+    /**
+     * Asserts that the [values] match the received values. This method checks the order and the
+     * elements.
+     * @param values expected to be in the [TestConsumer]
+     * @throws AssertionError if the values do not match the current values.
+     */
+    fun assertValues(values: List<T>) {
+        lock.withLock {
+            if (this.values != values) {
+                throw AssertionError("Expected $values but received ${this.values}")
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/core-testing/src/test/java/androidx/core/testing/util/TestConsumerTest.kt b/core/core-testing/src/test/java/androidx/core/testing/util/TestConsumerTest.kt
new file mode 100644
index 0000000..48e0f9d
--- /dev/null
+++ b/core/core-testing/src/test/java/androidx/core/testing/util/TestConsumerTest.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.testing.util
+
+import org.junit.Test
+
+class TestConsumerTest {
+
+    private val testConsumer = TestConsumer<Any>()
+
+    @Test
+    fun test_checkingValues_recordsValue() {
+        val values = listOf(Object(), Object(), Object())
+
+        values.forEach(testConsumer::accept)
+
+        testConsumer.assertValues(values)
+    }
+
+    @Test(expected = AssertionError::class)
+    fun test_checkingValues_checksSize() {
+        val values = listOf(Object(), Object(), Object())
+
+        values.forEach(testConsumer::accept)
+
+        testConsumer.assertValues(values.take(2))
+    }
+
+    @Test(expected = AssertionError::class)
+    fun test_checkingValues_checksOrder() {
+        val values = listOf(Object(), Object(), Object())
+
+        values.forEach(testConsumer::accept)
+
+        testConsumer.assertValues(values.reversed())
+    }
+}
\ No newline at end of file
diff --git a/core/core/api/current.txt b/core/core/api/current.txt
index 45453ce..d14ddbc 100644
--- a/core/core/api/current.txt
+++ b/core/core/api/current.txt
@@ -118,9 +118,9 @@
     field public static final int MODE_IGNORED = 1; // 0x1
   }
 
-  public final class BundleCompat {
-    method public static android.os.IBinder? getBinder(android.os.Bundle, String?);
-    method public static void putBinder(android.os.Bundle, String?, android.os.IBinder?);
+  @Deprecated public final class BundleCompat {
+    method @Deprecated public static android.os.IBinder? getBinder(android.os.Bundle, String?);
+    method @Deprecated public static void putBinder(android.os.Bundle, String?, android.os.IBinder?);
   }
 
   public class DialogCompat {
@@ -794,6 +794,7 @@
     method public void deleteUnlistedNotificationChannels(java.util.Collection<java.lang.String!>);
     method public static androidx.core.app.NotificationManagerCompat from(android.content.Context);
     method public java.util.List<android.service.notification.StatusBarNotification!> getActiveNotifications();
+    method public int getCurrentInterruptionFilter();
     method public static java.util.Set<java.lang.String!> getEnabledListenerPackages(android.content.Context);
     method public int getImportance();
     method public android.app.NotificationChannel? getNotificationChannel(String);
@@ -818,6 +819,11 @@
     field public static final int IMPORTANCE_MIN = 1; // 0x1
     field public static final int IMPORTANCE_NONE = 0; // 0x0
     field public static final int IMPORTANCE_UNSPECIFIED = -1000; // 0xfffffc18
+    field public static final int INTERRUPTION_FILTER_ALARMS = 4; // 0x4
+    field public static final int INTERRUPTION_FILTER_ALL = 1; // 0x1
+    field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
+    field public static final int INTERRUPTION_FILTER_PRIORITY = 2; // 0x2
+    field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0
   }
 
   public static class NotificationManagerCompat.NotificationWithIdAndTag {
@@ -1822,10 +1828,12 @@
   }
 
   public final class BundleCompat {
+    method public static android.os.IBinder? getBinder(android.os.Bundle, String?);
     method public static <T> T? getParcelable(android.os.Bundle, String?, Class<T!>);
     method public static android.os.Parcelable![]? getParcelableArray(android.os.Bundle, String?, Class<? extends android.os.Parcelable>);
     method public static <T> java.util.ArrayList<T!>? getParcelableArrayList(android.os.Bundle, String?, Class<? extends T>);
     method public static <T> android.util.SparseArray<T!>? getSparseParcelableArray(android.os.Bundle, String?, Class<? extends T>);
+    method public static void putBinder(android.os.Bundle, String?, android.os.IBinder?);
   }
 
   public final class CancellationSignal {
diff --git a/core/core/api/public_plus_experimental_current.txt b/core/core/api/public_plus_experimental_current.txt
index 7910e34..b4c65638b 100644
--- a/core/core/api/public_plus_experimental_current.txt
+++ b/core/core/api/public_plus_experimental_current.txt
@@ -118,9 +118,9 @@
     field public static final int MODE_IGNORED = 1; // 0x1
   }
 
-  public final class BundleCompat {
-    method public static android.os.IBinder? getBinder(android.os.Bundle, String?);
-    method public static void putBinder(android.os.Bundle, String?, android.os.IBinder?);
+  @Deprecated public final class BundleCompat {
+    method @Deprecated public static android.os.IBinder? getBinder(android.os.Bundle, String?);
+    method @Deprecated public static void putBinder(android.os.Bundle, String?, android.os.IBinder?);
   }
 
   public class DialogCompat {
@@ -794,6 +794,7 @@
     method public void deleteUnlistedNotificationChannels(java.util.Collection<java.lang.String!>);
     method public static androidx.core.app.NotificationManagerCompat from(android.content.Context);
     method public java.util.List<android.service.notification.StatusBarNotification!> getActiveNotifications();
+    method public int getCurrentInterruptionFilter();
     method public static java.util.Set<java.lang.String!> getEnabledListenerPackages(android.content.Context);
     method public int getImportance();
     method public android.app.NotificationChannel? getNotificationChannel(String);
@@ -818,6 +819,11 @@
     field public static final int IMPORTANCE_MIN = 1; // 0x1
     field public static final int IMPORTANCE_NONE = 0; // 0x0
     field public static final int IMPORTANCE_UNSPECIFIED = -1000; // 0xfffffc18
+    field public static final int INTERRUPTION_FILTER_ALARMS = 4; // 0x4
+    field public static final int INTERRUPTION_FILTER_ALL = 1; // 0x1
+    field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
+    field public static final int INTERRUPTION_FILTER_PRIORITY = 2; // 0x2
+    field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0
   }
 
   public static class NotificationManagerCompat.NotificationWithIdAndTag {
@@ -1828,10 +1834,12 @@
   }
 
   public final class BundleCompat {
+    method public static android.os.IBinder? getBinder(android.os.Bundle, String?);
     method public static <T> T? getParcelable(android.os.Bundle, String?, Class<T!>);
     method public static android.os.Parcelable![]? getParcelableArray(android.os.Bundle, String?, Class<? extends android.os.Parcelable>);
     method public static <T> java.util.ArrayList<T!>? getParcelableArrayList(android.os.Bundle, String?, Class<? extends T>);
     method public static <T> android.util.SparseArray<T!>? getSparseParcelableArray(android.os.Bundle, String?, Class<? extends T>);
+    method public static void putBinder(android.os.Bundle, String?, android.os.IBinder?);
   }
 
   public final class CancellationSignal {
diff --git a/core/core/api/restricted_current.txt b/core/core/api/restricted_current.txt
index 20329ba..0b794f3 100644
--- a/core/core/api/restricted_current.txt
+++ b/core/core/api/restricted_current.txt
@@ -136,9 +136,9 @@
     field public static final int MODE_IGNORED = 1; // 0x1
   }
 
-  public final class BundleCompat {
-    method public static android.os.IBinder? getBinder(android.os.Bundle, String?);
-    method public static void putBinder(android.os.Bundle, String?, android.os.IBinder?);
+  @Deprecated public final class BundleCompat {
+    method @Deprecated public static android.os.IBinder? getBinder(android.os.Bundle, String?);
+    method @Deprecated public static void putBinder(android.os.Bundle, String?, android.os.IBinder?);
   }
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ComponentActivity extends android.app.Activity implements androidx.core.view.KeyEventDispatcher.Component androidx.lifecycle.LifecycleOwner {
@@ -903,6 +903,7 @@
     method public void deleteUnlistedNotificationChannels(java.util.Collection<java.lang.String!>);
     method public static androidx.core.app.NotificationManagerCompat from(android.content.Context);
     method public java.util.List<android.service.notification.StatusBarNotification!> getActiveNotifications();
+    method public int getCurrentInterruptionFilter();
     method public static java.util.Set<java.lang.String!> getEnabledListenerPackages(android.content.Context);
     method public int getImportance();
     method public android.app.NotificationChannel? getNotificationChannel(String);
@@ -927,6 +928,11 @@
     field public static final int IMPORTANCE_MIN = 1; // 0x1
     field public static final int IMPORTANCE_NONE = 0; // 0x0
     field public static final int IMPORTANCE_UNSPECIFIED = -1000; // 0xfffffc18
+    field public static final int INTERRUPTION_FILTER_ALARMS = 4; // 0x4
+    field public static final int INTERRUPTION_FILTER_ALL = 1; // 0x1
+    field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
+    field public static final int INTERRUPTION_FILTER_PRIORITY = 2; // 0x2
+    field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0
   }
 
   public static class NotificationManagerCompat.NotificationWithIdAndTag {
@@ -2178,10 +2184,12 @@
   }
 
   public final class BundleCompat {
+    method public static android.os.IBinder? getBinder(android.os.Bundle, String?);
     method public static <T> T? getParcelable(android.os.Bundle, String?, Class<T!>);
     method public static android.os.Parcelable![]? getParcelableArray(android.os.Bundle, String?, Class<? extends android.os.Parcelable>);
     method public static <T> java.util.ArrayList<T!>? getParcelableArrayList(android.os.Bundle, String?, Class<? extends T>);
     method public static <T> android.util.SparseArray<T!>? getSparseParcelableArray(android.os.Bundle, String?, Class<? extends T>);
+    method public static void putBinder(android.os.Bundle, String?, android.os.IBinder?);
   }
 
   public final class CancellationSignal {
diff --git a/core/core/build.gradle b/core/core/build.gradle
index d5fc97b..fa351a1 100644
--- a/core/core/build.gradle
+++ b/core/core/build.gradle
@@ -11,6 +11,7 @@
     // Atomically versioned.
     constraints {
         implementation(project(":core:core-ktx"))
+        implementation(project(":core:core-testing"))
     }
 
     api("androidx.annotation:annotation:1.6.0")
diff --git a/core/core/lint-baseline.xml b/core/core/lint-baseline.xml
index 1a9a2b2..13cdc1d 100644
--- a/core/core/lint-baseline.xml
+++ b/core/core/lint-baseline.xml
@@ -3356,6 +3356,9 @@
         errorLine2="                                       ~~~~~~~~~">
         <location
             file="src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java"/>
+        <location
+            file="src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java"
+            message="Setter here"/>
     </issue>
 
     <issue
@@ -3365,6 +3368,9 @@
         errorLine2="                                ~~~~~~~~~~~~~~~~~">
         <location
             file="src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java"/>
+        <location
+            file="src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java"
+            message="Setter here"/>
     </issue>
 
     <issue
@@ -3374,6 +3380,9 @@
         errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java"/>
+        <location
+            file="src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java"
+            message="Setter here"/>
     </issue>
 
     <issue
@@ -3383,6 +3392,9 @@
         errorLine2="                                       ~~~~~~~~~~~">
         <location
             file="src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java"/>
+        <location
+            file="src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java"
+            message="Setter here"/>
     </issue>
 
     <issue
@@ -3392,6 +3404,9 @@
         errorLine2="                                       ~~~~~~~~~~~~">
         <location
             file="src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java"/>
+        <location
+            file="src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java"
+            message="Setter here"/>
     </issue>
 
     <issue
@@ -3410,6 +3425,9 @@
         errorLine2="                                       ~~~~~~~~~~~~~~~~~~">
         <location
             file="src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java"/>
+        <location
+            file="src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java"
+            message="Setter here"/>
     </issue>
 
     <issue
@@ -3419,6 +3437,9 @@
         errorLine2="                                       ~~~~~~~~~~~~~~~~~">
         <location
             file="src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java"/>
+        <location
+            file="src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java"
+            message="Setter here"/>
     </issue>
 
     <issue
diff --git a/core/core/src/androidTest/java/androidx/core/app/NotificationManagerCompatTest.java b/core/core/src/androidTest/java/androidx/core/app/NotificationManagerCompatTest.java
index 6a245b7..28b21f8 100644
--- a/core/core/src/androidTest/java/androidx/core/app/NotificationManagerCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/app/NotificationManagerCompatTest.java
@@ -31,7 +31,6 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -1173,4 +1172,32 @@
             assertEquals(0, notifs.size());
         }
     }
+
+    @Test
+    public void testInterruptionFilterConstantCorrespondence() {
+        assertEquals(NotificationManager.INTERRUPTION_FILTER_UNKNOWN,
+                NotificationManagerCompat.INTERRUPTION_FILTER_UNKNOWN);
+        assertEquals(NotificationManager.INTERRUPTION_FILTER_ALL,
+                NotificationManagerCompat.INTERRUPTION_FILTER_ALL);
+        assertEquals(NotificationManager.INTERRUPTION_FILTER_PRIORITY,
+                NotificationManagerCompat.INTERRUPTION_FILTER_PRIORITY);
+        assertEquals(NotificationManager.INTERRUPTION_FILTER_NONE,
+                NotificationManagerCompat.INTERRUPTION_FILTER_NONE);
+        assertEquals(NotificationManager.INTERRUPTION_FILTER_ALARMS,
+                NotificationManagerCompat.INTERRUPTION_FILTER_ALARMS);
+    }
+
+    @Test
+    public void testGetCurrentInterruptionFilter() {
+        NotificationManager fakeManager = mock(NotificationManager.class);
+        NotificationManagerCompat notificationManager = new NotificationManagerCompat(fakeManager,
+                mContext);
+        int filter = notificationManager.getCurrentInterruptionFilter();
+
+        if (Build.VERSION.SDK_INT >= 23) {
+            verify(fakeManager, times(1)).getCurrentInterruptionFilter();
+        } else {
+            assertEquals(NotificationManagerCompat.INTERRUPTION_FILTER_UNKNOWN, filter);
+        }
+    }
 }
\ No newline at end of file
diff --git a/core/core/src/androidTest/java/androidx/core/os/BundleCompatTest.java b/core/core/src/androidTest/java/androidx/core/os/BundleCompatTest.java
index d8cd469..778d43b 100644
--- a/core/core/src/androidTest/java/androidx/core/os/BundleCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/os/BundleCompatTest.java
@@ -22,7 +22,9 @@
 
 import android.content.Intent;
 import android.content.pm.Signature;
+import android.os.Binder;
 import android.os.Bundle;
+import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.SparseArray;
@@ -181,4 +183,13 @@
         p.setDataPosition(0);
         bundle.readFromParcel(p);
     }
+
+    @Test
+    public void getBinder() {
+        IBinder binder = new Binder();
+        Bundle bundle = new Bundle();
+        BundleCompat.putBinder(bundle, "binder", binder);
+        IBinder result = BundleCompat.getBinder(bundle, "binder");
+        assertEquals(binder, result);
+    }
 }
diff --git a/core/core/src/androidTest/java/androidx/core/widget/NestedScrollViewWithCollapsingToolbarTest.java b/core/core/src/androidTest/java/androidx/core/widget/NestedScrollViewWithCollapsingToolbarTest.java
index 74a1306..2885cc3 100644
--- a/core/core/src/androidTest/java/androidx/core/widget/NestedScrollViewWithCollapsingToolbarTest.java
+++ b/core/core/src/androidTest/java/androidx/core/widget/NestedScrollViewWithCollapsingToolbarTest.java
@@ -28,6 +28,7 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
@@ -277,7 +278,229 @@
         // Assert
         // Should trigger a scroll event in parent. Note: OnStartNestedScroll is triggered on
         // key action down only, not key action up, so that is why the count is one.
-        // Should trigger in parent of scroll event.
+        assertEquals(1, mParentNestedScrollView.getOnStartNestedScrollCount());
+        // Should not trigger in child (because child doesn't have its own inner NestedScrollView).
+        assertEquals(0, mChildNestedScrollView.getOnStartNestedScrollCount());
+    }
+
+    @Test
+    public void isOnStartNestedScrollCalled_keyboardPageDownInChild_calledInParent() {
+        // Arrange
+        setupNestedScrollViewInNestedScrollView(
+                ApplicationProvider.getApplicationContext(),
+                100,
+                600);
+
+        // Act
+        mChildNestedScrollView.requestFocus();
+        KeyEvent keyEventPressDown = new KeyEvent(
+                0,
+                0,
+                KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_PAGE_DOWN,
+                0);
+        mChildNestedScrollView.executeKeyEvent(keyEventPressDown);
+
+        KeyEvent keyEventPressUp = new KeyEvent(
+                0,
+                0,
+                KeyEvent.ACTION_UP,
+                KeyEvent.KEYCODE_PAGE_DOWN,
+                0);
+        mChildNestedScrollView.executeKeyEvent(keyEventPressUp);
+
+        // Assert
+        // Should trigger a scroll event in parent. Note: OnStartNestedScroll is triggered on
+        // key action down only, not key action up, so that is why the count is one.
+        assertEquals(1, mParentNestedScrollView.getOnStartNestedScrollCount());
+        // Should not trigger in child (because child doesn't have its own inner NestedScrollView).
+        assertEquals(0, mChildNestedScrollView.getOnStartNestedScrollCount());
+    }
+
+    @Test
+    public void isOnStartNestedScrollCalled_keyboardPageUpInChild_calledInParent() {
+        // Arrange
+        setupNestedScrollViewInNestedScrollView(
+                ApplicationProvider.getApplicationContext(),
+                100,
+                600);
+
+        // Move to bottom of the child NestedScrollView, so we can scroll up and not go past child.
+        int scrollRange = mChildNestedScrollView.getScrollRange();
+        mChildNestedScrollView.scrollTo(0, scrollRange);
+
+        // Act
+        mChildNestedScrollView.requestFocus();
+        KeyEvent keyEventPressDown = new KeyEvent(
+                0,
+                0,
+                KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_PAGE_UP,
+                0);
+        mChildNestedScrollView.executeKeyEvent(keyEventPressDown);
+
+        KeyEvent keyEventPressUp = new KeyEvent(
+                0,
+                0,
+                KeyEvent.ACTION_UP,
+                KeyEvent.KEYCODE_PAGE_UP,
+                0);
+        mChildNestedScrollView.executeKeyEvent(keyEventPressUp);
+
+        // Assert
+        // Should trigger a scroll event in parent. Note: OnStartNestedScroll is triggered on
+        // key action down only, not key action up, so that is why the count is one.
+        assertEquals(1, mParentNestedScrollView.getOnStartNestedScrollCount());
+        // Should not trigger in child (because child doesn't have its own inner NestedScrollView).
+        assertEquals(0, mChildNestedScrollView.getOnStartNestedScrollCount());
+    }
+
+    @Test
+    public void isOnStartNestedScrollCalled_keyboardMoveEndInChild_calledInParent() {
+        // Arrange
+        setupNestedScrollViewInNestedScrollView(
+                ApplicationProvider.getApplicationContext(),
+                100,
+                600);
+
+        // Act
+        mChildNestedScrollView.requestFocus();
+        KeyEvent keyEventPressDown = new KeyEvent(
+                0,
+                0,
+                KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_MOVE_END,
+                0);
+        mChildNestedScrollView.executeKeyEvent(keyEventPressDown);
+
+        KeyEvent keyEventPressUp = new KeyEvent(
+                0,
+                0,
+                KeyEvent.ACTION_UP,
+                KeyEvent.KEYCODE_MOVE_END,
+                0);
+        mChildNestedScrollView.executeKeyEvent(keyEventPressUp);
+
+        // Assert
+        // Should trigger a scroll event in parent. Note: OnStartNestedScroll is triggered on
+        // key action down only, not key action up, so that is why the count is one.
+        assertEquals(1, mParentNestedScrollView.getOnStartNestedScrollCount());
+        // Should not trigger in child (because child doesn't have its own inner NestedScrollView).
+        assertEquals(0, mChildNestedScrollView.getOnStartNestedScrollCount());
+    }
+
+
+    @Test
+    public void isOnStartNestedScrollCalled_keyboardMoveHomeInChild_calledInParent() {
+        // Arrange
+        setupNestedScrollViewInNestedScrollView(
+                ApplicationProvider.getApplicationContext(),
+                100,
+                600);
+
+        // Move to bottom of the child NestedScrollView, so we can scroll up and not go past child.
+        int scrollRange = mChildNestedScrollView.getScrollRange();
+        mChildNestedScrollView.scrollTo(0, scrollRange);
+
+        // Act
+        mChildNestedScrollView.requestFocus();
+        KeyEvent keyEventPressDown = new KeyEvent(
+                0,
+                0,
+                KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_MOVE_HOME,
+                0);
+        mChildNestedScrollView.executeKeyEvent(keyEventPressDown);
+
+        KeyEvent keyEventPressUp = new KeyEvent(
+                0,
+                0,
+                KeyEvent.ACTION_UP,
+                KeyEvent.KEYCODE_MOVE_HOME,
+                0);
+        mChildNestedScrollView.executeKeyEvent(keyEventPressUp);
+
+        // Assert
+        // Should trigger a scroll event in parent. Note: OnStartNestedScroll is triggered on
+        // key action down only, not key action up, so that is why the count is one.
+        assertEquals(1, mParentNestedScrollView.getOnStartNestedScrollCount());
+        // Should not trigger in child (because child doesn't have its own inner NestedScrollView).
+        assertEquals(0, mChildNestedScrollView.getOnStartNestedScrollCount());
+    }
+
+
+    @Test
+    public void isOnStartNestedScrollCalled_keyboardSpaceBarInChild_calledInParent() {
+        // Arrange
+        setupNestedScrollViewInNestedScrollView(
+                ApplicationProvider.getApplicationContext(),
+                100,
+                600);
+
+        // Act
+        mChildNestedScrollView.requestFocus();
+        KeyEvent keyEventPressDown = new KeyEvent(
+                0,
+                0,
+                KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_SPACE,
+                0);
+        mChildNestedScrollView.executeKeyEvent(keyEventPressDown);
+
+        KeyEvent keyEventPressUp = new KeyEvent(
+                0,
+                0,
+                KeyEvent.ACTION_UP,
+                KeyEvent.KEYCODE_SPACE,
+                0);
+        mChildNestedScrollView.executeKeyEvent(keyEventPressUp);
+
+        // Assert
+        // Should trigger a scroll event in parent. Note: OnStartNestedScroll is triggered on
+        // key action down only, not key action up, so that is why the count is one.
+        assertEquals(1, mParentNestedScrollView.getOnStartNestedScrollCount());
+        // Should not trigger in child (because child doesn't have its own inner NestedScrollView).
+        assertEquals(0, mChildNestedScrollView.getOnStartNestedScrollCount());
+    }
+
+
+    @Test
+    public void isOnStartNestedScrollCalled_keyboardShiftSpaceBarInChild_calledInParent() {
+        // Arrange
+        setupNestedScrollViewInNestedScrollView(
+                ApplicationProvider.getApplicationContext(),
+                100,
+                600);
+
+        // Move to bottom of the child NestedScrollView, so we can scroll up and not go past child.
+        int scrollRange = mChildNestedScrollView.getScrollRange();
+        mChildNestedScrollView.scrollTo(0, scrollRange);
+
+        // Act
+        mChildNestedScrollView.requestFocus();
+        KeyEvent keyEventPressDown = new KeyEvent(
+                0,
+                0,
+                KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_SPACE,
+                0,
+                KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_LEFT_ON
+        );
+        mChildNestedScrollView.executeKeyEvent(keyEventPressDown);
+
+        KeyEvent keyEventPressUp = new KeyEvent(
+                0,
+                0,
+                KeyEvent.ACTION_UP,
+                KeyEvent.KEYCODE_SPACE,
+                0,
+                KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_LEFT_ON
+        );
+        mChildNestedScrollView.executeKeyEvent(keyEventPressUp);
+
+        // Assert
+        // Should trigger a scroll event in parent. Note: OnStartNestedScroll is triggered on
+        // key action down only, not key action up, so that is why the count is one.
         assertEquals(1, mParentNestedScrollView.getOnStartNestedScrollCount());
         // Should not trigger in child (because child doesn't have its own inner NestedScrollView).
         assertEquals(0, mChildNestedScrollView.getOnStartNestedScrollCount());
@@ -321,8 +544,6 @@
         mChildNestedScrollView.executeKeyEvent(keyEventPressUp);
 
         // Assert
-        // Should trigger in parent of scroll event. Note: OnStartNestedScroll is triggered on
-        // key action down only, not key action up, so that is why the count is one.
         assertEquals(0, mParentNestedScrollView.getOnStartNestedScrollCount());
         // Should not trigger in child (because child doesn't have its own inner NestedScrollView).
         assertEquals(0, mChildNestedScrollView.getOnStartNestedScrollCount());
@@ -358,9 +579,6 @@
         mChildNestedScrollView.executeKeyEvent(keyEventPressUp);
 
         // Assert
-        // Should trigger in parent of scroll event. Note: OnStartNestedScroll is triggered on
-        // key action down only, not key action up, so that is why the count is one.
-        // Should trigger in parent of scroll event.
         assertEquals(0, mParentNestedScrollView.getOnStartNestedScrollCount());
         // Should not trigger in child (because child doesn't have its own inner NestedScrollView).
         assertEquals(0, mChildNestedScrollView.getOnStartNestedScrollCount());
@@ -397,9 +615,6 @@
         mChildNestedScrollView.executeKeyEvent(keyEventPressUp);
 
         // Assert
-        // Should trigger in parent of scroll event. Note: OnStartNestedScroll is triggered on
-        // key action down only, not key action up, so that is why the count is one.
-        // Should trigger in parent of scroll event.
         assertEquals(0, mParentNestedScrollView.getOnStartNestedScrollCount());
         // Should not trigger in child (because child doesn't have its own inner NestedScrollView).
         assertEquals(0, mChildNestedScrollView.getOnStartNestedScrollCount());
@@ -438,9 +653,77 @@
         mChildNestedScrollView.executeKeyEvent(keyEventPressUp);
 
         // Assert
-        // Should trigger in parent of scroll event. Note: OnStartNestedScroll is triggered on
-        // key action down only, not key action up, so that is why the count is one.
-        // Should trigger in parent of scroll event.
+        assertEquals(0, mParentNestedScrollView.getOnStartNestedScrollCount());
+        // Should not trigger in child (because child doesn't have its own inner NestedScrollView).
+        assertEquals(0, mChildNestedScrollView.getOnStartNestedScrollCount());
+    }
+
+
+    @Test
+    public void isOnStartNestedScrollCalled_keyboardPageUpInChildPastTop_notCalledInParent() {
+        // Arrange
+        setupNestedScrollViewInNestedScrollView(
+                ApplicationProvider.getApplicationContext(),
+                100,
+                600);
+
+        // Act
+        mChildNestedScrollView.requestFocus();
+        KeyEvent keyEventPressPageDown = new KeyEvent(
+                0,
+                0,
+                KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_PAGE_UP,
+                0
+        );
+        mChildNestedScrollView.executeKeyEvent(keyEventPressPageDown);
+
+        KeyEvent keyEventPressPageUp = new KeyEvent(
+                0,
+                0,
+                KeyEvent.ACTION_UP,
+                KeyEvent.KEYCODE_PAGE_UP,
+                0
+        );
+        mChildNestedScrollView.executeKeyEvent(keyEventPressPageUp);
+
+        // Assert
+        assertEquals(0, mParentNestedScrollView.getOnStartNestedScrollCount());
+        // Should not trigger in child (because child doesn't have its own inner NestedScrollView).
+        assertEquals(0, mChildNestedScrollView.getOnStartNestedScrollCount());
+    }
+
+    @Test
+    public void isOnStartNestedScrollCalled_keyboardPageDownInChildPastBottom_notCalledInParent() {
+        // Arrange
+        setupNestedScrollViewInNestedScrollView(
+                ApplicationProvider.getApplicationContext(),
+                100,
+                600);
+        // Move to bottom of the child NestedScrollView, so we can try scrolling past it.
+        int scrollRange = mChildNestedScrollView.getScrollRange();
+        mChildNestedScrollView.scrollTo(0, scrollRange);
+
+        mChildNestedScrollView.requestFocus();
+        KeyEvent keyEventPressDown = new KeyEvent(
+                0,
+                0,
+                KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_PAGE_DOWN,
+                0
+        );
+        mChildNestedScrollView.executeKeyEvent(keyEventPressDown);
+
+        KeyEvent keyEventPressUp = new KeyEvent(
+                0,
+                0,
+                KeyEvent.ACTION_UP,
+                KeyEvent.KEYCODE_PAGE_DOWN,
+                0
+        );
+        mChildNestedScrollView.executeKeyEvent(keyEventPressUp);
+
+        // Assert
         assertEquals(0, mParentNestedScrollView.getOnStartNestedScrollCount());
         // Should not trigger in child (because child doesn't have its own inner NestedScrollView).
         assertEquals(0, mChildNestedScrollView.getOnStartNestedScrollCount());
@@ -475,9 +758,6 @@
         mChildNestedScrollView.executeKeyEvent(keyEventPressUp);
 
         // Assert
-        // Should trigger in parent of scroll event. Note: OnStartNestedScroll is triggered on
-        // key action down only, not key action up, so that is why the count is one.
-        // Should trigger in parent of scroll event.
         assertEquals(0, mParentNestedScrollView.getOnStartNestedScrollCount());
         // Should not trigger in child (because child doesn't have its own inner NestedScrollView).
         assertEquals(0, mChildNestedScrollView.getOnStartNestedScrollCount());
@@ -513,9 +793,6 @@
         mChildNestedScrollView.executeKeyEvent(keyEventPressUp);
 
         // Assert
-        // Should trigger in parent of scroll event. Note: OnStartNestedScroll is triggered on
-        // key action down only, not key action up, so that is why the count is one.
-        // Should trigger in parent of scroll event.
         assertEquals(0, mParentNestedScrollView.getOnStartNestedScrollCount());
         // Should not trigger in child (because child doesn't have its own inner NestedScrollView).
         assertEquals(0, mChildNestedScrollView.getOnStartNestedScrollCount());
@@ -701,7 +978,12 @@
         }
 
         @Override
-        public boolean onStartNestedScroll(View child, View target, int axes, int type) {
+        public boolean onStartNestedScroll(
+                @NonNull View child,
+                @NonNull View target,
+                int axes,
+                int type
+        ) {
             mOnStartNestedScrollCount++;
             return super.onStartNestedScroll(child, target, axes, type);
         }
diff --git a/core/core/src/main/java/androidx/core/app/BundleCompat.java b/core/core/src/main/java/androidx/core/app/BundleCompat.java
index 03cadea..d632972 100644
--- a/core/core/src/main/java/androidx/core/app/BundleCompat.java
+++ b/core/core/src/main/java/androidx/core/app/BundleCompat.java
@@ -16,85 +16,20 @@
 
 package androidx.core.app;
 
-import android.annotation.SuppressLint;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.util.Log;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 
 /**
  * Helper for accessing features in {@link Bundle}.
+ *
+ * @deprecated Replaced with {@link androidx.core.os.BundleCompat}.
  */
+@Deprecated
 public final class BundleCompat {
 
-    @SuppressLint("BanUncheckedReflection") // Only called prior to API 18
-    static class BeforeApi18Impl {
-        private static final String TAG = "BundleCompatBaseImpl";
-
-        private static Method sGetIBinderMethod;
-        private static boolean sGetIBinderMethodFetched;
-
-        private static Method sPutIBinderMethod;
-        private static boolean sPutIBinderMethodFetched;
-
-        private BeforeApi18Impl() {
-        }
-
-        public static IBinder getBinder(Bundle bundle, String key) {
-            if (!sGetIBinderMethodFetched) {
-                try {
-                    sGetIBinderMethod = Bundle.class.getMethod("getIBinder", String.class);
-                    sGetIBinderMethod.setAccessible(true);
-                } catch (NoSuchMethodException e) {
-                    Log.i(TAG, "Failed to retrieve getIBinder method", e);
-                }
-                sGetIBinderMethodFetched = true;
-            }
-
-            if (sGetIBinderMethod != null) {
-                try {
-                    return (IBinder) sGetIBinderMethod.invoke(bundle, key);
-                } catch (InvocationTargetException | IllegalAccessException
-                        | IllegalArgumentException e) {
-                    Log.i(TAG, "Failed to invoke getIBinder via reflection", e);
-                    sGetIBinderMethod = null;
-                }
-            }
-            return null;
-        }
-
-        public static void putBinder(Bundle bundle, String key, IBinder binder) {
-            if (!sPutIBinderMethodFetched) {
-                try {
-                    sPutIBinderMethod =
-                            Bundle.class.getMethod("putIBinder", String.class, IBinder.class);
-                    sPutIBinderMethod.setAccessible(true);
-                } catch (NoSuchMethodException e) {
-                    Log.i(TAG, "Failed to retrieve putIBinder method", e);
-                }
-                sPutIBinderMethodFetched = true;
-            }
-
-            if (sPutIBinderMethod != null) {
-                try {
-                    sPutIBinderMethod.invoke(bundle, key, binder);
-                } catch (InvocationTargetException | IllegalAccessException
-                        | IllegalArgumentException e) {
-                    Log.i(TAG, "Failed to invoke putIBinder via reflection", e);
-                    sPutIBinderMethod = null;
-                }
-            }
-        }
-    }
-
     private BundleCompat() {}
 
     /**
@@ -106,11 +41,7 @@
      */
     @Nullable
     public static IBinder getBinder(@NonNull Bundle bundle, @Nullable String key) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            return Api18Impl.getBinder(bundle, key);
-        } else {
-            return BeforeApi18Impl.getBinder(bundle, key);
-        }
+        return androidx.core.os.BundleCompat.getBinder(bundle, key);
     }
 
     /**
@@ -122,27 +53,6 @@
      */
     public static void putBinder(@NonNull Bundle bundle, @Nullable String key,
             @Nullable IBinder binder) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            Api18Impl.putBinder(bundle, key, binder);
-        } else {
-            BeforeApi18Impl.putBinder(bundle, key, binder);
-        }
-    }
-
-    @RequiresApi(18)
-    static class Api18Impl {
-        private Api18Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static IBinder getBinder(Bundle bundle, String key) {
-            return bundle.getBinder(key);
-        }
-
-        @DoNotInline
-        static void putBinder(Bundle bundle, String key, IBinder value) {
-            bundle.putBinder(key, value);
-        }
+        androidx.core.os.BundleCompat.putBinder(bundle, key, binder);
     }
 }
diff --git a/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java b/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java
index 4e5e902..7ed0fcf 100644
--- a/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java
@@ -125,6 +125,41 @@
     private static SideChannelManager sSideChannelManager;
 
     /**
+     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
+     *     Normal interruption filter - no notifications are suppressed.
+     */
+    public static final int INTERRUPTION_FILTER_ALL = 1;
+
+    /**
+     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
+     *     Priority interruption filter - all notifications are suppressed except those that match
+     *     the priority criteria. Some audio streams are muted. See
+     *     {@link Policy#priorityCallSenders}, {@link Policy#priorityCategories},
+     *     {@link Policy#priorityMessageSenders} to define or query this criteria. Users can
+     *     additionally specify packages that can bypass this interruption filter.
+     */
+    public static final int INTERRUPTION_FILTER_PRIORITY = 2;
+
+    /**
+     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
+     *     No interruptions filter - all notifications are suppressed and all audio streams (except
+     *     those used for phone calls) and vibrations are muted.
+     */
+    public static final int INTERRUPTION_FILTER_NONE = 3;
+
+    /**
+     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
+     *     Alarms only interruption filter - all notifications except those of category
+     *     {@link Notification#CATEGORY_ALARM} are suppressed. Some audio streams are muted.
+     */
+    public static final int INTERRUPTION_FILTER_ALARMS = 4;
+
+    /** {@link #getCurrentInterruptionFilter() Interruption filter} constant -
+     *     returned when the value is unavailable for any reason.
+     */
+    public static final int INTERRUPTION_FILTER_UNKNOWN = 0;
+
+    /**
      * Value signifying that the user has not expressed an importance.
      *
      * This value is for persisting preferences, and should never be associated with
@@ -772,6 +807,22 @@
     }
 
     /**
+     * Gets the current notification interruption filter.
+     * <p>
+     * The interruption filter defines which notifications are allowed to
+     * interrupt the user (e.g. via sound &amp; vibration) and is applied
+     * globally.
+     */
+    public int getCurrentInterruptionFilter() {
+        if (Build.VERSION.SDK_INT < 23) {
+            // Prior to API 23, Interruption Filters were not implemented, so we return
+            // unknown filter level.
+            return INTERRUPTION_FILTER_UNKNOWN;
+        }
+        return Api23Impl.getCurrentInterruptionFilter(mNotificationManager);
+    }
+
+    /**
      * Push a notification task for distribution to notification side channels.
      */
     private void pushSideChannelQueue(Task task) {
@@ -1160,6 +1211,12 @@
             }
             return Arrays.asList(notifs);
         }
+
+        @DoNotInline
+        static int getCurrentInterruptionFilter(
+                NotificationManager notificationManager) {
+            return notificationManager.getCurrentInterruptionFilter();
+        }
     }
 
     /**
diff --git a/core/core/src/main/java/androidx/core/os/BundleCompat.java b/core/core/src/main/java/androidx/core/os/BundleCompat.java
index 15bb312..f68cf17 100644
--- a/core/core/src/main/java/androidx/core/os/BundleCompat.java
+++ b/core/core/src/main/java/androidx/core/os/BundleCompat.java
@@ -17,8 +17,11 @@
 package androidx.core.os;
 
 import android.annotation.SuppressLint;
+import android.os.Build;
 import android.os.Bundle;
+import android.os.IBinder;
 import android.os.Parcelable;
+import android.util.Log;
 import android.util.SparseArray;
 
 import androidx.annotation.DoNotInline;
@@ -27,6 +30,8 @@
 import androidx.annotation.OptIn;
 import androidx.annotation.RequiresApi;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 
 /**
@@ -44,12 +49,11 @@
      *     <li>A {@code null} value is explicitly associated with the key.
      *     <li>The object is not of type {@code clazz}.
      * </ul>
-     *
-     * <p><b>Note: </b> if the expected value is not a class provided by the Android platform,
-     * you must call {@link Bundle#setClassLoader(ClassLoader)} with the proper {@link ClassLoader}
-     * first.
-     * Otherwise, this method might throw an exception or return {@code null}.
-     *
+     * <p>
+     * <b>Note: </b> if the expected value is not a class provided by the Android platform, you
+     * must call {@link Bundle#setClassLoader(ClassLoader)} with the proper {@link ClassLoader}
+     * first. Otherwise, this method might throw an exception or return {@code null}.
+     * <p>
      * Compatibility behavior:
      * <ul>
      *     <li>{@link BuildCompat#isAtLeastU() Android U and later}, this method matches platform
@@ -83,12 +87,11 @@
      *     <li>A {@code null} value is explicitly associated with the key.
      *     <li>The object is not of type {@code clazz}.
      * </ul>
-     *
-     * <p><b>Note: </b> if the expected value is not a class provided by the Android platform,
-     * you must call {@link Bundle#setClassLoader(ClassLoader)} with the proper {@link ClassLoader}
-     * first.
-     * Otherwise, this method might throw an exception or return {@code null}.
-     *
+     * <p>
+     * <b>Note: </b> if the expected value is not a class provided by the Android platform, you
+     * must call {@link Bundle#setClassLoader(ClassLoader)} with the proper {@link ClassLoader}
+     * first. Otherwise, this method might throw an exception or return {@code null}.
+     * <p>
      * Compatibility behavior:
      * <ul>
      *     <li>{@link BuildCompat#isAtLeastU() Android U and later}, this method matches platform
@@ -121,12 +124,11 @@
      *     <li>A {@code null} value is explicitly associated with the key.
      *     <li>The object is not of type {@code clazz}.
      * </ul>
-     *
-     * <p><b>Note: </b> if the expected value is not a class provided by the Android platform,
-     * you must call {@link Bundle#setClassLoader(ClassLoader)} with the proper {@link ClassLoader}
-     * first.
-     * Otherwise, this method might throw an exception or return {@code null}.
-     *
+     * <p>
+     * <b>Note: </b> if the expected value is not a class provided by the Android platform, you
+     * must call {@link Bundle#setClassLoader(ClassLoader)} with the proper {@link ClassLoader}
+     * first. Otherwise, this method might throw an exception or return {@code null}.
+     * <p>
      * Compatibility behavior:
      * <ul>
      *     <li>{@link BuildCompat#isAtLeastU() Android U and later}, this method matches platform
@@ -135,7 +137,7 @@
      * </ul>
      *
      * @param in The bundle to retrieve from.
-     * @param key   a String, or {@code null}
+     * @param key a String, or {@code null}
      * @param clazz The type of the items inside the array list. This is only verified when
      *     unparceling.
      * @return an ArrayList<T> value, or {@code null}
@@ -186,6 +188,40 @@
         }
     }
 
+    /**
+     * A convenience method to handle getting an {@link IBinder} inside a {@link Bundle} for all
+     * Android versions.
+     *
+     * @param bundle The bundle to get the {@link IBinder}.
+     * @param key The key to use while getting the {@link IBinder}.
+     * @return The {@link IBinder} that was obtained.
+     */
+    @Nullable
+    public static IBinder getBinder(@NonNull Bundle bundle, @Nullable String key) {
+        if (Build.VERSION.SDK_INT >= 33) {
+            return Api18Impl.getBinder(bundle, key);
+        } else {
+            return BeforeApi18Impl.getBinder(bundle, key);
+        }
+    }
+
+    /**
+     * A convenience method to handle putting an {@link IBinder} inside a {@link Bundle} for all
+     * Android versions.
+     *
+     * @param bundle The bundle to insert the {@link IBinder}.
+     * @param key The key to use while putting the {@link IBinder}.
+     * @param binder The {@link IBinder} to put.
+     */
+    public static void putBinder(@NonNull Bundle bundle, @Nullable String key,
+            @Nullable IBinder binder) {
+        if (Build.VERSION.SDK_INT >= 18) {
+            Api18Impl.putBinder(bundle, key, binder);
+        } else {
+            BeforeApi18Impl.putBinder(bundle, key, binder);
+        }
+    }
+
     @RequiresApi(33)
     static class Api33Impl {
         private Api33Impl() {
@@ -216,4 +252,84 @@
             return in.getSparseParcelableArray(key, clazz);
         }
     }
+
+    @RequiresApi(18)
+    static class Api18Impl {
+        private Api18Impl() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static IBinder getBinder(Bundle bundle, String key) {
+            return bundle.getBinder(key);
+        }
+
+        @DoNotInline
+        static void putBinder(Bundle bundle, String key, IBinder value) {
+            bundle.putBinder(key, value);
+        }
+    }
+
+    @SuppressLint("BanUncheckedReflection") // Only called prior to API 18
+    static class BeforeApi18Impl {
+        private static final String TAG = "BundleCompat";
+
+        private static Method sGetIBinderMethod;
+        private static boolean sGetIBinderMethodFetched;
+
+        private static Method sPutIBinderMethod;
+        private static boolean sPutIBinderMethodFetched;
+
+        private BeforeApi18Impl() {
+            // This class is not instantiable.
+        }
+
+        @SuppressWarnings("JavaReflectionMemberAccess")
+        public static IBinder getBinder(Bundle bundle, String key) {
+            if (!sGetIBinderMethodFetched) {
+                try {
+                    sGetIBinderMethod = Bundle.class.getMethod("getIBinder", String.class);
+                    sGetIBinderMethod.setAccessible(true);
+                } catch (NoSuchMethodException e) {
+                    Log.i(TAG, "Failed to retrieve getIBinder method", e);
+                }
+                sGetIBinderMethodFetched = true;
+            }
+
+            if (sGetIBinderMethod != null) {
+                try {
+                    return (IBinder) sGetIBinderMethod.invoke(bundle, key);
+                } catch (InvocationTargetException | IllegalAccessException
+                         | IllegalArgumentException e) {
+                    Log.i(TAG, "Failed to invoke getIBinder via reflection", e);
+                    sGetIBinderMethod = null;
+                }
+            }
+            return null;
+        }
+
+        @SuppressWarnings("JavaReflectionMemberAccess")
+        public static void putBinder(Bundle bundle, String key, IBinder binder) {
+            if (!sPutIBinderMethodFetched) {
+                try {
+                    sPutIBinderMethod =
+                            Bundle.class.getMethod("putIBinder", String.class, IBinder.class);
+                    sPutIBinderMethod.setAccessible(true);
+                } catch (NoSuchMethodException e) {
+                    Log.i(TAG, "Failed to retrieve putIBinder method", e);
+                }
+                sPutIBinderMethodFetched = true;
+            }
+
+            if (sPutIBinderMethod != null) {
+                try {
+                    sPutIBinderMethod.invoke(bundle, key, binder);
+                } catch (InvocationTargetException | IllegalAccessException
+                         | IllegalArgumentException e) {
+                    Log.i(TAG, "Failed to invoke putIBinder via reflection", e);
+                    sPutIBinderMethod = null;
+                }
+            }
+        }
+    }
 }
diff --git a/core/core/src/main/java/androidx/core/widget/NestedScrollView.java b/core/core/src/main/java/androidx/core/widget/NestedScrollView.java
index dd19e2d..2b0cdce 100644
--- a/core/core/src/main/java/androidx/core/widget/NestedScrollView.java
+++ b/core/core/src/main/java/androidx/core/widget/NestedScrollView.java
@@ -704,22 +704,34 @@
         if (event.getAction() == KeyEvent.ACTION_DOWN) {
             switch (event.getKeyCode()) {
                 case KeyEvent.KEYCODE_DPAD_UP:
-                    if (!event.isAltPressed()) {
-                        handled = arrowScroll(View.FOCUS_UP);
-                    } else {
+                    if (event.isAltPressed()) {
                         handled = fullScroll(View.FOCUS_UP);
+                    } else {
+                        handled = arrowScroll(View.FOCUS_UP);
                     }
                     break;
                 case KeyEvent.KEYCODE_DPAD_DOWN:
-                    if (!event.isAltPressed()) {
-                        handled = arrowScroll(View.FOCUS_DOWN);
-                    } else {
+                    if (event.isAltPressed()) {
                         handled = fullScroll(View.FOCUS_DOWN);
+                    } else {
+                        handled = arrowScroll(View.FOCUS_DOWN);
                     }
                     break;
+                case KeyEvent.KEYCODE_PAGE_UP:
+                    handled = fullScroll(View.FOCUS_UP);
+                    break;
+                case KeyEvent.KEYCODE_PAGE_DOWN:
+                    handled = fullScroll(View.FOCUS_DOWN);
+                    break;
                 case KeyEvent.KEYCODE_SPACE:
                     pageScroll(event.isShiftPressed() ? View.FOCUS_UP : View.FOCUS_DOWN);
                     break;
+                case KeyEvent.KEYCODE_MOVE_HOME:
+                    pageScroll(View.FOCUS_UP);
+                    break;
+                case KeyEvent.KEYCODE_MOVE_END:
+                    pageScroll(View.FOCUS_DOWN);
+                    break;
             }
         }
 
diff --git a/credentials/credentials-play-services-auth/build.gradle b/credentials/credentials-play-services-auth/build.gradle
index f2ecf59..7fd1e0e 100644
--- a/credentials/credentials-play-services-auth/build.gradle
+++ b/credentials/credentials-play-services-auth/build.gradle
@@ -26,7 +26,7 @@
     api(libs.kotlinStdlib)
     api project(":credentials:credentials")
 
-    implementation("com.google.android.libraries.identity.googleid:googleid:0.0.2"){
+    implementation("com.google.android.libraries.identity.googleid:googleid:1.0.0"){
         exclude group: "androidx.credentials"
     }
 
diff --git a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerJavaTest.java b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerJavaTest.java
index 6689b7a..969f941 100644
--- a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerJavaTest.java
+++ b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerJavaTest.java
@@ -29,6 +29,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.google.android.gms.auth.api.identity.BeginSignInRequest;
+import com.google.android.libraries.identity.googleid.GetGoogleIdOption;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -109,8 +110,6 @@
 
     @Test
     public void convertRequestToPlayServices_setGoogleIdOptionRequestAndTrueAutoSelect_success() {
-        // TODO(b/270239625) fix pre u test cases for new GoogleIdOption signature
-        /*
         ActivityScenario<TestCredentialsActivity> activityScenario =
                 ActivityScenario.launch(TestCredentialsActivity.class);
 
@@ -119,7 +118,8 @@
                 .setNonce("nonce")
                 .setFilterByAuthorizedAccounts(true)
                 .setRequestVerifiedPhoneNumber(false)
-                .associatedLinkedAccounts("link_service_id", List.of("a", "b", "c"))
+                .associateLinkedAccounts("link_service_id", List.of("a", "b", "c"))
+                .setAutoSelectEnabled(true)
                 .build();
 
         activityScenario.onActivity(activity -> {
@@ -147,6 +147,5 @@
                     option.getIdTokenDepositionScopes());
 
         });
-        */
     }
 }
diff --git a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt
index f9cfd2c..9652061 100644
--- a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt
+++ b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt
@@ -28,6 +28,7 @@
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
+import com.google.android.libraries.identity.googleid.GetGoogleIdOption
 
 @RunWith(AndroidJUnit4::class)
 @SmallTest
@@ -78,8 +79,6 @@
 
     @Test
     fun convertRequestToPlayServices_setGoogleIdOptionRequest_success() {
-        // TODO(b/270239625) fix pre u test cases for new GoogleIdOption signature
-        /*
         val activityScenario = ActivityScenario.launch(
             TestCredentialsActivity::class.java
         )
@@ -89,7 +88,8 @@
             .setNonce("nonce")
             .setFilterByAuthorizedAccounts(true)
             .setRequestVerifiedPhoneNumber(false)
-            .associatedLinkedAccounts("link_service_id", listOf("a", "b", "c"))
+            .associateLinkedAccounts("link_service_id", listOf("a", "b", "c"))
+            .setAutoSelectEnabled(true)
             .build()
 
         activityScenario.onActivity { activity: TestCredentialsActivity? ->
@@ -116,6 +116,5 @@
             assertThat(actualOption.idTokenDepositionScopes)
                 .isEqualTo(option.idTokenDepositionScopes)
         }
-         */
     }
 }
\ No newline at end of file
diff --git a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/BeginSignInControllerUtility.kt b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/BeginSignInControllerUtility.kt
index e3e7c4f..b6416f5 100644
--- a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/BeginSignInControllerUtility.kt
+++ b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/BeginSignInControllerUtility.kt
@@ -72,8 +72,7 @@
                 } else if (option is GetGoogleIdOption) {
                     requestBuilder.setGoogleIdTokenRequestOptions(
                         convertToGoogleIdTokenOption(option))
-                    // TODO(b/270239625) add this bit to GID
-                    // autoSelect = autoSelect || option.isAutoSelectEnabled
+                    autoSelect = autoSelect || option.autoSelectEnabled
                 }
             }
             return requestBuilder
diff --git a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/CredentialProviderBeginSignInController.kt b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/CredentialProviderBeginSignInController.kt
index e1ca866..7b6ac57 100644
--- a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/CredentialProviderBeginSignInController.kt
+++ b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/controllers/BeginSignIn/CredentialProviderBeginSignInController.kt
@@ -228,7 +228,7 @@
         }
 
         if (response.profilePictureUri != null) {
-            cred.setProfilePictureUri(response.profilePictureUri.toString())
+            cred.setProfilePictureUri(response.profilePictureUri)
         }
 
         return cred.build()
diff --git a/datastore/datastore-core/src/commonMain/kotlin/androidx/datastore/core/DataStoreImpl.kt b/datastore/datastore-core/src/commonMain/kotlin/androidx/datastore/core/DataStoreImpl.kt
index 5612ced..386a01a 100644
--- a/datastore/datastore-core/src/commonMain/kotlin/androidx/datastore/core/DataStoreImpl.kt
+++ b/datastore/datastore-core/src/commonMain/kotlin/androidx/datastore/core/DataStoreImpl.kt
@@ -29,6 +29,7 @@
 import kotlinx.coroutines.SupervisorJob
 import kotlinx.coroutines.completeWith
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.conflate
 import kotlinx.coroutines.flow.dropWhile
 import kotlinx.coroutines.flow.emitAll
 import kotlinx.coroutines.flow.flow
@@ -76,14 +77,15 @@
          * Final. ReadException can transition to another ReadException, Data or Final.
          * Data can transition to another Data or Final. Final will not change.
          */
-        val latestVersionAtRead = coordinator.getVersion()
-        val currentDownStreamFlowState = inMemoryCache.currentState
-
-        if ((currentDownStreamFlowState !is Data) ||
-            (currentDownStreamFlowState.version < latestVersionAtRead)
-        ) {
-            // We need to send a read request because we don't have data yet / cached data is stale.
-            readActor.offer(Message.Read(currentDownStreamFlowState))
+        // the first read should not be blocked by ongoing writes, so it can be dirty read. If it is
+        // a unlocked read, the same value might be emitted to the flow again
+        val startState = readState(requireLock = false)
+        when (startState) {
+            is Data<T> -> emit(startState.value)
+            is UnInitialized -> error(BUG_MESSAGE)
+            is ReadException<T> -> throw startState.readException
+            // TODO(b/273990827): decide the contract of accessing when state is Final
+            is Final -> return@flow
         }
 
         emitAll(
@@ -91,16 +93,7 @@
                 // end the flow if we reach the final value
                 it !is Final
             }.dropWhile {
-                if (currentDownStreamFlowState is Data<T> && it is Data) {
-                    // we need to drop until initTasks are completed and set to null, and data
-                    // version >= the current version when entering flow
-                    it.version < latestVersionAtRead
-                } else {
-                    // we need to drop the last seen state since it was either an exception or
-                    // wasn't yet initialized. Since we sent a message to actor, we *will* see a
-                    // new value.
-                    it === currentDownStreamFlowState
-                }
+                it is Data && it.version <= startState.version
             }.map {
                 when (it) {
                     is ReadException<T> -> throw it.readException
@@ -125,6 +118,7 @@
         return ack.await()
     }
 
+    // cache is only set by the reads who have file lock, so cache always has stable data
     private val inMemoryCache = DataStoreInMemoryCache<T>()
 
     private val readAndInit = InitDataStore(initTasksList)
@@ -141,6 +135,11 @@
     private val writeActor = SimpleActor<Message.Update<T>>(
         scope = scope,
         onComplete = {
+            // TODO(b/267792241): remove it if updateCollector is better scoped
+            // no more reads so stop listening to file changes
+            if (::updateCollector.isInitialized) {
+                updateCollector.cancel()
+            }
             it?.let {
                 inMemoryCache.tryUpdate(Final(it))
             }
@@ -160,32 +159,25 @@
         handleUpdate(msg)
     }
 
-    private val readActor = SimpleActor<Message.Read<T>>(
-        scope = scope,
-        onComplete = {
-            // TODO(b/267792241): remove it if updateCollector is better scoped
-            // no more reads so stop listening to file changes
-            if (::updateCollector.isInitialized) {
-                updateCollector.cancel()
+    private suspend fun readState(requireLock: Boolean): State<T> =
+        withContext(scope.coroutineContext) {
+            if (inMemoryCache.currentState is Final) {
+                // if state is Final, just return it
+                inMemoryCache.currentState
+            } else {
+                try {
+                    // make sure we initialize properly before reading from file.
+                    readAndInitOrPropagateAndThrowFailure()
+                } catch (throwable: Throwable) {
+                    // init or read failed, it is already updated in the cached value
+                    // so we don't need to do anything.
+                    return@withContext ReadException(throwable, -1)
+                }
+                // after init, try to read again. If the init run for this block, it won't re-read
+                // the file and use cache, so this is an OK call to make wrt performance.
+                readDataAndUpdateCache(requireLock)
             }
-        },
-        onUndeliveredElement = { _, _ -> }
-    ) {
-        handleRead()
-    }
-
-    private suspend fun handleRead() {
-        try {
-            // make sure we initialize properly before reading from file.
-            readAndInitOrPropagateAndThrowFailure()
-            // after init, try to read again. If the init run for this block, it won't
-            // re-read the file and use cache, so this is an OK call to make wrt performance.
-            readDataAndUpdateCache()
-        } catch (throwable: Throwable) {
-            // init or read failed, it is already updated in the cached value
-            // so we don't need to do anything.
         }
-    }
 
     private suspend fun handleUpdate(update: Message.Update<T>) {
         update.ack.completeWith(
@@ -231,41 +223,64 @@
     }
 
     /**
-     * Reads the file and updates the cache unless current cached value is Data and
-     * its version is equal to the latest version.
+     * Reads the file and updates the cache unless current cached value is Data and its version is
+     * equal to the latest version, or it is unable to get lock.
      *
-     * Calling this method when state is UnInitialized is a bug and this method
-     * will throw if that happens.
+     * Calling this method when state is UnInitialized is a bug and this method will throw if that
+     * happens.
      */
-    private suspend fun readDataAndUpdateCache() {
+    private suspend fun readDataAndUpdateCache(requireLock: Boolean): State<T> {
         // Check if the cached version matches with shared memory counter
         val currentState = inMemoryCache.currentState
         // should not call this without initialization first running
         check(currentState !is UnInitialized) {
             BUG_MESSAGE
         }
-        val version = coordinator.getVersion()
+        val latestVersion = coordinator.getVersion()
         val cachedVersion = if (currentState is Data) currentState.version else -1
 
         // Return cached value if cached version is latest
-        if (currentState is Data && version == cachedVersion) {
-            return
+        if (currentState is Data && latestVersion == cachedVersion) {
+            return currentState
         }
-        val data = try {
-            coordinator.tryLock { locked ->
-                val result = readDataFromFileOrDefault()
-                Data(
-                    result,
-                    result.hashCode(),
-                    // use the latest version if we have the lock. Otherwise, use the
-                    // previous version that we read before entering the tryLock
-                    if (locked) coordinator.getVersion() else version
-                )
+        val (newState, acquiredLock) =
+            if (requireLock) {
+                coordinator.lock { attemptRead(acquiredLock = true) to true }
+            } else {
+                coordinator.tryLock { locked ->
+                    attemptRead(locked) to locked
+                }
             }
-        } catch (throwable: Throwable) {
-            ReadException(throwable, version)
+        if (acquiredLock) {
+            inMemoryCache.tryUpdate(newState)
         }
-        inMemoryCache.tryUpdate(data)
+        return newState
+    }
+
+    /**
+     * Caller is responsible to lock or tryLock, and pass the [acquiredLock] parameter to indicate
+     * if it has acquired lock.
+     */
+    private suspend fun attemptRead(acquiredLock: Boolean): State<T> {
+        // read version before file
+        val currentVersion = coordinator.getVersion()
+        // use current version if it has lock, otherwise use the older version between current and
+        // cached version, which guarantees correctness
+        val readVersion = if (acquiredLock) {
+            currentVersion
+        } else {
+            inMemoryCache.currentState.version
+        }
+        val readResult = runCatching { readDataFromFileOrDefault() }
+        return if (readResult.isSuccess) {
+            Data(
+                readResult.getOrThrow(),
+                readResult.getOrThrow().hashCode(),
+                readVersion
+            )
+        } else {
+            ReadException<T>(readResult.exceptionOrNull()!!, readVersion)
+        }
     }
 
     // Caller is responsible for (try to) getting file lock. It reads from the file directly without
@@ -298,8 +313,11 @@
         // The code in `writeScope` is run synchronously, i.e. the newVersion isn't returned until
         // the code in `writeScope` completes.
         storageConnection.writeScope {
-            writeData(newData)
+            // update version before write to file to avoid the case where if update version after
+            // file write, the process can crash after file write but before version increment, so
+            // the readers might skip reading forever because the version isn't changed
             newVersion = coordinator.incrementAndGetVersion()
+            writeData(newData)
             if (updateCache) {
                 inMemoryCache.tryUpdate(Data(newData, newData.hashCode(), newVersion))
             }
@@ -363,10 +381,11 @@
             inMemoryCache.tryUpdate(initData)
             if (!::updateCollector.isInitialized) {
                 updateCollector = scope.launch {
-                    coordinator.updateNotifications.collect {
+                    coordinator.updateNotifications.conflate().collect {
                         val currentState = inMemoryCache.currentState
                         if (currentState !is Final) {
-                            readActor.offer(Message.Read(currentState))
+                            // update triggered reads should always wait for lock
+                            readDataAndUpdateCache(requireLock = true)
                         }
                     }
                 }
diff --git a/datastore/datastore-core/src/commonMain/kotlin/androidx/datastore/core/DataStoreInMemoryCache.kt b/datastore/datastore-core/src/commonMain/kotlin/androidx/datastore/core/DataStoreInMemoryCache.kt
index 29f0c14..0fe02e1 100644
--- a/datastore/datastore-core/src/commonMain/kotlin/androidx/datastore/core/DataStoreInMemoryCache.kt
+++ b/datastore/datastore-core/src/commonMain/kotlin/androidx/datastore/core/DataStoreInMemoryCache.kt
@@ -56,17 +56,10 @@
                     // if version changed, and it will arrive here as either new data or
                     // new error with its new version.
                     //
-                    // The only other case that might happen is when a read happens in
-                    // parallel to a write.
-                    // In that case, read either has:
-                    // old version, old data
-                    // old version, new data
-                    // new version, new data
-                    // Since the write will send (new version, new data); it is OK to ignore
-                    // what read sent if it has old version (or ignore what write sent
-                    // if read already sent (new version, new data).
-                    // The key constraint here is that, we will never receive
-                    // (new version, old data) as version updates happen after data is written.
+                    // If a read happens in parallel to a write ("dirty read"), we will not update
+                    // the cache here but make it local in the flow that does the dirty read. In
+                    // this cache we guarantee the version matches with the data because only reads
+                    // that have file lock can set the cache.
                     if (newState.version > cached.version) {
                         newState
                     } else {
diff --git a/datastore/datastore-core/src/commonTest/kotlin/androidx/datastore/core/SingleProcessDataStoreTest.kt b/datastore/datastore-core/src/commonTest/kotlin/androidx/datastore/core/SingleProcessDataStoreTest.kt
index 79c682d..454ed64 100644
--- a/datastore/datastore-core/src/commonTest/kotlin/androidx/datastore/core/SingleProcessDataStoreTest.kt
+++ b/datastore/datastore-core/src/commonTest/kotlin/androidx/datastore/core/SingleProcessDataStoreTest.kt
@@ -912,6 +912,22 @@
         assertThat(asyncCollector.await()).containsExactly(2.toByte(), 3.toByte()).inOrder()
     }
 
+    @Test
+    fun testCancelledDataStoreScopeCantRead() = doTest {
+        // TODO(b/273990827): decide the contract of accessing when state is Final
+        dataStoreScope.cancel()
+
+        val flowCollector = async {
+            store.data.toList()
+        }
+        runCurrent()
+        assertThrows<CancellationException> { flowCollector.await() }
+
+        assertThrows<CancellationException> {
+            store.data.first()
+        }
+    }
+
     private class TestingCorruptionHandler(
         private val replaceWith: Byte? = null
     ) : CorruptionHandler<Byte> {
diff --git a/docs-tip-of-tree/build.gradle b/docs-tip-of-tree/build.gradle
index dceb753..fe0253b 100644
--- a/docs-tip-of-tree/build.gradle
+++ b/docs-tip-of-tree/build.gradle
@@ -128,6 +128,7 @@
     docs(project(":core:core-remoteviews"))
     docs(project(":core:core-splashscreen"))
     docs(project(":core:core-role"))
+    docs(project(":core:core-testing"))
     docs(project(":core:uwb:uwb"))
     docs(project(":core:uwb:uwb-rxjava3"))
     docs(project(":credentials:credentials"))
diff --git a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/GlanceTileServiceTest.kt b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/GlanceTileServiceTest.kt
index 6be7404..6959421 100644
--- a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/GlanceTileServiceTest.kt
+++ b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/GlanceTileServiceTest.kt
@@ -41,6 +41,7 @@
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
 import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.guava.await
 import kotlinx.coroutines.runBlocking
@@ -92,10 +93,11 @@
         )
 
         executor = InlineExecutorService()
-        tileServiceWithState = TestGlanceTileServiceWithState()
+        tileServiceWithState = TestGlanceTileServiceWithState(fakeCoroutineScope)
         tileServiceClientWithState = TestTileClient(
             tileServiceWithState,
-            executor
+            fakeCoroutineScope,
+            fakeCoroutineScope.coroutineContext[CoroutineDispatcher]!!
         )
 
         ovalBitmap =
@@ -248,7 +250,9 @@
 
         val tileRequest = RequestBuilders.TileRequest.Builder().build()
         val tileFuture = tileServiceClientWithState.requestTile(tileRequest)
+
         shadowOf(Looper.getMainLooper()).idle()
+
         val tile = tileFuture.await()
 
         assertThat(tile.timeline!!.timelineEntries).hasSize(1)
@@ -319,6 +323,7 @@
                 testTimelineMode.timeIntervals.elementAt(0) -> {
                     Text("No event")
                 }
+
                 testTimelineMode.timeIntervals.elementAt(1) -> {
                     Text("Coffee")
                     Image(
@@ -328,6 +333,7 @@
                         contentScale = ContentScale.FillBounds
                     )
                 }
+
                 testTimelineMode.timeIntervals.elementAt(2) -> {
                     Text("Work")
                     Image(
@@ -336,6 +342,7 @@
                         modifier = GlanceModifier.size(40.dp),
                     )
                 }
+
                 testTimelineMode.timeIntervals.elementAt(3) -> {
                     Text("Dinner")
                 }
@@ -343,8 +350,14 @@
         }
     }
 
-    private inner class TestGlanceTileServiceWithState : GlanceTileService() {
+    private inner class TestGlanceTileServiceWithState(scope: CoroutineScope) :
+        GlanceTileService() {
         override val stateDefinition = PreferencesGlanceStateDefinition
+
+        init {
+            stateDefinition.setCoroutineScope(scope)
+        }
+
         val prefsNameKey = stringPreferencesKey("user_name")
 
         @Composable
diff --git a/glance/glance/build.gradle b/glance/glance/build.gradle
index 1fd6934..bb05696 100644
--- a/glance/glance/build.gradle
+++ b/glance/glance/build.gradle
@@ -43,6 +43,9 @@
     implementation(libs.kotlinStdlib)
     implementation(project(":compose:runtime:runtime"))
 
+    // Force upgrade since 1.2.0 is not compatible with latest lint.
+    implementation("androidx.annotation:annotation-experimental:1.3.0")
+
     testImplementation(libs.robolectric)
     testImplementation(libs.testCore)
     testImplementation(libs.testRules)
diff --git a/glance/glance/src/androidMain/kotlin/androidx/glance/state/GlanceStateDefinition.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/state/GlanceStateDefinition.kt
index 9b7d161..59fb9fb 100644
--- a/glance/glance/src/androidMain/kotlin/androidx/glance/state/GlanceStateDefinition.kt
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/state/GlanceStateDefinition.kt
@@ -23,6 +23,7 @@
 import androidx.datastore.preferences.core.Preferences
 import androidx.datastore.preferences.preferencesDataStoreFile
 import java.io.File
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
@@ -151,12 +152,26 @@
 }
 
 /**
- * Base class helping the creation of a state using DataStore's [Preferences].
+ * Base class helping the creation of a state using DataStore's [Preferences] with an optional
+ * CoroutineScope for [DataStore].
  */
 object PreferencesGlanceStateDefinition : GlanceStateDefinition<Preferences> {
+    private var coroutineScope: CoroutineScope? = null
     override fun getLocation(context: Context, fileKey: String): File =
         context.preferencesDataStoreFile(fileKey)
 
-    override suspend fun getDataStore(context: Context, fileKey: String): DataStore<Preferences> =
-        PreferenceDataStoreFactory.create { context.preferencesDataStoreFile(fileKey) }
+    override suspend fun getDataStore(context: Context, fileKey: String): DataStore<Preferences> {
+        return coroutineScope?.let {
+            PreferenceDataStoreFactory.create(scope = it) {
+                context.preferencesDataStoreFile(
+                    fileKey
+                )
+            }
+        } ?: PreferenceDataStoreFactory.create { context.preferencesDataStoreFile(fileKey) }
+    }
+
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    fun setCoroutineScope(scope: CoroutineScope) {
+        coroutineScope = scope
+    }
 }
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 31189e2..8b9366c 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -212,7 +212,7 @@
 mockitoCore = { module = "org.mockito:mockito-core", version.ref = "mockito" }
 mockitoCore4 = { module = "org.mockito:mockito-core", version = "4.8.0" }
 mockitoAndroid = { module = "org.mockito:mockito-android", version.ref = "mockito" }
-mockitoKotlin = { module = "com.nhaarman.mockitokotlin2:mockito-kotlin", version = "2.1.0" }
+mockitoKotlin = { module = "org.mockito.kotlin:mockito-kotlin", version = "2.2.11" }
 mockitoKotlin4 = { module = "org.mockito.kotlin:mockito-kotlin", version = "4.0.0" }
 moshi = { module = "com.squareup.moshi:moshi", version.ref = "moshi" }
 moshiAdapters = { module = "com.squareup.moshi:moshi-adapters", version.ref = "moshi" }
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index 2843f37..26dab29 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -491,6 +491,14 @@
             <sha256 value="100a2c6db1ec4aab9545ead93be094c9728ecc671fba8353648d04ef405f30c8" origin="Generated by Gradle" reason="Artifact is not signed"/>
          </artifact>
       </component>
+      <component group="com.google.android.libraries.identity.googleid" name="googleid" version="1.0.0">
+         <artifact name="googleid-1.0.0.aar">
+            <sha256 value="7c6c910a751e32951afafd79be22f9d5222229ec59a92961515a8b0b6f8ecdcb" origin="Generated by Gradle" reason="Artifact is not signed"/>
+         </artifact>
+         <artifact name="googleid-1.0.0.pom">
+            <sha256 value="663aed69db1623331032fe4dedee4f2b1c9decbdad0ab06a4fc0be14b3e52c7f" origin="Generated by Gradle" reason="Artifact is not signed"/>
+         </artifact>
+      </component>
       <component group="com.google.android.odml" name="image" version="1.0.0-beta1">
          <artifact name="image-1.0.0-beta1.aar">
             <sha256 value="2e71aa31f83a9415277f119de67195726f07d1760e9542c111778c320e3aa1f2" origin="Generated by Gradle" reason="Artifact is not signed"/>
diff --git a/gradlew b/gradlew
index 11139b9..fc93b47 100755
--- a/gradlew
+++ b/gradlew
@@ -43,6 +43,9 @@
     # and doesn't set DIST_DIR and we want gradlew and Studio to match
 fi
 
+# Loading the AIDL lexer requires disabling Lint's bytecode verification
+export ANDROID_LINT_SKIP_BYTECODE_VERIFIER=true
+
 # unset ANDROID_BUILD_TOP so that Lint doesn't think we're building the platform itself
 unset ANDROID_BUILD_TOP
 # ----------------------------------------------------------------------------
diff --git a/graphics/filters/filters/build.gradle b/graphics/filters/filters/build.gradle
index 745c9a0..dc8a285 100644
--- a/graphics/filters/filters/build.gradle
+++ b/graphics/filters/filters/build.gradle
@@ -35,6 +35,9 @@
     implementation('androidx.media3:media3-exoplayer:' + media3Version)
     implementation('androidx.media3:media3-transformer:' + media3Version)
 
+    // Force upgrade since 1.2.0 is not compatible with latest lint.
+    implementation("androidx.annotation:annotation-experimental:1.3.0")
+
     // Test dependencies
     androidTestImplementation(libs.testExtJunit)
     androidTestImplementation(libs.testCore)
diff --git a/graphics/filters/filters/lint-baseline.xml b/graphics/filters/filters/lint-baseline.xml
new file mode 100644
index 0000000..9a42e316
--- /dev/null
+++ b/graphics/filters/filters/lint-baseline.xml
@@ -0,0 +1,301 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1=") : GlEffect {"
+        errorLine2="    ~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/Vignette.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="    Assertions.checkArgument("
+        errorLine2="               ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/Vignette.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="    Assertions.checkArgument("
+        errorLine2="               ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/Vignette.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="  @Throws(FrameProcessingException::class)"
+        errorLine2="          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/Vignette.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="  override fun toGlTextureProcessor("
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/Vignette.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="  SingleFrameGlTextureProcessor(useHdr) {"
+        errorLine2="  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="  SingleFrameGlTextureProcessor(useHdr) {"
+        errorLine2="  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="        GlProgram(context!!, VERTEX_SHADER_PATH, FRAGMENT_SHADER_PATH)"
+        errorLine2="        ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="        throw FrameProcessingException(e)"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="        throw FrameProcessingException(e)"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="    glProgram!!.setBufferAttribute("
+        errorLine2="                ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="      GlUtil.getNormalizedCoordinateBounds(),"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="      GlUtil.HOMOGENEOUS_COORDINATE_VECTOR_SIZE"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="    val identityMatrix = GlUtil.create4x4IdentityMatrix()"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="    glProgram!!.setFloatsUniform(&quot;uTransformationMatrix&quot;, identityMatrix)"
+        errorLine2="                ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="    glProgram!!.setFloatsUniform(&quot;uTexTransformationMatrix&quot;, identityMatrix)"
+        errorLine2="                ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="  override fun configure(inputWidth: Int, inputHeight: Int): Pair&lt;Int, Int> {"
+        errorLine2="               ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="  @Throws(FrameProcessingException::class)"
+        errorLine2="          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="  override fun drawFrame(inputTexId: Int, presentationTimeUs: Long) {"
+        errorLine2="               ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="      glProgram!!.use()"
+        errorLine2="                  ~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="      glProgram!!.setFloatUniform(&quot;uAspectRatio&quot;, this.aspectRatio)"
+        errorLine2="                  ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="      glProgram!!.setFloatUniform(&quot;uInnerRadius&quot;, this.vignetteEffect.innerRadius)"
+        errorLine2="                  ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="      glProgram!!.setFloatUniform(&quot;uOuterRadius&quot;, this.vignetteEffect.outerRadius)"
+        errorLine2="                  ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="      glProgram!!.setIntUniform(&quot;uShouldVignetteAlpha&quot;,"
+        errorLine2="                  ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="      glProgram!!.setIntUniform(&quot;uShouldVignetteColor&quot;,"
+        errorLine2="                  ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="      glProgram!!.setSamplerTexIdUniform(&quot;uTexSampler&quot;, inputTexId, /* texUnitIndex= */ 0)"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="      glProgram!!.bindAttributesAndUniforms()"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="      throw FrameProcessingException(e, presentationTimeUs)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="  @Throws(FrameProcessingException::class)"
+        errorLine2="          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="  override fun release() {"
+        errorLine2="               ~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="    super.release()"
+        errorLine2="          ~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="      glProgram!!.delete()"
+        errorLine2="                  ~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.media3.common.util.UnstableApi` or `@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)`"
+        errorLine1="      throw FrameProcessingException(e)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/filters/VignetteProcessor.kt"/>
+    </issue>
+
+</issues>
diff --git a/input/input-motionprediction/api/1.0.0-beta02.txt b/input/input-motionprediction/api/1.0.0-beta02.txt
new file mode 100644
index 0000000..b0eef8e
--- /dev/null
+++ b/input/input-motionprediction/api/1.0.0-beta02.txt
@@ -0,0 +1,11 @@
+// Signature format: 4.0
+package androidx.input.motionprediction {
+
+  public interface MotionEventPredictor {
+    method public static androidx.input.motionprediction.MotionEventPredictor newInstance(android.view.View);
+    method public android.view.MotionEvent? predict();
+    method public void record(android.view.MotionEvent);
+  }
+
+}
+
diff --git a/input/input-motionprediction/api/public_plus_experimental_1.0.0-beta02.txt b/input/input-motionprediction/api/public_plus_experimental_1.0.0-beta02.txt
new file mode 100644
index 0000000..b0eef8e
--- /dev/null
+++ b/input/input-motionprediction/api/public_plus_experimental_1.0.0-beta02.txt
@@ -0,0 +1,11 @@
+// Signature format: 4.0
+package androidx.input.motionprediction {
+
+  public interface MotionEventPredictor {
+    method public static androidx.input.motionprediction.MotionEventPredictor newInstance(android.view.View);
+    method public android.view.MotionEvent? predict();
+    method public void record(android.view.MotionEvent);
+  }
+
+}
+
diff --git a/input/input-motionprediction/api/res-1.0.0-beta02.txt b/input/input-motionprediction/api/res-1.0.0-beta02.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/input/input-motionprediction/api/res-1.0.0-beta02.txt
diff --git a/input/input-motionprediction/api/restricted_1.0.0-beta02.txt b/input/input-motionprediction/api/restricted_1.0.0-beta02.txt
new file mode 100644
index 0000000..b0eef8e
--- /dev/null
+++ b/input/input-motionprediction/api/restricted_1.0.0-beta02.txt
@@ -0,0 +1,11 @@
+// Signature format: 4.0
+package androidx.input.motionprediction {
+
+  public interface MotionEventPredictor {
+    method public static androidx.input.motionprediction.MotionEventPredictor newInstance(android.view.View);
+    method public android.view.MotionEvent? predict();
+    method public void record(android.view.MotionEvent);
+  }
+
+}
+
diff --git a/javascriptengine/javascriptengine/lint-baseline.xml b/javascriptengine/javascriptengine/lint-baseline.xml
index 6308c50..1705546 100644
--- a/javascriptengine/javascriptengine/lint-baseline.xml
+++ b/javascriptengine/javascriptengine/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
+<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
 
     <issue
         id="BanThreadSleep"
@@ -10,4 +10,22 @@
             file="src/androidTest/java/androidx/javascriptengine/WebViewJavaScriptSandboxTest.java"/>
     </issue>
 
+    <issue
+        id="BanThreadSleep"
+        message="Uses Thread.sleep()"
+        errorLine1="                Thread.sleep(1000);"
+        errorLine2="                       ~~~~~">
+        <location
+            file="src/androidTest/java/androidx/javascriptengine/WebViewJavaScriptSandboxTest.java"/>
+    </issue>
+
+    <issue
+        id="PrivateConstructorForUtilityClass"
+        message="Utility class is missing private constructor"
+        errorLine1="public class Utils {"
+        errorLine2="             ~~~~~">
+        <location
+            file="src/main/java/androidx/javascriptengine/common/Utils.java"/>
+    </issue>
+
 </issues>
diff --git a/leanback/leanback/lint-baseline.xml b/leanback/leanback/lint-baseline.xml
index 6804a05..667d89e 100644
--- a/leanback/leanback/lint-baseline.xml
+++ b/leanback/leanback/lint-baseline.xml
@@ -1574,6 +1574,9 @@
         errorLine2="                                                    ~~~~~~~~~~~~~~~~~">
         <location
             file="src/main/java/androidx/leanback/widget/ParallaxEffect.java"/>
+        <location
+            file="src/main/java/androidx/leanback/widget/ParallaxEffect.java"
+            message="Setter here"/>
     </issue>
 
     <issue
@@ -1583,6 +1586,9 @@
         errorLine2="                             ~~~~~~~~~~">
         <location
             file="src/main/java/androidx/leanback/widget/ParallaxEffect.java"/>
+        <location
+            file="src/main/java/androidx/leanback/widget/ParallaxEffect.java"
+            message="Setter here"/>
     </issue>
 
     <issue
diff --git a/libraryversions.toml b/libraryversions.toml
index 0b35a8c..29d60eb 100644
--- a/libraryversions.toml
+++ b/libraryversions.toml
@@ -8,26 +8,26 @@
 ARCH_CORE = "2.3.0-alpha01"
 ASYNCLAYOUTINFLATER = "1.1.0-alpha02"
 AUTOFILL = "1.3.0-alpha01"
-BENCHMARK = "1.2.0-alpha12"
+BENCHMARK = "1.2.0-alpha13"
 BIOMETRIC = "1.2.0-alpha06"
 BLUETOOTH = "1.0.0-alpha01"
 BROWSER = "1.6.0-alpha01"
 BUILDSRC_TESTS = "1.0.0-alpha01"
-CAMERA = "1.3.0-alpha05"
+CAMERA = "1.3.0-alpha06"
 CAMERA_PIPE = "1.0.0-alpha01"
 CARDVIEW = "1.1.0-alpha01"
 CAR_APP = "1.4.0-alpha01"
 COLLECTION = "1.3.0-alpha04"
-COMPOSE = "1.5.0-alpha01"
+COMPOSE = "1.5.0-alpha02"
 COMPOSE_COMPILER = "1.4.4"
-COMPOSE_MATERIAL3 = "1.1.0-beta01"
+COMPOSE_MATERIAL3 = "1.1.0-beta02"
 COMPOSE_RUNTIME_TRACING = "1.0.0-alpha03"
-CONSTRAINTLAYOUT = "2.2.0-alpha09"
-CONSTRAINTLAYOUT_COMPOSE = "1.1.0-alpha09"
-CONSTRAINTLAYOUT_CORE = "1.1.0-alpha09"
+CONSTRAINTLAYOUT = "2.2.0-alpha10"
+CONSTRAINTLAYOUT_COMPOSE = "1.1.0-alpha10"
+CONSTRAINTLAYOUT_CORE = "1.1.0-alpha10"
 CONTENTPAGER = "1.1.0-alpha01"
 COORDINATORLAYOUT = "1.3.0-alpha01"
-CORE = "1.11.0-alpha01"
+CORE = "1.11.0-alpha02"
 CORE_ANIMATION = "1.0.0-beta02"
 CORE_ANIMATION_TESTING = "1.0.0-beta01"
 CORE_APPDIGEST = "1.0.0-alpha01"
@@ -39,7 +39,7 @@
 CORE_ROLE = "1.2.0-alpha01"
 CORE_SPLASHSCREEN = "1.1.0-alpha01"
 CORE_UWB = "1.0.0-alpha05"
-CREDENTIALS = "1.0.0-alpha05"
+CREDENTIALS = "1.0.0-alpha06"
 CURSORADAPTER = "1.1.0-alpha01"
 CUSTOMVIEW = "1.2.0-alpha03"
 CUSTOMVIEW_POOLINGCONTAINER = "1.1.0-alpha01"
@@ -53,23 +53,23 @@
 EMOJI2 = "1.4.0-beta01"
 ENTERPRISE = "1.1.0-rc01"
 EXIFINTERFACE = "1.4.0-alpha01"
-FRAGMENT = "1.6.0-alpha08"
+FRAGMENT = "1.6.0-alpha09"
 FUTURES = "1.2.0-alpha01"
 GLANCE = "1.0.0-alpha06"
 GLANCE_TEMPLATE = "1.0.0-alpha01"
-GRAPHICS_CORE = "1.0.0-alpha03"
+GRAPHICS_CORE = "1.0.0-alpha04"
 GRAPHICS_FILTERS = "1.0.0-alpha01"
 GRAPHICS_SHAPES = "1.0.0-alpha01"
-GRIDLAYOUT = "1.1.0-alpha01"
+GRIDLAYOUT = "1.1.0-alpha02"
 HEALTH_CONNECT = "1.0.0-alpha11"
 HEALTH_SERVICES_CLIENT = "1.0.0-beta03"
 HEIFWRITER = "1.1.0-alpha02"
 HILT = "1.1.0-alpha02"
 HILT_NAVIGATION_COMPOSE = "1.1.0-alpha02"
-INPUT_MOTIONPREDICTION = "1.0.0-beta01"
+INPUT_MOTIONPREDICTION = "1.0.0-beta02"
 INSPECTION = "1.0.0"
 INTERPOLATOR = "1.1.0-alpha01"
-JAVASCRIPTENGINE = "1.0.0-alpha04"
+JAVASCRIPTENGINE = "1.0.0-alpha05"
 LEANBACK = "1.2.0-alpha03"
 LEANBACK_GRID = "1.0.0-alpha02"
 LEANBACK_PAGING = "1.1.0-alpha10"
@@ -84,14 +84,14 @@
 MEDIA2 = "1.3.0-alpha01"
 MEDIAROUTER = "1.4.0-rc01"
 METRICS = "1.0.0-alpha04"
-NAVIGATION = "2.6.0-alpha08"
+NAVIGATION = "2.6.0-alpha09"
 PAGING = "3.2.0-alpha05"
 PAGING_COMPOSE = "1.0.0-alpha19"
 PALETTE = "1.1.0-alpha01"
 PERCENTLAYOUT = "1.1.0-alpha01"
 PREFERENCE = "1.3.0-alpha01"
 PRINT = "1.1.0-beta01"
-PRIVACYSANDBOX_ADS = "1.0.0-beta02"
+PRIVACYSANDBOX_ADS = "1.0.0-beta03"
 PRIVACYSANDBOX_PLUGINS = "1.0.0-alpha01"
 PRIVACYSANDBOX_SDKRUNTIME = "1.0.0-alpha03"
 PRIVACYSANDBOX_TOOLS = "1.0.0-alpha04"
@@ -102,7 +102,7 @@
 RECYCLERVIEW_SELECTION = "1.2.0-alpha02"
 REMOTECALLBACK = "1.0.0-alpha02"
 RESOURCEINSPECTION = "1.1.0-alpha01"
-ROOM = "2.6.0-alpha01"
+ROOM = "2.6.0-alpha02"
 SAVEDSTATE = "1.3.0-alpha01"
 SECURITY = "1.1.0-alpha05"
 SECURITY_APP_AUTHENTICATOR = "1.0.0-alpha03"
@@ -115,7 +115,7 @@
 SLICE_BUILDERS_KTX = "1.0.0-alpha08"
 SLICE_REMOTECALLBACK = "1.0.0-alpha01"
 SLIDINGPANELAYOUT = "1.3.0-alpha01"
-SQLITE = "2.4.0-alpha01"
+SQLITE = "2.4.0-alpha02"
 SQLITE_INSPECTOR = "2.1.0-alpha01"
 STABLE_AIDL = "1.0.0-alpha01"
 STARTUP = "1.2.0-alpha03"
@@ -124,8 +124,8 @@
 TESTSCREENSHOT = "1.0.0-alpha01"
 TEST_UIAUTOMATOR = "2.3.0-alpha03"
 TEXT = "1.0.0-alpha01"
-TRACING = "1.2.0-beta02"
-TRACING_PERFETTO = "1.0.0-alpha13"
+TRACING = "1.2.0-beta03"
+TRACING_PERFETTO = "1.0.0-alpha14"
 TRANSITION = "1.5.0-alpha01"
 TV = "1.0.0-alpha05"
 TVPROVIDER = "1.1.0-alpha02"
@@ -136,15 +136,15 @@
 VIEWPAGER = "1.1.0-alpha02"
 VIEWPAGER2 = "1.2.0-alpha01"
 WEAR = "1.3.0-alpha05"
-WEAR_COMPOSE = "1.2.0-alpha07"
-WEAR_COMPOSE_MATERIAL3 = "1.0.0-alpha01"
+WEAR_COMPOSE = "1.2.0-alpha08"
+WEAR_COMPOSE_MATERIAL3 = "1.0.0-alpha02"
 WEAR_INPUT = "1.2.0-alpha03"
 WEAR_INPUT_TESTING = "1.2.0-alpha03"
 WEAR_ONGOING = "1.1.0-alpha01"
 WEAR_PHONE_INTERACTIONS = "1.1.0-alpha04"
-WEAR_PROTOLAYOUT = "1.0.0-alpha06"
+WEAR_PROTOLAYOUT = "1.0.0-alpha07"
 WEAR_REMOTE_INTERACTIONS = "1.1.0-alpha01"
-WEAR_TILES = "1.2.0-alpha02"
+WEAR_TILES = "1.2.0-alpha03"
 WEAR_WATCHFACE = "1.2.0-alpha07"
 WEBKIT = "1.7.0-beta01"
 WINDOW = "1.1.0-beta02"
diff --git a/lint-checks/integration-tests/lint-baseline.xml b/lint-checks/integration-tests/lint-baseline.xml
index cc88341..743e89a 100644
--- a/lint-checks/integration-tests/lint-baseline.xml
+++ b/lint-checks/integration-tests/lint-baseline.xml
@@ -515,6 +515,33 @@
     </issue>
 
     <issue
+        id="ImplicitCastClassVerificationFailure"
+        message="This expression has type android.app.Notification.CarExtender (introduced in API level 23) but it used as type android.app.Notification.Extender (introduced in API level 20). Run-time class verification will not be able to validate this implicit cast on devices between these API levels."
+        errorLine1="        builder.extend(extender);"
+        errorLine2="                       ~~~~~~~~">
+        <location
+            file="src/main/java/androidx/AutofixUnsafeCallWithImplicitParamCast.java"/>
+    </issue>
+
+    <issue
+        id="ImplicitCastClassVerificationFailure"
+        message="This expression has type android.graphics.drawable.AdaptiveIconDrawable (introduced in API level 26) but it used as type android.graphics.drawable.Drawable (introduced in API level 1). Run-time class verification will not be able to validate this implicit cast on devices between these API levels."
+        errorLine1="        return new AdaptiveIconDrawable(null, null);"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/AutofixUnsafeCallWithImplicitReturnCast.java"/>
+    </issue>
+
+    <issue
+        id="ImplicitCastClassVerificationFailure"
+        message="This expression has type android.app.Notification.DecoratedCustomViewStyle (introduced in API level 24) but it used as type android.app.Notification.Style (introduced in API level 16). Run-time class verification will not be able to validate this implicit cast on devices between these API levels."
+        errorLine1="        useStyle(new Notification.DecoratedCustomViewStyle());"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/AutofixUnsafeCallWithImplicitReturnCast.java"/>
+    </issue>
+
+    <issue
         id="LongLogTag"
         message="The logging tag can be at most 23 characters, was 24 (ActivityRecreatorChecked)"
         errorLine1="                    Log.e(LOG_TAG, &quot;Exception while invoking performStopActivity&quot;, t);"
diff --git a/privacysandbox/OWNERS b/privacysandbox/OWNERS
index 0e5347a..3d0f6bf 100644
--- a/privacysandbox/OWNERS
+++ b/privacysandbox/OWNERS
@@ -4,3 +4,4 @@
 nicoroulet@google.com
 akulakov@google.com
 npattan@google.com # For ads
+jmarkoff@google.com # DevRel
\ No newline at end of file
diff --git a/privacysandbox/ads/OWNERS b/privacysandbox/ads/OWNERS
index 67d0de6..213fd78 100644
--- a/privacysandbox/ads/OWNERS
+++ b/privacysandbox/ads/OWNERS
@@ -1,3 +1,11 @@
-# Please keep this list alphabetically sorted
-jmarkoff@google.com
-npattan@google.com
+# adservices.measurement OWNERS
+arpanah@google.com # Measurement Primary PoC
+lmohanan@google.com
+# adservices.customaudience, adservices.adselection OWNERS
+adigupt@google.com # FLEDGE Primary PoC
+galarragas@google.com
+# adservices.topics, .adid, .appsetid, .common OWNERS
+haoliuu@google.com # Primary PoC for Topics, Common
+npattan@google.com # Creator
+jmarkoff@google.com # DevRel Jetpack Lead
+carolinewang@google.com # DevRel TPM Lead
diff --git a/privacysandbox/ads/ads-adservices-java/api/1.0.0-beta03.txt b/privacysandbox/ads/ads-adservices-java/api/1.0.0-beta03.txt
new file mode 100644
index 0000000..26eea8b
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices-java/api/1.0.0-beta03.txt
@@ -0,0 +1,92 @@
+// Signature format: 4.0
+package androidx.privacysandbox.ads.adservices.java.adid {
+
+  public abstract class AdIdManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_AD_ID) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.adid.AdId> getAdIdAsync();
+    field public static final androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures.Companion Companion;
+  }
+
+  public static final class AdIdManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.adselection {
+
+  public abstract class AdSelectionManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> reportImpressionAsync(androidx.privacysandbox.ads.adservices.adselection.ReportImpressionRequest reportImpressionRequest);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.adselection.AdSelectionOutcome> selectAdsAsync(androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig);
+    field public static final androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures.Companion Companion;
+  }
+
+  public static final class AdSelectionManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.appsetid {
+
+  public abstract class AppSetIdManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures? from(android.content.Context context);
+    method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.appsetid.AppSetId> getAppSetIdAsync();
+    field public static final androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures.Companion Companion;
+  }
+
+  public static final class AppSetIdManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.customaudience {
+
+  public abstract class CustomAudienceManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> joinCustomAudienceAsync(androidx.privacysandbox.ads.adservices.customaudience.JoinCustomAudienceRequest request);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> leaveCustomAudienceAsync(androidx.privacysandbox.ads.adservices.customaudience.LeaveCustomAudienceRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures.Companion Companion;
+  }
+
+  public static final class CustomAudienceManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.measurement {
+
+  public abstract class MeasurementManagerFutures {
+    method public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> deleteRegistrationsAsync(androidx.privacysandbox.ads.adservices.measurement.DeletionRequest deletionRequest);
+    method public static final androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> getMeasurementApiStatusAsync();
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerSourceAsync(android.net.Uri attributionSource, android.view.InputEvent? inputEvent);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerTriggerAsync(android.net.Uri trigger);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerWebSourceAsync(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerWebTriggerAsync(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures.Companion Companion;
+  }
+
+  public static final class MeasurementManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.topics {
+
+  public abstract class TopicsManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_TOPICS) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.topics.GetTopicsResponse> getTopicsAsync(androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures.Companion Companion;
+  }
+
+  public static final class TopicsManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures? from(android.content.Context context);
+  }
+
+}
+
diff --git a/privacysandbox/ads/ads-adservices-java/api/public_plus_experimental_1.0.0-beta03.txt b/privacysandbox/ads/ads-adservices-java/api/public_plus_experimental_1.0.0-beta03.txt
new file mode 100644
index 0000000..26eea8b
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices-java/api/public_plus_experimental_1.0.0-beta03.txt
@@ -0,0 +1,92 @@
+// Signature format: 4.0
+package androidx.privacysandbox.ads.adservices.java.adid {
+
+  public abstract class AdIdManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_AD_ID) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.adid.AdId> getAdIdAsync();
+    field public static final androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures.Companion Companion;
+  }
+
+  public static final class AdIdManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.adselection {
+
+  public abstract class AdSelectionManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> reportImpressionAsync(androidx.privacysandbox.ads.adservices.adselection.ReportImpressionRequest reportImpressionRequest);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.adselection.AdSelectionOutcome> selectAdsAsync(androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig);
+    field public static final androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures.Companion Companion;
+  }
+
+  public static final class AdSelectionManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.appsetid {
+
+  public abstract class AppSetIdManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures? from(android.content.Context context);
+    method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.appsetid.AppSetId> getAppSetIdAsync();
+    field public static final androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures.Companion Companion;
+  }
+
+  public static final class AppSetIdManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.customaudience {
+
+  public abstract class CustomAudienceManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> joinCustomAudienceAsync(androidx.privacysandbox.ads.adservices.customaudience.JoinCustomAudienceRequest request);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> leaveCustomAudienceAsync(androidx.privacysandbox.ads.adservices.customaudience.LeaveCustomAudienceRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures.Companion Companion;
+  }
+
+  public static final class CustomAudienceManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.measurement {
+
+  public abstract class MeasurementManagerFutures {
+    method public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> deleteRegistrationsAsync(androidx.privacysandbox.ads.adservices.measurement.DeletionRequest deletionRequest);
+    method public static final androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> getMeasurementApiStatusAsync();
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerSourceAsync(android.net.Uri attributionSource, android.view.InputEvent? inputEvent);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerTriggerAsync(android.net.Uri trigger);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerWebSourceAsync(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerWebTriggerAsync(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures.Companion Companion;
+  }
+
+  public static final class MeasurementManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.topics {
+
+  public abstract class TopicsManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_TOPICS) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.topics.GetTopicsResponse> getTopicsAsync(androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures.Companion Companion;
+  }
+
+  public static final class TopicsManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures? from(android.content.Context context);
+  }
+
+}
+
diff --git a/privacysandbox/ads/ads-adservices-java/api/res-1.0.0-beta03.txt b/privacysandbox/ads/ads-adservices-java/api/res-1.0.0-beta03.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices-java/api/res-1.0.0-beta03.txt
diff --git a/privacysandbox/ads/ads-adservices-java/api/restricted_1.0.0-beta03.txt b/privacysandbox/ads/ads-adservices-java/api/restricted_1.0.0-beta03.txt
new file mode 100644
index 0000000..26eea8b
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices-java/api/restricted_1.0.0-beta03.txt
@@ -0,0 +1,92 @@
+// Signature format: 4.0
+package androidx.privacysandbox.ads.adservices.java.adid {
+
+  public abstract class AdIdManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_AD_ID) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.adid.AdId> getAdIdAsync();
+    field public static final androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures.Companion Companion;
+  }
+
+  public static final class AdIdManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.adid.AdIdManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.adselection {
+
+  public abstract class AdSelectionManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> reportImpressionAsync(androidx.privacysandbox.ads.adservices.adselection.ReportImpressionRequest reportImpressionRequest);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.adselection.AdSelectionOutcome> selectAdsAsync(androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig);
+    field public static final androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures.Companion Companion;
+  }
+
+  public static final class AdSelectionManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.appsetid {
+
+  public abstract class AppSetIdManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures? from(android.content.Context context);
+    method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.appsetid.AppSetId> getAppSetIdAsync();
+    field public static final androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures.Companion Companion;
+  }
+
+  public static final class AppSetIdManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.appsetid.AppSetIdManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.customaudience {
+
+  public abstract class CustomAudienceManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> joinCustomAudienceAsync(androidx.privacysandbox.ads.adservices.customaudience.JoinCustomAudienceRequest request);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> leaveCustomAudienceAsync(androidx.privacysandbox.ads.adservices.customaudience.LeaveCustomAudienceRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures.Companion Companion;
+  }
+
+  public static final class CustomAudienceManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.measurement {
+
+  public abstract class MeasurementManagerFutures {
+    method public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> deleteRegistrationsAsync(androidx.privacysandbox.ads.adservices.measurement.DeletionRequest deletionRequest);
+    method public static final androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> getMeasurementApiStatusAsync();
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerSourceAsync(android.net.Uri attributionSource, android.view.InputEvent? inputEvent);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerTriggerAsync(android.net.Uri trigger);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerWebSourceAsync(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> registerWebTriggerAsync(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures.Companion Companion;
+  }
+
+  public static final class MeasurementManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.measurement.MeasurementManagerFutures? from(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.java.topics {
+
+  public abstract class TopicsManagerFutures {
+    method public static final androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures? from(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_TOPICS) public abstract com.google.common.util.concurrent.ListenableFuture<androidx.privacysandbox.ads.adservices.topics.GetTopicsResponse> getTopicsAsync(androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest request);
+    field public static final androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures.Companion Companion;
+  }
+
+  public static final class TopicsManagerFutures.Companion {
+    method public androidx.privacysandbox.ads.adservices.java.topics.TopicsManagerFutures? from(android.content.Context context);
+  }
+
+}
+
diff --git a/privacysandbox/ads/ads-adservices/api/1.0.0-beta03.txt b/privacysandbox/ads/ads-adservices/api/1.0.0-beta03.txt
new file mode 100644
index 0000000..30cd307
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices/api/1.0.0-beta03.txt
@@ -0,0 +1,345 @@
+// Signature format: 4.0
+package androidx.privacysandbox.ads.adservices.adid {
+
+  public final class AdId {
+    method public String getAdId();
+    method public boolean isLimitAdTrackingEnabled();
+    property public final String adId;
+    property public final boolean isLimitAdTrackingEnabled;
+  }
+
+  public abstract class AdIdManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_AD_ID) public abstract suspend Object? getAdId(kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.adid.AdId>);
+    method public static final androidx.privacysandbox.ads.adservices.adid.AdIdManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.adid.AdIdManager.Companion Companion;
+  }
+
+  public static final class AdIdManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.adid.AdIdManager? obtain(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.adselection {
+
+  public final class AdSelectionConfig {
+    ctor public AdSelectionConfig(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier seller, android.net.Uri decisionLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> customAudienceBuyers, androidx.privacysandbox.ads.adservices.common.AdSelectionSignals adSelectionSignals, androidx.privacysandbox.ads.adservices.common.AdSelectionSignals sellerSignals, java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> perBuyerSignals, android.net.Uri trustedScoringSignalsUri);
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals getAdSelectionSignals();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> getCustomAudienceBuyers();
+    method public android.net.Uri getDecisionLogicUri();
+    method public java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> getPerBuyerSignals();
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getSeller();
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals getSellerSignals();
+    method public android.net.Uri getTrustedScoringSignalsUri();
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals adSelectionSignals;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> customAudienceBuyers;
+    property public final android.net.Uri decisionLogicUri;
+    property public final java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> perBuyerSignals;
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier seller;
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals sellerSignals;
+    property public final android.net.Uri trustedScoringSignalsUri;
+  }
+
+  public abstract class AdSelectionManager {
+    method public static final androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager? obtain(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? reportImpression(androidx.privacysandbox.ads.adservices.adselection.ReportImpressionRequest reportImpressionRequest, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? selectAds(androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig, kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.adselection.AdSelectionOutcome>);
+    field public static final androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager.Companion Companion;
+  }
+
+  public static final class AdSelectionManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager? obtain(android.content.Context context);
+  }
+
+  public final class AdSelectionOutcome {
+    ctor public AdSelectionOutcome(long adSelectionId, android.net.Uri renderUri);
+    method public long getAdSelectionId();
+    method public android.net.Uri getRenderUri();
+    property public final long adSelectionId;
+    property public final android.net.Uri renderUri;
+  }
+
+  public final class ReportImpressionRequest {
+    ctor public ReportImpressionRequest(long adSelectionId, androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig);
+    method public androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig getAdSelectionConfig();
+    method public long getAdSelectionId();
+    property public final androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig;
+    property public final long adSelectionId;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.appsetid {
+
+  public final class AppSetId {
+    ctor public AppSetId(String id, int scope);
+    method public String getId();
+    method public int getScope();
+    property public final String id;
+    property public final int scope;
+    field public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetId.Companion Companion;
+    field public static final int SCOPE_APP = 1; // 0x1
+    field public static final int SCOPE_DEVELOPER = 2; // 0x2
+  }
+
+  public static final class AppSetId.Companion {
+  }
+
+  public abstract class AppSetIdManager {
+    method public abstract suspend Object? getAppSetId(kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.appsetid.AppSetId>);
+    method public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager.Companion Companion;
+  }
+
+  public static final class AppSetIdManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager? obtain(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.common {
+
+  public final class AdData {
+    ctor public AdData(android.net.Uri renderUri, String metadata);
+    method public String getMetadata();
+    method public android.net.Uri getRenderUri();
+    property public final String metadata;
+    property public final android.net.Uri renderUri;
+  }
+
+  public final class AdSelectionSignals {
+    ctor public AdSelectionSignals(String signals);
+    method public String getSignals();
+    property public final String signals;
+  }
+
+  public final class AdTechIdentifier {
+    ctor public AdTechIdentifier(String identifier);
+    method public String getIdentifier();
+    property public final String identifier;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.customaudience {
+
+  public final class CustomAudience {
+    ctor public CustomAudience(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name, android.net.Uri dailyUpdateUri, android.net.Uri biddingLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads, optional java.time.Instant? activationTime, optional java.time.Instant? expirationTime, optional androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? userBiddingSignals, optional androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? trustedBiddingSignals);
+    method public java.time.Instant? getActivationTime();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> getAds();
+    method public android.net.Uri getBiddingLogicUri();
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getBuyer();
+    method public android.net.Uri getDailyUpdateUri();
+    method public java.time.Instant? getExpirationTime();
+    method public String getName();
+    method public androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? getTrustedBiddingSignals();
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? getUserBiddingSignals();
+    property public final java.time.Instant? activationTime;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads;
+    property public final android.net.Uri biddingLogicUri;
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer;
+    property public final android.net.Uri dailyUpdateUri;
+    property public final java.time.Instant? expirationTime;
+    property public final String name;
+    property public final androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? trustedBiddingSignals;
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? userBiddingSignals;
+  }
+
+  public static final class CustomAudience.Builder {
+    ctor public CustomAudience.Builder(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name, android.net.Uri dailyUpdateUri, android.net.Uri biddingLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience build();
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setActivationTime(java.time.Instant activationTime);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setAds(java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setBiddingLogicUri(android.net.Uri biddingLogicUri);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setBuyer(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setDailyUpdateUri(android.net.Uri dailyUpdateUri);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setExpirationTime(java.time.Instant expirationTime);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setName(String name);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setTrustedBiddingData(androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData trustedBiddingSignals);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setUserBiddingSignals(androidx.privacysandbox.ads.adservices.common.AdSelectionSignals userBiddingSignals);
+  }
+
+  public abstract class CustomAudienceManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? joinCustomAudience(androidx.privacysandbox.ads.adservices.customaudience.JoinCustomAudienceRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? leaveCustomAudience(androidx.privacysandbox.ads.adservices.customaudience.LeaveCustomAudienceRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static final androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager.Companion Companion;
+  }
+
+  public static final class CustomAudienceManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager? obtain(android.content.Context context);
+  }
+
+  public final class JoinCustomAudienceRequest {
+    ctor public JoinCustomAudienceRequest(androidx.privacysandbox.ads.adservices.customaudience.CustomAudience customAudience);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience getCustomAudience();
+    property public final androidx.privacysandbox.ads.adservices.customaudience.CustomAudience customAudience;
+  }
+
+  public final class LeaveCustomAudienceRequest {
+    ctor public LeaveCustomAudienceRequest(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name);
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getBuyer();
+    method public String getName();
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer;
+    property public final String name;
+  }
+
+  public final class TrustedBiddingData {
+    ctor public TrustedBiddingData(android.net.Uri trustedBiddingUri, java.util.List<java.lang.String> trustedBiddingKeys);
+    method public java.util.List<java.lang.String> getTrustedBiddingKeys();
+    method public android.net.Uri getTrustedBiddingUri();
+    property public final java.util.List<java.lang.String> trustedBiddingKeys;
+    property public final android.net.Uri trustedBiddingUri;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.measurement {
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class DeletionRequest {
+    ctor public DeletionRequest(int deletionMode, int matchBehavior, optional java.time.Instant start, optional java.time.Instant end, optional java.util.List<? extends android.net.Uri> domainUris, optional java.util.List<? extends android.net.Uri> originUris);
+    method public int getDeletionMode();
+    method public java.util.List<android.net.Uri> getDomainUris();
+    method public java.time.Instant getEnd();
+    method public int getMatchBehavior();
+    method public java.util.List<android.net.Uri> getOriginUris();
+    method public java.time.Instant getStart();
+    property public final int deletionMode;
+    property public final java.util.List<android.net.Uri> domainUris;
+    property public final java.time.Instant end;
+    property public final int matchBehavior;
+    property public final java.util.List<android.net.Uri> originUris;
+    property public final java.time.Instant start;
+    field public static final androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Companion Companion;
+    field public static final int DELETION_MODE_ALL = 0; // 0x0
+    field public static final int DELETION_MODE_EXCLUDE_INTERNAL_DATA = 1; // 0x1
+    field public static final int MATCH_BEHAVIOR_DELETE = 0; // 0x0
+    field public static final int MATCH_BEHAVIOR_PRESERVE = 1; // 0x1
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class DeletionRequest.Builder {
+    ctor public DeletionRequest.Builder(int deletionMode, int matchBehavior);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest build();
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setDomainUris(java.util.List<? extends android.net.Uri> domainUris);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setEnd(java.time.Instant end);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setOriginUris(java.util.List<? extends android.net.Uri> originUris);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setStart(java.time.Instant start);
+  }
+
+  public static final class DeletionRequest.Companion {
+  }
+
+  public abstract class MeasurementManager {
+    ctor public MeasurementManager();
+    method public abstract suspend Object? deleteRegistrations(androidx.privacysandbox.ads.adservices.measurement.DeletionRequest deletionRequest, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? getMeasurementApiStatus(kotlin.coroutines.Continuation<? super java.lang.Integer>);
+    method public static final androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerSource(android.net.Uri attributionSource, android.view.InputEvent? inputEvent, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerTrigger(android.net.Uri trigger, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebSource(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebTrigger(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    field public static final androidx.privacysandbox.ads.adservices.measurement.MeasurementManager.Companion Companion;
+    field public static final int MEASUREMENT_API_STATE_DISABLED = 0; // 0x0
+    field public static final int MEASUREMENT_API_STATE_ENABLED = 1; // 0x1
+  }
+
+  public static final class MeasurementManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebSourceParams {
+    ctor public WebSourceParams(android.net.Uri registrationUri, boolean debugKeyAllowed);
+    method public boolean getDebugKeyAllowed();
+    method public android.net.Uri getRegistrationUri();
+    property public final boolean debugKeyAllowed;
+    property public final android.net.Uri registrationUri;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebSourceRegistrationRequest {
+    ctor public WebSourceRegistrationRequest(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams, android.net.Uri topOriginUri, optional android.view.InputEvent? inputEvent, optional android.net.Uri? appDestination, optional android.net.Uri? webDestination, optional android.net.Uri? verifiedDestination);
+    method public android.net.Uri? getAppDestination();
+    method public android.view.InputEvent? getInputEvent();
+    method public android.net.Uri getTopOriginUri();
+    method public android.net.Uri? getVerifiedDestination();
+    method public android.net.Uri? getWebDestination();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> getWebSourceParams();
+    property public final android.net.Uri? appDestination;
+    property public final android.view.InputEvent? inputEvent;
+    property public final android.net.Uri topOriginUri;
+    property public final android.net.Uri? verifiedDestination;
+    property public final android.net.Uri? webDestination;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams;
+  }
+
+  public static final class WebSourceRegistrationRequest.Builder {
+    ctor public WebSourceRegistrationRequest.Builder(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams, android.net.Uri topOriginUri);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest build();
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setAppDestination(android.net.Uri? appDestination);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setInputEvent(android.view.InputEvent inputEvent);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setVerifiedDestination(android.net.Uri? verifiedDestination);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setWebDestination(android.net.Uri? webDestination);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebTriggerParams {
+    ctor public WebTriggerParams(android.net.Uri registrationUri, boolean debugKeyAllowed);
+    method public boolean getDebugKeyAllowed();
+    method public android.net.Uri getRegistrationUri();
+    property public final boolean debugKeyAllowed;
+    property public final android.net.Uri registrationUri;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebTriggerRegistrationRequest {
+    ctor public WebTriggerRegistrationRequest(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> webTriggerParams, android.net.Uri destination);
+    method public android.net.Uri getDestination();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> getWebTriggerParams();
+    property public final android.net.Uri destination;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> webTriggerParams;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.topics {
+
+  public final class GetTopicsRequest {
+    ctor public GetTopicsRequest(optional String adsSdkName, optional boolean shouldRecordObservation);
+    method public String getAdsSdkName();
+    method public boolean getShouldRecordObservation();
+    property public final String adsSdkName;
+    property public final boolean shouldRecordObservation;
+  }
+
+  public static final class GetTopicsRequest.Builder {
+    ctor public GetTopicsRequest.Builder();
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest build();
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest.Builder setAdsSdkName(String adsSdkName);
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest.Builder setShouldRecordObservation(boolean shouldRecordObservation);
+  }
+
+  public final class GetTopicsResponse {
+    ctor public GetTopicsResponse(java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> topics);
+    method public java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> getTopics();
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> topics;
+  }
+
+  public final class Topic {
+    ctor public Topic(long taxonomyVersion, long modelVersion, int topicId);
+    method public long getModelVersion();
+    method public long getTaxonomyVersion();
+    method public int getTopicId();
+    property public final long modelVersion;
+    property public final long taxonomyVersion;
+    property public final int topicId;
+  }
+
+  public abstract class TopicsManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_TOPICS) public abstract suspend Object? getTopics(androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest request, kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.topics.GetTopicsResponse>);
+    method public static final androidx.privacysandbox.ads.adservices.topics.TopicsManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.topics.TopicsManager.Companion Companion;
+  }
+
+  public static final class TopicsManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.topics.TopicsManager? obtain(android.content.Context context);
+  }
+
+}
+
diff --git a/privacysandbox/ads/ads-adservices/api/public_plus_experimental_1.0.0-beta03.txt b/privacysandbox/ads/ads-adservices/api/public_plus_experimental_1.0.0-beta03.txt
new file mode 100644
index 0000000..30cd307
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices/api/public_plus_experimental_1.0.0-beta03.txt
@@ -0,0 +1,345 @@
+// Signature format: 4.0
+package androidx.privacysandbox.ads.adservices.adid {
+
+  public final class AdId {
+    method public String getAdId();
+    method public boolean isLimitAdTrackingEnabled();
+    property public final String adId;
+    property public final boolean isLimitAdTrackingEnabled;
+  }
+
+  public abstract class AdIdManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_AD_ID) public abstract suspend Object? getAdId(kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.adid.AdId>);
+    method public static final androidx.privacysandbox.ads.adservices.adid.AdIdManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.adid.AdIdManager.Companion Companion;
+  }
+
+  public static final class AdIdManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.adid.AdIdManager? obtain(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.adselection {
+
+  public final class AdSelectionConfig {
+    ctor public AdSelectionConfig(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier seller, android.net.Uri decisionLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> customAudienceBuyers, androidx.privacysandbox.ads.adservices.common.AdSelectionSignals adSelectionSignals, androidx.privacysandbox.ads.adservices.common.AdSelectionSignals sellerSignals, java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> perBuyerSignals, android.net.Uri trustedScoringSignalsUri);
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals getAdSelectionSignals();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> getCustomAudienceBuyers();
+    method public android.net.Uri getDecisionLogicUri();
+    method public java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> getPerBuyerSignals();
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getSeller();
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals getSellerSignals();
+    method public android.net.Uri getTrustedScoringSignalsUri();
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals adSelectionSignals;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> customAudienceBuyers;
+    property public final android.net.Uri decisionLogicUri;
+    property public final java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> perBuyerSignals;
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier seller;
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals sellerSignals;
+    property public final android.net.Uri trustedScoringSignalsUri;
+  }
+
+  public abstract class AdSelectionManager {
+    method public static final androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager? obtain(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? reportImpression(androidx.privacysandbox.ads.adservices.adselection.ReportImpressionRequest reportImpressionRequest, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? selectAds(androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig, kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.adselection.AdSelectionOutcome>);
+    field public static final androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager.Companion Companion;
+  }
+
+  public static final class AdSelectionManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager? obtain(android.content.Context context);
+  }
+
+  public final class AdSelectionOutcome {
+    ctor public AdSelectionOutcome(long adSelectionId, android.net.Uri renderUri);
+    method public long getAdSelectionId();
+    method public android.net.Uri getRenderUri();
+    property public final long adSelectionId;
+    property public final android.net.Uri renderUri;
+  }
+
+  public final class ReportImpressionRequest {
+    ctor public ReportImpressionRequest(long adSelectionId, androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig);
+    method public androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig getAdSelectionConfig();
+    method public long getAdSelectionId();
+    property public final androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig;
+    property public final long adSelectionId;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.appsetid {
+
+  public final class AppSetId {
+    ctor public AppSetId(String id, int scope);
+    method public String getId();
+    method public int getScope();
+    property public final String id;
+    property public final int scope;
+    field public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetId.Companion Companion;
+    field public static final int SCOPE_APP = 1; // 0x1
+    field public static final int SCOPE_DEVELOPER = 2; // 0x2
+  }
+
+  public static final class AppSetId.Companion {
+  }
+
+  public abstract class AppSetIdManager {
+    method public abstract suspend Object? getAppSetId(kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.appsetid.AppSetId>);
+    method public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager.Companion Companion;
+  }
+
+  public static final class AppSetIdManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager? obtain(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.common {
+
+  public final class AdData {
+    ctor public AdData(android.net.Uri renderUri, String metadata);
+    method public String getMetadata();
+    method public android.net.Uri getRenderUri();
+    property public final String metadata;
+    property public final android.net.Uri renderUri;
+  }
+
+  public final class AdSelectionSignals {
+    ctor public AdSelectionSignals(String signals);
+    method public String getSignals();
+    property public final String signals;
+  }
+
+  public final class AdTechIdentifier {
+    ctor public AdTechIdentifier(String identifier);
+    method public String getIdentifier();
+    property public final String identifier;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.customaudience {
+
+  public final class CustomAudience {
+    ctor public CustomAudience(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name, android.net.Uri dailyUpdateUri, android.net.Uri biddingLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads, optional java.time.Instant? activationTime, optional java.time.Instant? expirationTime, optional androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? userBiddingSignals, optional androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? trustedBiddingSignals);
+    method public java.time.Instant? getActivationTime();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> getAds();
+    method public android.net.Uri getBiddingLogicUri();
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getBuyer();
+    method public android.net.Uri getDailyUpdateUri();
+    method public java.time.Instant? getExpirationTime();
+    method public String getName();
+    method public androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? getTrustedBiddingSignals();
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? getUserBiddingSignals();
+    property public final java.time.Instant? activationTime;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads;
+    property public final android.net.Uri biddingLogicUri;
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer;
+    property public final android.net.Uri dailyUpdateUri;
+    property public final java.time.Instant? expirationTime;
+    property public final String name;
+    property public final androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? trustedBiddingSignals;
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? userBiddingSignals;
+  }
+
+  public static final class CustomAudience.Builder {
+    ctor public CustomAudience.Builder(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name, android.net.Uri dailyUpdateUri, android.net.Uri biddingLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience build();
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setActivationTime(java.time.Instant activationTime);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setAds(java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setBiddingLogicUri(android.net.Uri biddingLogicUri);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setBuyer(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setDailyUpdateUri(android.net.Uri dailyUpdateUri);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setExpirationTime(java.time.Instant expirationTime);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setName(String name);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setTrustedBiddingData(androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData trustedBiddingSignals);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setUserBiddingSignals(androidx.privacysandbox.ads.adservices.common.AdSelectionSignals userBiddingSignals);
+  }
+
+  public abstract class CustomAudienceManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? joinCustomAudience(androidx.privacysandbox.ads.adservices.customaudience.JoinCustomAudienceRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? leaveCustomAudience(androidx.privacysandbox.ads.adservices.customaudience.LeaveCustomAudienceRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static final androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager.Companion Companion;
+  }
+
+  public static final class CustomAudienceManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager? obtain(android.content.Context context);
+  }
+
+  public final class JoinCustomAudienceRequest {
+    ctor public JoinCustomAudienceRequest(androidx.privacysandbox.ads.adservices.customaudience.CustomAudience customAudience);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience getCustomAudience();
+    property public final androidx.privacysandbox.ads.adservices.customaudience.CustomAudience customAudience;
+  }
+
+  public final class LeaveCustomAudienceRequest {
+    ctor public LeaveCustomAudienceRequest(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name);
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getBuyer();
+    method public String getName();
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer;
+    property public final String name;
+  }
+
+  public final class TrustedBiddingData {
+    ctor public TrustedBiddingData(android.net.Uri trustedBiddingUri, java.util.List<java.lang.String> trustedBiddingKeys);
+    method public java.util.List<java.lang.String> getTrustedBiddingKeys();
+    method public android.net.Uri getTrustedBiddingUri();
+    property public final java.util.List<java.lang.String> trustedBiddingKeys;
+    property public final android.net.Uri trustedBiddingUri;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.measurement {
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class DeletionRequest {
+    ctor public DeletionRequest(int deletionMode, int matchBehavior, optional java.time.Instant start, optional java.time.Instant end, optional java.util.List<? extends android.net.Uri> domainUris, optional java.util.List<? extends android.net.Uri> originUris);
+    method public int getDeletionMode();
+    method public java.util.List<android.net.Uri> getDomainUris();
+    method public java.time.Instant getEnd();
+    method public int getMatchBehavior();
+    method public java.util.List<android.net.Uri> getOriginUris();
+    method public java.time.Instant getStart();
+    property public final int deletionMode;
+    property public final java.util.List<android.net.Uri> domainUris;
+    property public final java.time.Instant end;
+    property public final int matchBehavior;
+    property public final java.util.List<android.net.Uri> originUris;
+    property public final java.time.Instant start;
+    field public static final androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Companion Companion;
+    field public static final int DELETION_MODE_ALL = 0; // 0x0
+    field public static final int DELETION_MODE_EXCLUDE_INTERNAL_DATA = 1; // 0x1
+    field public static final int MATCH_BEHAVIOR_DELETE = 0; // 0x0
+    field public static final int MATCH_BEHAVIOR_PRESERVE = 1; // 0x1
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class DeletionRequest.Builder {
+    ctor public DeletionRequest.Builder(int deletionMode, int matchBehavior);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest build();
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setDomainUris(java.util.List<? extends android.net.Uri> domainUris);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setEnd(java.time.Instant end);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setOriginUris(java.util.List<? extends android.net.Uri> originUris);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setStart(java.time.Instant start);
+  }
+
+  public static final class DeletionRequest.Companion {
+  }
+
+  public abstract class MeasurementManager {
+    ctor public MeasurementManager();
+    method public abstract suspend Object? deleteRegistrations(androidx.privacysandbox.ads.adservices.measurement.DeletionRequest deletionRequest, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? getMeasurementApiStatus(kotlin.coroutines.Continuation<? super java.lang.Integer>);
+    method public static final androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerSource(android.net.Uri attributionSource, android.view.InputEvent? inputEvent, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerTrigger(android.net.Uri trigger, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebSource(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebTrigger(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    field public static final androidx.privacysandbox.ads.adservices.measurement.MeasurementManager.Companion Companion;
+    field public static final int MEASUREMENT_API_STATE_DISABLED = 0; // 0x0
+    field public static final int MEASUREMENT_API_STATE_ENABLED = 1; // 0x1
+  }
+
+  public static final class MeasurementManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebSourceParams {
+    ctor public WebSourceParams(android.net.Uri registrationUri, boolean debugKeyAllowed);
+    method public boolean getDebugKeyAllowed();
+    method public android.net.Uri getRegistrationUri();
+    property public final boolean debugKeyAllowed;
+    property public final android.net.Uri registrationUri;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebSourceRegistrationRequest {
+    ctor public WebSourceRegistrationRequest(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams, android.net.Uri topOriginUri, optional android.view.InputEvent? inputEvent, optional android.net.Uri? appDestination, optional android.net.Uri? webDestination, optional android.net.Uri? verifiedDestination);
+    method public android.net.Uri? getAppDestination();
+    method public android.view.InputEvent? getInputEvent();
+    method public android.net.Uri getTopOriginUri();
+    method public android.net.Uri? getVerifiedDestination();
+    method public android.net.Uri? getWebDestination();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> getWebSourceParams();
+    property public final android.net.Uri? appDestination;
+    property public final android.view.InputEvent? inputEvent;
+    property public final android.net.Uri topOriginUri;
+    property public final android.net.Uri? verifiedDestination;
+    property public final android.net.Uri? webDestination;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams;
+  }
+
+  public static final class WebSourceRegistrationRequest.Builder {
+    ctor public WebSourceRegistrationRequest.Builder(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams, android.net.Uri topOriginUri);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest build();
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setAppDestination(android.net.Uri? appDestination);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setInputEvent(android.view.InputEvent inputEvent);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setVerifiedDestination(android.net.Uri? verifiedDestination);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setWebDestination(android.net.Uri? webDestination);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebTriggerParams {
+    ctor public WebTriggerParams(android.net.Uri registrationUri, boolean debugKeyAllowed);
+    method public boolean getDebugKeyAllowed();
+    method public android.net.Uri getRegistrationUri();
+    property public final boolean debugKeyAllowed;
+    property public final android.net.Uri registrationUri;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebTriggerRegistrationRequest {
+    ctor public WebTriggerRegistrationRequest(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> webTriggerParams, android.net.Uri destination);
+    method public android.net.Uri getDestination();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> getWebTriggerParams();
+    property public final android.net.Uri destination;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> webTriggerParams;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.topics {
+
+  public final class GetTopicsRequest {
+    ctor public GetTopicsRequest(optional String adsSdkName, optional boolean shouldRecordObservation);
+    method public String getAdsSdkName();
+    method public boolean getShouldRecordObservation();
+    property public final String adsSdkName;
+    property public final boolean shouldRecordObservation;
+  }
+
+  public static final class GetTopicsRequest.Builder {
+    ctor public GetTopicsRequest.Builder();
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest build();
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest.Builder setAdsSdkName(String adsSdkName);
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest.Builder setShouldRecordObservation(boolean shouldRecordObservation);
+  }
+
+  public final class GetTopicsResponse {
+    ctor public GetTopicsResponse(java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> topics);
+    method public java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> getTopics();
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> topics;
+  }
+
+  public final class Topic {
+    ctor public Topic(long taxonomyVersion, long modelVersion, int topicId);
+    method public long getModelVersion();
+    method public long getTaxonomyVersion();
+    method public int getTopicId();
+    property public final long modelVersion;
+    property public final long taxonomyVersion;
+    property public final int topicId;
+  }
+
+  public abstract class TopicsManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_TOPICS) public abstract suspend Object? getTopics(androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest request, kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.topics.GetTopicsResponse>);
+    method public static final androidx.privacysandbox.ads.adservices.topics.TopicsManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.topics.TopicsManager.Companion Companion;
+  }
+
+  public static final class TopicsManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.topics.TopicsManager? obtain(android.content.Context context);
+  }
+
+}
+
diff --git a/privacysandbox/ads/ads-adservices/api/res-1.0.0-beta03.txt b/privacysandbox/ads/ads-adservices/api/res-1.0.0-beta03.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices/api/res-1.0.0-beta03.txt
diff --git a/privacysandbox/ads/ads-adservices/api/restricted_1.0.0-beta03.txt b/privacysandbox/ads/ads-adservices/api/restricted_1.0.0-beta03.txt
new file mode 100644
index 0000000..30cd307
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices/api/restricted_1.0.0-beta03.txt
@@ -0,0 +1,345 @@
+// Signature format: 4.0
+package androidx.privacysandbox.ads.adservices.adid {
+
+  public final class AdId {
+    method public String getAdId();
+    method public boolean isLimitAdTrackingEnabled();
+    property public final String adId;
+    property public final boolean isLimitAdTrackingEnabled;
+  }
+
+  public abstract class AdIdManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_AD_ID) public abstract suspend Object? getAdId(kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.adid.AdId>);
+    method public static final androidx.privacysandbox.ads.adservices.adid.AdIdManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.adid.AdIdManager.Companion Companion;
+  }
+
+  public static final class AdIdManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.adid.AdIdManager? obtain(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.adselection {
+
+  public final class AdSelectionConfig {
+    ctor public AdSelectionConfig(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier seller, android.net.Uri decisionLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> customAudienceBuyers, androidx.privacysandbox.ads.adservices.common.AdSelectionSignals adSelectionSignals, androidx.privacysandbox.ads.adservices.common.AdSelectionSignals sellerSignals, java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> perBuyerSignals, android.net.Uri trustedScoringSignalsUri);
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals getAdSelectionSignals();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> getCustomAudienceBuyers();
+    method public android.net.Uri getDecisionLogicUri();
+    method public java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> getPerBuyerSignals();
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getSeller();
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals getSellerSignals();
+    method public android.net.Uri getTrustedScoringSignalsUri();
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals adSelectionSignals;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> customAudienceBuyers;
+    property public final android.net.Uri decisionLogicUri;
+    property public final java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> perBuyerSignals;
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier seller;
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals sellerSignals;
+    property public final android.net.Uri trustedScoringSignalsUri;
+  }
+
+  public abstract class AdSelectionManager {
+    method public static final androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager? obtain(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? reportImpression(androidx.privacysandbox.ads.adservices.adselection.ReportImpressionRequest reportImpressionRequest, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? selectAds(androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig, kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.adselection.AdSelectionOutcome>);
+    field public static final androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager.Companion Companion;
+  }
+
+  public static final class AdSelectionManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager? obtain(android.content.Context context);
+  }
+
+  public final class AdSelectionOutcome {
+    ctor public AdSelectionOutcome(long adSelectionId, android.net.Uri renderUri);
+    method public long getAdSelectionId();
+    method public android.net.Uri getRenderUri();
+    property public final long adSelectionId;
+    property public final android.net.Uri renderUri;
+  }
+
+  public final class ReportImpressionRequest {
+    ctor public ReportImpressionRequest(long adSelectionId, androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig);
+    method public androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig getAdSelectionConfig();
+    method public long getAdSelectionId();
+    property public final androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig;
+    property public final long adSelectionId;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.appsetid {
+
+  public final class AppSetId {
+    ctor public AppSetId(String id, int scope);
+    method public String getId();
+    method public int getScope();
+    property public final String id;
+    property public final int scope;
+    field public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetId.Companion Companion;
+    field public static final int SCOPE_APP = 1; // 0x1
+    field public static final int SCOPE_DEVELOPER = 2; // 0x2
+  }
+
+  public static final class AppSetId.Companion {
+  }
+
+  public abstract class AppSetIdManager {
+    method public abstract suspend Object? getAppSetId(kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.appsetid.AppSetId>);
+    method public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager.Companion Companion;
+  }
+
+  public static final class AppSetIdManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager? obtain(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.common {
+
+  public final class AdData {
+    ctor public AdData(android.net.Uri renderUri, String metadata);
+    method public String getMetadata();
+    method public android.net.Uri getRenderUri();
+    property public final String metadata;
+    property public final android.net.Uri renderUri;
+  }
+
+  public final class AdSelectionSignals {
+    ctor public AdSelectionSignals(String signals);
+    method public String getSignals();
+    property public final String signals;
+  }
+
+  public final class AdTechIdentifier {
+    ctor public AdTechIdentifier(String identifier);
+    method public String getIdentifier();
+    property public final String identifier;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.customaudience {
+
+  public final class CustomAudience {
+    ctor public CustomAudience(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name, android.net.Uri dailyUpdateUri, android.net.Uri biddingLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads, optional java.time.Instant? activationTime, optional java.time.Instant? expirationTime, optional androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? userBiddingSignals, optional androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? trustedBiddingSignals);
+    method public java.time.Instant? getActivationTime();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> getAds();
+    method public android.net.Uri getBiddingLogicUri();
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getBuyer();
+    method public android.net.Uri getDailyUpdateUri();
+    method public java.time.Instant? getExpirationTime();
+    method public String getName();
+    method public androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? getTrustedBiddingSignals();
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? getUserBiddingSignals();
+    property public final java.time.Instant? activationTime;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads;
+    property public final android.net.Uri biddingLogicUri;
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer;
+    property public final android.net.Uri dailyUpdateUri;
+    property public final java.time.Instant? expirationTime;
+    property public final String name;
+    property public final androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? trustedBiddingSignals;
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? userBiddingSignals;
+  }
+
+  public static final class CustomAudience.Builder {
+    ctor public CustomAudience.Builder(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name, android.net.Uri dailyUpdateUri, android.net.Uri biddingLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience build();
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setActivationTime(java.time.Instant activationTime);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setAds(java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setBiddingLogicUri(android.net.Uri biddingLogicUri);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setBuyer(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setDailyUpdateUri(android.net.Uri dailyUpdateUri);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setExpirationTime(java.time.Instant expirationTime);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setName(String name);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setTrustedBiddingData(androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData trustedBiddingSignals);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setUserBiddingSignals(androidx.privacysandbox.ads.adservices.common.AdSelectionSignals userBiddingSignals);
+  }
+
+  public abstract class CustomAudienceManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? joinCustomAudience(androidx.privacysandbox.ads.adservices.customaudience.JoinCustomAudienceRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? leaveCustomAudience(androidx.privacysandbox.ads.adservices.customaudience.LeaveCustomAudienceRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static final androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager.Companion Companion;
+  }
+
+  public static final class CustomAudienceManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager? obtain(android.content.Context context);
+  }
+
+  public final class JoinCustomAudienceRequest {
+    ctor public JoinCustomAudienceRequest(androidx.privacysandbox.ads.adservices.customaudience.CustomAudience customAudience);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience getCustomAudience();
+    property public final androidx.privacysandbox.ads.adservices.customaudience.CustomAudience customAudience;
+  }
+
+  public final class LeaveCustomAudienceRequest {
+    ctor public LeaveCustomAudienceRequest(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name);
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getBuyer();
+    method public String getName();
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer;
+    property public final String name;
+  }
+
+  public final class TrustedBiddingData {
+    ctor public TrustedBiddingData(android.net.Uri trustedBiddingUri, java.util.List<java.lang.String> trustedBiddingKeys);
+    method public java.util.List<java.lang.String> getTrustedBiddingKeys();
+    method public android.net.Uri getTrustedBiddingUri();
+    property public final java.util.List<java.lang.String> trustedBiddingKeys;
+    property public final android.net.Uri trustedBiddingUri;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.measurement {
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class DeletionRequest {
+    ctor public DeletionRequest(int deletionMode, int matchBehavior, optional java.time.Instant start, optional java.time.Instant end, optional java.util.List<? extends android.net.Uri> domainUris, optional java.util.List<? extends android.net.Uri> originUris);
+    method public int getDeletionMode();
+    method public java.util.List<android.net.Uri> getDomainUris();
+    method public java.time.Instant getEnd();
+    method public int getMatchBehavior();
+    method public java.util.List<android.net.Uri> getOriginUris();
+    method public java.time.Instant getStart();
+    property public final int deletionMode;
+    property public final java.util.List<android.net.Uri> domainUris;
+    property public final java.time.Instant end;
+    property public final int matchBehavior;
+    property public final java.util.List<android.net.Uri> originUris;
+    property public final java.time.Instant start;
+    field public static final androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Companion Companion;
+    field public static final int DELETION_MODE_ALL = 0; // 0x0
+    field public static final int DELETION_MODE_EXCLUDE_INTERNAL_DATA = 1; // 0x1
+    field public static final int MATCH_BEHAVIOR_DELETE = 0; // 0x0
+    field public static final int MATCH_BEHAVIOR_PRESERVE = 1; // 0x1
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class DeletionRequest.Builder {
+    ctor public DeletionRequest.Builder(int deletionMode, int matchBehavior);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest build();
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setDomainUris(java.util.List<? extends android.net.Uri> domainUris);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setEnd(java.time.Instant end);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setOriginUris(java.util.List<? extends android.net.Uri> originUris);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setStart(java.time.Instant start);
+  }
+
+  public static final class DeletionRequest.Companion {
+  }
+
+  public abstract class MeasurementManager {
+    ctor public MeasurementManager();
+    method public abstract suspend Object? deleteRegistrations(androidx.privacysandbox.ads.adservices.measurement.DeletionRequest deletionRequest, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? getMeasurementApiStatus(kotlin.coroutines.Continuation<? super java.lang.Integer>);
+    method public static final androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerSource(android.net.Uri attributionSource, android.view.InputEvent? inputEvent, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerTrigger(android.net.Uri trigger, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebSource(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebTrigger(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    field public static final androidx.privacysandbox.ads.adservices.measurement.MeasurementManager.Companion Companion;
+    field public static final int MEASUREMENT_API_STATE_DISABLED = 0; // 0x0
+    field public static final int MEASUREMENT_API_STATE_ENABLED = 1; // 0x1
+  }
+
+  public static final class MeasurementManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebSourceParams {
+    ctor public WebSourceParams(android.net.Uri registrationUri, boolean debugKeyAllowed);
+    method public boolean getDebugKeyAllowed();
+    method public android.net.Uri getRegistrationUri();
+    property public final boolean debugKeyAllowed;
+    property public final android.net.Uri registrationUri;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebSourceRegistrationRequest {
+    ctor public WebSourceRegistrationRequest(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams, android.net.Uri topOriginUri, optional android.view.InputEvent? inputEvent, optional android.net.Uri? appDestination, optional android.net.Uri? webDestination, optional android.net.Uri? verifiedDestination);
+    method public android.net.Uri? getAppDestination();
+    method public android.view.InputEvent? getInputEvent();
+    method public android.net.Uri getTopOriginUri();
+    method public android.net.Uri? getVerifiedDestination();
+    method public android.net.Uri? getWebDestination();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> getWebSourceParams();
+    property public final android.net.Uri? appDestination;
+    property public final android.view.InputEvent? inputEvent;
+    property public final android.net.Uri topOriginUri;
+    property public final android.net.Uri? verifiedDestination;
+    property public final android.net.Uri? webDestination;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams;
+  }
+
+  public static final class WebSourceRegistrationRequest.Builder {
+    ctor public WebSourceRegistrationRequest.Builder(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams, android.net.Uri topOriginUri);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest build();
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setAppDestination(android.net.Uri? appDestination);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setInputEvent(android.view.InputEvent inputEvent);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setVerifiedDestination(android.net.Uri? verifiedDestination);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setWebDestination(android.net.Uri? webDestination);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebTriggerParams {
+    ctor public WebTriggerParams(android.net.Uri registrationUri, boolean debugKeyAllowed);
+    method public boolean getDebugKeyAllowed();
+    method public android.net.Uri getRegistrationUri();
+    property public final boolean debugKeyAllowed;
+    property public final android.net.Uri registrationUri;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebTriggerRegistrationRequest {
+    ctor public WebTriggerRegistrationRequest(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> webTriggerParams, android.net.Uri destination);
+    method public android.net.Uri getDestination();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> getWebTriggerParams();
+    property public final android.net.Uri destination;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> webTriggerParams;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.topics {
+
+  public final class GetTopicsRequest {
+    ctor public GetTopicsRequest(optional String adsSdkName, optional boolean shouldRecordObservation);
+    method public String getAdsSdkName();
+    method public boolean getShouldRecordObservation();
+    property public final String adsSdkName;
+    property public final boolean shouldRecordObservation;
+  }
+
+  public static final class GetTopicsRequest.Builder {
+    ctor public GetTopicsRequest.Builder();
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest build();
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest.Builder setAdsSdkName(String adsSdkName);
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest.Builder setShouldRecordObservation(boolean shouldRecordObservation);
+  }
+
+  public final class GetTopicsResponse {
+    ctor public GetTopicsResponse(java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> topics);
+    method public java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> getTopics();
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> topics;
+  }
+
+  public final class Topic {
+    ctor public Topic(long taxonomyVersion, long modelVersion, int topicId);
+    method public long getModelVersion();
+    method public long getTaxonomyVersion();
+    method public int getTopicId();
+    property public final long modelVersion;
+    property public final long taxonomyVersion;
+    property public final int topicId;
+  }
+
+  public abstract class TopicsManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_TOPICS) public abstract suspend Object? getTopics(androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest request, kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.topics.GetTopicsResponse>);
+    method public static final androidx.privacysandbox.ads.adservices.topics.TopicsManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.topics.TopicsManager.Companion Companion;
+  }
+
+  public static final class TopicsManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.topics.TopicsManager? obtain(android.content.Context context);
+  }
+
+}
+
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/lint-baseline.xml b/privacysandbox/sdkruntime/sdkruntime-client/lint-baseline.xml
index 4179d5e..7b70e67 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/lint-baseline.xml
+++ b/privacysandbox/sdkruntime/sdkruntime-client/lint-baseline.xml
@@ -2,6 +2,24 @@
 <issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
 
     <issue
+        id="NewApi"
+        message="Call requires API level 33 (current min is 14): `android.app.sdksandbox.SdkSandboxManager#getSandboxedSdks`"
+        errorLine1="        `when`(sdkSandboxManager.sandboxedSdks)"
+        errorLine2="                                 ~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatSandboxedTest.kt"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 33 (current min is 14): `android.app.sdksandbox.SdkSandboxManager#getSandboxedSdks`"
+        errorLine1="        `when`(sdkSandboxManager.sandboxedSdks)"
+        errorLine2="                                 ~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatSandboxedTest.kt"/>
+    </issue>
+
+    <issue
         id="BanThreadSleep"
         message="Uses Thread.sleep()"
         errorLine1="        Thread.sleep(100)"
@@ -19,4 +37,13 @@
             file="src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/storage/CachedLocalSdkStorageTest.kt"/>
     </issue>
 
+    <issue
+        id="BanUncheckedReflection"
+        message="Calling `Method.invoke` without an SDK check"
+        errorLine1="        injectMethod.invoke(null, proxy)"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SandboxControllerInjector.kt"/>
+    </issue>
+
 </issues>
diff --git a/room/room-compiler/lint-baseline.xml b/room/room-compiler/lint-baseline.xml
deleted file mode 100644
index 0b7f2c4..0000000
--- a/room/room-compiler/lint-baseline.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 7.4.0-alpha08" type="baseline" client="gradle" dependencies="false" name="AGP (7.4.0-alpha08)" variant="all" version="7.4.0-alpha08">
-
-    <issue
-        id="SupportAnnotationUsage"
-        message="Did you mean `@get:VisibleForTesting`? Without `get:` this annotates the constructor parameter itself instead of the associated getter."
-        errorLine1="    @VisibleForTesting"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/kotlin/androidx/room/solver/types/NullAwareTypeConverters.kt"/>
-    </issue>
-
-</issues>
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/processor/PojoProcessor.kt b/room/room-compiler/src/main/kotlin/androidx/room/processor/PojoProcessor.kt
index 0f67cea..05c36d0 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/processor/PojoProcessor.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/processor/PojoProcessor.kt
@@ -742,8 +742,7 @@
                     fieldName = field.name,
                     jvmName = field.name,
                     type = field.type,
-                    callType = CallType.FIELD,
-                    isMutableField = !field.element.isFinal()
+                    callType = CallType.FIELD
                 )
             },
             assignFromMethod = { match ->
@@ -756,8 +755,7 @@
                             CallType.SYNTHETIC_METHOD
                         } else {
                             CallType.METHOD
-                        },
-                    isMutableField = !field.element.isFinal()
+                        }
                 )
             },
             reportAmbiguity = { matching ->
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/vo/FieldGetter.kt b/room/room-compiler/src/main/kotlin/androidx/room/vo/FieldGetter.kt
index 05165a4..28cd4c9 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/vo/FieldGetter.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/vo/FieldGetter.kt
@@ -30,7 +30,6 @@
     val jvmName: String,
     val type: XType,
     val callType: CallType,
-    val isMutableField: Boolean
 ) {
     fun writeGet(ownerVar: String, outVar: String, builder: XCodeBlock.Builder) {
         builder.addLocalVariable(
@@ -48,14 +47,11 @@
         scope: CodeGenScope
     ) {
         val varExpr = getterExpression(ownerVar, scope.language)
-        // A temporary local val is needed in Kotlin if the field or property is mutable (var)
-        // and is nullable since otherwise smart cast will fail indicating that the property
-        // might have changed when binding to statement.
-        val needTempVal = scope.language == CodeLanguage.KOTLIN &&
-            (callType == CallType.FIELD || callType == CallType.SYNTHETIC_METHOD) &&
-            type.nullability != XNullability.NONNULL &&
-            isMutableField
-        if (needTempVal) {
+        // A temporary local val is needed in Kotlin whenever the getter method returns nullable or
+        // the field / property is nullable such that a smart cast can be properly performed. Even
+        // if the field / property are immutable (val), we still use a local val in case the
+        // property is declared in another module, which would make the smart cast impossible.
+        if (scope.language == CodeLanguage.KOTLIN && type.nullability != XNullability.NONNULL) {
             val tmpField = scope.getTmpVar("_tmp${fieldName.capitalize(Locale.US)}")
             scope.builder.addLocalVariable(
                 name = tmpField,
@@ -81,7 +77,7 @@
                 CallType.FIELD, CallType.SYNTHETIC_METHOD ->
                     XCodeBlock.of(codeLanguage, "%L.%L", ownerVar, fieldName)
                 CallType.METHOD ->
-                    XCodeBlock.of(codeLanguage, "%L.%L", ownerVar, jvmName)
+                    XCodeBlock.of(codeLanguage, "%L.%L()", ownerVar, jvmName)
                 CallType.CONSTRUCTOR -> error("Getters should never be of type 'constructor'!")
             }
         }
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/EntityNameMatchingVariationsTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/EntityNameMatchingVariationsTest.kt
index 170837e..c71cc23 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/EntityNameMatchingVariationsTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/EntityNameMatchingVariationsTest.kt
@@ -78,7 +78,7 @@
             assertThat(field.setter)
                 .isEqualTo(FieldSetter(field.name, setterName, intType, CallType.METHOD))
             assertThat(field.getter)
-                .isEqualTo(FieldGetter(field.name, getterName, intType, CallType.METHOD, true))
+                .isEqualTo(FieldGetter(field.name, getterName, intType, CallType.METHOD))
         }
     }
 }
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/Fts3TableEntityProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/Fts3TableEntityProcessorTest.kt
index ec64f94..e959e20 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/Fts3TableEntityProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/Fts3TableEntityProcessorTest.kt
@@ -84,7 +84,7 @@
             assertThat(field.setter,
                 `is`(FieldSetter("rowId", "setRowId", intType, CallType.METHOD)))
             assertThat(field.getter,
-                `is`(FieldGetter("rowId", "getRowId", intType, CallType.METHOD, true)))
+                `is`(FieldGetter("rowId", "getRowId", intType, CallType.METHOD)))
             assertThat(entity.primaryKey.fields, `is`(Fields(field)))
             assertThat(entity.shadowTableName, `is`("MyEntity_content"))
             assertThat(entity.ftsVersion, `is`(FtsVersion.FTS3))
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/Fts4TableEntityProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/Fts4TableEntityProcessorTest.kt
index fef806c..178c2938 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/Fts4TableEntityProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/Fts4TableEntityProcessorTest.kt
@@ -71,7 +71,7 @@
             assertThat(field.setter,
                 `is`(FieldSetter("rowId", "setRowId", intType, CallType.METHOD)))
             assertThat(field.getter,
-                `is`(FieldGetter("rowId", "getRowId", intType, CallType.METHOD, true)))
+                `is`(FieldGetter("rowId", "getRowId", intType, CallType.METHOD)))
             assertThat(entity.primaryKey.fields, `is`(Fields(field)))
             assertThat(entity.shadowTableName, `is`("MyEntity_content"))
             assertThat(entity.ftsVersion, `is`(FtsVersion.FTS4))
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest.kt
index 7623237..b345b6f 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest.kt
@@ -2099,8 +2099,7 @@
                     fieldName = "isbn",
                     jvmName = "getIsbn",
                     type = stringType,
-                    callType = CallType.SYNTHETIC_METHOD,
-                    isMutableField = true
+                    callType = CallType.SYNTHETIC_METHOD
                 )
             )
             Truth.assertThat(
@@ -2121,8 +2120,7 @@
                     fieldName = "isbn2",
                     jvmName = "getIsbn2",
                     type = stringType.makeNullable(),
-                    callType = CallType.SYNTHETIC_METHOD,
-                    isMutableField = true
+                    callType = CallType.SYNTHETIC_METHOD
                 )
             )
             Truth.assertThat(
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/TableEntityProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/TableEntityProcessorTest.kt
index a7291ea..e7d8207 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/TableEntityProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/TableEntityProcessorTest.kt
@@ -77,7 +77,7 @@
             )
             assertThat(field.setter, `is`(FieldSetter("id", "setId", intType, CallType.METHOD)))
             assertThat(field.getter,
-                `is`(FieldGetter("id", "getId", intType, CallType.METHOD, true)))
+                `is`(FieldGetter("id", "getId", intType, CallType.METHOD)))
             assertThat(entity.primaryKey.fields, `is`(Fields(field)))
         }
     }
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/verifier/DatabaseVerifierTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/verifier/DatabaseVerifierTest.kt
index dd79611f..0abf406 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/verifier/DatabaseVerifierTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/verifier/DatabaseVerifierTest.kt
@@ -438,7 +438,7 @@
     }
 
     private fun assignGetterSetter(f: Field, name: String, type: XType) {
-        f.getter = FieldGetter(f.name, name, type, CallType.FIELD, true)
+        f.getter = FieldGetter(f.name, name, type, CallType.FIELD)
         f.setter = FieldSetter(f.name, name, type, CallType.FIELD)
     }
 
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/writer/DaoKotlinCodeGenTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/writer/DaoKotlinCodeGenTest.kt
index 7cf8c7f..11f0ed7 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/writer/DaoKotlinCodeGenTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/writer/DaoKotlinCodeGenTest.kt
@@ -86,21 +86,34 @@
             interface MyDao {
               @Query("SELECT * FROM MyEntity")
               fun getEntity(): MyEntity
+
+              @Insert
+              fun addEntity(item: MyEntity)
             }
             """.trimIndent()
         )
         val javaEntity = Source.java(
             "MyEntity",
             """
+            import androidx.annotation.Nullable;
             import androidx.room.*;
             
             @Entity
             public class MyEntity {
               @PrimaryKey
               private long mValue;
-              
+
+              @Nullable
+              private String mNullableValue;
+
               public long getValue() { return mValue; }
               public void setValue(long value) { mValue = value; }
+
+              @Nullable
+              public String getNullableValue() { return mNullableValue; }
+              public void setNullableValue(@Nullable String nullableValue) {
+                mNullableValue = nullableValue;
+              }
             }
             """.trimIndent()
         )
@@ -110,6 +123,59 @@
         )
     }
 
+    // b/274760383
+    @Test
+    fun pojoRowAdapter_otherModule() {
+        val testName = object {}.javaClass.enclosingMethod!!.name
+        val lib = compileFiles(
+            sources = listOf(
+                Source.kotlin(
+                    "MyEntity.kt",
+                """
+                import androidx.room.*
+
+                @Entity
+                class MyEntity(
+                    @PrimaryKey
+                    val pk: Int,
+                    val primitive: Long = 0,
+                    val string: String = "",
+                    val nullableString: String? = null,
+                    @JvmField val fieldString: String = "",
+                    @JvmField val nullableFieldString: String? = null
+                ) {
+                    var variablePrimitive: Long = 0
+                    var variableString: String = ""
+                    var variableNullableString: String? = null
+                    @JvmField var variableFieldString: String = ""
+                    @JvmField var variableNullableFieldString: String? = null
+                }
+                """.trimIndent()
+                )
+            )
+        )
+        val src = Source.kotlin(
+            "MyDao.kt",
+            """
+            import androidx.room.*
+
+            @Dao
+            interface MyDao {
+              @Query("SELECT * FROM MyEntity")
+              fun getEntity(): MyEntity
+
+              @Insert
+              fun addEntity(item: MyEntity)
+            }
+            """.trimIndent()
+        )
+        runTest(
+            sources = listOf(src, databaseSrc),
+            expectedFilePath = getTestGoldenPath(testName),
+            compiledFiles = lib
+        )
+    }
+
     @Test
     fun pojoRowAdapter_internalVisibility() {
         val testName = object {}.javaClass.enclosingMethod!!.name
@@ -1310,6 +1376,7 @@
             expectedFilePath = getTestGoldenPath(testName)
         )
     }
+
     @Test
     fun queryResultAdapter_optional() {
         val testName = object {}.javaClass.enclosingMethod!!.name
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/entityRowAdapter.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/entityRowAdapter.kt
index e42eb9f..e823e0a 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/entityRowAdapter.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/entityRowAdapter.kt
@@ -36,10 +36,11 @@
                 val _tmp: Int = if (entity.valueBoolean) 1 else 0
                 statement.bindLong(2, _tmp.toLong())
                 statement.bindString(3, entity.valueString)
-                if (entity.valueNullableString == null) {
+                val _tmpValueNullableString: String? = entity.valueNullableString
+                if (_tmpValueNullableString == null) {
                     statement.bindNull(4)
                 } else {
-                    statement.bindString(4, entity.valueNullableString)
+                    statement.bindString(4, _tmpValueNullableString)
                 }
                 statement.bindLong(5, entity.variablePrimitive)
                 val _tmpVariableNullableBoolean: Boolean? = entity.variableNullableBoolean
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_boolean.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_boolean.kt
index ab6a26f..e4aa4f3 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_boolean.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_boolean.kt
@@ -34,7 +34,8 @@
                 statement.bindLong(1, entity.pk.toLong())
                 val _tmp: Int = if (entity.boolean) 1 else 0
                 statement.bindLong(2, _tmp.toLong())
-                val _tmp_1: Int? = entity.nullableBoolean?.let { if (it) 1 else 0 }
+                val _tmpNullableBoolean: Boolean? = entity.nullableBoolean
+                val _tmp_1: Int? = _tmpNullableBoolean?.let { if (it) 1 else 0 }
                 if (_tmp_1 == null) {
                     statement.bindNull(3)
                 } else {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_byteArray.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_byteArray.kt
index 53dfdd2..284798e 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_byteArray.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_byteArray.kt
@@ -33,10 +33,11 @@
             public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindBlob(2, entity.byteArray)
-                if (entity.nullableByteArray == null) {
+                val _tmpNullableByteArray: ByteArray? = entity.nullableByteArray
+                if (_tmpNullableByteArray == null) {
                     statement.bindNull(3)
                 } else {
-                    statement.bindBlob(3, entity.nullableByteArray)
+                    statement.bindBlob(3, _tmpNullableByteArray)
                 }
             }
         }
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_enum.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_enum.kt
index 480173c..25aa37e 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_enum.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_enum.kt
@@ -33,10 +33,11 @@
             public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindString(2, __Fruit_enumToString(entity.enum))
-                if (entity.nullableEnum == null) {
+                val _tmpNullableEnum: Fruit? = entity.nullableEnum
+                if (_tmpNullableEnum == null) {
                     statement.bindNull(3)
                 } else {
-                    statement.bindString(3, __Fruit_enumToString(entity.nullableEnum))
+                    statement.bindString(3, __Fruit_enumToString(_tmpNullableEnum))
                 }
             }
         }
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_otherModule.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_otherModule.kt
new file mode 100644
index 0000000..8b4945d
--- /dev/null
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_otherModule.kt
@@ -0,0 +1,153 @@
+import android.database.Cursor
+import androidx.room.EntityInsertionAdapter
+import androidx.room.RoomDatabase
+import androidx.room.RoomSQLiteQuery
+import androidx.room.RoomSQLiteQuery.Companion.acquire
+import androidx.room.util.getColumnIndexOrThrow
+import androidx.room.util.query
+import androidx.sqlite.db.SupportSQLiteStatement
+import java.lang.Class
+import javax.`annotation`.processing.Generated
+import kotlin.Int
+import kotlin.Long
+import kotlin.String
+import kotlin.Suppress
+import kotlin.Unit
+import kotlin.collections.List
+import kotlin.jvm.JvmStatic
+
+@Generated(value = ["androidx.room.RoomProcessor"])
+@Suppress(names = ["UNCHECKED_CAST", "DEPRECATION", "REDUNDANT_PROJECTION"])
+public class MyDao_Impl(
+    __db: RoomDatabase,
+) : MyDao {
+    private val __db: RoomDatabase
+
+    private val __insertionAdapterOfMyEntity: EntityInsertionAdapter<MyEntity>
+    init {
+        this.__db = __db
+        this.__insertionAdapterOfMyEntity = object : EntityInsertionAdapter<MyEntity>(__db) {
+            public override fun createQuery(): String =
+                "INSERT OR ABORT INTO `MyEntity` (`pk`,`primitive`,`string`,`nullableString`,`fieldString`,`nullableFieldString`,`variablePrimitive`,`variableString`,`variableNullableString`,`variableFieldString`,`variableNullableFieldString`) VALUES (?,?,?,?,?,?,?,?,?,?,?)"
+
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+                statement.bindLong(1, entity.pk.toLong())
+                statement.bindLong(2, entity.primitive)
+                statement.bindString(3, entity.string)
+                val _tmpNullableString: String? = entity.nullableString
+                if (_tmpNullableString == null) {
+                    statement.bindNull(4)
+                } else {
+                    statement.bindString(4, _tmpNullableString)
+                }
+                statement.bindString(5, entity.fieldString)
+                val _tmpNullableFieldString: String? = entity.nullableFieldString
+                if (_tmpNullableFieldString == null) {
+                    statement.bindNull(6)
+                } else {
+                    statement.bindString(6, _tmpNullableFieldString)
+                }
+                statement.bindLong(7, entity.variablePrimitive)
+                statement.bindString(8, entity.variableString)
+                val _tmpVariableNullableString: String? = entity.variableNullableString
+                if (_tmpVariableNullableString == null) {
+                    statement.bindNull(9)
+                } else {
+                    statement.bindString(9, _tmpVariableNullableString)
+                }
+                statement.bindString(10, entity.variableFieldString)
+                val _tmpVariableNullableFieldString: String? = entity.variableNullableFieldString
+                if (_tmpVariableNullableFieldString == null) {
+                    statement.bindNull(11)
+                } else {
+                    statement.bindString(11, _tmpVariableNullableFieldString)
+                }
+            }
+        }
+    }
+
+    public override fun addEntity(item: MyEntity): Unit {
+        __db.assertNotSuspendingTransaction()
+        __db.beginTransaction()
+        try {
+            __insertionAdapterOfMyEntity.insert(item)
+            __db.setTransactionSuccessful()
+        } finally {
+            __db.endTransaction()
+        }
+    }
+
+    public override fun getEntity(): MyEntity {
+        val _sql: String = "SELECT * FROM MyEntity"
+        val _statement: RoomSQLiteQuery = acquire(_sql, 0)
+        __db.assertNotSuspendingTransaction()
+        val _cursor: Cursor = query(__db, _statement, false, null)
+        try {
+            val _cursorIndexOfPk: Int = getColumnIndexOrThrow(_cursor, "pk")
+            val _cursorIndexOfPrimitive: Int = getColumnIndexOrThrow(_cursor, "primitive")
+            val _cursorIndexOfString: Int = getColumnIndexOrThrow(_cursor, "string")
+            val _cursorIndexOfNullableString: Int = getColumnIndexOrThrow(_cursor, "nullableString")
+            val _cursorIndexOfFieldString: Int = getColumnIndexOrThrow(_cursor, "fieldString")
+            val _cursorIndexOfNullableFieldString: Int = getColumnIndexOrThrow(_cursor,
+                "nullableFieldString")
+            val _cursorIndexOfVariablePrimitive: Int = getColumnIndexOrThrow(_cursor, "variablePrimitive")
+            val _cursorIndexOfVariableString: Int = getColumnIndexOrThrow(_cursor, "variableString")
+            val _cursorIndexOfVariableNullableString: Int = getColumnIndexOrThrow(_cursor,
+                "variableNullableString")
+            val _cursorIndexOfVariableFieldString: Int = getColumnIndexOrThrow(_cursor,
+                "variableFieldString")
+            val _cursorIndexOfVariableNullableFieldString: Int = getColumnIndexOrThrow(_cursor,
+                "variableNullableFieldString")
+            val _result: MyEntity
+            if (_cursor.moveToFirst()) {
+                val _tmpPk: Int
+                _tmpPk = _cursor.getInt(_cursorIndexOfPk)
+                val _tmpPrimitive: Long
+                _tmpPrimitive = _cursor.getLong(_cursorIndexOfPrimitive)
+                val _tmpString: String
+                _tmpString = _cursor.getString(_cursorIndexOfString)
+                val _tmpNullableString: String?
+                if (_cursor.isNull(_cursorIndexOfNullableString)) {
+                    _tmpNullableString = null
+                } else {
+                    _tmpNullableString = _cursor.getString(_cursorIndexOfNullableString)
+                }
+                val _tmpFieldString: String
+                _tmpFieldString = _cursor.getString(_cursorIndexOfFieldString)
+                val _tmpNullableFieldString: String?
+                if (_cursor.isNull(_cursorIndexOfNullableFieldString)) {
+                    _tmpNullableFieldString = null
+                } else {
+                    _tmpNullableFieldString = _cursor.getString(_cursorIndexOfNullableFieldString)
+                }
+                _result =
+                    MyEntity(_tmpPk,_tmpPrimitive,_tmpString,_tmpNullableString,_tmpFieldString,_tmpNullableFieldString)
+                _result.variablePrimitive = _cursor.getLong(_cursorIndexOfVariablePrimitive)
+                _result.variableString = _cursor.getString(_cursorIndexOfVariableString)
+                if (_cursor.isNull(_cursorIndexOfVariableNullableString)) {
+                    _result.variableNullableString = null
+                } else {
+                    _result.variableNullableString = _cursor.getString(_cursorIndexOfVariableNullableString)
+                }
+                _result.variableFieldString = _cursor.getString(_cursorIndexOfVariableFieldString)
+                if (_cursor.isNull(_cursorIndexOfVariableNullableFieldString)) {
+                    _result.variableNullableFieldString = null
+                } else {
+                    _result.variableNullableFieldString =
+                        _cursor.getString(_cursorIndexOfVariableNullableFieldString)
+                }
+            } else {
+                error("Cursor was empty, but expected a single item.")
+            }
+            return _result
+        } finally {
+            _cursor.close()
+            _statement.release()
+        }
+    }
+
+    public companion object {
+        @JvmStatic
+        public fun getRequiredConverters(): List<Class<*>> = emptyList()
+    }
+}
\ No newline at end of file
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_primitives_nullable.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_primitives_nullable.kt
index 19411e3..3ec68d0 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_primitives_nullable.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_primitives_nullable.kt
@@ -36,40 +36,47 @@
                 "INSERT OR ABORT INTO `MyEntity` (`int`,`short`,`byte`,`long`,`char`,`float`,`double`) VALUES (?,?,?,?,?,?,?)"
 
             public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
-                if (entity.int == null) {
+                val _tmpInt: Int? = entity.int
+                if (_tmpInt == null) {
                     statement.bindNull(1)
                 } else {
-                    statement.bindLong(1, entity.int.toLong())
+                    statement.bindLong(1, _tmpInt.toLong())
                 }
-                if (entity.short == null) {
+                val _tmpShort: Short? = entity.short
+                if (_tmpShort == null) {
                     statement.bindNull(2)
                 } else {
-                    statement.bindLong(2, entity.short.toLong())
+                    statement.bindLong(2, _tmpShort.toLong())
                 }
-                if (entity.byte == null) {
+                val _tmpByte: Byte? = entity.byte
+                if (_tmpByte == null) {
                     statement.bindNull(3)
                 } else {
-                    statement.bindLong(3, entity.byte.toLong())
+                    statement.bindLong(3, _tmpByte.toLong())
                 }
-                if (entity.long == null) {
+                val _tmpLong: Long? = entity.long
+                if (_tmpLong == null) {
                     statement.bindNull(4)
                 } else {
-                    statement.bindLong(4, entity.long)
+                    statement.bindLong(4, _tmpLong)
                 }
-                if (entity.char == null) {
+                val _tmpChar: Char? = entity.char
+                if (_tmpChar == null) {
                     statement.bindNull(5)
                 } else {
-                    statement.bindLong(5, entity.char.toLong())
+                    statement.bindLong(5, _tmpChar.toLong())
                 }
-                if (entity.float == null) {
+                val _tmpFloat: Float? = entity.float
+                if (_tmpFloat == null) {
                     statement.bindNull(6)
                 } else {
-                    statement.bindDouble(6, entity.float.toDouble())
+                    statement.bindDouble(6, _tmpFloat.toDouble())
                 }
-                if (entity.double == null) {
+                val _tmpDouble: Double? = entity.double
+                if (_tmpDouble == null) {
                     statement.bindNull(7)
                 } else {
-                    statement.bindDouble(7, entity.double)
+                    statement.bindDouble(7, _tmpDouble)
                 }
             }
         }
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_string.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_string.kt
index 534cef8..0a4b23b 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_string.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_string.kt
@@ -31,10 +31,11 @@
 
             public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
                 statement.bindString(1, entity.string)
-                if (entity.nullableString == null) {
+                val _tmpNullableString: String? = entity.nullableString
+                if (_tmpNullableString == null) {
                     statement.bindNull(2)
                 } else {
-                    statement.bindString(2, entity.nullableString)
+                    statement.bindString(2, _tmpNullableString)
                 }
             }
         }
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_uuid.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_uuid.kt
index 884c2a9..dd7f1df 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_uuid.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_uuid.kt
@@ -35,10 +35,11 @@
             public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
                 statement.bindLong(1, entity.pk.toLong())
                 statement.bindBlob(2, convertUUIDToByte(entity.uuid))
-                if (entity.nullableUuid == null) {
+                val _tmpNullableUuid: UUID? = entity.nullableUuid
+                if (_tmpNullableUuid == null) {
                     statement.bindNull(3)
                 } else {
-                    statement.bindBlob(3, convertUUIDToByte(entity.nullableUuid))
+                    statement.bindBlob(3, convertUUIDToByte(_tmpNullableUuid))
                 }
             }
         }
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_variableProperty_java.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_variableProperty_java.kt
index 6a0ead8..9ffae96 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_variableProperty_java.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/pojoRowAdapter_variableProperty_java.kt
@@ -1,15 +1,18 @@
 import android.database.Cursor
+import androidx.room.EntityInsertionAdapter
 import androidx.room.RoomDatabase
 import androidx.room.RoomSQLiteQuery
 import androidx.room.RoomSQLiteQuery.Companion.acquire
 import androidx.room.util.getColumnIndexOrThrow
 import androidx.room.util.query
+import androidx.sqlite.db.SupportSQLiteStatement
 import java.lang.Class
 import javax.`annotation`.processing.Generated
 import kotlin.Int
 import kotlin.Long
 import kotlin.String
 import kotlin.Suppress
+import kotlin.Unit
 import kotlin.collections.List
 import kotlin.jvm.JvmStatic
 
@@ -19,8 +22,35 @@
     __db: RoomDatabase,
 ) : MyDao {
     private val __db: RoomDatabase
+
+    private val __insertionAdapterOfMyEntity: EntityInsertionAdapter<MyEntity>
     init {
         this.__db = __db
+        this.__insertionAdapterOfMyEntity = object : EntityInsertionAdapter<MyEntity>(__db) {
+            public override fun createQuery(): String =
+                "INSERT OR ABORT INTO `MyEntity` (`mValue`,`mNullableValue`) VALUES (?,?)"
+
+            public override fun bind(statement: SupportSQLiteStatement, entity: MyEntity): Unit {
+                statement.bindLong(1, entity.getValue())
+                val _tmpMNullableValue: String? = entity.getNullableValue()
+                if (_tmpMNullableValue == null) {
+                    statement.bindNull(2)
+                } else {
+                    statement.bindString(2, _tmpMNullableValue)
+                }
+            }
+        }
+    }
+
+    public override fun addEntity(item: MyEntity): Unit {
+        __db.assertNotSuspendingTransaction()
+        __db.beginTransaction()
+        try {
+            __insertionAdapterOfMyEntity.insert(item)
+            __db.setTransactionSuccessful()
+        } finally {
+            __db.endTransaction()
+        }
     }
 
     public override fun getEntity(): MyEntity {
@@ -30,12 +60,20 @@
         val _cursor: Cursor = query(__db, _statement, false, null)
         try {
             val _cursorIndexOfMValue: Int = getColumnIndexOrThrow(_cursor, "mValue")
+            val _cursorIndexOfMNullableValue: Int = getColumnIndexOrThrow(_cursor, "mNullableValue")
             val _result: MyEntity
             if (_cursor.moveToFirst()) {
                 _result = MyEntity()
                 val _tmpMValue: Long
                 _tmpMValue = _cursor.getLong(_cursorIndexOfMValue)
                 _result.setValue(_tmpMValue)
+                val _tmpMNullableValue: String?
+                if (_cursor.isNull(_cursorIndexOfMNullableValue)) {
+                    _tmpMNullableValue = null
+                } else {
+                    _tmpMNullableValue = _cursor.getString(_cursorIndexOfMNullableValue)
+                }
+                _result.setNullableValue(_tmpMNullableValue)
             } else {
                 error("Cursor was empty, but expected a single item.")
             }
diff --git a/room/room-rxjava2/lint-baseline.xml b/room/room-rxjava2/lint-baseline.xml
index 3744975..02e92c5 100644
--- a/room/room-rxjava2/lint-baseline.xml
+++ b/room/room-rxjava2/lint-baseline.xml
@@ -139,7 +139,7 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public static &lt;T> Single&lt;T> createSingle(final Callable&lt;T> callable) {"
+        errorLine1="    public static &lt;T> Single&lt;T> createSingle(final Callable&lt;? extends T> callable) {"
         errorLine2="                      ~~~~~~~~~">
         <location
             file="src/main/java/androidx/room/RxRoom.java"/>
@@ -148,8 +148,8 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public static &lt;T> Single&lt;T> createSingle(final Callable&lt;T> callable) {"
-        errorLine2="                                                   ~~~~~~~~~~~">
+        errorLine1="    public static &lt;T> Single&lt;T> createSingle(final Callable&lt;? extends T> callable) {"
+        errorLine2="                                                   ~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="src/main/java/androidx/room/RxRoom.java"/>
     </issue>
diff --git a/samples/AndroidXDemos/lint-baseline.xml b/samples/AndroidXDemos/lint-baseline.xml
index 9bd9dcf..ac89c9e 100644
--- a/samples/AndroidXDemos/lint-baseline.xml
+++ b/samples/AndroidXDemos/lint-baseline.xml
@@ -45,7 +45,7 @@
         <location
             file="src/main/res/layout/appcompat_night_mode.xml"/>
         <location
-            file="src/main/res/layout/appcompat_night_mode.xml"/>
+            file="src/main/res/layout/appcompat_night_mode.xml"
             message="`wrap_content` here may not work well with WebView below"/>
     </issue>
 
diff --git a/settings.gradle b/settings.gradle
index 0f23320..4a28986 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -600,6 +600,7 @@
 includeProject(":contentpager:contentpager", [BuildType.MAIN])
 includeProject(":coordinatorlayout:coordinatorlayout", [BuildType.MAIN])
 includeProject(":core:core", [BuildType.MAIN, BuildType.GLANCE, BuildType.MEDIA, BuildType.FLAN, BuildType.COMPOSE, BuildType.WEAR])
+includeProject(":core:core-testing", [BuildType.MAIN, BuildType.GLANCE, BuildType.MEDIA, BuildType.FLAN, BuildType.COMPOSE, BuildType.WEAR])
 includeProject(":core:core:integration-tests:publishing", [BuildType.MAIN])
 includeProject(":core:core-animation", [BuildType.MAIN])
 includeProject(":core:core-animation-integration-tests:testapp", [BuildType.MAIN])
diff --git a/swiperefreshlayout/swiperefreshlayout/lint-baseline.xml b/swiperefreshlayout/swiperefreshlayout/lint-baseline.xml
index f9d16b9..be24f80 100644
--- a/swiperefreshlayout/swiperefreshlayout/lint-baseline.xml
+++ b/swiperefreshlayout/swiperefreshlayout/lint-baseline.xml
@@ -16,15 +16,6 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public void draw(Canvas canvas) {"
-        errorLine2="                     ~~~~~~">
-        <location
-            file="src/main/java/androidx/swiperefreshlayout/widget/CircularProgressDrawable.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
         errorLine1="    public void setColorFilter(ColorFilter colorFilter) {"
         errorLine2="                               ~~~~~~~~~~~">
         <location
@@ -34,7 +25,7 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {"
+        errorLine1="    public boolean onStartNestedScroll(View child, View target, int axes) {"
         errorLine2="                                       ~~~~">
         <location
             file="src/main/java/androidx/swiperefreshlayout/widget/SwipeRefreshLayout.java"/>
@@ -43,7 +34,7 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {"
+        errorLine1="    public boolean onStartNestedScroll(View child, View target, int axes) {"
         errorLine2="                                                   ~~~~">
         <location
             file="src/main/java/androidx/swiperefreshlayout/widget/SwipeRefreshLayout.java"/>
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/FontPaddingWithCustomFallbackTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/FontPaddingWithCustomFallbackTest.kt
index 7b70ec8..c5c6cee 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/FontPaddingWithCustomFallbackTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/FontPaddingWithCustomFallbackTest.kt
@@ -12,10 +12,10 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.testutils.fonts.R
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.spy
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextAndroidCanvasTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextAndroidCanvasTest.kt
index a1908cf..c12d1a3 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextAndroidCanvasTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextAndroidCanvasTest.kt
@@ -19,9 +19,9 @@
 import android.graphics.Canvas
 import android.graphics.Rect
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.whenever
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
 import org.junit.Test
 
 class TextAndroidCanvasTest {
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutSpanTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutSpanTest.kt
index 60813ab..8a8387f 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutSpanTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutSpanTest.kt
@@ -29,7 +29,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.testutils.fonts.R
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.any
+import org.mockito.kotlin.any
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/LetterSpacingSpanPxTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/LetterSpacingSpanPxTest.kt
index bc6345c..e40871d 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/LetterSpacingSpanPxTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/LetterSpacingSpanPxTest.kt
@@ -20,11 +20,11 @@
 import androidx.compose.ui.text.android.InternalPlatformTextApi
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.doReturn
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.never
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/tracing/tracing-ktx/api/1.2.0-beta03.txt b/tracing/tracing-ktx/api/1.2.0-beta03.txt
new file mode 100644
index 0000000..13d99d1
--- /dev/null
+++ b/tracing/tracing-ktx/api/1.2.0-beta03.txt
@@ -0,0 +1,12 @@
+// Signature format: 4.0
+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 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);
+  }
+
+}
+
diff --git a/tracing/tracing-ktx/api/public_plus_experimental_1.2.0-beta03.txt b/tracing/tracing-ktx/api/public_plus_experimental_1.2.0-beta03.txt
new file mode 100644
index 0000000..13d99d1
--- /dev/null
+++ b/tracing/tracing-ktx/api/public_plus_experimental_1.2.0-beta03.txt
@@ -0,0 +1,12 @@
+// Signature format: 4.0
+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 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);
+  }
+
+}
+
diff --git a/tracing/tracing-ktx/api/res-1.2.0-beta03.txt b/tracing/tracing-ktx/api/res-1.2.0-beta03.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tracing/tracing-ktx/api/res-1.2.0-beta03.txt
diff --git a/tracing/tracing-ktx/api/restricted_1.2.0-beta03.txt b/tracing/tracing-ktx/api/restricted_1.2.0-beta03.txt
new file mode 100644
index 0000000..13d99d1
--- /dev/null
+++ b/tracing/tracing-ktx/api/restricted_1.2.0-beta03.txt
@@ -0,0 +1,12 @@
+// Signature format: 4.0
+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 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);
+  }
+
+}
+
diff --git a/tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc b/tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc
index 6b374c9..8ff0690 100644
--- a/tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc
+++ b/tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc
@@ -25,7 +25,7 @@
 // Concept of version useful e.g. for human-readable error messages, and stable once released.
 // Does not replace the need for a binary verification mechanism (e.g. checksum check).
 // TODO: populate using CMake
-#define VERSION "1.0.0-alpha13"
+#define VERSION "1.0.0-alpha14"
 
 namespace tracing_perfetto {
     void RegisterWithPerfetto() {
diff --git a/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/jni/test/PerfettoNativeTest.kt b/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/jni/test/PerfettoNativeTest.kt
index 7611798..c869b03 100644
--- a/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/jni/test/PerfettoNativeTest.kt
+++ b/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/jni/test/PerfettoNativeTest.kt
@@ -30,7 +30,7 @@
         init {
             PerfettoNative.loadLib()
         }
-        const val libraryVersion = "1.0.0-alpha13" // TODO: get using reflection
+        const val libraryVersion = "1.0.0-alpha14" // TODO: get using reflection
     }
 
     @Test
diff --git a/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/jni/PerfettoNative.kt b/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/jni/PerfettoNative.kt
index 3ab9718..99808c3 100644
--- a/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/jni/PerfettoNative.kt
+++ b/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/jni/PerfettoNative.kt
@@ -25,12 +25,12 @@
 
     // TODO(224510255): load from a file produced at build time
     object Metadata {
-        const val version = "1.0.0-alpha13"
+        const val version = "1.0.0-alpha14"
         val checksums = mapOf(
-            "arm64-v8a" to "3513a43f87bb7b455a626fbbe3e0f2b65585ad929d81825ce7126fcfe250a6bb",
-            "armeabi-v7a" to "de02d5fcc0f2cfacb2376f18836326886f23cd3df7359d9e0edae93bd6e3e7c8",
-            "x86" to "4ae9b924dc06ac16b0cc591b7bd61197f51efcbfebc0909fdf78778fef1f715c",
-            "x86_64" to "793b66df2d387626f005e15a4ab564acb6e32cd33dc17ec58e46e4fef05326c2",
+            "arm64-v8a" to "8a1bcce00f057c9fb89bf15e82eab868cccbf852008a7aabff1f62bcbbb7f0a5",
+            "armeabi-v7a" to "f3fa9ceefd0de73530a1c113076971d2a33b220801a2d9f0aca82c3a12dcd239",
+            "x86" to "8e76c311e07c8a90efa4f863b5e62e4e9f66f4a271c9abadee2118d82b680a70",
+            "x86_64" to "1f86e16f363f6df6e593b9c83cdd1187e252448c9aed067859c0785339b3f56d",
         )
     }
 
diff --git a/tracing/tracing/api/1.2.0-beta03.txt b/tracing/tracing/api/1.2.0-beta03.txt
new file mode 100644
index 0000000..c883da2
--- /dev/null
+++ b/tracing/tracing/api/1.2.0-beta03.txt
@@ -0,0 +1,15 @@
+// Signature format: 4.0
+package androidx.tracing {
+
+  public final class Trace {
+    method public static void beginAsyncSection(String, int);
+    method public static void beginSection(String);
+    method public static void endAsyncSection(String, int);
+    method public static void endSection();
+    method public static void forceEnableAppTracing();
+    method public static boolean isEnabled();
+    method public static void setCounter(String, int);
+  }
+
+}
+
diff --git a/tracing/tracing/api/public_plus_experimental_1.2.0-beta03.txt b/tracing/tracing/api/public_plus_experimental_1.2.0-beta03.txt
new file mode 100644
index 0000000..c883da2
--- /dev/null
+++ b/tracing/tracing/api/public_plus_experimental_1.2.0-beta03.txt
@@ -0,0 +1,15 @@
+// Signature format: 4.0
+package androidx.tracing {
+
+  public final class Trace {
+    method public static void beginAsyncSection(String, int);
+    method public static void beginSection(String);
+    method public static void endAsyncSection(String, int);
+    method public static void endSection();
+    method public static void forceEnableAppTracing();
+    method public static boolean isEnabled();
+    method public static void setCounter(String, int);
+  }
+
+}
+
diff --git a/tracing/tracing/api/res-1.2.0-beta03.txt b/tracing/tracing/api/res-1.2.0-beta03.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tracing/tracing/api/res-1.2.0-beta03.txt
diff --git a/tracing/tracing/api/restricted_1.2.0-beta03.txt b/tracing/tracing/api/restricted_1.2.0-beta03.txt
new file mode 100644
index 0000000..c883da2
--- /dev/null
+++ b/tracing/tracing/api/restricted_1.2.0-beta03.txt
@@ -0,0 +1,15 @@
+// Signature format: 4.0
+package androidx.tracing {
+
+  public final class Trace {
+    method public static void beginAsyncSection(String, int);
+    method public static void beginSection(String);
+    method public static void endAsyncSection(String, int);
+    method public static void endSection();
+    method public static void forceEnableAppTracing();
+    method public static boolean isEnabled();
+    method public static void setCounter(String, int);
+  }
+
+}
+
diff --git a/wear/compose/compose-material3/src/androidMain/kotlin/androidx/wear/compose/material3/DefaultPlatformTextStyle.kt b/wear/compose/compose-material3/src/androidMain/kotlin/androidx/wear/compose/material3/DefaultPlatformTextStyle.kt
new file mode 100644
index 0000000..65dd2202
--- /dev/null
+++ b/wear/compose/compose-material3/src/androidMain/kotlin/androidx/wear/compose/material3/DefaultPlatformTextStyle.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.wear.compose.material3
+
+import androidx.compose.ui.text.PlatformTextStyle
+
+private const val DefaultIncludeFontPadding = true
+
+@Suppress("DEPRECATION")
+private val DefaultPlatformTextStyle = PlatformTextStyle(
+    includeFontPadding = DefaultIncludeFontPadding
+)
+internal fun defaultPlatformTextStyle(): PlatformTextStyle = DefaultPlatformTextStyle
\ No newline at end of file
diff --git a/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/Text.kt b/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/Text.kt
index 9efaa5e..b8c9829 100644
--- a/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/Text.kt
+++ b/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/Text.kt
@@ -242,7 +242,7 @@
  * @see ProvideTextStyle
  */
 public val LocalTextStyle: ProvidableCompositionLocal<TextStyle> =
-    compositionLocalOf(structuralEqualityPolicy()) { TextStyle.Default }
+    compositionLocalOf(structuralEqualityPolicy()) { DefaultTextStyle }
 
 /**
  * This function is used to set the current value of [LocalTextStyle], merging the given style
diff --git a/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/Typography.kt b/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/Typography.kt
index 34d16b6..96e3f33 100644
--- a/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/Typography.kt
+++ b/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/Typography.kt
@@ -17,6 +17,7 @@
 
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.staticCompositionLocalOf
+import androidx.compose.ui.text.PlatformTextStyle
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.font.FontFamily
 import androidx.compose.ui.text.font.FontWeight
@@ -97,85 +98,85 @@
 ) {
     public constructor (
         defaultFontFamily: FontFamily = FontFamily.Default,
-        displayExtraLarge: TextStyle = TextStyle(
+        displayExtraLarge: TextStyle = DefaultTextStyle.copy(
             fontWeight = FontWeight.Medium,
             fontSize = 50.sp,
             lineHeight = 56.sp,
             letterSpacing = 0.5.sp
         ),
-        displayLarge: TextStyle = TextStyle(
+        displayLarge: TextStyle = DefaultTextStyle.copy(
             fontWeight = FontWeight.Medium,
             fontSize = 40.sp,
             lineHeight = 46.sp,
             letterSpacing = 0.5.sp
         ),
-        displayMedium: TextStyle = TextStyle(
+        displayMedium: TextStyle = DefaultTextStyle.copy(
             fontWeight = FontWeight.Medium,
             fontSize = 34.sp,
             lineHeight = 40.sp,
             letterSpacing = 1.sp
         ),
-        displaySmall: TextStyle = TextStyle(
+        displaySmall: TextStyle = DefaultTextStyle.copy(
             fontWeight = FontWeight.Medium,
             fontSize = 30.sp,
             lineHeight = 36.sp,
             letterSpacing = 0.8.sp,
         ),
-        titleLarge: TextStyle = TextStyle(
+        titleLarge: TextStyle = DefaultTextStyle.copy(
             fontWeight = FontWeight.Medium,
             fontSize = 24.sp,
             lineHeight = 28.sp,
             letterSpacing = 0.2.sp
         ),
-        titleMedium: TextStyle = TextStyle(
+        titleMedium: TextStyle = DefaultTextStyle.copy(
             fontWeight = FontWeight.Medium,
             fontSize = 20.sp,
             lineHeight = 24.sp,
             letterSpacing = 0.2.sp
         ),
-        titleSmall: TextStyle = TextStyle(
+        titleSmall: TextStyle = DefaultTextStyle.copy(
             fontWeight = FontWeight.Medium,
             fontSize = 16.sp,
             lineHeight = 20.sp,
             letterSpacing = 0.2.sp
         ),
-        bodyLarge: TextStyle = TextStyle(
+        bodyLarge: TextStyle = DefaultTextStyle.copy(
             fontWeight = FontWeight.Normal,
             fontSize = 16.sp,
             lineHeight = 20.sp,
             letterSpacing = 0.18.sp
         ),
-        bodyMedium: TextStyle = TextStyle(
+        bodyMedium: TextStyle = DefaultTextStyle.copy(
             fontWeight = FontWeight.Medium,
             fontSize = 16.sp,
             lineHeight = 20.sp,
             letterSpacing = 0.2.sp
         ),
-        bodySmall: TextStyle = TextStyle(
+        bodySmall: TextStyle = DefaultTextStyle.copy(
             fontWeight = FontWeight.Normal,
             fontSize = 14.sp,
             lineHeight = 18.sp,
             letterSpacing = 0.2.sp
         ),
-        buttonMedium: TextStyle = TextStyle(
+        buttonMedium: TextStyle = DefaultTextStyle.copy(
             fontWeight = FontWeight.Medium,
             fontSize = 15.sp,
             lineHeight = 19.sp,
             letterSpacing = 0.2.sp
         ),
-        captionLarge: TextStyle = TextStyle(
+        captionLarge: TextStyle = DefaultTextStyle.copy(
             fontWeight = FontWeight.Medium,
             fontSize = 14.sp,
             lineHeight = 18.sp,
             letterSpacing = 0.3.sp
         ),
-        captionMedium: TextStyle = TextStyle(
+        captionMedium: TextStyle = DefaultTextStyle.copy(
             fontWeight = FontWeight.Medium,
             fontSize = 12.sp,
             lineHeight = 16.sp,
             letterSpacing = 0.4.sp
         ),
-        captionSmall: TextStyle = TextStyle(
+        captionSmall: TextStyle = DefaultTextStyle.copy(
             fontWeight = FontWeight.Medium,
             fontSize = 10.sp,
             lineHeight = 14.sp,
@@ -293,6 +294,13 @@
 }
 
 /**
+ * Returns theme default [TextStyle] with default [PlatformTextStyle].
+ */
+internal val DefaultTextStyle = TextStyle.Default.copy(
+    platformStyle = defaultPlatformTextStyle()
+)
+
+/**
  * This Ambient holds on to the current definition of typography for this application as described
  * by the Wear Material spec. You can read the values in it when creating custom components that
  * want to use Wear Material types, as well as override the values when you want to re-style a part
diff --git a/wear/protolayout/protolayout-expression-pipeline/build.gradle b/wear/protolayout/protolayout-expression-pipeline/build.gradle
index c07d335..d9db9ac 100644
--- a/wear/protolayout/protolayout-expression-pipeline/build.gradle
+++ b/wear/protolayout/protolayout-expression-pipeline/build.gradle
@@ -27,7 +27,7 @@
     implementation("androidx.collection:collection:1.2.0")
     implementation("androidx.core:core:1.7.0")
 
-    implementation("androidx.annotation:annotation-experimental:1.2.0")
+    implementation("androidx.annotation:annotation-experimental:1.3.0")
     implementation(project(path: ":wear:protolayout:protolayout-proto", configuration: "shadow"))
     implementation(project(":wear:protolayout:protolayout-expression"))
 
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/MainThreadExecutor.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/MainThreadExecutor.java
index 600bb618..fbe8d56 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/MainThreadExecutor.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/MainThreadExecutor.java
@@ -35,6 +35,10 @@
 
     @Override
     public void execute(Runnable r) {
-        mHandler.post(r);
+        if (mHandler.getLooper().isCurrentThread()) {
+            r.run();
+        } else {
+            mHandler.post(r);
+        }
     }
 }
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluatorTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluatorTest.java
index 630218e..cb10184 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluatorTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluatorTest.java
@@ -20,12 +20,9 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.robolectric.Shadows.shadowOf;
-
 import static java.lang.Integer.MAX_VALUE;
 
 import android.icu.util.ULocale;
-import android.os.Looper;
 
 import androidx.annotation.NonNull;
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool;
@@ -362,7 +359,6 @@
                     };
 
             this.mExpressionEvaluator.accept(evaluator, callback);
-            shadowOf(Looper.getMainLooper()).idle();
 
             assertThat(results).hasSize(1);
             assertThat(results).containsExactly(mExpectedValue);
diff --git a/wear/protolayout/protolayout-expression/build.gradle b/wear/protolayout/protolayout-expression/build.gradle
index 7bb1001..c9777d4 100644
--- a/wear/protolayout/protolayout-expression/build.gradle
+++ b/wear/protolayout/protolayout-expression/build.gradle
@@ -25,10 +25,11 @@
     annotationProcessor(libs.nullaway)
     api("androidx.annotation:annotation:1.2.0")
 
-    implementation("androidx.annotation:annotation-experimental:1.2.0")
+    implementation("androidx.annotation:annotation-experimental:1.3.0")
     implementation(project(path: ":wear:protolayout:protolayout-proto", configuration: "shadow"))
 
-    compileOnly(libs.kotlinStdlib) // For annotation-experimental
+    // Upgrade transitive kotlin-stdlib dependency from annotation-experimental.
+    implementation(libs.kotlinStdlib)
 
     testImplementation(libs.testExtJunit)
     testImplementation(libs.testExtTruth)
diff --git a/wear/protolayout/protolayout-expression/lint-baseline.xml b/wear/protolayout/protolayout-expression/lint-baseline.xml
new file mode 100644
index 0000000..6de0061
--- /dev/null
+++ b/wear/protolayout/protolayout-expression/lint-baseline.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.protolayout.expression.ProtoLayoutExperimental` or `@OptIn(markerClass = androidx.wear.protolayout.expression.ProtoLayoutExperimental.class)`"
+        errorLine1="        return PlatformInt32Source.fromProto(proto.getPlatformSource());"
+        errorLine2="                                   ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.protolayout.expression.ProtoLayoutExperimental` or `@OptIn(markerClass = androidx.wear.protolayout.expression.ProtoLayoutExperimental.class)`"
+        errorLine1="        return PlatformInt32Source.fromProto(proto.getPlatformSource());"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java"/>
+    </issue>
+
+</issues>
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java
index ae5fa6c..2b2f4bf 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java
@@ -19,6 +19,7 @@
 import static androidx.wear.protolayout.expression.Preconditions.checkNotNull;
 
 import android.annotation.SuppressLint;
+
 import androidx.annotation.ColorInt;
 import androidx.annotation.IntDef;
 import androidx.annotation.IntRange;
@@ -38,6502 +39,6457 @@
 import androidx.wear.protolayout.expression.proto.DynamicProto;
 import androidx.wear.protolayout.protobuf.ExtensionRegistryLite;
 import androidx.wear.protolayout.protobuf.InvalidProtocolBufferException;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.time.Instant;
 
 /** Builders for dynamic primitive types used by layout elements. */
 public final class DynamicBuilders {
-  private DynamicBuilders() {}
-
-  /**
-   * The type of data to provide to a {@link PlatformInt32Source}.
-   *
-   * @since 1.2
-   */
-  @RestrictTo(RestrictTo.Scope.LIBRARY)
-  @IntDef({
-    PLATFORM_INT32_SOURCE_TYPE_UNDEFINED,
-    PLATFORM_INT32_SOURCE_TYPE_CURRENT_HEART_RATE,
-    PLATFORM_INT32_SOURCE_TYPE_DAILY_STEP_COUNT
-  })
-  @Retention(RetentionPolicy.SOURCE)
-  @ProtoLayoutExperimental
-  @interface PlatformInt32SourceType {}
-
-  /**
-   * Undefined source.
-   *
-   * @since 1.2
-   */
-  @ProtoLayoutExperimental static final int PLATFORM_INT32_SOURCE_TYPE_UNDEFINED = 0;
-
-  /**
-   * The user's current heart rate. Note that to use this data source, your app must already have
-   * the "BODY_SENSORS" permission granted to it. If this permission is not present, this source
-   * type will never yield any data.
-   *
-   * @since 1.2
-   */
-  @ProtoLayoutExperimental static final int PLATFORM_INT32_SOURCE_TYPE_CURRENT_HEART_RATE = 1;
-
-  /**
-   * The user's current daily steps. This is the number of steps they have taken since midnight, and
-   * will reset to zero at midnight. Note that to use this data source, your app must already have
-   * the "ACTIVITY_RECOGNITION" permission granted to it. If this permission is not present, this
-   * source type will never yield any data.
-   *
-   * @since 1.2
-   */
-  @ProtoLayoutExperimental static final int PLATFORM_INT32_SOURCE_TYPE_DAILY_STEP_COUNT = 2;
-
-  /**
-   * The type of arithmetic operation used in {@link ArithmeticInt32Op} and {@link
-   * ArithmeticFloatOp}.
-   *
-   * @since 1.2
-   */
-  @RestrictTo(RestrictTo.Scope.LIBRARY)
-  @IntDef({
-      ARITHMETIC_OP_TYPE_UNDEFINED,
-      ARITHMETIC_OP_TYPE_ADD,
-      ARITHMETIC_OP_TYPE_SUBTRACT,
-      ARITHMETIC_OP_TYPE_MULTIPLY,
-      ARITHMETIC_OP_TYPE_DIVIDE,
-      ARITHMETIC_OP_TYPE_MODULO
-  })
-  @Retention(RetentionPolicy.SOURCE)
-  @interface ArithmeticOpType {
-
-  }
-
-  /**
-   * Undefined operation type.
-   *
-   * @since 1.2
-   */
-  static final int ARITHMETIC_OP_TYPE_UNDEFINED = 0;
-
-  /**
-   * Addition.
-   *
-   * @since 1.2
-   */
-  static final int ARITHMETIC_OP_TYPE_ADD = 1;
-
-  /**
-   * Subtraction.
-   *
-   * @since 1.2
-   */
-  static final int ARITHMETIC_OP_TYPE_SUBTRACT = 2;
-
-  /**
-   * Multiplication.
-   *
-   * @since 1.2
-   */
-  static final int ARITHMETIC_OP_TYPE_MULTIPLY = 3;
-
-  /**
-   * Division.
-   *
-   * @since 1.2
-   */
-  static final int ARITHMETIC_OP_TYPE_DIVIDE = 4;
-
-  /**
-   * Modulus.
-   *
-   * @since 1.2
-   */
-  static final int ARITHMETIC_OP_TYPE_MODULO = 5;
-
-  /**
-   * Rounding mode to use when converting a float to an int32.
-   *
-   * @since 1.2
-   */
-  @RestrictTo(RestrictTo.Scope.LIBRARY)
-  @IntDef({ROUND_MODE_UNDEFINED, ROUND_MODE_FLOOR, ROUND_MODE_ROUND, ROUND_MODE_CEILING})
-  @Retention(RetentionPolicy.SOURCE)
-  @interface FloatToInt32RoundMode {}
-
-  /**
-   * An undefined rounding mode.
-   *
-   * @since 1.2
-   */
-  static final int ROUND_MODE_UNDEFINED = 0;
-
-  /**
-   * Use floor(x) when rounding.
-   *
-   * @since 1.2
-   */
-  static final int ROUND_MODE_FLOOR = 1;
-
-  /**
-   * Use round(x) when rounding (i.e. rounds to the closest int).
-   *
-   * @since 1.2
-   */
-  static final int ROUND_MODE_ROUND = 2;
-
-  /**
-   * Use ceil(x) when rounding.
-   *
-   * @since 1.2
-   */
-  static final int ROUND_MODE_CEILING = 3;
-
-  /**
-   * The type of comparison used in {@link ComparisonInt32Op} and {@link ComparisonFloatOp}.
-   *
-   * @since 1.2
-   */
-  @RestrictTo(RestrictTo.Scope.LIBRARY)
-  @IntDef({
-      COMPARISON_OP_TYPE_UNDEFINED,
-      COMPARISON_OP_TYPE_EQUALS,
-      COMPARISON_OP_TYPE_NOT_EQUALS,
-      COMPARISON_OP_TYPE_LESS_THAN,
-      COMPARISON_OP_TYPE_LESS_THAN_OR_EQUAL_TO,
-      COMPARISON_OP_TYPE_GREATER_THAN,
-      COMPARISON_OP_TYPE_GREATER_THAN_OR_EQUAL_TO
-  })
-  @Retention(RetentionPolicy.SOURCE)
-  @interface ComparisonOpType {}
-
-  /**
-   * Undefined operation type.
-   *
-   * @since 1.2
-   */
-  static final int COMPARISON_OP_TYPE_UNDEFINED = 0;
-
-  /**
-   * Equality check (result = LHS == RHS). For floats, for equality check, small epsilon is used,
-   * i.e.: (result = abs(LHS - RHS) < epsilon).
-   *
-   * @since 1.2
-   */
-  static final int COMPARISON_OP_TYPE_EQUALS = 1;
-
-  /**
-   * Not equal check (result = LHS != RHS).
-   *
-   * @since 1.2
-   */
-  static final int COMPARISON_OP_TYPE_NOT_EQUALS = 2;
-
-  /**
-   * Strictly less than (result = LHS < RHS).
-   *
-   * @since 1.2
-   */
-  static final int COMPARISON_OP_TYPE_LESS_THAN = 3;
-
-  /**
-   * Less than or equal to (result = LHS <= RHS).
-   *
-   * @since 1.2
-   */
-  static final int COMPARISON_OP_TYPE_LESS_THAN_OR_EQUAL_TO = 4;
-
-  /**
-   * Strictly greater than (result = LHS > RHS).
-   *
-   * @since 1.2
-   */
-  static final int COMPARISON_OP_TYPE_GREATER_THAN = 5;
-
-  /**
-   * Greater than or equal to (result = LHS >= RHS).
-   *
-   * @since 1.2
-   */
-  static final int COMPARISON_OP_TYPE_GREATER_THAN_OR_EQUAL_TO = 6;
-
-  /**
-   * The type of logical operation to carry out in a {@link LogicalBoolOp} operation.
-   *
-   * @since 1.2
-   */
-  @RestrictTo(RestrictTo.Scope.LIBRARY)
-  @IntDef({LOGICAL_OP_TYPE_UNDEFINED, LOGICAL_OP_TYPE_AND, LOGICAL_OP_TYPE_OR})
-  @Retention(RetentionPolicy.SOURCE)
-  @interface LogicalOpType {}
-
-  /**
-   * Undefined operation type.
-   *
-   * @since 1.2
-   */
-  static final int LOGICAL_OP_TYPE_UNDEFINED = 0;
-
-  /**
-   * Logical AND.
-   *
-   * @since 1.2
-   */
-  static final int LOGICAL_OP_TYPE_AND = 1;
-
-  /**
-   * Logical OR.
-   *
-   * @since 1.2
-   */
-  static final int LOGICAL_OP_TYPE_OR = 2;
-
-  /**
-   * The duration part to retrieve using {@link GetDurationPartOp}.
-   *
-   * @since 1.2
-   */
-  @RestrictTo(RestrictTo.Scope.LIBRARY)
-  @IntDef({
-    DURATION_PART_TYPE_UNDEFINED,
-    DURATION_PART_TYPE_TOTAL_DAYS,
-    DURATION_PART_TYPE_TOTAL_HOURS,
-    DURATION_PART_TYPE_TOTAL_MINUTES,
-    DURATION_PART_TYPE_TOTAL_SECONDS,
-    DURATION_PART_TYPE_DAYS,
-    DURATION_PART_TYPE_HOURS,
-    DURATION_PART_TYPE_MINUTES,
-    DURATION_PART_TYPE_SECONDS
-  })
-  @Retention(RetentionPolicy.SOURCE)
-  @interface DurationPartType {}
-
-  /**
-   * Undefined duration part type.
-   *
-   * @since 1.2
-   */
-  static final int DURATION_PART_TYPE_UNDEFINED = 0;
-
-  /**
-   * Total number of days in a duration. The fraction part of the result will be truncated. This is
-   * based on the standard definition of a day as 24 hours. Notice that the duration can be
-   * negative, in which case total number of days will be also negative.
-   *
-   * @since 1.2
-   */
-  static final int DURATION_PART_TYPE_TOTAL_DAYS = 1;
-
-  /**
-   * Total number of hours in a duration. The fraction part of the result will be truncated. Notice
-   * that the duration can be negative, in which case total number of hours will be also negative.
-   *
-   * @since 1.2
-   */
-  static final int DURATION_PART_TYPE_TOTAL_HOURS = 2;
-
-  /**
-   * Total number of minutes in a duration. The fraction part of the result will be truncated.
-   * Notice that the duration can be negative, in which case total number of minutes will be also
-   * negative.
-   *
-   * @since 1.2
-   */
-  static final int DURATION_PART_TYPE_TOTAL_MINUTES = 3;
-
-  /**
-   * Total number of seconds in a duration. Notice that the duration can be negative, in which case
-   * total number of seconds will be also negative.
-   *
-   * @since 1.2
-   */
-  static final int DURATION_PART_TYPE_TOTAL_SECONDS = 4;
-
-  /**
-   * Number of days part in the duration. This represents the absolute value of the total number of
-   * days in the duration based on the 24 hours day definition. The fraction part of the result will
-   * be truncated.
-   *
-   * @since 1.2
-   */
-  static final int DURATION_PART_TYPE_DAYS = 5;
-
-  /**
-   * Number of hours part in the duration. This represents the absolute value of remaining hours
-   * when dividing total hours by hours in a day (24 hours).
-   *
-   * @since 1.2
-   */
-  static final int DURATION_PART_TYPE_HOURS = 6;
-
-  /**
-   * Number of minutes part in the duration. This represents the absolute value of remaining minutes
-   * when dividing total minutes by minutes in an hour (60 minutes).
-   *
-   * @since 1.2
-   */
-  static final int DURATION_PART_TYPE_MINUTES = 7;
-
-  /**
-   * Number of seconds part in the duration. This represents the absolute value of remaining seconds
-   * when dividing total seconds by seconds in a minute (60 seconds).
-   *
-   * @since 1.2
-   */
-  static final int DURATION_PART_TYPE_SECONDS = 8;
-
-  /**
-   * A dynamic Int32 which sources its data from some platform data source, e.g. from sensors, or
-   * the current time.
-   *
-   * @since 1.2
-   */
-  @ProtoLayoutExperimental
-  static final class PlatformInt32Source implements DynamicInt32 {
-    private final DynamicProto.PlatformInt32Source mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    PlatformInt32Source(DynamicProto.PlatformInt32Source impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
+    private DynamicBuilders() {}
 
     /**
-     * Gets the source to load data from.
+     * The type of data to provide to a {@link PlatformInt32Source}.
      *
      * @since 1.2
      */
-    @PlatformInt32SourceType
-    public int getSourceType() {
-      return mImpl.getSourceType().getNumber();
-    }
-
-    /** @hide */
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-    /**
-     * Creates a new wrapper instance from the proto.
-     *
-     * @hide
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public static PlatformInt32Source fromProto(
-        @NonNull DynamicProto.PlatformInt32Source proto, @Nullable Fingerprint fingerprint) {
-      return new PlatformInt32Source(proto, fingerprint);
-    }
-
-    @NonNull
-    static PlatformInt32Source fromProto(@NonNull DynamicProto.PlatformInt32Source proto) {
-      return fromProto(proto, null);
-    }
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @IntDef({
+        PLATFORM_INT32_SOURCE_TYPE_UNDEFINED,
+        PLATFORM_INT32_SOURCE_TYPE_CURRENT_HEART_RATE,
+        PLATFORM_INT32_SOURCE_TYPE_DAILY_STEP_COUNT
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @ProtoLayoutExperimental
+    @interface PlatformInt32SourceType {}
 
     /**
-     * Returns the internal proto instance.
-     *
-     * @hide
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    DynamicProto.PlatformInt32Source toProto() {
-      return mImpl;
-    }
-
-    /** @hide */
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
-      return DynamicProto.DynamicInt32.newBuilder().setPlatformSource(mImpl).build();
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-      return "PlatformInt32Source{" + "sourceType=" + getSourceType() + "}";
-    }
-
-    /** Builder for {@link PlatformInt32Source}. */
-    public static final class Builder implements DynamicInt32.Builder {
-      private final DynamicProto.PlatformInt32Source.Builder mImpl =
-          DynamicProto.PlatformInt32Source.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(1355180718);
-
-      public Builder() {}
-
-      /**
-       * Sets the source to load data from.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setSourceType(@PlatformInt32SourceType int sourceType) {
-        mImpl.setSourceType(DynamicProto.PlatformInt32SourceType.forNumber(sourceType));
-        mFingerprint.recordPropertyUpdate(1, sourceType);
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public PlatformInt32Source build() {
-        return new PlatformInt32Source(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * An arithmetic operation, operating on two Int32 instances. This implements simple binary
-   * operations of the form "result = LHS <op> RHS", where the available operation types are
-   * described in {@code ArithmeticOpType}.
-   *
-   * @since 1.2
-   */
-  static final class ArithmeticInt32Op implements DynamicInt32 {
-
-    private final DynamicProto.ArithmeticInt32Op mImpl;
-    @Nullable
-    private final Fingerprint mFingerprint;
-
-    ArithmeticInt32Op(DynamicProto.ArithmeticInt32Op impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
-
-    /**
-     * Gets left hand side of the arithmetic operation.
+     * Undefined source.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicInt32 getInputLhs() {
-      if (mImpl.hasInputLhs()) {
-        return DynamicBuilders.dynamicInt32FromProto(mImpl.getInputLhs());
-      } else {
-        return null;
-      }
-    }
+    @ProtoLayoutExperimental static final int PLATFORM_INT32_SOURCE_TYPE_UNDEFINED = 0;
 
     /**
-     * Gets right hand side of the arithmetic operation.
+     * The user's current heart rate. Note that to use this data source, your app must already have
+     * the "BODY_SENSORS" permission granted to it. If this permission is not present, this source
+     * type will never yield any data.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicInt32 getInputRhs() {
-      if (mImpl.hasInputRhs()) {
-        return DynamicBuilders.dynamicInt32FromProto(mImpl.getInputRhs());
-      } else {
-        return null;
-      }
-    }
+    @ProtoLayoutExperimental static final int PLATFORM_INT32_SOURCE_TYPE_CURRENT_HEART_RATE = 1;
 
     /**
-     * Gets the type of operation to carry out.
+     * The user's current daily steps. This is the number of steps they have taken since midnight,
+     * and will reset to zero at midnight. Note that to use this data source, your app must already
+     * have the "ACTIVITY_RECOGNITION" permission granted to it. If this permission is not present,
+     * this source type will never yield any data.
      *
      * @since 1.2
      */
-    @ArithmeticOpType
-    public int getOperationType() {
-      return mImpl.getOperationType().getNumber();
-    }
+    @ProtoLayoutExperimental static final int PLATFORM_INT32_SOURCE_TYPE_DAILY_STEP_COUNT = 2;
 
     /**
-     */
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static ArithmeticInt32Op fromProto(@NonNull DynamicProto.ArithmeticInt32Op proto) {
-      return new ArithmeticInt32Op(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.ArithmeticInt32Op toProto() {
-      return mImpl;
-    }
-
-    /**
-     */
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
-      return DynamicProto.DynamicInt32.newBuilder().setArithmeticOperation(mImpl).build();
-    }
-
-    /**
-     * Builder for {@link ArithmeticInt32Op}.
-     */
-    public static final class Builder implements DynamicInt32.Builder {
-
-      private final DynamicProto.ArithmeticInt32Op.Builder mImpl =
-          DynamicProto.ArithmeticInt32Op.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-2012727925);
-
-      public Builder() {
-      }
-
-      /**
-       * Sets left hand side of the arithmetic operation.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInputLhs(@NonNull DynamicInt32 inputLhs) {
-        mImpl.setInputLhs(inputLhs.toDynamicInt32Proto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(inputLhs.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets right hand side of the arithmetic operation.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInputRhs(@NonNull DynamicInt32 inputRhs) {
-        mImpl.setInputRhs(inputRhs.toDynamicInt32Proto());
-        mFingerprint.recordPropertyUpdate(
-            2, checkNotNull(inputRhs.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the type of operation to carry out.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setOperationType(@ArithmeticOpType int operationType) {
-        mImpl.setOperationType(DynamicProto.ArithmeticOpType.forNumber(operationType));
-        mFingerprint.recordPropertyUpdate(3, operationType);
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public ArithmeticInt32Op build() {
-        return new ArithmeticInt32Op(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * A dynamic Int32 which sources its data from the tile's state.
-   *
-   * @since 1.2
-   */
-  static final class StateInt32Source implements DynamicInt32 {
-    private final DynamicProto.StateInt32Source mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    StateInt32Source(DynamicProto.StateInt32Source impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
-
-    /**
-     * Gets the key in the state to bind to.
+     * The type of arithmetic operation used in {@link ArithmeticInt32Op} and {@link
+     * ArithmeticFloatOp}.
      *
      * @since 1.2
      */
-    @NonNull
-    public String getSourceKey() {
-      return mImpl.getSourceKey();
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static StateInt32Source fromProto(@NonNull DynamicProto.StateInt32Source proto) {
-      return new StateInt32Source(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.StateInt32Source toProto() {
-      return mImpl;
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
-      return DynamicProto.DynamicInt32.newBuilder().setStateSource(mImpl).build();
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-      return "StateInt32Source{" + "sourceKey=" + getSourceKey() + "}";
-    }
-
-    /** Builder for {@link StateInt32Source}. */
-    public static final class Builder implements DynamicInt32.Builder {
-      private final DynamicProto.StateInt32Source.Builder mImpl =
-          DynamicProto.StateInt32Source.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(58614749);
-
-      public Builder() {}
-
-      /**
-       * Sets the key in the state to bind to.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setSourceKey(@NonNull String sourceKey) {
-        mImpl.setSourceKey(sourceKey);
-        mFingerprint.recordPropertyUpdate(1, sourceKey.hashCode());
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public StateInt32Source build() {
-        return new StateInt32Source(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * A conditional operator which yields an integer depending on the boolean operand. This
-   * implements "int result = condition ? value_if_true : value_if_false".
-   *
-   * @since 1.2
-   */
-  static final class ConditionalInt32Op implements DynamicInt32 {
-
-    private final DynamicProto.ConditionalInt32Op mImpl;
-    @Nullable
-    private final Fingerprint mFingerprint;
-
-    ConditionalInt32Op(DynamicProto.ConditionalInt32Op impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @IntDef({
+        ARITHMETIC_OP_TYPE_UNDEFINED,
+        ARITHMETIC_OP_TYPE_ADD,
+        ARITHMETIC_OP_TYPE_SUBTRACT,
+        ARITHMETIC_OP_TYPE_MULTIPLY,
+        ARITHMETIC_OP_TYPE_DIVIDE,
+        ARITHMETIC_OP_TYPE_MODULO
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface ArithmeticOpType {}
 
     /**
-     * Gets the condition to use.
+     * Undefined operation type.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicBool getCondition() {
-      if (mImpl.hasCondition()) {
-        return DynamicBuilders.dynamicBoolFromProto(mImpl.getCondition());
-      } else {
-        return null;
-      }
-    }
+    static final int ARITHMETIC_OP_TYPE_UNDEFINED = 0;
 
     /**
-     * Gets the integer to yield if condition is true.
+     * Addition.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicInt32 getValueIfTrue() {
-      if (mImpl.hasValueIfTrue()) {
-        return DynamicBuilders.dynamicInt32FromProto(mImpl.getValueIfTrue());
-      } else {
-        return null;
-      }
-    }
+    static final int ARITHMETIC_OP_TYPE_ADD = 1;
 
     /**
-     * Gets the integer to yield if condition is false.
+     * Subtraction.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicInt32 getValueIfFalse() {
-      if (mImpl.hasValueIfFalse()) {
-        return DynamicBuilders.dynamicInt32FromProto(mImpl.getValueIfFalse());
-      } else {
-        return null;
-      }
-    }
+    static final int ARITHMETIC_OP_TYPE_SUBTRACT = 2;
 
     /**
-     */
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static ConditionalInt32Op fromProto(@NonNull DynamicProto.ConditionalInt32Op proto) {
-      return new ConditionalInt32Op(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.ConditionalInt32Op toProto() {
-      return mImpl;
-    }
-
-    /**
-     */
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
-      return DynamicProto.DynamicInt32.newBuilder().setConditionalOp(mImpl).build();
-    }
-
-    /**
-     * Builder for {@link ConditionalInt32Op}.
-     */
-    public static final class Builder implements DynamicInt32.Builder {
-
-      private final DynamicProto.ConditionalInt32Op.Builder mImpl =
-          DynamicProto.ConditionalInt32Op.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(1444834226);
-
-      public Builder() {
-      }
-
-      /**
-       * Sets the condition to use.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setCondition(@NonNull DynamicBool condition) {
-        mImpl.setCondition(condition.toDynamicBoolProto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(condition.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the integer to yield if condition is true.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setValueIfTrue(@NonNull DynamicInt32 valueIfTrue) {
-        mImpl.setValueIfTrue(valueIfTrue.toDynamicInt32Proto());
-        mFingerprint.recordPropertyUpdate(
-            2, checkNotNull(valueIfTrue.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the integer to yield if condition is false.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setValueIfFalse(@NonNull DynamicInt32 valueIfFalse) {
-        mImpl.setValueIfFalse(valueIfFalse.toDynamicInt32Proto());
-        mFingerprint.recordPropertyUpdate(
-            3, checkNotNull(valueIfFalse.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public ConditionalInt32Op build() {
-        return new ConditionalInt32Op(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * A conditional operator which yields a float depending on the boolean operand. This implements
-   * "float result = condition ? value_if_true : value_if_false".
-   *
-   * @since 1.2
-   */
-  static final class ConditionalFloatOp implements DynamicFloat {
-
-    private final DynamicProto.ConditionalFloatOp mImpl;
-    @Nullable
-    private final Fingerprint mFingerprint;
-
-    ConditionalFloatOp(DynamicProto.ConditionalFloatOp impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
-
-    /**
-     * Gets the condition to use.
+     * Multiplication.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicBool getCondition() {
-      if (mImpl.hasCondition()) {
-        return DynamicBuilders.dynamicBoolFromProto(mImpl.getCondition());
-      } else {
-        return null;
-      }
-    }
+    static final int ARITHMETIC_OP_TYPE_MULTIPLY = 3;
 
     /**
-     * Gets the float to yield if condition is true.
+     * Division.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicFloat getValueIfTrue() {
-      if (mImpl.hasValueIfTrue()) {
-        return DynamicBuilders.dynamicFloatFromProto(mImpl.getValueIfTrue());
-      } else {
-        return null;
-      }
-    }
+    static final int ARITHMETIC_OP_TYPE_DIVIDE = 4;
 
     /**
-     * Gets the float to yield if condition is false.
+     * Modulus.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicFloat getValueIfFalse() {
-      if (mImpl.hasValueIfFalse()) {
-        return DynamicBuilders.dynamicFloatFromProto(mImpl.getValueIfFalse());
-      } else {
-        return null;
-      }
-    }
+    static final int ARITHMETIC_OP_TYPE_MODULO = 5;
 
     /**
-     */
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static ConditionalFloatOp fromProto(@NonNull DynamicProto.ConditionalFloatOp proto) {
-      return new ConditionalFloatOp(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.ConditionalFloatOp toProto() {
-      return mImpl;
-    }
-
-    /**
-     */
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicFloat toDynamicFloatProto() {
-      return DynamicProto.DynamicFloat.newBuilder().setConditionalOp(mImpl).build();
-    }
-
-    /**
-     * Builder for {@link ConditionalFloatOp}.
-     */
-    public static final class Builder implements DynamicFloat.Builder {
-
-      private final DynamicProto.ConditionalFloatOp.Builder mImpl =
-          DynamicProto.ConditionalFloatOp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(1968171153);
-
-      public Builder() {
-      }
-
-      /**
-       * Sets the condition to use.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setCondition(@NonNull DynamicBool condition) {
-        mImpl.setCondition(condition.toDynamicBoolProto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(condition.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the float to yield if condition is true.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setValueIfTrue(@NonNull DynamicFloat valueIfTrue) {
-        mImpl.setValueIfTrue(valueIfTrue.toDynamicFloatProto());
-        mFingerprint.recordPropertyUpdate(
-            2, checkNotNull(valueIfTrue.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the float to yield if condition is false.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setValueIfFalse(@NonNull DynamicFloat valueIfFalse) {
-        mImpl.setValueIfFalse(valueIfFalse.toDynamicFloatProto());
-        mFingerprint.recordPropertyUpdate(
-            3, checkNotNull(valueIfFalse.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public ConditionalFloatOp build() {
-        return new ConditionalFloatOp(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * Converts a Float to an Int32, with a customizable rounding mode.
-   *
-   * @since 1.2
-   */
-  static final class FloatToInt32Op implements DynamicInt32 {
-    private final DynamicProto.FloatToInt32Op mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    FloatToInt32Op(DynamicProto.FloatToInt32Op impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
-
-    /**
-     * Gets the float to round.
+     * Rounding mode to use when converting a float to an int32.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicFloat getInput() {
-      if (mImpl.hasInput()) {
-        return DynamicBuilders.dynamicFloatFromProto(mImpl.getInput());
-      } else {
-        return null;
-      }
-    }
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @IntDef({ROUND_MODE_UNDEFINED, ROUND_MODE_FLOOR, ROUND_MODE_ROUND, ROUND_MODE_CEILING})
+    @Retention(RetentionPolicy.SOURCE)
+    @interface FloatToInt32RoundMode {}
 
     /**
-     * Gets the rounding mode to use. Defaults to ROUND_MODE_FLOOR if not specified.
+     * An undefined rounding mode.
      *
      * @since 1.2
      */
-    @FloatToInt32RoundMode
-    public int getRoundMode() {
-      return mImpl.getRoundMode().getNumber();
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static FloatToInt32Op fromProto(@NonNull DynamicProto.FloatToInt32Op proto) {
-      return new FloatToInt32Op(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.FloatToInt32Op toProto() {
-      return mImpl;
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
-      return DynamicProto.DynamicInt32.newBuilder().setFloatToInt(mImpl).build();
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-      return "FloatToInt32Op{" + "input=" + getInput() + ", roundMode=" + getRoundMode() + "}";
-    }
-
-    /** Builder for {@link FloatToInt32Op}. */
-    public static final class Builder implements DynamicInt32.Builder {
-      private final DynamicProto.FloatToInt32Op.Builder mImpl =
-          DynamicProto.FloatToInt32Op.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-1272973414);
-
-      public Builder() {}
-
-      /**
-       * Sets the float to round.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInput(@NonNull DynamicFloat input) {
-        mImpl.setInput(input.toDynamicFloatProto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the rounding mode to use. Defaults to ROUND_MODE_FLOOR if not specified.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setRoundMode(@FloatToInt32RoundMode int roundMode) {
-        mImpl.setRoundMode(DynamicProto.FloatToInt32RoundMode.forNumber(roundMode));
-        mFingerprint.recordPropertyUpdate(2, roundMode);
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public FloatToInt32Op build() {
-        return new FloatToInt32Op(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * A static interpolation node, between two fixed int32 values.
-   *
-   * @since 1.2
-   */
-  static final class AnimatableFixedInt32 implements DynamicInt32 {
-    private final DynamicProto.AnimatableFixedInt32 mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    AnimatableFixedInt32(
-            DynamicProto.AnimatableFixedInt32 impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
+    static final int ROUND_MODE_UNDEFINED = 0;
 
     /**
-     * Gets the value to start animating from.
+     * Use floor(x) when rounding.
      *
      * @since 1.2
      */
-    public int getFromValue() {
-      return mImpl.getFromValue();
-    }
+    static final int ROUND_MODE_FLOOR = 1;
 
     /**
-     * Gets the value to animate to.
+     * Use round(x) when rounding (i.e. rounds to the closest int).
      *
      * @since 1.2
      */
-    public int getToValue() {
-      return mImpl.getToValue();
-    }
+    static final int ROUND_MODE_ROUND = 2;
 
     /**
-     * Gets the animation parameters for duration, delay, etc.
+     * Use ceil(x) when rounding.
      *
      * @since 1.2
      */
-    @Nullable
-    public AnimationSpec getAnimationSpec() {
-      if (mImpl.hasAnimationSpec()) {
-        return AnimationSpec.fromProto(mImpl.getAnimationSpec());
-      } else {
-        return null;
-      }
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-    /**
-     * Creates a new wrapper instance from the proto.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public static AnimatableFixedInt32 fromProto(
-            @NonNull DynamicProto.AnimatableFixedInt32 proto, @Nullable Fingerprint fingerprint) {
-      return new AnimatableFixedInt32(proto, fingerprint);
-    }
-
-    @NonNull
-    static AnimatableFixedInt32 fromProto(@NonNull DynamicProto.AnimatableFixedInt32 proto) {
-      return fromProto(proto, null);
-    }
+    static final int ROUND_MODE_CEILING = 3;
 
     /**
-     * Returns the internal proto instance.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    DynamicProto.AnimatableFixedInt32 toProto() {
-      return mImpl;
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
-      return DynamicProto.DynamicInt32.newBuilder().setAnimatableFixed(mImpl).build();
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-      return "AnimatableFixedInt32{"
-              + "fromValue="
-              + getFromValue()
-              + ", toValue="
-              + getToValue()
-              + ", animationSpec="
-              + getAnimationSpec()
-              + "}";
-    }
-
-    /** Builder for {@link AnimatableFixedInt32}. */
-    public static final class Builder implements DynamicInt32.Builder {
-      private final DynamicProto.AnimatableFixedInt32.Builder mImpl =
-              DynamicProto.AnimatableFixedInt32.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-1831435966);
-
-      public Builder() {}
-
-      /**
-       * Sets the value to start animating from.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public AnimatableFixedInt32.Builder setFromValue(int fromValue) {
-        mImpl.setFromValue(fromValue);
-        mFingerprint.recordPropertyUpdate(1, fromValue);
-        return this;
-      }
-
-      /**
-       * Sets the value to animate to.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public AnimatableFixedInt32.Builder setToValue(int toValue) {
-        mImpl.setToValue(toValue);
-        mFingerprint.recordPropertyUpdate(2, toValue);
-        return this;
-      }
-
-      /**
-       * Sets the animation parameters for duration, delay, etc.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
-        mImpl.setAnimationSpec(animationSpec.toProto());
-        mFingerprint.recordPropertyUpdate(
-            3, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public AnimatableFixedInt32 build() {
-        return new AnimatableFixedInt32(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * A dynamic interpolation node. This will watch the value of its input and, when the first update
-   * arrives, immediately emit that value. On subsequent updates, it will animate between the old
-   * and new values.
-   *
-   * <p>If this node receives an invalid value (e.g. as a result of an upstream node having no
-   * value), then it will emit a single invalid value, and forget its "stored" value. The next valid
-   * value that arrives is then used as the "first" value again.
-   *
-   * @since 1.2
-   */
-  static final class AnimatableDynamicInt32 implements DynamicInt32 {
-    private final DynamicProto.AnimatableDynamicInt32 mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    AnimatableDynamicInt32(
-            DynamicProto.AnimatableDynamicInt32 impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
-
-    /**
-     * Gets the value to watch, and animate when it changes.
+     * The type of comparison used in {@link ComparisonInt32Op} and {@link ComparisonFloatOp}.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicInt32 getInput() {
-      if (mImpl.hasInput()) {
-        return dynamicInt32FromProto(mImpl.getInput());
-      } else {
-        return null;
-      }
-    }
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @IntDef({
+        COMPARISON_OP_TYPE_UNDEFINED,
+        COMPARISON_OP_TYPE_EQUALS,
+        COMPARISON_OP_TYPE_NOT_EQUALS,
+        COMPARISON_OP_TYPE_LESS_THAN,
+        COMPARISON_OP_TYPE_LESS_THAN_OR_EQUAL_TO,
+        COMPARISON_OP_TYPE_GREATER_THAN,
+        COMPARISON_OP_TYPE_GREATER_THAN_OR_EQUAL_TO
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface ComparisonOpType {}
 
     /**
-     * Gets the animation parameters for duration, delay, etc.
+     * Undefined operation type.
      *
      * @since 1.2
      */
-    @Nullable
-    public AnimationSpec getAnimationSpec() {
-      if (mImpl.hasAnimationSpec()) {
-        return AnimationSpec.fromProto(mImpl.getAnimationSpec());
-      } else {
-        return null;
-      }
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-    /**
-     * Creates a new wrapper instance from the proto.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public static AnimatableDynamicInt32 fromProto(
-            @NonNull DynamicProto.AnimatableDynamicInt32 proto, @Nullable Fingerprint fingerprint) {
-      return new AnimatableDynamicInt32(proto, fingerprint);
-    }
-
-    @NonNull
-    static AnimatableDynamicInt32 fromProto(@NonNull DynamicProto.AnimatableDynamicInt32 proto) {
-      return fromProto(proto, null);
-    }
+    static final int COMPARISON_OP_TYPE_UNDEFINED = 0;
 
     /**
-     * Returns the internal proto instance.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    DynamicProto.AnimatableDynamicInt32 toProto() {
-      return mImpl;
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
-      return DynamicProto.DynamicInt32.newBuilder().setAnimatableDynamic(mImpl).build();
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-      return "AnimatableDynamicInt32{"
-          + "input="
-          + getInput()
-          + ", animationSpec="
-          + getAnimationSpec()
-          + "}";
-    }
-
-    /** Builder for {@link AnimatableDynamicInt32}. */
-    public static final class Builder implements DynamicInt32.Builder {
-      private final DynamicProto.AnimatableDynamicInt32.Builder mImpl =
-              DynamicProto.AnimatableDynamicInt32.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-1554674954);
-
-      public Builder() {}
-
-      /**
-       * Sets the value to watch, and animate when it changes.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public AnimatableDynamicInt32.Builder setInput(@NonNull DynamicInt32 input) {
-        mImpl.setInput(input.toDynamicInt32Proto());
-        mFingerprint.recordPropertyUpdate(
-                1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the animation parameters for duration, delay, etc.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
-        mImpl.setAnimationSpec(animationSpec.toProto());
-        mFingerprint.recordPropertyUpdate(
-            2, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public AnimatableDynamicInt32 build() {
-        return new AnimatableDynamicInt32(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * Interface defining a dynamic int32 type.
-   *
-   * <p>It offers a set of helper methods for creating arithmetic and logical expressions, e.g.
-   * {@link #plus(int)}, {@link #times(int)}, {@link #eq(int)}, etc. These helper methods produce
-   * expression trees based on the order in which they were called in an expression. Thus, no
-   * operator precedence rules are applied.
-   *
-   * <p>For example the following expression is equivalent to {@code result = ((a + b)*c)/d }:
-   *
-   * <pre>{@code
-   * a.plus(b).times(c).div(d);
-   * }</pre>
-   *
-   * More complex expressions can be created by nesting expressions. For example the following
-   * expression is equivalent to {@code result = (a + b)*(c - d) }:
-   *
-   * <pre>{@code
-   * (a.plus(b)).times(c.minus(d));
-   * }</pre>
-   *
-   * @since 1.2
-   */
-  public interface DynamicInt32 extends DynamicType {
-    /**
-     * Get the protocol buffer representation of this object.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    DynamicProto.DynamicInt32 toDynamicInt32Proto();
-
-    /**
-     * Creates a {@link DynamicInt32} from a byte array generated by {@link
-     * #toDynamicInt32ByteArray()}.
-     */
-    @NonNull
-    static DynamicInt32 fromByteArray(@NonNull byte[] byteArray) {
-      try {
-        return dynamicInt32FromProto(
-            DynamicProto.DynamicInt32.parseFrom(
-                byteArray, ExtensionRegistryLite.getEmptyRegistry()));
-      } catch (InvalidProtocolBufferException e) {
-        throw new IllegalArgumentException("Byte array could not be parsed into DynamicInt32", e);
-      }
-    }
-
-    /** Creates a byte array that can later be used with {@link #fromByteArray(byte[])}. */
-    @NonNull
-    default byte[] toDynamicInt32ByteArray() {
-      return toDynamicInt32Proto().toByteArray();
-    }
-
-    /** Creates a constant-valued {@link DynamicInt32}. */
-    @NonNull
-    static DynamicInt32 constant(int constant) {
-      return new FixedInt32.Builder().setValue(constant).build();
-    }
-
-    /**
-     * Creates a {@link DynamicInt32} that is bound to the value of an item of the State.
-     *
-     * @param stateKey The key to a {@link StateEntryValue} with an int value from the provider's
-     *     state.
-     */
-    @NonNull
-    static DynamicInt32 fromState(@NonNull String stateKey) {
-      return new StateInt32Source.Builder().setSourceKey(stateKey).build();
-    }
-
-    /**
-     * Creates a {@link DynamicInt32} which will animate from {@code start} to {@code end}.
-     *
-     * @param start The start value of the range.
-     * @param end The end value of the range.
-     */
-    @NonNull
-    static DynamicInt32 animate(int start, int end) {
-      return new AnimatableFixedInt32.Builder().setFromValue(start).setToValue(end).build();
-    }
-
-    /**
-     * Creates a {@link DynamicInt32} which will animate from {@code start} to {@code end} with the
-     * given animation parameters.
-     *
-     * @param start The start value of the range.
-     * @param end The end value of the range.
-     * @param animationSpec The animation parameters.
-     */
-    @NonNull
-    static DynamicInt32 animate(int start, int end, @NonNull AnimationSpec animationSpec) {
-      return new AnimatableFixedInt32.Builder()
-          .setFromValue(start)
-          .setToValue(end)
-          .setAnimationSpec(animationSpec)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicInt32} that is bound to the value of an item of the State. Every time
-     * the state value changes, this {@link DynamicInt32} will animate from its current value to the
-     * new value (from the state).
-     *
-     * @param stateKey The key to a {@link StateEntryValue} with an int value from the provider's
-     *     state.
-     */
-    @NonNull
-    static DynamicInt32 animate(@NonNull String stateKey) {
-      return new AnimatableDynamicInt32.Builder().setInput(fromState(stateKey)).build();
-    }
-
-    /**
-     * Creates a {@link DynamicInt32} that is bound to the value of an item of the State. Every time
-     * the state value changes, this {@link DynamicInt32} will animate from its current value to the
-     * new value (from the state).
-     *
-     * @param stateKey The key to a {@link StateEntryValue} with an int value from the provider's
-     *     state.
-     * @param animationSpec The animation parameters.
-     */
-    @NonNull
-    static DynamicInt32 animate(@NonNull String stateKey, @NonNull AnimationSpec animationSpec) {
-      return new AnimatableDynamicInt32.Builder()
-          .setInput(fromState(stateKey))
-          .setAnimationSpec(animationSpec)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicInt32} that is bound to the value of this {@link DynamicInt32} and
-     * every time its value is changing, it animates from its current value to the new value.
-     *
-     * @param animationSpec The animation parameters.
-     */
-    @NonNull
-    default DynamicInt32 animate(@NonNull AnimationSpec animationSpec) {
-      return new AnimatableDynamicInt32.Builder()
-          .setInput(this)
-          .setAnimationSpec(animationSpec)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicInt32} that is bound to the value of this {@link DynamicInt32} and
-     * every time its value is changing, it animates from its current value to the new value.
-     */
-    @NonNull
-    default DynamicInt32 animate() {
-      return new AnimatableDynamicInt32.Builder().setInput(this).build();
-    }
-
-    /** Convert the value represented by this {@link DynamicInt32} into a {@link DynamicFloat}. */
-    @NonNull
-    default DynamicFloat asFloat() {
-      return new Int32ToFloatOp.Builder().setInput(this).build();
-    }
-
-    /**
-     * Bind the value of this {@link DynamicInt32} to the result of a conditional expression. This
-     * will use the value given in either {@link ConditionScope#use} or {@link
-     * ConditionScopes.IfTrueScope#elseUse} depending on the value yielded from {@code condition}.
-     */
-    @NonNull
-    static ConditionScope<DynamicInt32, Integer> onCondition(@NonNull DynamicBool condition) {
-      return new ConditionScopes.ConditionScope<>(
-          (trueValue, falseValue) ->
-              new ConditionalInt32Op.Builder()
-                  .setCondition(condition)
-                  .setValueIfTrue(trueValue)
-                  .setValueIfFalse(falseValue)
-                  .build(),
-          DynamicInt32::constant);
-    }
-
-    /**
-     * Creates a {@link DynamicInt32} containing the result of adding another {@link DynamicInt32}
-     * to this {@link DynamicInt32}; As an example, the following is equal to {@code
-     * DynamicInt32.constant(13)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).plus(DynamicInt32.constant(6));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicInt32} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicInt32 plus(@NonNull DynamicInt32 other) {
-      return new ArithmeticInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_ADD)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFlaot} containing the result of adding a {@link DynamicFloat} to this
-     * {@link DynamicInt32}; As an example, the following is equal to {@code
-     * DynamicFloat.constant(13.5f)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).plus(DynamicFloat.constant(6.5f));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat plus(@NonNull DynamicFloat other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this.asFloat())
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_ADD)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicInt32} containing the result of adding an integer to this {@link
-     * DynamicInt32}; As an example, the following is equal to {@code DynamicInt32.constant(13)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).plus(6);
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicInt32} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicInt32 plus(int other) {
-      return new ArithmeticInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_ADD)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFlaot} containing the result of adding a float to this {@link
-     * DynamicInt32}; As an example, the following is equal to {@code DynamicFloat.constant(13.5f)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).plus(6.5f);
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat plus(float other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this.asFloat())
-          .setInputRhs(DynamicFloat.constant(other))
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_ADD)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicInt32} containing the result of subtracting another {@link
-     * DynamicInt32} from this {@link DynamicInt32}; As an example, the following is equal to {@code
-     * DynamicInt32.constant(2)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).minus(DynamicInt32.constant(5));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicInt32} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicInt32 minus(@NonNull DynamicInt32 other) {
-      return new ArithmeticInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_SUBTRACT)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of subtracting a {@link DynamicFloat}
-     * from this {@link DynamicInt32}; As an example, the following is equal to {@code
-     * DynamicFloat.constant(1.5f)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).minus(DynamicFloat.constant(5.5f));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat minus(@NonNull DynamicFloat other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this.asFloat())
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_SUBTRACT)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicInt32} containing the result of subtracting an integer from this
-     * {@link DynamicInt32}; As an example, the following is equal to {@code
-     * DynamicInt32.constant(2)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).minus(5);
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicInt32} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicInt32 minus(int other) {
-      return new ArithmeticInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_SUBTRACT)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of subtracting a float from this {@link
-     * DynamicInt32}; As an example, the following is equal to {@code DynamicFloat.constant(1.5f)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).minus(5.5f);
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat minus(float other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this.asFloat())
-          .setInputRhs(DynamicFloat.constant(other))
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_SUBTRACT)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicInt32} containing the result of multiplying this {@link DynamicInt32}
-     * by another {@link DynamicInt32}; As an example, the following is equal to {@code
-     * DynamicInt32.constant(35)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).times(DynamicInt32.constant(5));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicInt32} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicInt32 times(@NonNull DynamicInt32 other) {
-      return new ArithmeticInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MULTIPLY)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of multiplying this {@link DynamicInt32}
-     * by a {@link DynamicFloat}; As an example, the following is equal to {@code
-     * DynamicFloat.constant(38.5f)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).times(DynamicFloat.constant(5.5f));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat times(@NonNull DynamicFloat other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this.asFloat())
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MULTIPLY)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicInt32} containing the result of multiplying this {@link DynamicInt32}
-     * by an integer; As an example, the following is equal to {@code DynamicInt32.constant(35)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).times(5);
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicInt32} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicInt32 times(int other) {
-      return new ArithmeticInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MULTIPLY)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of multiplying this {@link DynamicInt32}
-     * by a float; As an example, the following is equal to {@code DynamicFloat.constant(38.5f)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).times(5.5f);
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat times(float other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this.asFloat())
-          .setInputRhs(DynamicFloat.constant(other))
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MULTIPLY)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicInt32} containing the result of dividing this {@link DynamicInt32} by
-     * another {@link DynamicInt32}; As an example, the following is equal to {@code
-     * DynamicInt32.constant(1)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).div(DynamicInt32.constant(5));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicInt32} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicInt32 div(@NonNull DynamicInt32 other) {
-      return new ArithmeticInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_DIVIDE)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of dividing this {@link DynamicInt32} by
-     * a {@link DynamicFloat}; As an example, the following is equal to {@code
-     * DynamicFloat.constant(1.4f)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).div(DynamicFloat.constant(5f));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat div(@NonNull DynamicFloat other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this.asFloat())
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_DIVIDE)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicInt32} containing the result of dividing this {@link DynamicInt32} by
-     * an integer; As an example, the following is equal to {@code DynamicInt32.constant(1)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).div(5);
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicInt32} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicInt32 div(int other) {
-      return new ArithmeticInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_DIVIDE)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of dividing this {@link DynamicInt32} by
-     * a float; As an example, the following is equal to {@code DynamicFloat.constant(1.4f)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).div(5f);
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat div(float other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this.asFloat())
-          .setInputRhs(DynamicFloat.constant(other))
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_DIVIDE)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicInt32} containing the reminder of dividing this {@link DynamicInt32}
-     * by another {@link DynamicInt32}; As an example, the following is equal to {@code
-     * DynamicInt32.constant(2)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).rem(DynamicInt32.constant(5));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicInt32} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicInt32 rem(@NonNull DynamicInt32 other) {
-      return new ArithmeticInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MODULO)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the reminder of dividing this {@link DynamicInt32}
-     * by a {@link DynamicFloat}; As an example, the following is equal to {@code
-     * DynamicFloat.constant(1.5f)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).rem(DynamicInt32.constant(5.5f));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat rem(@NonNull DynamicFloat other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this.asFloat())
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MODULO)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicInt32} containing the reminder of dividing this {@link DynamicInt32}
-     * by an integer; As an example, the following is equal to {@code DynamicInt32.constant(2)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).rem(5);
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicInt32} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicInt32 rem(int other) {
-      return new ArithmeticInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MODULO)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicInt32} containing the reminder of dividing this {@link DynamicInt32}
-     * by a float; As an example, the following is equal to {@code DynamicFloat.constant(1.5f)}
-     *
-     * <pre>
-     *   DynamicInt32.constant(7).rem(5.5f);
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat rem(float other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this.asFloat())
-          .setInputRhs(DynamicFloat.constant(other))
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MODULO)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} and
-     * {@code other} are equal, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool eq(@NonNull DynamicInt32 other) {
-      return new ComparisonInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_EQUALS)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} and
-     * {@code other} are equal, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool eq(int other) {
-      return new ComparisonInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_EQUALS)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} and
-     * {@code other} are not equal, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool ne(@NonNull DynamicInt32 other) {
-      return new ComparisonInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_NOT_EQUALS)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} and
-     * {@code other} are not equal, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool ne(int other) {
-      return new ComparisonInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_NOT_EQUALS)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is less
-     * than {@code other}, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool lt(@NonNull DynamicInt32 other) {
-      return new ComparisonInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_LESS_THAN)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is less
-     * than {@code other}, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool lt(int other) {
-      return new ComparisonInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_LESS_THAN)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is less
-     * than or equal to {@code other}, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool lte(@NonNull DynamicInt32 other) {
-      return new ComparisonInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_LESS_THAN_OR_EQUAL_TO)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is less
-     * than or equal to {@code other}, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool lte(int other) {
-      return new ComparisonInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_LESS_THAN_OR_EQUAL_TO)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
-     * greater than {@code other}, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool gt(@NonNull DynamicInt32 other) {
-      return new ComparisonInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_GREATER_THAN)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
-     * greater than {@code other}, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool gt(int other) {
-      return new ComparisonInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_GREATER_THAN)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
-     * greater than or equal to {@code other}, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool gte(@NonNull DynamicInt32 other) {
-      return new ComparisonInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_GREATER_THAN_OR_EQUAL_TO)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
-     * greater than or equal to {@code other}, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool gte(int other) {
-      return new ComparisonInt32Op.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_GREATER_THAN_OR_EQUAL_TO)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicString} that contains the formatted value of this {@link
-     * DynamicInt32} (with default formatting parameters). As an example, in the English locale, the
-     * following is equal to {@code DynamicString.constant("12")}
-     *
-     * <pre>
-     *   DynamicInt32.constant(12).format()
-     * </pre>
-     */
-    @NonNull
-    default DynamicString format() {
-      return IntFormatter.with().buildForInput(this);
-    }
-
-    /**
-     * Returns a {@link DynamicString} that contains the formatted value of this {@link
-     * DynamicInt32}. As an example, in the English locale, the following is equal to {@code
-     * DynamicString.constant("0,012")}
-     *
-     * <pre>
-     *   DynamicInt32.constant(12)
-     *            .format(
-     *                IntFormatter.with().minIntegerDigits(4).groupingUsed(true));
-     * </pre>
-     *
-     * @param formatter The formatting parameter.
-     */
-    @NonNull
-    default DynamicString format(@NonNull IntFormatter formatter) {
-      return formatter.buildForInput(this);
-    }
-
-    /** Allows formatting {@link DynamicInt32} into a {@link DynamicString}. */
-    class IntFormatter {
-      private final Int32FormatOp.Builder builder;
-
-      private IntFormatter() {
-        builder = new Int32FormatOp.Builder();
-      }
-
-      /** Creates an instance of {@link IntFormatter} with default configuration. */
-      @NonNull
-      public static IntFormatter with() {
-        return new IntFormatter();
-      }
-
-      /**
-       * Sets minimum number of integer digits for the formatter. Defaults to one if not specified.
-       */
-      @NonNull
-      public IntFormatter minIntegerDigits(@IntRange(from = 0) int minIntegerDigits) {
-        builder.setMinIntegerDigits(minIntegerDigits);
-        return this;
-      }
-
-      /** Sets whether grouping is used for the formatter. Defaults to false if not specified. */
-      @NonNull
-      public IntFormatter groupingUsed(boolean groupingUsed) {
-        builder.setGroupingUsed(groupingUsed);
-        return this;
-      }
-
-      @NonNull
-      Int32FormatOp buildForInput(@NonNull DynamicInt32 dynamicInt32) {
-        return builder.setInput(dynamicInt32).build();
-      }
-    }
-
-    /**
-     * Get the fingerprint for this object or null if unknown.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    Fingerprint getFingerprint();
-
-    /**
-     * Builder to create {@link DynamicInt32} objects.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    interface Builder {
-
-      /** Builds an instance with values accumulated in this Builder. */
-      @NonNull
-      DynamicInt32 build();
-    }
-  }
-
-  /**
-   * Creates a new wrapper instance from the proto. Intended for testing purposes only. An object
-   * created using this method can't be added to any other wrapper.
-   *
-   */
-  @RestrictTo(Scope.LIBRARY_GROUP)
-  @NonNull
-  public static DynamicInt32 dynamicInt32FromProto(@NonNull DynamicProto.DynamicInt32 proto) {
-    if (proto.hasFixed()) {
-      return FixedInt32.fromProto(proto.getFixed());
-    }
-    if(proto.hasPlatformSource()) {
-        return PlatformInt32Source.fromProto(proto.getPlatformSource());
-    }
-    if (proto.hasArithmeticOperation()) {
-      return ArithmeticInt32Op.fromProto(proto.getArithmeticOperation());
-    }
-    if (proto.hasStateSource()) {
-      return StateInt32Source.fromProto(proto.getStateSource());
-    }
-    if (proto.hasConditionalOp()) {
-      return ConditionalInt32Op.fromProto(proto.getConditionalOp());
-    }
-    if (proto.hasFloatToInt()) {
-      return FloatToInt32Op.fromProto(proto.getFloatToInt());
-    }
-    if (proto.hasDurationPart()) {
-      return GetDurationPartOp.fromProto(proto.getDurationPart());
-    }
-    if (proto.hasAnimatableFixed()) {
-      return AnimatableFixedInt32.fromProto(proto.getAnimatableFixed());
-    }
-    if (proto.hasAnimatableDynamic()) {
-      return AnimatableDynamicInt32.fromProto(proto.getAnimatableDynamic());
-    }
-    throw new IllegalStateException("Proto was not a recognised instance of DynamicInt32");
-  }
-
-  /**
-   * Simple formatting for dynamic int32.
-   *
-   * @since 1.2
-   */
-  static final class Int32FormatOp implements DynamicString {
-    private final DynamicProto.Int32FormatOp mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    Int32FormatOp(DynamicProto.Int32FormatOp impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
-
-    /**
-     * Gets the source of Int32 data to convert to a string.
+     * Equality check (result = LHS == RHS). For floats, for equality check, small epsilon is used,
+     * i.e.: (result = abs(LHS - RHS) < epsilon).
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicInt32 getInput() {
-      if (mImpl.hasInput()) {
-        return DynamicBuilders.dynamicInt32FromProto(mImpl.getInput());
-      } else {
-        return null;
-      }
-    }
+    static final int COMPARISON_OP_TYPE_EQUALS = 1;
 
     /**
-     * Gets minimum integer digits. Sign and grouping characters are not considered when applying
-     * minIntegerDigits constraint. If not defined, defaults to one. For example,in the English
-     * locale, applying minIntegerDigit=4 to 12 would yield "0012".
+     * Not equal check (result = LHS != RHS).
      *
      * @since 1.2
      */
-    @IntRange(from = 0)
-    public int getMinIntegerDigits() {
-      return mImpl.getMinIntegerDigits();
-    }
+    static final int COMPARISON_OP_TYPE_NOT_EQUALS = 2;
 
     /**
-     * Gets digit grouping used. Grouping size and grouping character depend on the current locale.
-     * If not defined, defaults to false. For example, in the English locale, using grouping with
-     * 1234 would yield "1,234".
+     * Strictly less than (result = LHS < RHS).
      *
      * @since 1.2
      */
-    public boolean getGroupingUsed() {
-      return mImpl.getGroupingUsed();
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static Int32FormatOp fromProto(@NonNull DynamicProto.Int32FormatOp proto) {
-      return new Int32FormatOp(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.Int32FormatOp toProto() {
-      return mImpl;
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicString toDynamicStringProto() {
-      return DynamicProto.DynamicString.newBuilder().setInt32FormatOp(mImpl).build();
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-      return "Int32FormatOp{"
-          + "input="
-          + getInput()
-          + ", minIntegerDigits="
-          + getMinIntegerDigits()
-          + ", groupingUsed="
-          + getGroupingUsed()
-          + "}";
-    }
-
-    /** Builder for {@link Int32FormatOp}. */
-    public static final class Builder implements DynamicString.Builder {
-      private final DynamicProto.Int32FormatOp.Builder mImpl =
-          DynamicProto.Int32FormatOp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(196209833);
-
-      public Builder() {}
-
-      /**
-       * Sets the source of Int32 data to convert to a string.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInput(@NonNull DynamicInt32 input) {
-        mImpl.setInput(input.toDynamicInt32Proto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets minimum integer digits. Sign and grouping characters are not considered when applying
-       * minIntegerDigits constraint. If not defined, defaults to one. For example,in the English
-       * locale, applying minIntegerDigit=4 to 12 would yield "0012".
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setMinIntegerDigits(@IntRange(from = 0) int minIntegerDigits) {
-        mImpl.setMinIntegerDigits(minIntegerDigits);
-        mFingerprint.recordPropertyUpdate(4, minIntegerDigits);
-        return this;
-      }
-
-      /**
-       * Sets digit grouping used. Grouping size and grouping character depend on the current
-       * locale. If not defined, defaults to false. For example, in the English locale, using
-       * grouping with 1234 would yield "1,234".
-       *
-       * @since 1.2
-       */
-      @SuppressLint("MissingGetterMatchingBuilder")
-      @NonNull
-      public Builder setGroupingUsed(boolean groupingUsed) {
-        mImpl.setGroupingUsed(groupingUsed);
-        mFingerprint.recordPropertyUpdate(5, Boolean.hashCode(groupingUsed));
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public Int32FormatOp build() {
-        return new Int32FormatOp(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * A dynamic String which sources its data from the tile's state.
-   *
-   * @since 1.2
-   */
-  static final class StateStringSource implements DynamicString {
-    private final DynamicProto.StateStringSource mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    StateStringSource(DynamicProto.StateStringSource impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
+    static final int COMPARISON_OP_TYPE_LESS_THAN = 3;
 
     /**
-     * Gets the key in the state to bind to.
+     * Less than or equal to (result = LHS <= RHS).
      *
      * @since 1.2
      */
-    @NonNull
-    public String getSourceKey() {
-      return mImpl.getSourceKey();
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static StateStringSource fromProto(@NonNull DynamicProto.StateStringSource proto) {
-      return new StateStringSource(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.StateStringSource toProto() {
-      return mImpl;
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicString toDynamicStringProto() {
-      return DynamicProto.DynamicString.newBuilder().setStateSource(mImpl).build();
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-      return "StateStringSource{" + "sourceKey=" + getSourceKey() + "}";
-    }
-
-    /** Builder for {@link StateStringSource}. */
-    public static final class Builder implements DynamicString.Builder {
-      private final DynamicProto.StateStringSource.Builder mImpl =
-          DynamicProto.StateStringSource.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(1261652090);
-
-      public Builder() {}
-
-      /**
-       * Sets the key in the state to bind to.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setSourceKey(@NonNull String sourceKey) {
-        mImpl.setSourceKey(sourceKey);
-        mFingerprint.recordPropertyUpdate(1, sourceKey.hashCode());
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public StateStringSource build() {
-        return new StateStringSource(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * A conditional operator which yields an string depending on the boolean operand. This implements
-   * "string result = condition ? value_if_true : value_if_false".
-   *
-   * @since 1.2
-   */
-  static final class ConditionalStringOp implements DynamicString {
-    private final DynamicProto.ConditionalStringOp mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    ConditionalStringOp(DynamicProto.ConditionalStringOp impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
+    static final int COMPARISON_OP_TYPE_LESS_THAN_OR_EQUAL_TO = 4;
 
     /**
-     * Gets the condition to use.
+     * Strictly greater than (result = LHS > RHS).
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicBool getCondition() {
-      if (mImpl.hasCondition()) {
-        return DynamicBuilders.dynamicBoolFromProto(mImpl.getCondition());
-      } else {
-        return null;
-      }
-    }
+    static final int COMPARISON_OP_TYPE_GREATER_THAN = 5;
 
     /**
-     * Gets the string to yield if condition is true.
+     * Greater than or equal to (result = LHS >= RHS).
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicString getValueIfTrue() {
-      if (mImpl.hasValueIfTrue()) {
-        return DynamicBuilders.dynamicStringFromProto(mImpl.getValueIfTrue());
-      } else {
-        return null;
-      }
-    }
+    static final int COMPARISON_OP_TYPE_GREATER_THAN_OR_EQUAL_TO = 6;
 
     /**
-     * Gets the string to yield if condition is false.
+     * The type of logical operation to carry out in a {@link LogicalBoolOp} operation.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicString getValueIfFalse() {
-      if (mImpl.hasValueIfFalse()) {
-        return DynamicBuilders.dynamicStringFromProto(mImpl.getValueIfFalse());
-      } else {
-        return null;
-      }
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static ConditionalStringOp fromProto(@NonNull DynamicProto.ConditionalStringOp proto) {
-      return new ConditionalStringOp(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.ConditionalStringOp toProto() {
-      return mImpl;
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicString toDynamicStringProto() {
-      return DynamicProto.DynamicString.newBuilder().setConditionalOp(mImpl).build();
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-      return "ConditionalStringOp{"
-          + "condition="
-          + getCondition()
-          + ", valueIfTrue="
-          + getValueIfTrue()
-          + ", valueIfFalse="
-          + getValueIfFalse()
-          + "}";
-    }
-
-    /** Builder for {@link ConditionalStringOp}. */
-    public static final class Builder implements DynamicString.Builder {
-      private final DynamicProto.ConditionalStringOp.Builder mImpl =
-          DynamicProto.ConditionalStringOp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-1535849633);
-
-      public Builder() {}
-
-      /**
-       * Sets the condition to use.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setCondition(@NonNull DynamicBool condition) {
-        mImpl.setCondition(condition.toDynamicBoolProto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(condition.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the string to yield if condition is true.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setValueIfTrue(@NonNull DynamicString valueIfTrue) {
-        mImpl.setValueIfTrue(valueIfTrue.toDynamicStringProto());
-        mFingerprint.recordPropertyUpdate(
-            2, checkNotNull(valueIfTrue.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the string to yield if condition is false.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setValueIfFalse(@NonNull DynamicString valueIfFalse) {
-        mImpl.setValueIfFalse(valueIfFalse.toDynamicStringProto());
-        mFingerprint.recordPropertyUpdate(
-            3, checkNotNull(valueIfFalse.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public ConditionalStringOp build() {
-        return new ConditionalStringOp(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * This implements simple string concatenation "result = LHS+RHS".
-   *
-   * @since 1.2
-   */
-  static final class ConcatStringOp implements DynamicString {
-
-    private final DynamicProto.ConcatStringOp mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    ConcatStringOp(DynamicProto.ConcatStringOp impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @IntDef({LOGICAL_OP_TYPE_UNDEFINED, LOGICAL_OP_TYPE_AND, LOGICAL_OP_TYPE_OR})
+    @Retention(RetentionPolicy.SOURCE)
+    @interface LogicalOpType {}
 
     /**
-     * Gets left hand side of the concatenation operation.
+     * Undefined operation type.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicString getInputLhs() {
-      if (mImpl.hasInputLhs()) {
-        return DynamicBuilders.dynamicStringFromProto(mImpl.getInputLhs());
-      } else {
-        return null;
-      }
-    }
+    static final int LOGICAL_OP_TYPE_UNDEFINED = 0;
 
     /**
-     * Gets right hand side of the concatenation operation.
+     * Logical AND.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicString getInputRhs() {
-      if (mImpl.hasInputRhs()) {
-        return DynamicBuilders.dynamicStringFromProto(mImpl.getInputRhs());
-      } else {
-        return null;
-      }
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static ConcatStringOp fromProto(@NonNull DynamicProto.ConcatStringOp proto) {
-      return new ConcatStringOp(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.ConcatStringOp toProto() {
-      return mImpl;
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicString toDynamicStringProto() {
-      return DynamicProto.DynamicString.newBuilder().setConcatOp(mImpl).build();
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-      return "ConcatStringOp{" + "inputLhs=" + getInputLhs() + ", inputRhs=" + getInputRhs() + "}";
-    }
-
-    /** Builder for {@link ConcatStringOp}. */
-    public static final class Builder implements DynamicString.Builder {
-      private final DynamicProto.ConcatStringOp.Builder mImpl =
-          DynamicProto.ConcatStringOp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-1516620377);
-
-      public Builder() {}
-
-      /**
-       * Sets left hand side of the concatenation operation.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInputLhs(@NonNull DynamicString inputLhs) {
-        mImpl.setInputLhs(inputLhs.toDynamicStringProto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(inputLhs.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets right hand side of the concatenation operation.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInputRhs(@NonNull DynamicString inputRhs) {
-        mImpl.setInputRhs(inputRhs.toDynamicStringProto());
-        mFingerprint.recordPropertyUpdate(
-            2, checkNotNull(inputRhs.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public ConcatStringOp build() {
-        return new ConcatStringOp(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * Simple formatting for dynamic floats.
-   *
-   * @since 1.2
-   */
-  static final class FloatFormatOp implements DynamicString {
-    private final DynamicProto.FloatFormatOp mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    FloatFormatOp(DynamicProto.FloatFormatOp impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
+    static final int LOGICAL_OP_TYPE_AND = 1;
 
     /**
-     * Gets the source of Float data to convert to a string.
+     * Logical OR.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicFloat getInput() {
-      if (mImpl.hasInput()) {
-        return DynamicBuilders.dynamicFloatFromProto(mImpl.getInput());
-      } else {
-        return null;
-      }
-    }
+    static final int LOGICAL_OP_TYPE_OR = 2;
 
     /**
-     * Gets maximum fraction digits. Rounding will be applied if maxFractionDigits is smaller than
-     * number of fraction digits. If not defined, defaults to three. minimumFractionDigits must be
-     * <= maximumFractionDigits. If the condition is not satisfied, then minimumFractionDigits will
-     * be used for both fields.
+     * The duration part to retrieve using {@link GetDurationPartOp}.
      *
      * @since 1.2
      */
-    @IntRange(from = 0)
-    public int getMaxFractionDigits() {
-      return mImpl.getMaxFractionDigits();
-    }
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @IntDef({
+        DURATION_PART_TYPE_UNDEFINED,
+        DURATION_PART_TYPE_TOTAL_DAYS,
+        DURATION_PART_TYPE_TOTAL_HOURS,
+        DURATION_PART_TYPE_TOTAL_MINUTES,
+        DURATION_PART_TYPE_TOTAL_SECONDS,
+        DURATION_PART_TYPE_DAYS,
+        DURATION_PART_TYPE_HOURS,
+        DURATION_PART_TYPE_MINUTES,
+        DURATION_PART_TYPE_SECONDS
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface DurationPartType {}
 
     /**
-     * Gets minimum fraction digits. Zeros will be appended to the end to satisfy this constraint.
-     * If not defined, defaults to zero. minimumFractionDigits must be <= maximumFractionDigits. If
-     * the condition is not satisfied, then minimumFractionDigits will be used for both fields.
+     * Undefined duration part type.
      *
      * @since 1.2
      */
-    @IntRange(from = 0)
-    public int getMinFractionDigits() {
-      return mImpl.getMinFractionDigits();
-    }
+    static final int DURATION_PART_TYPE_UNDEFINED = 0;
 
     /**
-     * Gets minimum integer digits. Sign and grouping characters are not considered when applying
-     * minIntegerDigits constraint. If not defined, defaults to one. For example, in the English
-     * locale, applying minIntegerDigit=4 to 12.34 would yield "0012.34".
+     * Total number of days in a duration. The fraction part of the result will be truncated. This
+     * is based on the standard definition of a day as 24 hours. Notice that the duration can be
+     * negative, in which case total number of days will be also negative.
      *
      * @since 1.2
      */
-    @IntRange(from = 0)
-    public int getMinIntegerDigits() {
-      return mImpl.getMinIntegerDigits();
-    }
+    static final int DURATION_PART_TYPE_TOTAL_DAYS = 1;
 
     /**
-     * Gets digit grouping used. Grouping size and grouping character depend on the current locale.
-     * If not defined, defaults to false. For example, in the English locale, using grouping with
-     * 1234.56 would yield "1,234.56".
+     * Total number of hours in a duration. The fraction part of the result will be truncated.
+     * Notice that the duration can be negative, in which case total number of hours will be also
+     * negative.
      *
      * @since 1.2
      */
-    public boolean getGroupingUsed() {
-      return mImpl.getGroupingUsed();
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static FloatFormatOp fromProto(@NonNull DynamicProto.FloatFormatOp proto) {
-      return new FloatFormatOp(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.FloatFormatOp toProto() {
-      return mImpl;
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicString toDynamicStringProto() {
-      return DynamicProto.DynamicString.newBuilder().setFloatFormatOp(mImpl).build();
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-      return "FloatFormatOp{"
-          + "input="
-          + getInput()
-          + ", maxFractionDigits="
-          + getMaxFractionDigits()
-          + ", minFractionDigits="
-          + getMinFractionDigits()
-          + ", minIntegerDigits="
-          + getMinIntegerDigits()
-          + ", groupingUsed="
-          + getGroupingUsed()
-          + "}";
-    }
-
-    /** Builder for {@link FloatFormatOp}. */
-    public static final class Builder implements DynamicString.Builder {
-      private final DynamicProto.FloatFormatOp.Builder mImpl =
-          DynamicProto.FloatFormatOp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-5150153);
-
-      public Builder() {}
-
-      /**
-       * Sets the source of Float data to convert to a string.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInput(@NonNull DynamicFloat input) {
-        mImpl.setInput(input.toDynamicFloatProto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets maximum fraction digits. Rounding will be applied if maxFractionDigits is smaller than
-       * number of fraction digits. If not defined, defaults to three. minimumFractionDigits must be
-       * <= maximumFractionDigits. If the condition is not satisfied, then minimumFractionDigits
-       * will be used for both fields.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setMaxFractionDigits(@IntRange(from = 0) int maxFractionDigits) {
-        mImpl.setMaxFractionDigits(maxFractionDigits);
-        mFingerprint.recordPropertyUpdate(2, maxFractionDigits);
-        return this;
-      }
-
-      /**
-       * Sets minimum fraction digits. Zeros will be appended to the end to satisfy this constraint.
-       * If not defined, defaults to zero. minimumFractionDigits must be <= maximumFractionDigits.
-       * If the condition is not satisfied, then minimumFractionDigits will be used for both fields.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setMinFractionDigits(@IntRange(from = 0) int minFractionDigits) {
-        mImpl.setMinFractionDigits(minFractionDigits);
-        mFingerprint.recordPropertyUpdate(3, minFractionDigits);
-        return this;
-      }
-
-      /**
-       * Sets minimum integer digits. Sign and grouping characters are not considered when applying
-       * minIntegerDigits constraint. If not defined, defaults to one. For example, in the English
-       * locale, applying minIntegerDigit=4 to 12.34 would yield "0012.34".
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setMinIntegerDigits(@IntRange(from = 0) int minIntegerDigits) {
-        mImpl.setMinIntegerDigits(minIntegerDigits);
-        mFingerprint.recordPropertyUpdate(4, minIntegerDigits);
-        return this;
-      }
-
-      /**
-       * Sets digit grouping used. Grouping size and grouping character depend on the current
-       * locale. If not defined, defaults to false. For example, in the English locale, using
-       * grouping with 1234.56 would yield "1,234.56".
-       *
-       * @since 1.2
-       */
-      @SuppressLint("MissingGetterMatchingBuilder")
-      @NonNull
-      public Builder setGroupingUsed(boolean groupingUsed) {
-        mImpl.setGroupingUsed(groupingUsed);
-        mFingerprint.recordPropertyUpdate(5, Boolean.hashCode(groupingUsed));
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public FloatFormatOp build() {
-        return new FloatFormatOp(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * Interface defining a dynamic string type.
-   *
-   * @since 1.2
-   */
-  public interface DynamicString extends DynamicType {
-    /**
-     * Get the protocol buffer representation of this object.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    DynamicProto.DynamicString toDynamicStringProto();
+    static final int DURATION_PART_TYPE_TOTAL_HOURS = 2;
 
     /**
-     * Creates a {@link DynamicString} from a byte array generated by {@link
-     * #toDynamicStringByteArray()}.
-     */
-    @NonNull
-    static DynamicString fromByteArray(@NonNull byte[] byteArray) {
-      try {
-        return dynamicStringFromProto(
-            DynamicProto.DynamicString.parseFrom(
-                byteArray, ExtensionRegistryLite.getEmptyRegistry()));
-      } catch (InvalidProtocolBufferException e) {
-        throw new IllegalArgumentException("Byte array could not be parsed into DynamicString", e);
-      }
-    }
-
-    /** Creates a byte array that can later be used with {@link #fromByteArray(byte[])}. */
-    @NonNull
-    default byte[] toDynamicStringByteArray() {
-      return toDynamicStringProto().toByteArray();
-    }
-
-    /** Creates a constant-valued {@link DynamicString}. */
-    @NonNull
-    static DynamicString constant(@NonNull String constant) {
-      return new FixedString.Builder().setValue(constant).build();
-    }
-
-    /**
-     * Creates a {@link DynamicString} that is bound to the value of an item of the State.
-     *
-     * @param stateKey The key to a {@link StateEntryValue} with a string value from the provider's
-     *     state.
-     */
-    @NonNull
-    static DynamicString fromState(@NonNull String stateKey) {
-      return new StateStringSource.Builder().setSourceKey(stateKey).build();
-    }
-
-    /**
-     * Creates a {@link DynamicString} that is bound to the result of a conditional expression. It
-     * will use the value given in either {@link ConditionScope#use} or {@link
-     * ConditionScopes.IfTrueScope#elseUse} depending on the value yielded from {@code condition}.
-     *
-     * @param condition The value used for evaluting this condition.
-     */
-    @NonNull
-    static ConditionScope<DynamicString, String> onCondition(@NonNull DynamicBool condition) {
-      return new ConditionScopes.ConditionScope<>(
-          (trueValue, falseValue) ->
-              new ConditionalStringOp.Builder()
-                  .setCondition(condition)
-                  .setValueIfTrue(trueValue)
-                  .setValueIfFalse(falseValue)
-                  .build(),
-          DynamicString::constant);
-    }
-
-    /**
-     * Returns a new {@link DynamicString} that has the result of concatenating this {@link
-     * DynamicString} with {@code other}. i.e. {@code result = this + other}
-     *
-     * @param other The right hand side operand of the concatenation.
-     */
-    @NonNull
-    default DynamicString concat(@NonNull DynamicString other) {
-      return new DynamicBuilders.ConcatStringOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .build();
-    }
-
-    /**
-     * Get the fingerprint for this object or null if unknown.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    Fingerprint getFingerprint();
-
-    /**
-     * Builder to create {@link DynamicString} objects.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    interface Builder {
-
-      /** Builds an instance with values accumulated in this Builder. */
-      @NonNull
-      DynamicString build();
-    }
-  }
-
-  /**
-   * Creates a new wrapper instance from the proto. Intended for testing purposes only. An object
-   * created using this method can't be added to any other wrapper.
-   *
-   */
-  @RestrictTo(Scope.LIBRARY_GROUP)
-  @NonNull
-  public static DynamicString dynamicStringFromProto(@NonNull DynamicProto.DynamicString proto) {
-    if (proto.hasFixed()) {
-      return FixedString.fromProto(proto.getFixed());
-    }
-    if (proto.hasInt32FormatOp()) {
-      return Int32FormatOp.fromProto(proto.getInt32FormatOp());
-    }
-    if (proto.hasStateSource()) {
-      return StateStringSource.fromProto(proto.getStateSource());
-    }
-    if (proto.hasConditionalOp()) {
-      return ConditionalStringOp.fromProto(proto.getConditionalOp());
-    }
-    if (proto.hasConcatOp()) {
-      return ConcatStringOp.fromProto(proto.getConcatOp());
-    }
-    if (proto.hasFloatFormatOp()) {
-      return FloatFormatOp.fromProto(proto.getFloatFormatOp());
-    }
-    throw new IllegalStateException("Proto was not a recognised instance of DynamicString");
-  }
-
-  /**
-   * An arithmetic operation, operating on two Float instances. This implements simple binary
-   * operations of the form "result = LHS <op> RHS", where the available operation types are
-   * described in {@code ArithmeticOpType}.
-   *
-   * @since 1.2
-   */
-  static final class ArithmeticFloatOp implements DynamicFloat {
-
-    private final DynamicProto.ArithmeticFloatOp mImpl;
-    @Nullable
-    private final Fingerprint mFingerprint;
-
-    ArithmeticFloatOp(DynamicProto.ArithmeticFloatOp impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
-
-    /**
-     * Gets left hand side of the arithmetic operation.
+     * Total number of minutes in a duration. The fraction part of the result will be truncated.
+     * Notice that the duration can be negative, in which case total number of minutes will be also
+     * negative.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicFloat getInputLhs() {
-      if (mImpl.hasInputLhs()) {
-        return DynamicBuilders.dynamicFloatFromProto(mImpl.getInputLhs());
-      } else {
-        return null;
-      }
-    }
+    static final int DURATION_PART_TYPE_TOTAL_MINUTES = 3;
 
     /**
-     * Gets right hand side of the arithmetic operation.
+     * Total number of seconds in a duration. Notice that the duration can be negative, in which
+     * case total number of seconds will be also negative.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicFloat getInputRhs() {
-      if (mImpl.hasInputRhs()) {
-        return DynamicBuilders.dynamicFloatFromProto(mImpl.getInputRhs());
-      } else {
-        return null;
-      }
-    }
+    static final int DURATION_PART_TYPE_TOTAL_SECONDS = 4;
 
     /**
-     * Gets the type of operation to carry out.
+     * Number of days part in the duration. This represents the absolute value of the total number
+     * of days in the duration based on the 24 hours day definition. The fraction part of the result
+     * will be truncated.
      *
      * @since 1.2
      */
-    @ArithmeticOpType
-    public int getOperationType() {
-      return mImpl.getOperationType().getNumber();
-    }
+    static final int DURATION_PART_TYPE_DAYS = 5;
 
     /**
-     */
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static ArithmeticFloatOp fromProto(@NonNull DynamicProto.ArithmeticFloatOp proto) {
-      return new ArithmeticFloatOp(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.ArithmeticFloatOp toProto() {
-      return mImpl;
-    }
-
-    /**
-     */
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicFloat toDynamicFloatProto() {
-      return DynamicProto.DynamicFloat.newBuilder().setArithmeticOperation(mImpl).build();
-    }
-
-    /**
-     * Builder for {@link ArithmeticFloatOp}.
-     */
-    public static final class Builder implements DynamicFloat.Builder {
-
-      private final DynamicProto.ArithmeticFloatOp.Builder mImpl =
-          DynamicProto.ArithmeticFloatOp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-1818249334);
-
-      public Builder() {
-      }
-
-      /**
-       * Sets left hand side of the arithmetic operation.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInputLhs(@NonNull DynamicFloat inputLhs) {
-        mImpl.setInputLhs(inputLhs.toDynamicFloatProto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(inputLhs.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets right hand side of the arithmetic operation.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInputRhs(@NonNull DynamicFloat inputRhs) {
-        mImpl.setInputRhs(inputRhs.toDynamicFloatProto());
-        mFingerprint.recordPropertyUpdate(
-            2, checkNotNull(inputRhs.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the type of operation to carry out.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setOperationType(@ArithmeticOpType int operationType) {
-        mImpl.setOperationType(DynamicProto.ArithmeticOpType.forNumber(operationType));
-        mFingerprint.recordPropertyUpdate(3, operationType);
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public ArithmeticFloatOp build() {
-        return new ArithmeticFloatOp(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * A dynamic Float which sources its data from the tile's state.
-   *
-   * @since 1.2
-   */
-  static final class StateFloatSource implements DynamicFloat {
-    private final DynamicProto.StateFloatSource mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    StateFloatSource(DynamicProto.StateFloatSource impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
-
-    /**
-     * Gets the key in the state to bind to.
+     * Number of hours part in the duration. This represents the absolute value of remaining hours
+     * when dividing total hours by hours in a day (24 hours).
      *
      * @since 1.2
      */
-    @NonNull
-    public String getSourceKey() {
-      return mImpl.getSourceKey();
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static StateFloatSource fromProto(@NonNull DynamicProto.StateFloatSource proto) {
-      return new StateFloatSource(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.StateFloatSource toProto() {
-      return mImpl;
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicFloat toDynamicFloatProto() {
-      return DynamicProto.DynamicFloat.newBuilder().setStateSource(mImpl).build();
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-      return "StateFloatSource{" + "sourceKey=" + getSourceKey() + "}";
-    }
-
-    /** Builder for {@link StateFloatSource}. */
-    public static final class Builder implements DynamicFloat.Builder {
-      private final DynamicProto.StateFloatSource.Builder mImpl =
-          DynamicProto.StateFloatSource.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(384370154);
-
-      public Builder() {}
-
-      /**
-       * Sets the key in the state to bind to.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setSourceKey(@NonNull String sourceKey) {
-        mImpl.setSourceKey(sourceKey);
-        mFingerprint.recordPropertyUpdate(1, sourceKey.hashCode());
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public StateFloatSource build() {
-        return new StateFloatSource(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * An operation to convert an Int32 value in the dynamic data pipeline to a Float value.
-   *
-   * @since 1.2
-   */
-  static final class Int32ToFloatOp implements DynamicFloat {
-    private final DynamicProto.Int32ToFloatOp mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    Int32ToFloatOp(DynamicProto.Int32ToFloatOp impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
+    static final int DURATION_PART_TYPE_HOURS = 6;
 
     /**
-     * Gets the input Int32 to convert to a Float.
+     * Number of minutes part in the duration. This represents the absolute value of remaining
+     * minutes when dividing total minutes by minutes in an hour (60 minutes).
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicInt32 getInput() {
-      if (mImpl.hasInput()) {
-        return DynamicBuilders.dynamicInt32FromProto(mImpl.getInput());
-      } else {
-        return null;
-      }
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static Int32ToFloatOp fromProto(@NonNull DynamicProto.Int32ToFloatOp proto) {
-      return new Int32ToFloatOp(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.Int32ToFloatOp toProto() {
-      return mImpl;
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicFloat toDynamicFloatProto() {
-      return DynamicProto.DynamicFloat.newBuilder().setInt32ToFloatOperation(mImpl).build();
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-      return "Int32ToFloatOp{" + "input=" + getInput() + "}";
-    }
-
-    /** Builder for {@link Int32ToFloatOp}. */
-    public static final class Builder implements DynamicFloat.Builder {
-      private final DynamicProto.Int32ToFloatOp.Builder mImpl =
-          DynamicProto.Int32ToFloatOp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-619592745);
-
-      public Builder() {}
-
-      /**
-       * Sets the input Int32 to convert to a Float.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInput(@NonNull DynamicInt32 input) {
-        mImpl.setInput(input.toDynamicInt32Proto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public Int32ToFloatOp build() {
-        return new Int32ToFloatOp(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * A static interpolation node, between two fixed floating point values.
-   *
-   * @since 1.2
-   */
-  static final class AnimatableFixedFloat implements DynamicFloat {
-    private final DynamicProto.AnimatableFixedFloat mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    AnimatableFixedFloat(
-        DynamicProto.AnimatableFixedFloat impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
+    static final int DURATION_PART_TYPE_MINUTES = 7;
 
     /**
-     * Gets the number to start animating from.
+     * Number of seconds part in the duration. This represents the absolute value of remaining
+     * seconds when dividing total seconds by seconds in a minute (60 seconds).
      *
      * @since 1.2
      */
-    public float getFromValue() {
-      return mImpl.getFromValue();
-    }
+    static final int DURATION_PART_TYPE_SECONDS = 8;
 
     /**
-     * Gets the number to animate to.
+     * A dynamic Int32 which sources its data from some platform data source, e.g. from sensors, or
+     * the current time.
      *
      * @since 1.2
      */
-    public float getToValue() {
-      return mImpl.getToValue();
+    @ProtoLayoutExperimental
+    static final class PlatformInt32Source implements DynamicInt32 {
+        private final DynamicProto.PlatformInt32Source mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        PlatformInt32Source(
+                DynamicProto.PlatformInt32Source impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the source to load data from.
+         *
+         * @since 1.2
+         */
+        @PlatformInt32SourceType
+        public int getSourceType() {
+            return mImpl.getSourceType().getNumber();
+        }
+
+        /** @hide */
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+        /**
+         * Creates a new wrapper instance from the proto.
+         *
+         * @hide
+         */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public static PlatformInt32Source fromProto(
+                @NonNull DynamicProto.PlatformInt32Source proto,
+                @Nullable Fingerprint fingerprint) {
+            return new PlatformInt32Source(proto, fingerprint);
+        }
+
+        @NonNull
+        static PlatformInt32Source fromProto(@NonNull DynamicProto.PlatformInt32Source proto) {
+            return fromProto(proto, null);
+        }
+
+        /**
+         * Returns the internal proto instance.
+         *
+         * @hide
+         */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        DynamicProto.PlatformInt32Source toProto() {
+            return mImpl;
+        }
+
+        /** @hide */
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
+            return DynamicProto.DynamicInt32.newBuilder().setPlatformSource(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "PlatformInt32Source{" + "sourceType=" + getSourceType() + "}";
+        }
+
+        /** Builder for {@link PlatformInt32Source}. */
+        public static final class Builder implements DynamicInt32.Builder {
+            private final DynamicProto.PlatformInt32Source.Builder mImpl =
+                    DynamicProto.PlatformInt32Source.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(1355180718);
+
+            public Builder() {}
+
+            /**
+             * Sets the source to load data from.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setSourceType(@PlatformInt32SourceType int sourceType) {
+                mImpl.setSourceType(DynamicProto.PlatformInt32SourceType.forNumber(sourceType));
+                mFingerprint.recordPropertyUpdate(1, sourceType);
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public PlatformInt32Source build() {
+                return new PlatformInt32Source(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the animation parameters for duration, delay, etc.
+     * An arithmetic operation, operating on two Int32 instances. This implements simple binary
+     * operations of the form "result = LHS <op> RHS", where the available operation types are
+     * described in {@code ArithmeticOpType}.
      *
      * @since 1.2
      */
-    @Nullable
-    public AnimationSpec getAnimationSpec() {
-      if (mImpl.hasAnimationSpec()) {
-        return AnimationSpec.fromProto(mImpl.getAnimationSpec());
-      } else {
-        return null;
-      }
-    }
+    static final class ArithmeticInt32Op implements DynamicInt32 {
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
+        private final DynamicProto.ArithmeticInt32Op mImpl;
+        @Nullable private final Fingerprint mFingerprint;
 
-    @NonNull
-    static AnimatableFixedFloat fromProto(@NonNull DynamicProto.AnimatableFixedFloat proto) {
-      return new AnimatableFixedFloat(proto, null);
-    }
+        ArithmeticInt32Op(DynamicProto.ArithmeticInt32Op impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
 
-    @NonNull
-    DynamicProto.AnimatableFixedFloat toProto() {
-      return mImpl;
-    }
+        /**
+         * Gets left hand side of the arithmetic operation.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicInt32 getInputLhs() {
+            if (mImpl.hasInputLhs()) {
+                return DynamicBuilders.dynamicInt32FromProto(mImpl.getInputLhs());
+            } else {
+                return null;
+            }
+        }
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicFloat toDynamicFloatProto() {
-      return DynamicProto.DynamicFloat.newBuilder().setAnimatableFixed(mImpl).build();
-    }
+        /**
+         * Gets right hand side of the arithmetic operation.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicInt32 getInputRhs() {
+            if (mImpl.hasInputRhs()) {
+                return DynamicBuilders.dynamicInt32FromProto(mImpl.getInputRhs());
+            } else {
+                return null;
+            }
+        }
 
-    @Override
-    @NonNull
-    public String toString() {
-      return "AnimatableFixedFloat{"
-          + "fromValue="
-          + getFromValue()
-          + ", toValue="
-          + getToValue()
-          + ", animationSpec="
-          + getAnimationSpec()
-          + "}";
-    }
+        /**
+         * Gets the type of operation to carry out.
+         *
+         * @since 1.2
+         */
+        @ArithmeticOpType
+        public int getOperationType() {
+            return mImpl.getOperationType().getNumber();
+        }
 
-    /** Builder for {@link AnimatableFixedFloat}. */
-    public static final class Builder implements DynamicFloat.Builder {
-      private final DynamicProto.AnimatableFixedFloat.Builder mImpl =
-          DynamicProto.AnimatableFixedFloat.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(1964707538);
+        /** */
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
 
-      public Builder() {}
+        @NonNull
+        static ArithmeticInt32Op fromProto(@NonNull DynamicProto.ArithmeticInt32Op proto) {
+            return new ArithmeticInt32Op(proto, null);
+        }
 
-      /**
-       * Sets the number to start animating from.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setFromValue(float fromValue) {
-        mImpl.setFromValue(fromValue);
-        mFingerprint.recordPropertyUpdate(1, Float.floatToIntBits(fromValue));
-        return this;
-      }
+        @NonNull
+        DynamicProto.ArithmeticInt32Op toProto() {
+            return mImpl;
+        }
 
-      /**
-       * Sets the number to animate to.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setToValue(float toValue) {
-        mImpl.setToValue(toValue);
-        mFingerprint.recordPropertyUpdate(2, Float.floatToIntBits(toValue));
-        return this;
-      }
+        /** */
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
+            return DynamicProto.DynamicInt32.newBuilder().setArithmeticOperation(mImpl).build();
+        }
 
-      /**
-       * Sets the animation parameters for duration, delay, etc.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
-        mImpl.setAnimationSpec(animationSpec.toProto());
-        mFingerprint.recordPropertyUpdate(
-            3, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
+        /** Builder for {@link ArithmeticInt32Op}. */
+        public static final class Builder implements DynamicInt32.Builder {
 
-      @Override
-      @NonNull
-      public AnimatableFixedFloat build() {
-        return new AnimatableFixedFloat(mImpl.build(), mFingerprint);
-      }
-    }
-  }
+            private final DynamicProto.ArithmeticInt32Op.Builder mImpl =
+                    DynamicProto.ArithmeticInt32Op.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(-2012727925);
 
-  /**
-   * A dynamic interpolation node. This will watch the value of its input and, when the first update
-   * arrives, immediately emit that value. On subsequent updates, it will animate between the old
-   * and new values.
-   *
-   * <p>If this node receives an invalid value (e.g. as a result of an upstream node having no
-   * value), then it will emit a single invalid value, and forget its "stored" value. The next valid
-   * value that arrives is then used as the "first" value again.
-   *
-   * @since 1.2
-   */
-  static final class AnimatableDynamicFloat implements DynamicFloat {
-    private final DynamicProto.AnimatableDynamicFloat mImpl;
-    @Nullable private final Fingerprint mFingerprint;
+            public Builder() {}
 
-    AnimatableDynamicFloat(
-        DynamicProto.AnimatableDynamicFloat impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
+            /**
+             * Sets left hand side of the arithmetic operation.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInputLhs(@NonNull DynamicInt32 inputLhs) {
+                mImpl.setInputLhs(inputLhs.toDynamicInt32Proto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(inputLhs.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets right hand side of the arithmetic operation.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInputRhs(@NonNull DynamicInt32 inputRhs) {
+                mImpl.setInputRhs(inputRhs.toDynamicInt32Proto());
+                mFingerprint.recordPropertyUpdate(
+                        2, checkNotNull(inputRhs.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the type of operation to carry out.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setOperationType(@ArithmeticOpType int operationType) {
+                mImpl.setOperationType(DynamicProto.ArithmeticOpType.forNumber(operationType));
+                mFingerprint.recordPropertyUpdate(3, operationType);
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public ArithmeticInt32Op build() {
+                return new ArithmeticInt32Op(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the value to watch, and animate when it changes.
+     * A dynamic Int32 which sources its data from the tile's state.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicFloat getInput() {
-      if (mImpl.hasInput()) {
-        return DynamicBuilders.dynamicFloatFromProto(mImpl.getInput());
-      } else {
-        return null;
-      }
+    static final class StateInt32Source implements DynamicInt32 {
+        private final DynamicProto.StateInt32Source mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        StateInt32Source(DynamicProto.StateInt32Source impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the key in the state to bind to.
+         *
+         * @since 1.2
+         */
+        @NonNull
+        public String getSourceKey() {
+            return mImpl.getSourceKey();
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static StateInt32Source fromProto(@NonNull DynamicProto.StateInt32Source proto) {
+            return new StateInt32Source(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.StateInt32Source toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
+            return DynamicProto.DynamicInt32.newBuilder().setStateSource(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "StateInt32Source{" + "sourceKey=" + getSourceKey() + "}";
+        }
+
+        /** Builder for {@link StateInt32Source}. */
+        public static final class Builder implements DynamicInt32.Builder {
+            private final DynamicProto.StateInt32Source.Builder mImpl =
+                    DynamicProto.StateInt32Source.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(58614749);
+
+            public Builder() {}
+
+            /**
+             * Sets the key in the state to bind to.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setSourceKey(@NonNull String sourceKey) {
+                mImpl.setSourceKey(sourceKey);
+                mFingerprint.recordPropertyUpdate(1, sourceKey.hashCode());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public StateInt32Source build() {
+                return new StateInt32Source(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the animation parameters for duration, delay, etc.
+     * A conditional operator which yields an integer depending on the boolean operand. This
+     * implements "int result = condition ? value_if_true : value_if_false".
      *
      * @since 1.2
      */
-    @Nullable
-    public AnimationSpec getAnimationSpec() {
-      if (mImpl.hasAnimationSpec()) {
-        return AnimationSpec.fromProto(mImpl.getAnimationSpec());
-      } else {
-        return null;
-      }
-    }
+    static final class ConditionalInt32Op implements DynamicInt32 {
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
+        private final DynamicProto.ConditionalInt32Op mImpl;
+        @Nullable private final Fingerprint mFingerprint;
 
-    @NonNull
-    static AnimatableDynamicFloat fromProto(@NonNull DynamicProto.AnimatableDynamicFloat proto) {
-      return new AnimatableDynamicFloat(proto, null);
-    }
+        ConditionalInt32Op(
+                DynamicProto.ConditionalInt32Op impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
 
-    @NonNull
-    DynamicProto.AnimatableDynamicFloat toProto() {
-      return mImpl;
-    }
+        /**
+         * Gets the condition to use.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicBool getCondition() {
+            if (mImpl.hasCondition()) {
+                return DynamicBuilders.dynamicBoolFromProto(mImpl.getCondition());
+            } else {
+                return null;
+            }
+        }
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicFloat toDynamicFloatProto() {
-      return DynamicProto.DynamicFloat.newBuilder().setAnimatableDynamic(mImpl).build();
-    }
+        /**
+         * Gets the integer to yield if condition is true.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicInt32 getValueIfTrue() {
+            if (mImpl.hasValueIfTrue()) {
+                return DynamicBuilders.dynamicInt32FromProto(mImpl.getValueIfTrue());
+            } else {
+                return null;
+            }
+        }
 
-    @Override
-    @NonNull
-    public String toString() {
-      return "AnimatableDynamicFloat{"
-          + "input="
-          + getInput()
-          + ", animationSpec="
-          + getAnimationSpec()
-          + "}";
-    }
+        /**
+         * Gets the integer to yield if condition is false.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicInt32 getValueIfFalse() {
+            if (mImpl.hasValueIfFalse()) {
+                return DynamicBuilders.dynamicInt32FromProto(mImpl.getValueIfFalse());
+            } else {
+                return null;
+            }
+        }
 
-    /** Builder for {@link AnimatableDynamicFloat}. */
-    public static final class Builder implements DynamicFloat.Builder {
-      private final DynamicProto.AnimatableDynamicFloat.Builder mImpl =
-          DynamicProto.AnimatableDynamicFloat.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(1543182280);
+        /** */
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
 
-      public Builder() {}
+        @NonNull
+        static ConditionalInt32Op fromProto(@NonNull DynamicProto.ConditionalInt32Op proto) {
+            return new ConditionalInt32Op(proto, null);
+        }
 
-      /**
-       * Sets the value to watch, and animate when it changes.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInput(@NonNull DynamicFloat input) {
-        mImpl.setInput(input.toDynamicFloatProto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
+        @NonNull
+        DynamicProto.ConditionalInt32Op toProto() {
+            return mImpl;
+        }
 
-      /**
-       * Sets the animation parameters for duration, delay, etc.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
-        mImpl.setAnimationSpec(animationSpec.toProto());
-        mFingerprint.recordPropertyUpdate(
-            3, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
+        /** */
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
+            return DynamicProto.DynamicInt32.newBuilder().setConditionalOp(mImpl).build();
+        }
 
-      @Override
-      @NonNull
-      public AnimatableDynamicFloat build() {
-        return new AnimatableDynamicFloat(mImpl.build(), mFingerprint);
-      }
-    }
-  }
+        /** Builder for {@link ConditionalInt32Op}. */
+        public static final class Builder implements DynamicInt32.Builder {
 
-  /**
-   * Interface defining a dynamic float type.
-   *
-   * <p>It offers a set of helper methods for creating arithmetic and logical expressions, e.g.
-   * {@link #plus(float)}, {@link #times(float)}, {@link #eq(float)}, etc. These helper methods
-   * produce expression trees based on the order in which they were called in an expression. Thus,
-   * no operator precedence rules are applied.
-   *
-   * <p>For example the following expression is equivalent to {@code result = ((a + b)*c)/d }:
-   *
-   * <pre>{@code
-   * a.plus(b).times(c).div(d);
-   * }</pre>
-   *
-   * More complex expressions can be created by nesting expressions. For example the following
-   * expression is equivalent to {@code result = (a + b)*(c - d) }:
-   *
-   * <pre>{@code
-   * (a.plus(b)).times(c.minus(d));
-   * }</pre>
-   *
-   * @since 1.2
-   */
-  public interface DynamicFloat extends DynamicType {
-    /**
-     * Get the protocol buffer representation of this object.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    DynamicProto.DynamicFloat toDynamicFloatProto();
+            private final DynamicProto.ConditionalInt32Op.Builder mImpl =
+                    DynamicProto.ConditionalInt32Op.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(1444834226);
 
-    /**
-     * Creates a {@link DynamicFloat} from a byte array generated by {@link
-     * #toDynamicFloatByteArray()}.
-     */
-    @NonNull
-    static DynamicFloat fromByteArray(@NonNull byte[] byteArray) {
-      try {
-        return dynamicFloatFromProto(
-            DynamicProto.DynamicFloat.parseFrom(
-                byteArray, ExtensionRegistryLite.getEmptyRegistry()));
-      } catch (InvalidProtocolBufferException e) {
-        throw new IllegalArgumentException("Byte array could not be parsed into DynamicFloat", e);
-      }
-    }
+            public Builder() {}
 
-    /** Creates a byte array that can later be used with {@link #fromByteArray(byte[])}. */
-    @NonNull
-    default byte[] toDynamicFloatByteArray() {
-      return toDynamicFloatProto().toByteArray();
-    }
+            /**
+             * Sets the condition to use.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setCondition(@NonNull DynamicBool condition) {
+                mImpl.setCondition(condition.toDynamicBoolProto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(condition.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
 
-    /** Creates a constant-valued {@link DynamicFloat}. */
-    @NonNull
-    static DynamicFloat constant(float constant) {
-      return new FixedFloat.Builder().setValue(constant).build();
+            /**
+             * Sets the integer to yield if condition is true.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setValueIfTrue(@NonNull DynamicInt32 valueIfTrue) {
+                mImpl.setValueIfTrue(valueIfTrue.toDynamicInt32Proto());
+                mFingerprint.recordPropertyUpdate(
+                        2, checkNotNull(valueIfTrue.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the integer to yield if condition is false.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setValueIfFalse(@NonNull DynamicInt32 valueIfFalse) {
+                mImpl.setValueIfFalse(valueIfFalse.toDynamicInt32Proto());
+                mFingerprint.recordPropertyUpdate(
+                        3, checkNotNull(valueIfFalse.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public ConditionalInt32Op build() {
+                return new ConditionalInt32Op(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Creates a {@link DynamicFloat} that is bound to the value of an item of the State.
-     *
-     * @param stateKey The key to a {@link StateEntryValue} with a float value from the provider's
-     *     state.
-     */
-    @NonNull
-    static DynamicFloat fromState(@NonNull String stateKey) {
-      return new StateFloatSource.Builder().setSourceKey(stateKey).build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} which will animate over the range of floats from {@code start}
-     * to {@code end}.
-     *
-     * @param start The start value of the range.
-     * @param end The end value of the range.
-     */
-    @NonNull
-    static DynamicFloat animate(float start, float end) {
-      return new AnimatableFixedFloat.Builder().setFromValue(start).setToValue(end).build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} which will animate over the range of floats from {@code start}
-     * to {@code end} with the given animation parameters.
-     *
-     * @param start The start value of the range.
-     * @param end The end value of the range.
-     * @param animationSpec The animation parameters.
-     */
-    @NonNull
-    static DynamicFloat animate(float start, float end, @NonNull AnimationSpec animationSpec) {
-      return new AnimatableFixedFloat.Builder()
-          .setFromValue(start)
-          .setToValue(end)
-          .setAnimationSpec(animationSpec)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} that is bound to the value of an item of the State. Every time
-     * the state value changes, this {@link DynamicFloat} will animate from its current value to the
-     * new value (from the state).
-     *
-     * @param stateKey The key to a {@link StateEntryValue} with a float value from the providers
-     *     state.
-     */
-    @NonNull
-    static DynamicFloat animate(@NonNull String stateKey) {
-      return new AnimatableDynamicFloat.Builder().setInput(fromState(stateKey)).build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} that is bound to the value of an item of the State. Every time
-     * the state value changes, this {@link DynamicFloat} will animate from its current value to the
-     * new value (from the state).
-     *
-     * @param stateKey The key to a {@link StateEntryValue} with a float value from the providers
-     *     state.
-     * @param animationSpec The animation parameters.
-     */
-    @NonNull
-    static DynamicFloat animate(@NonNull String stateKey, @NonNull AnimationSpec animationSpec) {
-      return new AnimatableDynamicFloat.Builder()
-          .setInput(fromState(stateKey))
-          .setAnimationSpec(animationSpec)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicFloat} that is bound to the value of this {@link DynamicFloat} and
-     * every time its value is changing, it animates from its current value to the new value.
-     *
-     * @param animationSpec The animation parameters.
-     */
-    @NonNull
-    default DynamicFloat animate(@NonNull AnimationSpec animationSpec) {
-      return new AnimatableDynamicFloat.Builder()
-          .setInput(this)
-          .setAnimationSpec(animationSpec)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicFloat} that is bound to the value of this {@link DynamicFloat} and
-     * every time its value is changing, it animates from its current value to the new value.
-     */
-    @NonNull
-    default DynamicFloat animate() {
-      return new AnimatableDynamicFloat.Builder().setInput(this).build();
-    }
-
-    /**
-     * Returns a {@link DynamicInt32} which holds the largest integer value that is smaller than or
-     * equal to this {@link DynamicFloat}, i.e. {@code int result = (int) Math.floor(this)}
-     */
-    @NonNull
-    default DynamicInt32 asInt() {
-      return new FloatToInt32Op.Builder()
-          .setRoundMode(DynamicBuilders.ROUND_MODE_FLOOR)
-          .setInput(this)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of adding another {@link DynamicFloat}
-     * to this {@link DynamicFloat}; As an example, the following is equal to {@code
-     * DynamicFloat.constant(13f)}
-     *
-     * <pre>
-     *   DynamicFloat.constant(7f).plus(DynamicFloat.constant(5f));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat plus(@NonNull DynamicFloat other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_ADD)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of adding a float to this {@link
-     * DynamicFloat}; As an example, the following is equal to {@code DynamicFloat.constant(13f)}
-     *
-     * <pre>
-     *   DynamicFloat.constant(7f).plus(5f);
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat plus(float other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_ADD)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of adding a {@link DynamicInt32} to this
-     * {@link DynamicFloat}; As an example, the following is equal to {@code
-     * DynamicFloat.constant(13f)}
-     *
-     * <pre>
-     *   DynamicFloat.constant(7f).plus(DynamicInt32.constant(5));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat plus(@NonNull DynamicInt32 other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other.asFloat())
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_ADD)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of subtracting another {@link
-     * DynamicFloat} from this {@link DynamicFloat}; As an example, the following is equal to {@code
-     * DynamicFloat.constant(2f)}
-     *
-     * <pre>
-     *   DynamicFloat.constant(7f).minus(DynamicFloat.constant(5f));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat minus(@NonNull DynamicFloat other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_SUBTRACT)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of subtracting a flaot from this {@link
-     * DynamicFloat}; As an example, the following is equal to {@code DynamicFloat.constant(2f)}
-     *
-     * <pre>
-     *   DynamicFloat.constant(7f).minus(5f);
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat minus(float other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_SUBTRACT)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of subtracting a {@link DynamicInt32}
-     * from this {@link DynamicFloat}; As an example, the following is equal to {@code
-     * DynamicFloat.constant(2f)}
-     *
-     * <pre>
-     *   DynamicFloat.constant(7f).minus(DynamicInt32.constant(5));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat minus(@NonNull DynamicInt32 other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other.asFloat())
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_SUBTRACT)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of multiplying this {@link DynamicFloat}
-     * by another {@link DynamicFloat}; As an example, the following is equal to {@code
-     * DynamicFloat.constant(35f)}
-     *
-     * <pre>
-     *   DynamicFloat.constant(7f).times(DynamicFloat.constant(5f));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat times(@NonNull DynamicFloat other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MULTIPLY)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of multiplying this {@link DynamicFloat}
-     * by a flaot; As an example, the following is equal to {@code DynamicFloat.constant(35f)}
-     *
-     * <pre>
-     *   DynamicFloat.constant(7f).times(5f);
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat times(float other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MULTIPLY)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of multiplying this {@link DynamicFloat}
-     * by a {@link DynamicInt32}; As an example, the following is equal to {@code
-     * DynamicFloat.constant(35f)}
-     *
-     * <pre>
-     *   DynamicFloat.constant(7f).times(DynamicInt32.constant(5));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat times(@NonNull DynamicInt32 other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other.asFloat())
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MULTIPLY)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of dividing this {@link DynamicFloat} by
-     * another {@link DynamicFloat}; As an example, the following is equal to {@code
-     * DynamicFloat.constant(1.4f)}
-     *
-     * <pre>
-     *   DynamicFloat.constant(7f).div(DynamicFloat.constant(5f));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat div(@NonNull DynamicFloat other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_DIVIDE)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of dividing this {@link DynamicFloat} by
-     * a float; As an example, the following is equal to {@code DynamicFloat.constant(1.4f)}
-     *
-     * <pre>
-     *   DynamicFloat.constant(7f).div(5f);
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat div(float other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_DIVIDE)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the result of dividing this {@link DynamicFloat} by
-     * a {@link DynamicInt32}; As an example, the following is equal to {@code
-     * DynamicFloat.constant(1.4f)}
-     *
-     * <pre>
-     *   DynamicFloat.constant(7f).div(DynamicInt32.constant(5));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat div(@NonNull DynamicInt32 other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other.asFloat())
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_DIVIDE)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the reminder of dividing this {@link DynamicFloat}
-     * by another {@link DynamicFloat}; As an example, the following is equal to {@code
-     * DynamicFloat.constant(1.5f)}
-     *
-     * <pre>
-     *   DynamicFloat.constant(7f).rem(DynamicFloat.constant(5.5f));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat rem(@NonNull DynamicFloat other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MODULO)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the reminder of dividing this {@link DynamicFloat}
-     * by a float; As an example, the following is equal to {@code DynamicFloat.constant(1.5f)}
-     *
-     * <pre>
-     *   DynamicFloat.constant(7f).rem(5.5f);
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat rem(float other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MODULO)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicFloat} containing the reminder of dividing this {@link DynamicFloat}
-     * by a {@link DynamicInt32}; As an example, the following is equal to {@code
-     * DynamicFloat.constant(2f)}
-     *
-     * <pre>
-     *   DynamicFloat.constant(7f).rem(DynamicInt32.constant(5));
-     * </pre>
-     *
-     * The operation's evaluation order depends only on its position in the expression; no operator
-     * precedence rules are applied. See {@link DynamicFloat} for more information on operation
-     * evaluation order.
-     *
-     * @return a new instance of {@link DynamicFloat} containing the result of the operation.
-     */
-    @SuppressWarnings("KotlinOperator")
-    @NonNull
-    default DynamicFloat rem(@NonNull DynamicInt32 other) {
-      return new ArithmeticFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other.asFloat())
-          .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MODULO)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} and
-     * {@code other} are equal, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool eq(@NonNull DynamicFloat other) {
-      return new ComparisonFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_EQUALS)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} and
-     * {@code other} are equal, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool eq(float other) {
-      return new ComparisonFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_EQUALS)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} and
-     * {@code other} are not equal, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool ne(@NonNull DynamicFloat other) {
-      return new ComparisonFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_NOT_EQUALS)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} and
-     * {@code other} are not equal, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool ne(float other) {
-      return new ComparisonFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_NOT_EQUALS)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} is less
-     * than {@code other}, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool lt(@NonNull DynamicFloat other) {
-      return new ComparisonFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_LESS_THAN)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} is less
-     * than {@code other}, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool lt(float other) {
-      return new ComparisonFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_LESS_THAN)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} is less
-     * than or equal to {@code other}, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool lte(@NonNull DynamicFloat other) {
-      return new ComparisonFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_LESS_THAN_OR_EQUAL_TO)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} is less
-     * than or equal to {@code other}, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool lte(float other) {
-      return new ComparisonFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_LESS_THAN_OR_EQUAL_TO)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} is
-     * greater than {@code other}, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool gt(@NonNull DynamicFloat other) {
-      return new ComparisonFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_GREATER_THAN)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} is
-     * greater than {@code other}, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool gt(float other) {
-      return new ComparisonFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_GREATER_THAN)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} is
-     * greater than or equal to {@code other}, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool gte(@NonNull DynamicFloat other) {
-      return new ComparisonFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(other)
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_GREATER_THAN_OR_EQUAL_TO)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} is
-     * greater than or equal to {@code other}, otherwise it's false.
-     */
-    @NonNull
-    default DynamicBool gte(float other) {
-      return new ComparisonFloatOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(constant(other))
-          .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_GREATER_THAN_OR_EQUAL_TO)
-          .build();
-    }
-
-    /**
-     * Bind the value of this {@link DynamicFloat} to the result of a conditional expression. This
-     * will use the value given in either {@link ConditionScope#use} or {@link
-     * ConditionScopes.IfTrueScope#elseUse} depending on the value yielded from {@code condition}.
-     */
-    @NonNull
-    static ConditionScope<DynamicFloat, Float> onCondition(@NonNull DynamicBool condition) {
-      return new ConditionScopes.ConditionScope<>(
-          (trueValue, falseValue) ->
-              new ConditionalFloatOp.Builder()
-                  .setCondition(condition)
-                  .setValueIfTrue(trueValue)
-                  .setValueIfFalse(falseValue)
-                  .build(),
-          DynamicFloat::constant);
-    }
-
-    /**
-     * Returns a {@link DynamicString} that contains the formatted value of this {@link
-     * DynamicFloat} (with default formatting parameters). As an example, in the English locale, the
-     * following is equal to {@code DynamicString.constant("12.346")}
-     *
-     * <pre>
-     *   DynamicFloat.constant(12.34567f).format();
-     * </pre>
-     */
-    @NonNull
-    default DynamicString format() {
-      return FloatFormatter.with().buildForInput(this);
-    }
-
-    /**
-     * Returns a {@link DynamicString} that contains the formatted value of this {@link
-     * DynamicFloat}. As an example, in the English locale, the following is equal to {@code
-     * DynamicString.constant("0,012.34")}
-     *
-     * <pre>
-     *   DynamicFloat.constant(12.345f)
-     *       .format(
-     *           FloatFormatter.with().maxFractionDigits(2).minIntegerDigits(4).groupingUsed(true));
-     * </pre>
-     *
-     * @param formatter The formatting parameter.
-     */
-    @NonNull
-    default DynamicString format(@NonNull FloatFormatter formatter) {
-      return formatter.buildForInput(this);
-    }
-
-    /** Allows formatting {@link DynamicFloat} into a {@link DynamicString}. */
-    class FloatFormatter {
-      private final FloatFormatOp.Builder builder;
-
-      private FloatFormatter() {
-        builder = new FloatFormatOp.Builder();
-      }
-
-      /** Creates an instance of {@link FloatFormatter} with default configuration. */
-      @NonNull
-      public static FloatFormatter with() {
-        return new FloatFormatter();
-      }
-
-      /**
-       * Sets minimum number of fraction digits for the formatter. Defaults to zero if not
-       * specified. minimumFractionDigits must be <= maximumFractionDigits. If the condition is not
-       * satisfied, then minimumFractionDigits will be used for both fields.
-       */
-      @NonNull
-      public FloatFormatter minFractionDigits(@IntRange(from = 0) int minFractionDigits) {
-        builder.setMinFractionDigits(minFractionDigits);
-        return this;
-      }
-
-      /**
-       * Sets maximum number of fraction digits for the formatter. Defaults to three if not
-       * specified. minimumFractionDigits must be <= maximumFractionDigits. If the condition is not
-       * satisfied, then minimumFractionDigits will be used for both fields.
-       */
-      @NonNull
-      public FloatFormatter maxFractionDigits(@IntRange(from = 0) int maxFractionDigits) {
-        builder.setMaxFractionDigits(maxFractionDigits);
-        return this;
-      }
-
-      /**
-       * Sets minimum number of integer digits for the formatter. Defaults to one if not specified.
-       */
-      @NonNull
-      public FloatFormatter minIntegerDigits(@IntRange(from = 0) int minIntegerDigits) {
-        builder.setMinIntegerDigits(minIntegerDigits);
-        return this;
-      }
-
-      /** Sets whether grouping is used for the formatter. Defaults to false if not specified. */
-      @NonNull
-      public FloatFormatter groupingUsed(boolean groupingUsed) {
-        builder.setGroupingUsed(groupingUsed);
-        return this;
-      }
-
-      @NonNull
-      FloatFormatOp buildForInput(@NonNull DynamicFloat dynamicFloat) {
-        return builder.setInput(dynamicFloat).build();
-      }
-    }
-
-    /**
-     * Get the fingerprint for this object or null if unknown.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    Fingerprint getFingerprint();
-
-    /**
-     * Builder to create {@link DynamicFloat} objects.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    interface Builder {
-
-      /** Builds an instance with values accumulated in this Builder. */
-      @NonNull
-      DynamicFloat build();
-    }
-  }
-
-  /**
-   * Creates a new wrapper instance from the proto. Intended for testing purposes only. An object
-   * created using this method can't be added to any other wrapper.
-   *
-   */
-  @RestrictTo(Scope.LIBRARY_GROUP)
-  @NonNull
-  public static DynamicFloat dynamicFloatFromProto(@NonNull DynamicProto.DynamicFloat proto) {
-    if (proto.hasFixed()) {
-      return FixedFloat.fromProto(proto.getFixed());
-    }
-    if (proto.hasArithmeticOperation()) {
-      return ArithmeticFloatOp.fromProto(proto.getArithmeticOperation());
-    }
-    if (proto.hasInt32ToFloatOperation()) {
-      return Int32ToFloatOp.fromProto(proto.getInt32ToFloatOperation());
-    }
-    if (proto.hasStateSource()) {
-      return StateFloatSource.fromProto(proto.getStateSource());
-    }
-    if (proto.hasConditionalOp()) {
-      return ConditionalFloatOp.fromProto(proto.getConditionalOp());
-    }
-    if (proto.hasAnimatableFixed()) {
-      return AnimatableFixedFloat.fromProto(proto.getAnimatableFixed());
-    }
-    if (proto.hasAnimatableDynamic()) {
-      return AnimatableDynamicFloat.fromProto(proto.getAnimatableDynamic());
-    }
-    throw new IllegalStateException("Proto was not a recognised instance of DynamicFloat");
-  }
-
-  /**
-   * A dynamic boolean type which sources its data from the tile's state.
-   *
-   * @since 1.2
-   */
-  static final class StateBoolSource implements DynamicBool {
-    private final DynamicProto.StateBoolSource mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    StateBoolSource(DynamicProto.StateBoolSource impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
-
-    /**
-     * Gets the key in the state to bind to.
+     * A conditional operator which yields a float depending on the boolean operand. This implements
+     * "float result = condition ? value_if_true : value_if_false".
      *
      * @since 1.2
      */
-    @NonNull
-    public String getSourceKey() {
-      return mImpl.getSourceKey();
-    }
+    static final class ConditionalFloatOp implements DynamicFloat {
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
+        private final DynamicProto.ConditionalFloatOp mImpl;
+        @Nullable private final Fingerprint mFingerprint;
 
-    @NonNull
-    static StateBoolSource fromProto(@NonNull DynamicProto.StateBoolSource proto) {
-      return new StateBoolSource(proto, null);
-    }
+        ConditionalFloatOp(
+                DynamicProto.ConditionalFloatOp impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
 
-    @NonNull
-    DynamicProto.StateBoolSource toProto() {
-      return mImpl;
-    }
+        /**
+         * Gets the condition to use.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicBool getCondition() {
+            if (mImpl.hasCondition()) {
+                return DynamicBuilders.dynamicBoolFromProto(mImpl.getCondition());
+            } else {
+                return null;
+            }
+        }
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicBool toDynamicBoolProto() {
-      return DynamicProto.DynamicBool.newBuilder().setStateSource(mImpl).build();
-    }
+        /**
+         * Gets the float to yield if condition is true.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicFloat getValueIfTrue() {
+            if (mImpl.hasValueIfTrue()) {
+                return DynamicBuilders.dynamicFloatFromProto(mImpl.getValueIfTrue());
+            } else {
+                return null;
+            }
+        }
 
-    @Override
-    @NonNull
-    public String toString() {
-      return "StateBoolSource{" + "sourceKey=" + getSourceKey() + "}";
-    }
+        /**
+         * Gets the float to yield if condition is false.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicFloat getValueIfFalse() {
+            if (mImpl.hasValueIfFalse()) {
+                return DynamicBuilders.dynamicFloatFromProto(mImpl.getValueIfFalse());
+            } else {
+                return null;
+            }
+        }
 
-    /** Builder for {@link StateBoolSource}. */
-    public static final class Builder implements DynamicBool.Builder {
+        /** */
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
 
-      private final DynamicProto.StateBoolSource.Builder mImpl =
-          DynamicProto.StateBoolSource.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(1818702779);
+        @NonNull
+        static ConditionalFloatOp fromProto(@NonNull DynamicProto.ConditionalFloatOp proto) {
+            return new ConditionalFloatOp(proto, null);
+        }
 
-      public Builder() {}
+        @NonNull
+        DynamicProto.ConditionalFloatOp toProto() {
+            return mImpl;
+        }
 
-      /**
-       * Sets the key in the state to bind to.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setSourceKey(@NonNull String sourceKey) {
-        mImpl.setSourceKey(sourceKey);
-        mFingerprint.recordPropertyUpdate(1, sourceKey.hashCode());
-        return this;
-      }
+        /** */
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicFloat toDynamicFloatProto() {
+            return DynamicProto.DynamicFloat.newBuilder().setConditionalOp(mImpl).build();
+        }
 
-      @Override
-      @NonNull
-      public StateBoolSource build() {
-        return new StateBoolSource(mImpl.build(), mFingerprint);
-      }
-    }
-  }
+        /** Builder for {@link ConditionalFloatOp}. */
+        public static final class Builder implements DynamicFloat.Builder {
 
-  /**
-   * A comparison operation, operating on two Int32 instances. This implements various comparison
-   * operations of the form "boolean result = LHS <op> RHS", where the available operation types are
-   * described in {@code ComparisonOpType}.
-   *
-   * @since 1.2
-   */
-  static final class ComparisonInt32Op implements DynamicBool {
+            private final DynamicProto.ConditionalFloatOp.Builder mImpl =
+                    DynamicProto.ConditionalFloatOp.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(1968171153);
 
-    private final DynamicProto.ComparisonInt32Op mImpl;
-    @Nullable
-    private final Fingerprint mFingerprint;
+            public Builder() {}
 
-    ComparisonInt32Op(DynamicProto.ComparisonInt32Op impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
+            /**
+             * Sets the condition to use.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setCondition(@NonNull DynamicBool condition) {
+                mImpl.setCondition(condition.toDynamicBoolProto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(condition.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the float to yield if condition is true.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setValueIfTrue(@NonNull DynamicFloat valueIfTrue) {
+                mImpl.setValueIfTrue(valueIfTrue.toDynamicFloatProto());
+                mFingerprint.recordPropertyUpdate(
+                        2, checkNotNull(valueIfTrue.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the float to yield if condition is false.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setValueIfFalse(@NonNull DynamicFloat valueIfFalse) {
+                mImpl.setValueIfFalse(valueIfFalse.toDynamicFloatProto());
+                mFingerprint.recordPropertyUpdate(
+                        3, checkNotNull(valueIfFalse.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public ConditionalFloatOp build() {
+                return new ConditionalFloatOp(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the left hand side of the comparison operation.
+     * Converts a Float to an Int32, with a customizable rounding mode.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicInt32 getInputLhs() {
-      if (mImpl.hasInputLhs()) {
-        return DynamicBuilders.dynamicInt32FromProto(mImpl.getInputLhs());
-      } else {
-        return null;
-      }
+    static final class FloatToInt32Op implements DynamicInt32 {
+        private final DynamicProto.FloatToInt32Op mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        FloatToInt32Op(DynamicProto.FloatToInt32Op impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the float to round.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicFloat getInput() {
+            if (mImpl.hasInput()) {
+                return DynamicBuilders.dynamicFloatFromProto(mImpl.getInput());
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets the rounding mode to use. Defaults to ROUND_MODE_FLOOR if not specified.
+         *
+         * @since 1.2
+         */
+        @FloatToInt32RoundMode
+        public int getRoundMode() {
+            return mImpl.getRoundMode().getNumber();
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static FloatToInt32Op fromProto(@NonNull DynamicProto.FloatToInt32Op proto) {
+            return new FloatToInt32Op(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.FloatToInt32Op toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
+            return DynamicProto.DynamicInt32.newBuilder().setFloatToInt(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "FloatToInt32Op{"
+                    + "input="
+                    + getInput()
+                    + ", roundMode="
+                    + getRoundMode()
+                    + "}";
+        }
+
+        /** Builder for {@link FloatToInt32Op}. */
+        public static final class Builder implements DynamicInt32.Builder {
+            private final DynamicProto.FloatToInt32Op.Builder mImpl =
+                    DynamicProto.FloatToInt32Op.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(-1272973414);
+
+            public Builder() {}
+
+            /**
+             * Sets the float to round.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInput(@NonNull DynamicFloat input) {
+                mImpl.setInput(input.toDynamicFloatProto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the rounding mode to use. Defaults to ROUND_MODE_FLOOR if not specified.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setRoundMode(@FloatToInt32RoundMode int roundMode) {
+                mImpl.setRoundMode(DynamicProto.FloatToInt32RoundMode.forNumber(roundMode));
+                mFingerprint.recordPropertyUpdate(2, roundMode);
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public FloatToInt32Op build() {
+                return new FloatToInt32Op(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the right hand side of the comparison operation.
+     * A static interpolation node, between two fixed int32 values.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicInt32 getInputRhs() {
-      if (mImpl.hasInputRhs()) {
-        return DynamicBuilders.dynamicInt32FromProto(mImpl.getInputRhs());
-      } else {
-        return null;
-      }
+    static final class AnimatableFixedInt32 implements DynamicInt32 {
+        private final DynamicProto.AnimatableFixedInt32 mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        AnimatableFixedInt32(
+                DynamicProto.AnimatableFixedInt32 impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the value to start animating from.
+         *
+         * @since 1.2
+         */
+        public int getFromValue() {
+            return mImpl.getFromValue();
+        }
+
+        /**
+         * Gets the value to animate to.
+         *
+         * @since 1.2
+         */
+        public int getToValue() {
+            return mImpl.getToValue();
+        }
+
+        /**
+         * Gets the animation parameters for duration, delay, etc.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public AnimationSpec getAnimationSpec() {
+            if (mImpl.hasAnimationSpec()) {
+                return AnimationSpec.fromProto(mImpl.getAnimationSpec());
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+        /** Creates a new wrapper instance from the proto. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public static AnimatableFixedInt32 fromProto(
+                @NonNull DynamicProto.AnimatableFixedInt32 proto,
+                @Nullable Fingerprint fingerprint) {
+            return new AnimatableFixedInt32(proto, fingerprint);
+        }
+
+        @NonNull
+        static AnimatableFixedInt32 fromProto(@NonNull DynamicProto.AnimatableFixedInt32 proto) {
+            return fromProto(proto, null);
+        }
+
+        /** Returns the internal proto instance. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        DynamicProto.AnimatableFixedInt32 toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
+            return DynamicProto.DynamicInt32.newBuilder().setAnimatableFixed(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "AnimatableFixedInt32{"
+                    + "fromValue="
+                    + getFromValue()
+                    + ", toValue="
+                    + getToValue()
+                    + ", animationSpec="
+                    + getAnimationSpec()
+                    + "}";
+        }
+
+        /** Builder for {@link AnimatableFixedInt32}. */
+        public static final class Builder implements DynamicInt32.Builder {
+            private final DynamicProto.AnimatableFixedInt32.Builder mImpl =
+                    DynamicProto.AnimatableFixedInt32.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(-1831435966);
+
+            public Builder() {}
+
+            /**
+             * Sets the value to start animating from.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public AnimatableFixedInt32.Builder setFromValue(int fromValue) {
+                mImpl.setFromValue(fromValue);
+                mFingerprint.recordPropertyUpdate(1, fromValue);
+                return this;
+            }
+
+            /**
+             * Sets the value to animate to.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public AnimatableFixedInt32.Builder setToValue(int toValue) {
+                mImpl.setToValue(toValue);
+                mFingerprint.recordPropertyUpdate(2, toValue);
+                return this;
+            }
+
+            /**
+             * Sets the animation parameters for duration, delay, etc.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
+                mImpl.setAnimationSpec(animationSpec.toProto());
+                mFingerprint.recordPropertyUpdate(
+                        3, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public AnimatableFixedInt32 build() {
+                return new AnimatableFixedInt32(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the type of the operation.
+     * A dynamic interpolation node. This will watch the value of its input and, when the first
+     * update arrives, immediately emit that value. On subsequent updates, it will animate between
+     * the old and new values.
+     *
+     * <p>If this node receives an invalid value (e.g. as a result of an upstream node having no
+     * value), then it will emit a single invalid value, and forget its "stored" value. The next
+     * valid value that arrives is then used as the "first" value again.
      *
      * @since 1.2
      */
-    @ComparisonOpType
-    public int getOperationType() {
-      return mImpl.getOperationType().getNumber();
+    static final class AnimatableDynamicInt32 implements DynamicInt32 {
+        private final DynamicProto.AnimatableDynamicInt32 mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        AnimatableDynamicInt32(
+                DynamicProto.AnimatableDynamicInt32 impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the value to watch, and animate when it changes.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicInt32 getInput() {
+            if (mImpl.hasInput()) {
+                return dynamicInt32FromProto(mImpl.getInput());
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets the animation parameters for duration, delay, etc.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public AnimationSpec getAnimationSpec() {
+            if (mImpl.hasAnimationSpec()) {
+                return AnimationSpec.fromProto(mImpl.getAnimationSpec());
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+        /** Creates a new wrapper instance from the proto. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public static AnimatableDynamicInt32 fromProto(
+                @NonNull DynamicProto.AnimatableDynamicInt32 proto,
+                @Nullable Fingerprint fingerprint) {
+            return new AnimatableDynamicInt32(proto, fingerprint);
+        }
+
+        @NonNull
+        static AnimatableDynamicInt32 fromProto(
+                @NonNull DynamicProto.AnimatableDynamicInt32 proto) {
+            return fromProto(proto, null);
+        }
+
+        /** Returns the internal proto instance. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        DynamicProto.AnimatableDynamicInt32 toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
+            return DynamicProto.DynamicInt32.newBuilder().setAnimatableDynamic(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "AnimatableDynamicInt32{"
+                    + "input="
+                    + getInput()
+                    + ", animationSpec="
+                    + getAnimationSpec()
+                    + "}";
+        }
+
+        /** Builder for {@link AnimatableDynamicInt32}. */
+        public static final class Builder implements DynamicInt32.Builder {
+            private final DynamicProto.AnimatableDynamicInt32.Builder mImpl =
+                    DynamicProto.AnimatableDynamicInt32.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(-1554674954);
+
+            public Builder() {}
+
+            /**
+             * Sets the value to watch, and animate when it changes.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public AnimatableDynamicInt32.Builder setInput(@NonNull DynamicInt32 input) {
+                mImpl.setInput(input.toDynamicInt32Proto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the animation parameters for duration, delay, etc.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
+                mImpl.setAnimationSpec(animationSpec.toProto());
+                mFingerprint.recordPropertyUpdate(
+                        2, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public AnimatableDynamicInt32 build() {
+                return new AnimatableDynamicInt32(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     */
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static ComparisonInt32Op fromProto(@NonNull DynamicProto.ComparisonInt32Op proto) {
-      return new ComparisonInt32Op(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.ComparisonInt32Op toProto() {
-      return mImpl;
-    }
-
-    /**
-     */
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicBool toDynamicBoolProto() {
-      return DynamicProto.DynamicBool.newBuilder().setInt32Comparison(mImpl).build();
-    }
-
-    /**
-     * Builder for {@link ComparisonInt32Op}.
-     */
-    public static final class Builder implements DynamicBool.Builder {
-
-      private final DynamicProto.ComparisonInt32Op.Builder mImpl =
-          DynamicProto.ComparisonInt32Op.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-1112207999);
-
-      public Builder() {
-      }
-
-      /**
-       * Sets the left hand side of the comparison operation.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInputLhs(@NonNull DynamicInt32 inputLhs) {
-        mImpl.setInputLhs(inputLhs.toDynamicInt32Proto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(inputLhs.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the right hand side of the comparison operation.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInputRhs(@NonNull DynamicInt32 inputRhs) {
-        mImpl.setInputRhs(inputRhs.toDynamicInt32Proto());
-        mFingerprint.recordPropertyUpdate(
-            2, checkNotNull(inputRhs.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the type of the operation.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setOperationType(@ComparisonOpType int operationType) {
-        mImpl.setOperationType(DynamicProto.ComparisonOpType.forNumber(operationType));
-        mFingerprint.recordPropertyUpdate(3, operationType);
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public ComparisonInt32Op build() {
-        return new ComparisonInt32Op(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * A comparison operation, operating on two Float instances. This implements various comparison
-   * operations of the form "boolean result = LHS <op> RHS", where the available operation types are
-   * described in {@code ComparisonOpType}.
-   *
-   * @since 1.2
-   */
-  static final class ComparisonFloatOp implements DynamicBool {
-
-    private final DynamicProto.ComparisonFloatOp mImpl;
-    @Nullable
-    private final Fingerprint mFingerprint;
-
-    ComparisonFloatOp(DynamicProto.ComparisonFloatOp impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
-
-    /**
-     * Gets the left hand side of the comparison operation.
+     * Interface defining a dynamic int32 type.
+     *
+     * <p>It offers a set of helper methods for creating arithmetic and logical expressions, e.g.
+     * {@link #plus(int)}, {@link #times(int)}, {@link #eq(int)}, etc. These helper methods produce
+     * expression trees based on the order in which they were called in an expression. Thus, no
+     * operator precedence rules are applied.
+     *
+     * <p>For example the following expression is equivalent to {@code result = ((a + b)*c)/d }:
+     *
+     * <pre>{@code
+     * a.plus(b).times(c).div(d);
+     * }</pre>
+     *
+     * More complex expressions can be created by nesting expressions. For example the following
+     * expression is equivalent to {@code result = (a + b)*(c - d) }:
+     *
+     * <pre>{@code
+     * (a.plus(b)).times(c.minus(d));
+     * }</pre>
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicFloat getInputLhs() {
-      if (mImpl.hasInputLhs()) {
-        return DynamicBuilders.dynamicFloatFromProto(mImpl.getInputLhs());
-      } else {
-        return null;
-      }
+    public interface DynamicInt32 extends DynamicType {
+        /** Get the protocol buffer representation of this object. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        DynamicProto.DynamicInt32 toDynamicInt32Proto();
+
+        /**
+         * Creates a {@link DynamicInt32} from a byte array generated by {@link
+         * #toDynamicInt32ByteArray()}.
+         */
+        @NonNull
+        static DynamicInt32 fromByteArray(@NonNull byte[] byteArray) {
+            try {
+                return dynamicInt32FromProto(
+                        DynamicProto.DynamicInt32.parseFrom(
+                                byteArray, ExtensionRegistryLite.getEmptyRegistry()));
+            } catch (InvalidProtocolBufferException e) {
+                throw new IllegalArgumentException(
+                        "Byte array could not be parsed into DynamicInt32", e);
+            }
+        }
+
+        /** Creates a byte array that can later be used with {@link #fromByteArray(byte[])}. */
+        @NonNull
+        default byte[] toDynamicInt32ByteArray() {
+            return toDynamicInt32Proto().toByteArray();
+        }
+
+        /** Creates a constant-valued {@link DynamicInt32}. */
+        @NonNull
+        static DynamicInt32 constant(int constant) {
+            return new FixedInt32.Builder().setValue(constant).build();
+        }
+
+        /**
+         * Creates a {@link DynamicInt32} that is bound to the value of an item of the State.
+         *
+         * @param stateKey The key to a {@link StateEntryValue} with an int value from the
+         *     provider's state.
+         */
+        @NonNull
+        static DynamicInt32 fromState(@NonNull String stateKey) {
+            return new StateInt32Source.Builder().setSourceKey(stateKey).build();
+        }
+
+        /**
+         * Creates a {@link DynamicInt32} which will animate from {@code start} to {@code end}.
+         *
+         * @param start The start value of the range.
+         * @param end The end value of the range.
+         */
+        @NonNull
+        static DynamicInt32 animate(int start, int end) {
+            return new AnimatableFixedInt32.Builder().setFromValue(start).setToValue(end).build();
+        }
+
+        /**
+         * Creates a {@link DynamicInt32} which will animate from {@code start} to {@code end} with
+         * the given animation parameters.
+         *
+         * @param start The start value of the range.
+         * @param end The end value of the range.
+         * @param animationSpec The animation parameters.
+         */
+        @NonNull
+        static DynamicInt32 animate(int start, int end, @NonNull AnimationSpec animationSpec) {
+            return new AnimatableFixedInt32.Builder()
+                    .setFromValue(start)
+                    .setToValue(end)
+                    .setAnimationSpec(animationSpec)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicInt32} that is bound to the value of an item of the State. Every
+         * time the state value changes, this {@link DynamicInt32} will animate from its current
+         * value to the new value (from the state).
+         *
+         * @param stateKey The key to a {@link StateEntryValue} with an int value from the
+         *     provider's state.
+         */
+        @NonNull
+        static DynamicInt32 animate(@NonNull String stateKey) {
+            return new AnimatableDynamicInt32.Builder().setInput(fromState(stateKey)).build();
+        }
+
+        /**
+         * Creates a {@link DynamicInt32} that is bound to the value of an item of the State. Every
+         * time the state value changes, this {@link DynamicInt32} will animate from its current
+         * value to the new value (from the state).
+         *
+         * @param stateKey The key to a {@link StateEntryValue} with an int value from the
+         *     provider's state.
+         * @param animationSpec The animation parameters.
+         */
+        @NonNull
+        static DynamicInt32 animate(
+                @NonNull String stateKey, @NonNull AnimationSpec animationSpec) {
+            return new AnimatableDynamicInt32.Builder()
+                    .setInput(fromState(stateKey))
+                    .setAnimationSpec(animationSpec)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicInt32} that is bound to the value of this {@link DynamicInt32}
+         * and every time its value is changing, it animates from its current value to the new
+         * value.
+         *
+         * @param animationSpec The animation parameters.
+         */
+        @NonNull
+        default DynamicInt32 animate(@NonNull AnimationSpec animationSpec) {
+            return new AnimatableDynamicInt32.Builder()
+                    .setInput(this)
+                    .setAnimationSpec(animationSpec)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicInt32} that is bound to the value of this {@link DynamicInt32}
+         * and every time its value is changing, it animates from its current value to the new
+         * value.
+         */
+        @NonNull
+        default DynamicInt32 animate() {
+            return new AnimatableDynamicInt32.Builder().setInput(this).build();
+        }
+
+        /**
+         * Convert the value represented by this {@link DynamicInt32} into a {@link DynamicFloat}.
+         */
+        @NonNull
+        default DynamicFloat asFloat() {
+            return new Int32ToFloatOp.Builder().setInput(this).build();
+        }
+
+        /**
+         * Bind the value of this {@link DynamicInt32} to the result of a conditional expression.
+         * This will use the value given in either {@link ConditionScope#use} or {@link
+         * ConditionScopes.IfTrueScope#elseUse} depending on the value yielded from {@code
+         * condition}.
+         */
+        @NonNull
+        static ConditionScope<DynamicInt32, Integer> onCondition(@NonNull DynamicBool condition) {
+            return new ConditionScopes.ConditionScope<>(
+                    (trueValue, falseValue) ->
+                            new ConditionalInt32Op.Builder()
+                                    .setCondition(condition)
+                                    .setValueIfTrue(trueValue)
+                                    .setValueIfFalse(falseValue)
+                                    .build(),
+                    DynamicInt32::constant);
+        }
+
+        /**
+         * Creates a {@link DynamicInt32} containing the result of adding another {@link
+         * DynamicInt32} to this {@link DynamicInt32}; As an example, the following is equal to
+         * {@code DynamicInt32.constant(13)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).plus(DynamicInt32.constant(6));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicInt32} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicInt32 plus(@NonNull DynamicInt32 other) {
+            return new ArithmeticInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_ADD)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFlaot} containing the result of adding a {@link DynamicFloat} to
+         * this {@link DynamicInt32}; As an example, the following is equal to {@code
+         * DynamicFloat.constant(13.5f)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).plus(DynamicFloat.constant(6.5f));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat plus(@NonNull DynamicFloat other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this.asFloat())
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_ADD)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicInt32} containing the result of adding an integer to this {@link
+         * DynamicInt32}; As an example, the following is equal to {@code DynamicInt32.constant(13)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).plus(6);
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicInt32} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicInt32 plus(int other) {
+            return new ArithmeticInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_ADD)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFlaot} containing the result of adding a float to this {@link
+         * DynamicInt32}; As an example, the following is equal to {@code
+         * DynamicFloat.constant(13.5f)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).plus(6.5f);
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat plus(float other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this.asFloat())
+                    .setInputRhs(DynamicFloat.constant(other))
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_ADD)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicInt32} containing the result of subtracting another {@link
+         * DynamicInt32} from this {@link DynamicInt32}; As an example, the following is equal to
+         * {@code DynamicInt32.constant(2)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).minus(DynamicInt32.constant(5));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicInt32} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicInt32 minus(@NonNull DynamicInt32 other) {
+            return new ArithmeticInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_SUBTRACT)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of subtracting a {@link
+         * DynamicFloat} from this {@link DynamicInt32}; As an example, the following is equal to
+         * {@code DynamicFloat.constant(1.5f)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).minus(DynamicFloat.constant(5.5f));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat minus(@NonNull DynamicFloat other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this.asFloat())
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_SUBTRACT)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicInt32} containing the result of subtracting an integer from this
+         * {@link DynamicInt32}; As an example, the following is equal to {@code
+         * DynamicInt32.constant(2)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).minus(5);
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicInt32} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicInt32 minus(int other) {
+            return new ArithmeticInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_SUBTRACT)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of subtracting a float from this
+         * {@link DynamicInt32}; As an example, the following is equal to {@code
+         * DynamicFloat.constant(1.5f)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).minus(5.5f);
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat minus(float other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this.asFloat())
+                    .setInputRhs(DynamicFloat.constant(other))
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_SUBTRACT)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicInt32} containing the result of multiplying this {@link
+         * DynamicInt32} by another {@link DynamicInt32}; As an example, the following is equal to
+         * {@code DynamicInt32.constant(35)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).times(DynamicInt32.constant(5));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicInt32} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicInt32 times(@NonNull DynamicInt32 other) {
+            return new ArithmeticInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MULTIPLY)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of multiplying this {@link
+         * DynamicInt32} by a {@link DynamicFloat}; As an example, the following is equal to {@code
+         * DynamicFloat.constant(38.5f)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).times(DynamicFloat.constant(5.5f));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat times(@NonNull DynamicFloat other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this.asFloat())
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MULTIPLY)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicInt32} containing the result of multiplying this {@link
+         * DynamicInt32} by an integer; As an example, the following is equal to {@code
+         * DynamicInt32.constant(35)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).times(5);
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicInt32} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicInt32 times(int other) {
+            return new ArithmeticInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MULTIPLY)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of multiplying this {@link
+         * DynamicInt32} by a float; As an example, the following is equal to {@code
+         * DynamicFloat.constant(38.5f)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).times(5.5f);
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat times(float other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this.asFloat())
+                    .setInputRhs(DynamicFloat.constant(other))
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MULTIPLY)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicInt32} containing the result of dividing this {@link
+         * DynamicInt32} by another {@link DynamicInt32}; As an example, the following is equal to
+         * {@code DynamicInt32.constant(1)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).div(DynamicInt32.constant(5));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicInt32} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicInt32 div(@NonNull DynamicInt32 other) {
+            return new ArithmeticInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_DIVIDE)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of dividing this {@link
+         * DynamicInt32} by a {@link DynamicFloat}; As an example, the following is equal to {@code
+         * DynamicFloat.constant(1.4f)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).div(DynamicFloat.constant(5f));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat div(@NonNull DynamicFloat other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this.asFloat())
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_DIVIDE)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicInt32} containing the result of dividing this {@link
+         * DynamicInt32} by an integer; As an example, the following is equal to {@code
+         * DynamicInt32.constant(1)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).div(5);
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicInt32} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicInt32 div(int other) {
+            return new ArithmeticInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_DIVIDE)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of dividing this {@link
+         * DynamicInt32} by a float; As an example, the following is equal to {@code
+         * DynamicFloat.constant(1.4f)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).div(5f);
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat div(float other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this.asFloat())
+                    .setInputRhs(DynamicFloat.constant(other))
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_DIVIDE)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicInt32} containing the reminder of dividing this {@link
+         * DynamicInt32} by another {@link DynamicInt32}; As an example, the following is equal to
+         * {@code DynamicInt32.constant(2)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).rem(DynamicInt32.constant(5));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicInt32} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicInt32 rem(@NonNull DynamicInt32 other) {
+            return new ArithmeticInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MODULO)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the reminder of dividing this {@link
+         * DynamicInt32} by a {@link DynamicFloat}; As an example, the following is equal to {@code
+         * DynamicFloat.constant(1.5f)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).rem(DynamicInt32.constant(5.5f));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat rem(@NonNull DynamicFloat other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this.asFloat())
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MODULO)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicInt32} containing the reminder of dividing this {@link
+         * DynamicInt32} by an integer; As an example, the following is equal to {@code
+         * DynamicInt32.constant(2)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).rem(5);
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicInt32} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicInt32 rem(int other) {
+            return new ArithmeticInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MODULO)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicInt32} containing the reminder of dividing this {@link
+         * DynamicInt32} by a float; As an example, the following is equal to {@code
+         * DynamicFloat.constant(1.5f)}
+         *
+         * <pre>
+         *   DynamicInt32.constant(7).rem(5.5f);
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat rem(float other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this.asFloat())
+                    .setInputRhs(DynamicFloat.constant(other))
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MODULO)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} and
+         * {@code other} are equal, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool eq(@NonNull DynamicInt32 other) {
+            return new ComparisonInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_EQUALS)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} and
+         * {@code other} are equal, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool eq(int other) {
+            return new ComparisonInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_EQUALS)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} and
+         * {@code other} are not equal, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool ne(@NonNull DynamicInt32 other) {
+            return new ComparisonInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_NOT_EQUALS)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} and
+         * {@code other} are not equal, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool ne(int other) {
+            return new ComparisonInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_NOT_EQUALS)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
+         * less than {@code other}, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool lt(@NonNull DynamicInt32 other) {
+            return new ComparisonInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_LESS_THAN)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
+         * less than {@code other}, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool lt(int other) {
+            return new ComparisonInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_LESS_THAN)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
+         * less than or equal to {@code other}, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool lte(@NonNull DynamicInt32 other) {
+            return new ComparisonInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_LESS_THAN_OR_EQUAL_TO)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
+         * less than or equal to {@code other}, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool lte(int other) {
+            return new ComparisonInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_LESS_THAN_OR_EQUAL_TO)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
+         * greater than {@code other}, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool gt(@NonNull DynamicInt32 other) {
+            return new ComparisonInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_GREATER_THAN)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
+         * greater than {@code other}, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool gt(int other) {
+            return new ComparisonInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_GREATER_THAN)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
+         * greater than or equal to {@code other}, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool gte(@NonNull DynamicInt32 other) {
+            return new ComparisonInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_GREATER_THAN_OR_EQUAL_TO)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
+         * greater than or equal to {@code other}, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool gte(int other) {
+            return new ComparisonInt32Op.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_GREATER_THAN_OR_EQUAL_TO)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicString} that contains the formatted value of this {@link
+         * DynamicInt32} (with default formatting parameters). As an example, in the English locale,
+         * the following is equal to {@code DynamicString.constant("12")}
+         *
+         * <pre>
+         *   DynamicInt32.constant(12).format()
+         * </pre>
+         */
+        @NonNull
+        default DynamicString format() {
+            return IntFormatter.with().buildForInput(this);
+        }
+
+        /**
+         * Returns a {@link DynamicString} that contains the formatted value of this {@link
+         * DynamicInt32}. As an example, in the English locale, the following is equal to {@code
+         * DynamicString.constant("0,012")}
+         *
+         * <pre>
+         *   DynamicInt32.constant(12)
+         *            .format(
+         *                IntFormatter.with().minIntegerDigits(4).groupingUsed(true));
+         * </pre>
+         *
+         * @param formatter The formatting parameter.
+         */
+        @NonNull
+        default DynamicString format(@NonNull IntFormatter formatter) {
+            return formatter.buildForInput(this);
+        }
+
+        /** Allows formatting {@link DynamicInt32} into a {@link DynamicString}. */
+        class IntFormatter {
+            private final Int32FormatOp.Builder builder;
+
+            private IntFormatter() {
+                builder = new Int32FormatOp.Builder();
+            }
+
+            /** Creates an instance of {@link IntFormatter} with default configuration. */
+            @NonNull
+            public static IntFormatter with() {
+                return new IntFormatter();
+            }
+
+            /**
+             * Sets minimum number of integer digits for the formatter. Defaults to one if not
+             * specified.
+             */
+            @NonNull
+            public IntFormatter minIntegerDigits(@IntRange(from = 0) int minIntegerDigits) {
+                builder.setMinIntegerDigits(minIntegerDigits);
+                return this;
+            }
+
+            /**
+             * Sets whether grouping is used for the formatter. Defaults to false if not specified.
+             */
+            @NonNull
+            public IntFormatter groupingUsed(boolean groupingUsed) {
+                builder.setGroupingUsed(groupingUsed);
+                return this;
+            }
+
+            @NonNull
+            Int32FormatOp buildForInput(@NonNull DynamicInt32 dynamicInt32) {
+                return builder.setInput(dynamicInt32).build();
+            }
+        }
+
+        /** Get the fingerprint for this object or null if unknown. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        Fingerprint getFingerprint();
+
+        /** Builder to create {@link DynamicInt32} objects. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        interface Builder {
+
+            /** Builds an instance with values accumulated in this Builder. */
+            @NonNull
+            DynamicInt32 build();
+        }
     }
 
     /**
-     * Gets the right hand side of the comparison operation.
+     * Creates a new wrapper instance from the proto. Intended for testing purposes only. An object
+     * created using this method can't be added to any other wrapper.
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @NonNull
+    public static DynamicInt32 dynamicInt32FromProto(@NonNull DynamicProto.DynamicInt32 proto) {
+        if (proto.hasFixed()) {
+            return FixedInt32.fromProto(proto.getFixed());
+        }
+        if (proto.hasPlatformSource()) {
+            return PlatformInt32Source.fromProto(proto.getPlatformSource());
+        }
+        if (proto.hasArithmeticOperation()) {
+            return ArithmeticInt32Op.fromProto(proto.getArithmeticOperation());
+        }
+        if (proto.hasStateSource()) {
+            return StateInt32Source.fromProto(proto.getStateSource());
+        }
+        if (proto.hasConditionalOp()) {
+            return ConditionalInt32Op.fromProto(proto.getConditionalOp());
+        }
+        if (proto.hasFloatToInt()) {
+            return FloatToInt32Op.fromProto(proto.getFloatToInt());
+        }
+        if (proto.hasDurationPart()) {
+            return GetDurationPartOp.fromProto(proto.getDurationPart());
+        }
+        if (proto.hasAnimatableFixed()) {
+            return AnimatableFixedInt32.fromProto(proto.getAnimatableFixed());
+        }
+        if (proto.hasAnimatableDynamic()) {
+            return AnimatableDynamicInt32.fromProto(proto.getAnimatableDynamic());
+        }
+        throw new IllegalStateException("Proto was not a recognised instance of DynamicInt32");
+    }
+
+    /**
+     * Simple formatting for dynamic int32.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicFloat getInputRhs() {
-      if (mImpl.hasInputRhs()) {
-        return DynamicBuilders.dynamicFloatFromProto(mImpl.getInputRhs());
-      } else {
-        return null;
-      }
+    static final class Int32FormatOp implements DynamicString {
+        private final DynamicProto.Int32FormatOp mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        Int32FormatOp(DynamicProto.Int32FormatOp impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the source of Int32 data to convert to a string.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicInt32 getInput() {
+            if (mImpl.hasInput()) {
+                return DynamicBuilders.dynamicInt32FromProto(mImpl.getInput());
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets minimum integer digits. Sign and grouping characters are not considered when
+         * applying minIntegerDigits constraint. If not defined, defaults to one. For example,in the
+         * English locale, applying minIntegerDigit=4 to 12 would yield "0012".
+         *
+         * @since 1.2
+         */
+        @IntRange(from = 0)
+        public int getMinIntegerDigits() {
+            return mImpl.getMinIntegerDigits();
+        }
+
+        /**
+         * Gets digit grouping used. Grouping size and grouping character depend on the current
+         * locale. If not defined, defaults to false. For example, in the English locale, using
+         * grouping with 1234 would yield "1,234".
+         *
+         * @since 1.2
+         */
+        public boolean getGroupingUsed() {
+            return mImpl.getGroupingUsed();
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static Int32FormatOp fromProto(@NonNull DynamicProto.Int32FormatOp proto) {
+            return new Int32FormatOp(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.Int32FormatOp toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicString toDynamicStringProto() {
+            return DynamicProto.DynamicString.newBuilder().setInt32FormatOp(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "Int32FormatOp{"
+                    + "input="
+                    + getInput()
+                    + ", minIntegerDigits="
+                    + getMinIntegerDigits()
+                    + ", groupingUsed="
+                    + getGroupingUsed()
+                    + "}";
+        }
+
+        /** Builder for {@link Int32FormatOp}. */
+        public static final class Builder implements DynamicString.Builder {
+            private final DynamicProto.Int32FormatOp.Builder mImpl =
+                    DynamicProto.Int32FormatOp.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(196209833);
+
+            public Builder() {}
+
+            /**
+             * Sets the source of Int32 data to convert to a string.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInput(@NonNull DynamicInt32 input) {
+                mImpl.setInput(input.toDynamicInt32Proto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets minimum integer digits. Sign and grouping characters are not considered when
+             * applying minIntegerDigits constraint. If not defined, defaults to one. For example,in
+             * the English locale, applying minIntegerDigit=4 to 12 would yield "0012".
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setMinIntegerDigits(@IntRange(from = 0) int minIntegerDigits) {
+                mImpl.setMinIntegerDigits(minIntegerDigits);
+                mFingerprint.recordPropertyUpdate(4, minIntegerDigits);
+                return this;
+            }
+
+            /**
+             * Sets digit grouping used. Grouping size and grouping character depend on the current
+             * locale. If not defined, defaults to false. For example, in the English locale, using
+             * grouping with 1234 would yield "1,234".
+             *
+             * @since 1.2
+             */
+            @SuppressLint("MissingGetterMatchingBuilder")
+            @NonNull
+            public Builder setGroupingUsed(boolean groupingUsed) {
+                mImpl.setGroupingUsed(groupingUsed);
+                mFingerprint.recordPropertyUpdate(5, Boolean.hashCode(groupingUsed));
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public Int32FormatOp build() {
+                return new Int32FormatOp(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the type of the operation.
+     * A dynamic String which sources its data from the tile's state.
      *
      * @since 1.2
      */
-    @ComparisonOpType
-    public int getOperationType() {
-      return mImpl.getOperationType().getNumber();
+    static final class StateStringSource implements DynamicString {
+        private final DynamicProto.StateStringSource mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        StateStringSource(DynamicProto.StateStringSource impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the key in the state to bind to.
+         *
+         * @since 1.2
+         */
+        @NonNull
+        public String getSourceKey() {
+            return mImpl.getSourceKey();
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static StateStringSource fromProto(@NonNull DynamicProto.StateStringSource proto) {
+            return new StateStringSource(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.StateStringSource toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicString toDynamicStringProto() {
+            return DynamicProto.DynamicString.newBuilder().setStateSource(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "StateStringSource{" + "sourceKey=" + getSourceKey() + "}";
+        }
+
+        /** Builder for {@link StateStringSource}. */
+        public static final class Builder implements DynamicString.Builder {
+            private final DynamicProto.StateStringSource.Builder mImpl =
+                    DynamicProto.StateStringSource.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(1261652090);
+
+            public Builder() {}
+
+            /**
+             * Sets the key in the state to bind to.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setSourceKey(@NonNull String sourceKey) {
+                mImpl.setSourceKey(sourceKey);
+                mFingerprint.recordPropertyUpdate(1, sourceKey.hashCode());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public StateStringSource build() {
+                return new StateStringSource(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     */
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static ComparisonFloatOp fromProto(@NonNull DynamicProto.ComparisonFloatOp proto) {
-      return new ComparisonFloatOp(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.ComparisonFloatOp toProto() {
-      return mImpl;
-    }
-
-    /**
-     */
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicBool toDynamicBoolProto() {
-      return DynamicProto.DynamicBool.newBuilder().setFloatComparison(mImpl).build();
-    }
-
-    /**
-     * Builder for {@link ComparisonFloatOp}.
-     */
-    public static final class Builder implements DynamicBool.Builder {
-
-      private final DynamicProto.ComparisonFloatOp.Builder mImpl =
-          DynamicProto.ComparisonFloatOp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-1679565270);
-
-      public Builder() {
-      }
-
-      /**
-       * Sets the left hand side of the comparison operation.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInputLhs(@NonNull DynamicFloat inputLhs) {
-        mImpl.setInputLhs(inputLhs.toDynamicFloatProto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(inputLhs.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the right hand side of the comparison operation.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInputRhs(@NonNull DynamicFloat inputRhs) {
-        mImpl.setInputRhs(inputRhs.toDynamicFloatProto());
-        mFingerprint.recordPropertyUpdate(
-            2, checkNotNull(inputRhs.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the type of the operation.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setOperationType(@ComparisonOpType int operationType) {
-        mImpl.setOperationType(DynamicProto.ComparisonOpType.forNumber(operationType));
-        mFingerprint.recordPropertyUpdate(3, operationType);
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public ComparisonFloatOp build() {
-        return new ComparisonFloatOp(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * A boolean operation which implements a "NOT" operator, i.e. "boolean result = !input".
-   *
-   * @since 1.2
-   */
-  static final class NotBoolOp implements DynamicBool {
-    private final DynamicProto.NotBoolOp mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    NotBoolOp(DynamicProto.NotBoolOp impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
-
-    /**
-     * Gets the input, whose value to negate.
+     * A conditional operator which yields an string depending on the boolean operand. This
+     * implements "string result = condition ? value_if_true : value_if_false".
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicBool getInput() {
-      if (mImpl.hasInput()) {
-        return DynamicBuilders.dynamicBoolFromProto(mImpl.getInput());
-      } else {
-        return null;
-      }
-    }
+    static final class ConditionalStringOp implements DynamicString {
+        private final DynamicProto.ConditionalStringOp mImpl;
+        @Nullable private final Fingerprint mFingerprint;
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
+        ConditionalStringOp(
+                DynamicProto.ConditionalStringOp impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
 
-    @NonNull
-    static NotBoolOp fromProto(@NonNull DynamicProto.NotBoolOp proto) {
-      return new NotBoolOp(proto, null);
-    }
+        /**
+         * Gets the condition to use.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicBool getCondition() {
+            if (mImpl.hasCondition()) {
+                return DynamicBuilders.dynamicBoolFromProto(mImpl.getCondition());
+            } else {
+                return null;
+            }
+        }
 
-    @NonNull
-    DynamicProto.NotBoolOp toProto() {
-      return mImpl;
-    }
+        /**
+         * Gets the string to yield if condition is true.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicString getValueIfTrue() {
+            if (mImpl.hasValueIfTrue()) {
+                return DynamicBuilders.dynamicStringFromProto(mImpl.getValueIfTrue());
+            } else {
+                return null;
+            }
+        }
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicBool toDynamicBoolProto() {
-      return DynamicProto.DynamicBool.newBuilder().setNotOp(mImpl).build();
-    }
+        /**
+         * Gets the string to yield if condition is false.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicString getValueIfFalse() {
+            if (mImpl.hasValueIfFalse()) {
+                return DynamicBuilders.dynamicStringFromProto(mImpl.getValueIfFalse());
+            } else {
+                return null;
+            }
+        }
 
-    @Override
-    @NonNull
-    public String toString() {
-      return "NotBoolOp{" + "input=" + getInput() + "}";
-    }
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
 
-    /** Builder for {@link NotBoolOp}. */
-    public static final class Builder implements DynamicBool.Builder {
-      private final DynamicProto.NotBoolOp.Builder mImpl = DynamicProto.NotBoolOp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(91300638);
+        @NonNull
+        static ConditionalStringOp fromProto(@NonNull DynamicProto.ConditionalStringOp proto) {
+            return new ConditionalStringOp(proto, null);
+        }
 
-      public Builder() {}
+        @NonNull
+        DynamicProto.ConditionalStringOp toProto() {
+            return mImpl;
+        }
 
-      /**
-       * Sets the input, whose value to negate.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInput(@NonNull DynamicBool input) {
-        mImpl.setInput(input.toDynamicBoolProto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicString toDynamicStringProto() {
+            return DynamicProto.DynamicString.newBuilder().setConditionalOp(mImpl).build();
+        }
 
-      @Override
-      @NonNull
-      public NotBoolOp build() {
-        return new NotBoolOp(mImpl.build(), mFingerprint);
-      }
-    }
-  }
+        @Override
+        @NonNull
+        public String toString() {
+            return "ConditionalStringOp{"
+                    + "condition="
+                    + getCondition()
+                    + ", valueIfTrue="
+                    + getValueIfTrue()
+                    + ", valueIfFalse="
+                    + getValueIfFalse()
+                    + "}";
+        }
 
-  /**
-   * A logical boolean operator, implementing "boolean result = LHS <op> RHS", for various boolean
-   * operators (i.e. AND/OR).
-   *
-   * @since 1.2
-   */
-  static final class LogicalBoolOp implements DynamicBool {
-    private final DynamicProto.LogicalBoolOp mImpl;
-    @Nullable private final Fingerprint mFingerprint;
+        /** Builder for {@link ConditionalStringOp}. */
+        public static final class Builder implements DynamicString.Builder {
+            private final DynamicProto.ConditionalStringOp.Builder mImpl =
+                    DynamicProto.ConditionalStringOp.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(-1535849633);
 
-    LogicalBoolOp(DynamicProto.LogicalBoolOp impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
+            public Builder() {}
+
+            /**
+             * Sets the condition to use.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setCondition(@NonNull DynamicBool condition) {
+                mImpl.setCondition(condition.toDynamicBoolProto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(condition.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the string to yield if condition is true.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setValueIfTrue(@NonNull DynamicString valueIfTrue) {
+                mImpl.setValueIfTrue(valueIfTrue.toDynamicStringProto());
+                mFingerprint.recordPropertyUpdate(
+                        2, checkNotNull(valueIfTrue.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the string to yield if condition is false.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setValueIfFalse(@NonNull DynamicString valueIfFalse) {
+                mImpl.setValueIfFalse(valueIfFalse.toDynamicStringProto());
+                mFingerprint.recordPropertyUpdate(
+                        3, checkNotNull(valueIfFalse.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public ConditionalStringOp build() {
+                return new ConditionalStringOp(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the left hand side of the logical operation.
+     * This implements simple string concatenation "result = LHS+RHS".
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicBool getInputLhs() {
-      if (mImpl.hasInputLhs()) {
-        return DynamicBuilders.dynamicBoolFromProto(mImpl.getInputLhs());
-      } else {
-        return null;
-      }
+    static final class ConcatStringOp implements DynamicString {
+
+        private final DynamicProto.ConcatStringOp mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        ConcatStringOp(DynamicProto.ConcatStringOp impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets left hand side of the concatenation operation.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicString getInputLhs() {
+            if (mImpl.hasInputLhs()) {
+                return DynamicBuilders.dynamicStringFromProto(mImpl.getInputLhs());
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets right hand side of the concatenation operation.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicString getInputRhs() {
+            if (mImpl.hasInputRhs()) {
+                return DynamicBuilders.dynamicStringFromProto(mImpl.getInputRhs());
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static ConcatStringOp fromProto(@NonNull DynamicProto.ConcatStringOp proto) {
+            return new ConcatStringOp(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.ConcatStringOp toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicString toDynamicStringProto() {
+            return DynamicProto.DynamicString.newBuilder().setConcatOp(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "ConcatStringOp{"
+                    + "inputLhs="
+                    + getInputLhs()
+                    + ", inputRhs="
+                    + getInputRhs()
+                    + "}";
+        }
+
+        /** Builder for {@link ConcatStringOp}. */
+        public static final class Builder implements DynamicString.Builder {
+            private final DynamicProto.ConcatStringOp.Builder mImpl =
+                    DynamicProto.ConcatStringOp.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(-1516620377);
+
+            public Builder() {}
+
+            /**
+             * Sets left hand side of the concatenation operation.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInputLhs(@NonNull DynamicString inputLhs) {
+                mImpl.setInputLhs(inputLhs.toDynamicStringProto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(inputLhs.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets right hand side of the concatenation operation.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInputRhs(@NonNull DynamicString inputRhs) {
+                mImpl.setInputRhs(inputRhs.toDynamicStringProto());
+                mFingerprint.recordPropertyUpdate(
+                        2, checkNotNull(inputRhs.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public ConcatStringOp build() {
+                return new ConcatStringOp(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the right hand side of the logical operation.
+     * Simple formatting for dynamic floats.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicBool getInputRhs() {
-      if (mImpl.hasInputRhs()) {
-        return DynamicBuilders.dynamicBoolFromProto(mImpl.getInputRhs());
-      } else {
-        return null;
-      }
+    static final class FloatFormatOp implements DynamicString {
+        private final DynamicProto.FloatFormatOp mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        FloatFormatOp(DynamicProto.FloatFormatOp impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the source of Float data to convert to a string.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicFloat getInput() {
+            if (mImpl.hasInput()) {
+                return DynamicBuilders.dynamicFloatFromProto(mImpl.getInput());
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets maximum fraction digits. Rounding will be applied if maxFractionDigits is smaller
+         * than number of fraction digits. If not defined, defaults to three. minimumFractionDigits
+         * must be <= maximumFractionDigits. If the condition is not satisfied, then
+         * minimumFractionDigits will be used for both fields.
+         *
+         * @since 1.2
+         */
+        @IntRange(from = 0)
+        public int getMaxFractionDigits() {
+            return mImpl.getMaxFractionDigits();
+        }
+
+        /**
+         * Gets minimum fraction digits. Zeros will be appended to the end to satisfy this
+         * constraint. If not defined, defaults to zero. minimumFractionDigits must be <=
+         * maximumFractionDigits. If the condition is not satisfied, then minimumFractionDigits will
+         * be used for both fields.
+         *
+         * @since 1.2
+         */
+        @IntRange(from = 0)
+        public int getMinFractionDigits() {
+            return mImpl.getMinFractionDigits();
+        }
+
+        /**
+         * Gets minimum integer digits. Sign and grouping characters are not considered when
+         * applying minIntegerDigits constraint. If not defined, defaults to one. For example, in
+         * the English locale, applying minIntegerDigit=4 to 12.34 would yield "0012.34".
+         *
+         * @since 1.2
+         */
+        @IntRange(from = 0)
+        public int getMinIntegerDigits() {
+            return mImpl.getMinIntegerDigits();
+        }
+
+        /**
+         * Gets digit grouping used. Grouping size and grouping character depend on the current
+         * locale. If not defined, defaults to false. For example, in the English locale, using
+         * grouping with 1234.56 would yield "1,234.56".
+         *
+         * @since 1.2
+         */
+        public boolean getGroupingUsed() {
+            return mImpl.getGroupingUsed();
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static FloatFormatOp fromProto(@NonNull DynamicProto.FloatFormatOp proto) {
+            return new FloatFormatOp(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.FloatFormatOp toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicString toDynamicStringProto() {
+            return DynamicProto.DynamicString.newBuilder().setFloatFormatOp(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "FloatFormatOp{"
+                    + "input="
+                    + getInput()
+                    + ", maxFractionDigits="
+                    + getMaxFractionDigits()
+                    + ", minFractionDigits="
+                    + getMinFractionDigits()
+                    + ", minIntegerDigits="
+                    + getMinIntegerDigits()
+                    + ", groupingUsed="
+                    + getGroupingUsed()
+                    + "}";
+        }
+
+        /** Builder for {@link FloatFormatOp}. */
+        public static final class Builder implements DynamicString.Builder {
+            private final DynamicProto.FloatFormatOp.Builder mImpl =
+                    DynamicProto.FloatFormatOp.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(-5150153);
+
+            public Builder() {}
+
+            /**
+             * Sets the source of Float data to convert to a string.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInput(@NonNull DynamicFloat input) {
+                mImpl.setInput(input.toDynamicFloatProto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets maximum fraction digits. Rounding will be applied if maxFractionDigits is
+             * smaller than number of fraction digits. If not defined, defaults to three.
+             * minimumFractionDigits must be <= maximumFractionDigits. If the condition is not
+             * satisfied, then minimumFractionDigits will be used for both fields.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setMaxFractionDigits(@IntRange(from = 0) int maxFractionDigits) {
+                mImpl.setMaxFractionDigits(maxFractionDigits);
+                mFingerprint.recordPropertyUpdate(2, maxFractionDigits);
+                return this;
+            }
+
+            /**
+             * Sets minimum fraction digits. Zeros will be appended to the end to satisfy this
+             * constraint. If not defined, defaults to zero. minimumFractionDigits must be <=
+             * maximumFractionDigits. If the condition is not satisfied, then minimumFractionDigits
+             * will be used for both fields.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setMinFractionDigits(@IntRange(from = 0) int minFractionDigits) {
+                mImpl.setMinFractionDigits(minFractionDigits);
+                mFingerprint.recordPropertyUpdate(3, minFractionDigits);
+                return this;
+            }
+
+            /**
+             * Sets minimum integer digits. Sign and grouping characters are not considered when
+             * applying minIntegerDigits constraint. If not defined, defaults to one. For example,
+             * in the English locale, applying minIntegerDigit=4 to 12.34 would yield "0012.34".
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setMinIntegerDigits(@IntRange(from = 0) int minIntegerDigits) {
+                mImpl.setMinIntegerDigits(minIntegerDigits);
+                mFingerprint.recordPropertyUpdate(4, minIntegerDigits);
+                return this;
+            }
+
+            /**
+             * Sets digit grouping used. Grouping size and grouping character depend on the current
+             * locale. If not defined, defaults to false. For example, in the English locale, using
+             * grouping with 1234.56 would yield "1,234.56".
+             *
+             * @since 1.2
+             */
+            @SuppressLint("MissingGetterMatchingBuilder")
+            @NonNull
+            public Builder setGroupingUsed(boolean groupingUsed) {
+                mImpl.setGroupingUsed(groupingUsed);
+                mFingerprint.recordPropertyUpdate(5, Boolean.hashCode(groupingUsed));
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public FloatFormatOp build() {
+                return new FloatFormatOp(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the operation type to apply to LHS/RHS.
+     * Interface defining a dynamic string type.
      *
      * @since 1.2
      */
-    @LogicalOpType
-    public int getOperationType() {
-      return mImpl.getOperationType().getNumber();
+    public interface DynamicString extends DynamicType {
+        /** Get the protocol buffer representation of this object. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        DynamicProto.DynamicString toDynamicStringProto();
+
+        /**
+         * Creates a {@link DynamicString} from a byte array generated by {@link
+         * #toDynamicStringByteArray()}.
+         */
+        @NonNull
+        static DynamicString fromByteArray(@NonNull byte[] byteArray) {
+            try {
+                return dynamicStringFromProto(
+                        DynamicProto.DynamicString.parseFrom(
+                                byteArray, ExtensionRegistryLite.getEmptyRegistry()));
+            } catch (InvalidProtocolBufferException e) {
+                throw new IllegalArgumentException(
+                        "Byte array could not be parsed into DynamicString", e);
+            }
+        }
+
+        /** Creates a byte array that can later be used with {@link #fromByteArray(byte[])}. */
+        @NonNull
+        default byte[] toDynamicStringByteArray() {
+            return toDynamicStringProto().toByteArray();
+        }
+
+        /** Creates a constant-valued {@link DynamicString}. */
+        @NonNull
+        static DynamicString constant(@NonNull String constant) {
+            return new FixedString.Builder().setValue(constant).build();
+        }
+
+        /**
+         * Creates a {@link DynamicString} that is bound to the value of an item of the State.
+         *
+         * @param stateKey The key to a {@link StateEntryValue} with a string value from the
+         *     provider's state.
+         */
+        @NonNull
+        static DynamicString fromState(@NonNull String stateKey) {
+            return new StateStringSource.Builder().setSourceKey(stateKey).build();
+        }
+
+        /**
+         * Creates a {@link DynamicString} that is bound to the result of a conditional expression.
+         * It will use the value given in either {@link ConditionScope#use} or {@link
+         * ConditionScopes.IfTrueScope#elseUse} depending on the value yielded from {@code
+         * condition}.
+         *
+         * @param condition The value used for evaluting this condition.
+         */
+        @NonNull
+        static ConditionScope<DynamicString, String> onCondition(@NonNull DynamicBool condition) {
+            return new ConditionScopes.ConditionScope<>(
+                    (trueValue, falseValue) ->
+                            new ConditionalStringOp.Builder()
+                                    .setCondition(condition)
+                                    .setValueIfTrue(trueValue)
+                                    .setValueIfFalse(falseValue)
+                                    .build(),
+                    DynamicString::constant);
+        }
+
+        /**
+         * Returns a new {@link DynamicString} that has the result of concatenating this {@link
+         * DynamicString} with {@code other}. i.e. {@code result = this + other}
+         *
+         * @param other The right hand side operand of the concatenation.
+         */
+        @NonNull
+        default DynamicString concat(@NonNull DynamicString other) {
+            return new DynamicBuilders.ConcatStringOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .build();
+        }
+
+        /** Get the fingerprint for this object or null if unknown. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        Fingerprint getFingerprint();
+
+        /** Builder to create {@link DynamicString} objects. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        interface Builder {
+
+            /** Builds an instance with values accumulated in this Builder. */
+            @NonNull
+            DynamicString build();
+        }
     }
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static LogicalBoolOp fromProto(@NonNull DynamicProto.LogicalBoolOp proto) {
-      return new LogicalBoolOp(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.LogicalBoolOp toProto() {
-      return mImpl;
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicBool toDynamicBoolProto() {
-      return DynamicProto.DynamicBool.newBuilder().setLogicalOp(mImpl).build();
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-      return "LogicalBoolOp{"
-          + "inputLhs="
-          + getInputLhs()
-          + ", inputRhs="
-          + getInputRhs()
-          + ", operationType="
-          + getOperationType()
-          + "}";
-    }
-
-    /** Builder for {@link LogicalBoolOp}. */
-    public static final class Builder implements DynamicBool.Builder {
-      private final DynamicProto.LogicalBoolOp.Builder mImpl =
-          DynamicProto.LogicalBoolOp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(1067523409);
-
-      public Builder() {}
-
-      /**
-       * Sets the left hand side of the logical operation.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInputLhs(@NonNull DynamicBool inputLhs) {
-        mImpl.setInputLhs(inputLhs.toDynamicBoolProto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(inputLhs.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the right hand side of the logical operation.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInputRhs(@NonNull DynamicBool inputRhs) {
-        mImpl.setInputRhs(inputRhs.toDynamicBoolProto());
-        mFingerprint.recordPropertyUpdate(
-            2, checkNotNull(inputRhs.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the operation type to apply to LHS/RHS.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setOperationType(@LogicalOpType int operationType) {
-        mImpl.setOperationType(DynamicProto.LogicalOpType.forNumber(operationType));
-        mFingerprint.recordPropertyUpdate(3, operationType);
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public LogicalBoolOp build() {
-        return new LogicalBoolOp(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * Interface defining a dynamic boolean type.
-   *
-   * @since 1.2
-   */
-  public interface DynamicBool extends DynamicType {
     /**
-     * Get the protocol buffer representation of this object.
-     *
+     * Creates a new wrapper instance from the proto. Intended for testing purposes only. An object
+     * created using this method can't be added to any other wrapper.
      */
     @RestrictTo(Scope.LIBRARY_GROUP)
     @NonNull
-    DynamicProto.DynamicBool toDynamicBoolProto();
-
-    /**
-     * Creates a {@link DynamicBool} from a byte array generated by {@link
-     * #toDynamicBoolByteArray()}.
-     */
-    @NonNull
-    static DynamicBool fromByteArray(@NonNull byte[] byteArray) {
-      try {
-        return dynamicBoolFromProto(
-            DynamicProto.DynamicBool.parseFrom(
-                byteArray, ExtensionRegistryLite.getEmptyRegistry()));
-      } catch (InvalidProtocolBufferException e) {
-        throw new IllegalArgumentException("Byte array could not be parsed into DynamicBool", e);
-      }
-    }
-
-    /** Creates a byte array that can later be used with {@link #fromByteArray(byte[])}. */
-    @NonNull
-    default byte[] toDynamicBoolByteArray() {
-      return toDynamicBoolProto().toByteArray();
-    }
-
-    /** Creates a constant-valued {@link DynamicBool}. */
-    @NonNull
-    static DynamicBool constant(boolean constant) {
-      return new FixedBool.Builder().setValue(constant).build();
+    public static DynamicString dynamicStringFromProto(@NonNull DynamicProto.DynamicString proto) {
+        if (proto.hasFixed()) {
+            return FixedString.fromProto(proto.getFixed());
+        }
+        if (proto.hasInt32FormatOp()) {
+            return Int32FormatOp.fromProto(proto.getInt32FormatOp());
+        }
+        if (proto.hasStateSource()) {
+            return StateStringSource.fromProto(proto.getStateSource());
+        }
+        if (proto.hasConditionalOp()) {
+            return ConditionalStringOp.fromProto(proto.getConditionalOp());
+        }
+        if (proto.hasConcatOp()) {
+            return ConcatStringOp.fromProto(proto.getConcatOp());
+        }
+        if (proto.hasFloatFormatOp()) {
+            return FloatFormatOp.fromProto(proto.getFloatFormatOp());
+        }
+        throw new IllegalStateException("Proto was not a recognised instance of DynamicString");
     }
 
     /**
-     * Creates a {@link DynamicBool} that is bound to the value of an item of the State.
-     *
-     * @param stateKey The key to a {@link StateEntryValue} with a boolean value from the provider's
-     *     state.
-     */
-    @NonNull
-    static DynamicBool fromState(@NonNull String stateKey) {
-      return new StateBoolSource.Builder().setSourceKey(stateKey).build();
-    }
-
-    /** Returns a {@link DynamicBool} that has the same value as this {@link DynamicBool}. */
-    @NonNull
-    default DynamicBool isTrue() {
-      return this;
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that has the opposite value of this {@link DynamicBool}. i.e.
-     * {code result = !this}
-     */
-    @NonNull
-    default DynamicBool isFalse() {
-      return new NotBoolOp.Builder().setInput(this).build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if this {@link DynamicBool} and {@code input} are
-     * both true, otherwise it is false. i.e. {@code boolean result = this && input}
-     *
-     * @param input The right hand operand of the "and" operation.
-     */
-    @NonNull
-    default DynamicBool and(@NonNull DynamicBool input) {
-      return new LogicalBoolOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(input)
-          .setOperationType(DynamicBuilders.LOGICAL_OP_TYPE_AND)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicBool} that is true if this {@link DynamicBool} or {@code input} are
-     * true, otherwise it is false. i.e. {@code boolean result = this || input}
-     *
-     * @param input The right hand operand of the "or" operation.
-     */
-    @NonNull
-    default DynamicBool or(@NonNull DynamicBool input) {
-      return new LogicalBoolOp.Builder()
-          .setInputLhs(this)
-          .setInputRhs(input)
-          .setOperationType(DynamicBuilders.LOGICAL_OP_TYPE_OR)
-          .build();
-    }
-
-    /**
-     * Get the fingerprint for this object or null if unknown.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    Fingerprint getFingerprint();
-
-    /**
-     * Builder to create {@link DynamicBool} objects.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    interface Builder {
-
-      /** Builds an instance with values accumulated in this Builder. */
-      @NonNull
-      DynamicBool build();
-    }
-  }
-
-  /**
-   * Creates a new wrapper instance from the proto. Intended for testing purposes only. An object
-   * created using this method can't be added to any other wrapper.
-   *
-   */
-  @RestrictTo(Scope.LIBRARY_GROUP)
-  @NonNull
-  public static DynamicBool dynamicBoolFromProto(@NonNull DynamicProto.DynamicBool proto) {
-    if (proto.hasFixed()) {
-      return FixedBool.fromProto(proto.getFixed());
-    }
-    if (proto.hasStateSource()) {
-      return StateBoolSource.fromProto(proto.getStateSource());
-    }
-    if (proto.hasInt32Comparison()) {
-      return ComparisonInt32Op.fromProto(proto.getInt32Comparison());
-    }
-    if (proto.hasNotOp()) {
-      return NotBoolOp.fromProto(proto.getNotOp());
-    }
-    if (proto.hasLogicalOp()) {
-      return LogicalBoolOp.fromProto(proto.getLogicalOp());
-    }
-    if (proto.hasFloatComparison()) {
-      return ComparisonFloatOp.fromProto(proto.getFloatComparison());
-    }
-    throw new IllegalStateException("Proto was not a recognised instance of DynamicBool");
-  }
-
-  /**
-   * A dynamic Color which sources its data from the tile's state.
-   *
-   * @since 1.2
-   */
-  static final class StateColorSource implements DynamicColor {
-    private final DynamicProto.StateColorSource mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    StateColorSource(DynamicProto.StateColorSource impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
-
-    /**
-     * Gets the key in the state to bind to.
+     * An arithmetic operation, operating on two Float instances. This implements simple binary
+     * operations of the form "result = LHS <op> RHS", where the available operation types are
+     * described in {@code ArithmeticOpType}.
      *
      * @since 1.2
      */
-    @NonNull
-    public String getSourceKey() {
-      return mImpl.getSourceKey();
-    }
+    static final class ArithmeticFloatOp implements DynamicFloat {
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
+        private final DynamicProto.ArithmeticFloatOp mImpl;
+        @Nullable private final Fingerprint mFingerprint;
 
-    @NonNull
-    static StateColorSource fromProto(@NonNull DynamicProto.StateColorSource proto) {
-      return new StateColorSource(proto, null);
-    }
+        ArithmeticFloatOp(DynamicProto.ArithmeticFloatOp impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
 
-    @NonNull
-    DynamicProto.StateColorSource toProto() {
-      return mImpl;
-    }
+        /**
+         * Gets left hand side of the arithmetic operation.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicFloat getInputLhs() {
+            if (mImpl.hasInputLhs()) {
+                return DynamicBuilders.dynamicFloatFromProto(mImpl.getInputLhs());
+            } else {
+                return null;
+            }
+        }
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicColor toDynamicColorProto() {
-      return DynamicProto.DynamicColor.newBuilder().setStateSource(mImpl).build();
-    }
+        /**
+         * Gets right hand side of the arithmetic operation.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicFloat getInputRhs() {
+            if (mImpl.hasInputRhs()) {
+                return DynamicBuilders.dynamicFloatFromProto(mImpl.getInputRhs());
+            } else {
+                return null;
+            }
+        }
 
-    @Override
-    @NonNull
-    public String toString() {
-      return "StateColorSource{" + "sourceKey=" + getSourceKey() + "}";
-    }
+        /**
+         * Gets the type of operation to carry out.
+         *
+         * @since 1.2
+         */
+        @ArithmeticOpType
+        public int getOperationType() {
+            return mImpl.getOperationType().getNumber();
+        }
 
-    /** Builder for {@link StateColorSource}. */
-    public static final class Builder implements DynamicColor.Builder {
-      private final DynamicProto.StateColorSource.Builder mImpl =
-          DynamicProto.StateColorSource.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(1981221690);
+        /** */
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
 
-      public Builder() {}
+        @NonNull
+        static ArithmeticFloatOp fromProto(@NonNull DynamicProto.ArithmeticFloatOp proto) {
+            return new ArithmeticFloatOp(proto, null);
+        }
 
-      /**
-       * Sets the key in the state to bind to.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setSourceKey(@NonNull String sourceKey) {
-        mImpl.setSourceKey(sourceKey);
-        mFingerprint.recordPropertyUpdate(1, sourceKey.hashCode());
-        return this;
-      }
+        @NonNull
+        DynamicProto.ArithmeticFloatOp toProto() {
+            return mImpl;
+        }
 
-      @Override
-      @NonNull
-      public StateColorSource build() {
-        return new StateColorSource(mImpl.build(), mFingerprint);
-      }
-    }
-  }
+        /** */
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicFloat toDynamicFloatProto() {
+            return DynamicProto.DynamicFloat.newBuilder().setArithmeticOperation(mImpl).build();
+        }
 
-  /**
-   * A static interpolation node, between two fixed color values.
-   *
-   * @since 1.2
-   */
-  static final class AnimatableFixedColor implements DynamicColor {
-    private final DynamicProto.AnimatableFixedColor mImpl;
-    @Nullable private final Fingerprint mFingerprint;
+        /** Builder for {@link ArithmeticFloatOp}. */
+        public static final class Builder implements DynamicFloat.Builder {
 
-    AnimatableFixedColor(
-        DynamicProto.AnimatableFixedColor impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
+            private final DynamicProto.ArithmeticFloatOp.Builder mImpl =
+                    DynamicProto.ArithmeticFloatOp.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(-1818249334);
+
+            public Builder() {}
+
+            /**
+             * Sets left hand side of the arithmetic operation.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInputLhs(@NonNull DynamicFloat inputLhs) {
+                mImpl.setInputLhs(inputLhs.toDynamicFloatProto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(inputLhs.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets right hand side of the arithmetic operation.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInputRhs(@NonNull DynamicFloat inputRhs) {
+                mImpl.setInputRhs(inputRhs.toDynamicFloatProto());
+                mFingerprint.recordPropertyUpdate(
+                        2, checkNotNull(inputRhs.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the type of operation to carry out.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setOperationType(@ArithmeticOpType int operationType) {
+                mImpl.setOperationType(DynamicProto.ArithmeticOpType.forNumber(operationType));
+                mFingerprint.recordPropertyUpdate(3, operationType);
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public ArithmeticFloatOp build() {
+                return new ArithmeticFloatOp(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the color value (in ARGB format) to start animating from.
+     * A dynamic Float which sources its data from the tile's state.
      *
      * @since 1.2
      */
-    @ColorInt
-    public int getFromArgb() {
-      return mImpl.getFromArgb();
+    static final class StateFloatSource implements DynamicFloat {
+        private final DynamicProto.StateFloatSource mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        StateFloatSource(DynamicProto.StateFloatSource impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the key in the state to bind to.
+         *
+         * @since 1.2
+         */
+        @NonNull
+        public String getSourceKey() {
+            return mImpl.getSourceKey();
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static StateFloatSource fromProto(@NonNull DynamicProto.StateFloatSource proto) {
+            return new StateFloatSource(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.StateFloatSource toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicFloat toDynamicFloatProto() {
+            return DynamicProto.DynamicFloat.newBuilder().setStateSource(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "StateFloatSource{" + "sourceKey=" + getSourceKey() + "}";
+        }
+
+        /** Builder for {@link StateFloatSource}. */
+        public static final class Builder implements DynamicFloat.Builder {
+            private final DynamicProto.StateFloatSource.Builder mImpl =
+                    DynamicProto.StateFloatSource.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(384370154);
+
+            public Builder() {}
+
+            /**
+             * Sets the key in the state to bind to.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setSourceKey(@NonNull String sourceKey) {
+                mImpl.setSourceKey(sourceKey);
+                mFingerprint.recordPropertyUpdate(1, sourceKey.hashCode());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public StateFloatSource build() {
+                return new StateFloatSource(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the color value (in ARGB format) to animate to.
+     * An operation to convert an Int32 value in the dynamic data pipeline to a Float value.
      *
      * @since 1.2
      */
-    @ColorInt
-    public int getToArgb() {
-      return mImpl.getToArgb();
+    static final class Int32ToFloatOp implements DynamicFloat {
+        private final DynamicProto.Int32ToFloatOp mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        Int32ToFloatOp(DynamicProto.Int32ToFloatOp impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the input Int32 to convert to a Float.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicInt32 getInput() {
+            if (mImpl.hasInput()) {
+                return DynamicBuilders.dynamicInt32FromProto(mImpl.getInput());
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static Int32ToFloatOp fromProto(@NonNull DynamicProto.Int32ToFloatOp proto) {
+            return new Int32ToFloatOp(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.Int32ToFloatOp toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicFloat toDynamicFloatProto() {
+            return DynamicProto.DynamicFloat.newBuilder().setInt32ToFloatOperation(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "Int32ToFloatOp{" + "input=" + getInput() + "}";
+        }
+
+        /** Builder for {@link Int32ToFloatOp}. */
+        public static final class Builder implements DynamicFloat.Builder {
+            private final DynamicProto.Int32ToFloatOp.Builder mImpl =
+                    DynamicProto.Int32ToFloatOp.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(-619592745);
+
+            public Builder() {}
+
+            /**
+             * Sets the input Int32 to convert to a Float.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInput(@NonNull DynamicInt32 input) {
+                mImpl.setInput(input.toDynamicInt32Proto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public Int32ToFloatOp build() {
+                return new Int32ToFloatOp(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the animation parameters for duration, delay, etc.
+     * A static interpolation node, between two fixed floating point values.
      *
      * @since 1.2
      */
-    @Nullable
-    public AnimationSpec getAnimationSpec() {
-      if (mImpl.hasAnimationSpec()) {
-        return AnimationSpec.fromProto(mImpl.getAnimationSpec());
-      } else {
-        return null;
-      }
-    }
+    static final class AnimatableFixedFloat implements DynamicFloat {
+        private final DynamicProto.AnimatableFixedFloat mImpl;
+        @Nullable private final Fingerprint mFingerprint;
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
+        AnimatableFixedFloat(
+                DynamicProto.AnimatableFixedFloat impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
 
-    @NonNull
-    static AnimatableFixedColor fromProto(@NonNull DynamicProto.AnimatableFixedColor proto) {
-      return new AnimatableFixedColor(proto, null);
-    }
+        /**
+         * Gets the number to start animating from.
+         *
+         * @since 1.2
+         */
+        public float getFromValue() {
+            return mImpl.getFromValue();
+        }
 
-    @NonNull
-    DynamicProto.AnimatableFixedColor toProto() {
-      return mImpl;
-    }
+        /**
+         * Gets the number to animate to.
+         *
+         * @since 1.2
+         */
+        public float getToValue() {
+            return mImpl.getToValue();
+        }
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicColor toDynamicColorProto() {
-      return DynamicProto.DynamicColor.newBuilder().setAnimatableFixed(mImpl).build();
-    }
+        /**
+         * Gets the animation parameters for duration, delay, etc.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public AnimationSpec getAnimationSpec() {
+            if (mImpl.hasAnimationSpec()) {
+                return AnimationSpec.fromProto(mImpl.getAnimationSpec());
+            } else {
+                return null;
+            }
+        }
 
-    @Override
-    @NonNull
-    public String toString() {
-      return "AnimatableFixedColor{"
-          + "fromArgb="
-          + getFromArgb()
-          + ", toArgb="
-          + getToArgb()
-          + ", animationSpec="
-          + getAnimationSpec()
-          + "}";
-    }
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
 
-    /** Builder for {@link AnimatableFixedColor}. */
-    public static final class Builder implements DynamicColor.Builder {
-      private final DynamicProto.AnimatableFixedColor.Builder mImpl =
-          DynamicProto.AnimatableFixedColor.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(2051778294);
+        @NonNull
+        static AnimatableFixedFloat fromProto(@NonNull DynamicProto.AnimatableFixedFloat proto) {
+            return new AnimatableFixedFloat(proto, null);
+        }
 
-      public Builder() {}
+        @NonNull
+        DynamicProto.AnimatableFixedFloat toProto() {
+            return mImpl;
+        }
 
-      /**
-       * Sets the color value (in ARGB format) to start animating from.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setFromArgb(@ColorInt int fromArgb) {
-        mImpl.setFromArgb(fromArgb);
-        mFingerprint.recordPropertyUpdate(1, fromArgb);
-        return this;
-      }
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicFloat toDynamicFloatProto() {
+            return DynamicProto.DynamicFloat.newBuilder().setAnimatableFixed(mImpl).build();
+        }
 
-      /**
-       * Sets the color value (in ARGB format) to animate to.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setToArgb(@ColorInt int toArgb) {
-        mImpl.setToArgb(toArgb);
-        mFingerprint.recordPropertyUpdate(2, toArgb);
-        return this;
-      }
+        @Override
+        @NonNull
+        public String toString() {
+            return "AnimatableFixedFloat{"
+                    + "fromValue="
+                    + getFromValue()
+                    + ", toValue="
+                    + getToValue()
+                    + ", animationSpec="
+                    + getAnimationSpec()
+                    + "}";
+        }
 
-      /**
-       * Sets the animation parameters for duration, delay, etc.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
-        mImpl.setAnimationSpec(animationSpec.toProto());
-        mFingerprint.recordPropertyUpdate(
-            3, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
+        /** Builder for {@link AnimatableFixedFloat}. */
+        public static final class Builder implements DynamicFloat.Builder {
+            private final DynamicProto.AnimatableFixedFloat.Builder mImpl =
+                    DynamicProto.AnimatableFixedFloat.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(1964707538);
 
-      @Override
-      @NonNull
-      public AnimatableFixedColor build() {
-        return new AnimatableFixedColor(mImpl.build(), mFingerprint);
-      }
-    }
-  }
+            public Builder() {}
 
-  /**
-   * A dynamic interpolation node. This will watch the value of its input and, when the first update
-   * arrives, immediately emit that value. On subsequent updates, it will animate between the old
-   * and new values.
-   *
-   * <p>If this node receives an invalid value (e.g. as a result of an upstream node having no
-   * value), then it will emit a single invalid value, and forget its "stored" value. The next valid
-   * value that arrives is then used as the "first" value again.
-   *
-   * @since 1.2
-   */
-  static final class AnimatableDynamicColor implements DynamicColor {
-    private final DynamicProto.AnimatableDynamicColor mImpl;
-    @Nullable private final Fingerprint mFingerprint;
+            /**
+             * Sets the number to start animating from.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setFromValue(float fromValue) {
+                mImpl.setFromValue(fromValue);
+                mFingerprint.recordPropertyUpdate(1, Float.floatToIntBits(fromValue));
+                return this;
+            }
 
-    AnimatableDynamicColor(
-        DynamicProto.AnimatableDynamicColor impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
+            /**
+             * Sets the number to animate to.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setToValue(float toValue) {
+                mImpl.setToValue(toValue);
+                mFingerprint.recordPropertyUpdate(2, Float.floatToIntBits(toValue));
+                return this;
+            }
+
+            /**
+             * Sets the animation parameters for duration, delay, etc.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
+                mImpl.setAnimationSpec(animationSpec.toProto());
+                mFingerprint.recordPropertyUpdate(
+                        3, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public AnimatableFixedFloat build() {
+                return new AnimatableFixedFloat(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the value to watch, and animate when it changes.
+     * A dynamic interpolation node. This will watch the value of its input and, when the first
+     * update arrives, immediately emit that value. On subsequent updates, it will animate between
+     * the old and new values.
+     *
+     * <p>If this node receives an invalid value (e.g. as a result of an upstream node having no
+     * value), then it will emit a single invalid value, and forget its "stored" value. The next
+     * valid value that arrives is then used as the "first" value again.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicColor getInput() {
-      if (mImpl.hasInput()) {
-        return DynamicBuilders.dynamicColorFromProto(mImpl.getInput());
-      } else {
-        return null;
-      }
+    static final class AnimatableDynamicFloat implements DynamicFloat {
+        private final DynamicProto.AnimatableDynamicFloat mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        AnimatableDynamicFloat(
+                DynamicProto.AnimatableDynamicFloat impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the value to watch, and animate when it changes.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicFloat getInput() {
+            if (mImpl.hasInput()) {
+                return DynamicBuilders.dynamicFloatFromProto(mImpl.getInput());
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets the animation parameters for duration, delay, etc.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public AnimationSpec getAnimationSpec() {
+            if (mImpl.hasAnimationSpec()) {
+                return AnimationSpec.fromProto(mImpl.getAnimationSpec());
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static AnimatableDynamicFloat fromProto(
+                @NonNull DynamicProto.AnimatableDynamicFloat proto) {
+            return new AnimatableDynamicFloat(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.AnimatableDynamicFloat toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicFloat toDynamicFloatProto() {
+            return DynamicProto.DynamicFloat.newBuilder().setAnimatableDynamic(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "AnimatableDynamicFloat{"
+                    + "input="
+                    + getInput()
+                    + ", animationSpec="
+                    + getAnimationSpec()
+                    + "}";
+        }
+
+        /** Builder for {@link AnimatableDynamicFloat}. */
+        public static final class Builder implements DynamicFloat.Builder {
+            private final DynamicProto.AnimatableDynamicFloat.Builder mImpl =
+                    DynamicProto.AnimatableDynamicFloat.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(1543182280);
+
+            public Builder() {}
+
+            /**
+             * Sets the value to watch, and animate when it changes.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInput(@NonNull DynamicFloat input) {
+                mImpl.setInput(input.toDynamicFloatProto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the animation parameters for duration, delay, etc.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
+                mImpl.setAnimationSpec(animationSpec.toProto());
+                mFingerprint.recordPropertyUpdate(
+                        3, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public AnimatableDynamicFloat build() {
+                return new AnimatableDynamicFloat(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the animation parameters for duration, delay, etc.
+     * Interface defining a dynamic float type.
+     *
+     * <p>It offers a set of helper methods for creating arithmetic and logical expressions, e.g.
+     * {@link #plus(float)}, {@link #times(float)}, {@link #eq(float)}, etc. These helper methods
+     * produce expression trees based on the order in which they were called in an expression. Thus,
+     * no operator precedence rules are applied.
+     *
+     * <p>For example the following expression is equivalent to {@code result = ((a + b)*c)/d }:
+     *
+     * <pre>{@code
+     * a.plus(b).times(c).div(d);
+     * }</pre>
+     *
+     * More complex expressions can be created by nesting expressions. For example the following
+     * expression is equivalent to {@code result = (a + b)*(c - d) }:
+     *
+     * <pre>{@code
+     * (a.plus(b)).times(c.minus(d));
+     * }</pre>
      *
      * @since 1.2
      */
-    @Nullable
-    public AnimationSpec getAnimationSpec() {
-      if (mImpl.hasAnimationSpec()) {
-        return AnimationSpec.fromProto(mImpl.getAnimationSpec());
-      } else {
-        return null;
-      }
+    public interface DynamicFloat extends DynamicType {
+        /** Get the protocol buffer representation of this object. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        DynamicProto.DynamicFloat toDynamicFloatProto();
+
+        /**
+         * Creates a {@link DynamicFloat} from a byte array generated by {@link
+         * #toDynamicFloatByteArray()}.
+         */
+        @NonNull
+        static DynamicFloat fromByteArray(@NonNull byte[] byteArray) {
+            try {
+                return dynamicFloatFromProto(
+                        DynamicProto.DynamicFloat.parseFrom(
+                                byteArray, ExtensionRegistryLite.getEmptyRegistry()));
+            } catch (InvalidProtocolBufferException e) {
+                throw new IllegalArgumentException(
+                        "Byte array could not be parsed into DynamicFloat", e);
+            }
+        }
+
+        /** Creates a byte array that can later be used with {@link #fromByteArray(byte[])}. */
+        @NonNull
+        default byte[] toDynamicFloatByteArray() {
+            return toDynamicFloatProto().toByteArray();
+        }
+
+        /** Creates a constant-valued {@link DynamicFloat}. */
+        @NonNull
+        static DynamicFloat constant(float constant) {
+            return new FixedFloat.Builder().setValue(constant).build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} that is bound to the value of an item of the State.
+         *
+         * @param stateKey The key to a {@link StateEntryValue} with a float value from the
+         *     provider's state.
+         */
+        @NonNull
+        static DynamicFloat fromState(@NonNull String stateKey) {
+            return new StateFloatSource.Builder().setSourceKey(stateKey).build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} which will animate over the range of floats from {@code
+         * start} to {@code end}.
+         *
+         * @param start The start value of the range.
+         * @param end The end value of the range.
+         */
+        @NonNull
+        static DynamicFloat animate(float start, float end) {
+            return new AnimatableFixedFloat.Builder().setFromValue(start).setToValue(end).build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} which will animate over the range of floats from {@code
+         * start} to {@code end} with the given animation parameters.
+         *
+         * @param start The start value of the range.
+         * @param end The end value of the range.
+         * @param animationSpec The animation parameters.
+         */
+        @NonNull
+        static DynamicFloat animate(float start, float end, @NonNull AnimationSpec animationSpec) {
+            return new AnimatableFixedFloat.Builder()
+                    .setFromValue(start)
+                    .setToValue(end)
+                    .setAnimationSpec(animationSpec)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} that is bound to the value of an item of the State. Every
+         * time the state value changes, this {@link DynamicFloat} will animate from its current
+         * value to the new value (from the state).
+         *
+         * @param stateKey The key to a {@link StateEntryValue} with a float value from the
+         *     providers state.
+         */
+        @NonNull
+        static DynamicFloat animate(@NonNull String stateKey) {
+            return new AnimatableDynamicFloat.Builder().setInput(fromState(stateKey)).build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} that is bound to the value of an item of the State. Every
+         * time the state value changes, this {@link DynamicFloat} will animate from its current
+         * value to the new value (from the state).
+         *
+         * @param stateKey The key to a {@link StateEntryValue} with a float value from the
+         *     providers state.
+         * @param animationSpec The animation parameters.
+         */
+        @NonNull
+        static DynamicFloat animate(
+                @NonNull String stateKey, @NonNull AnimationSpec animationSpec) {
+            return new AnimatableDynamicFloat.Builder()
+                    .setInput(fromState(stateKey))
+                    .setAnimationSpec(animationSpec)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicFloat} that is bound to the value of this {@link DynamicFloat}
+         * and every time its value is changing, it animates from its current value to the new
+         * value.
+         *
+         * @param animationSpec The animation parameters.
+         */
+        @NonNull
+        default DynamicFloat animate(@NonNull AnimationSpec animationSpec) {
+            return new AnimatableDynamicFloat.Builder()
+                    .setInput(this)
+                    .setAnimationSpec(animationSpec)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicFloat} that is bound to the value of this {@link DynamicFloat}
+         * and every time its value is changing, it animates from its current value to the new
+         * value.
+         */
+        @NonNull
+        default DynamicFloat animate() {
+            return new AnimatableDynamicFloat.Builder().setInput(this).build();
+        }
+
+        /**
+         * Returns a {@link DynamicInt32} which holds the largest integer value that is smaller than
+         * or equal to this {@link DynamicFloat}, i.e. {@code int result = (int) Math.floor(this)}
+         */
+        @NonNull
+        default DynamicInt32 asInt() {
+            return new FloatToInt32Op.Builder()
+                    .setRoundMode(DynamicBuilders.ROUND_MODE_FLOOR)
+                    .setInput(this)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of adding another {@link
+         * DynamicFloat} to this {@link DynamicFloat}; As an example, the following is equal to
+         * {@code DynamicFloat.constant(13f)}
+         *
+         * <pre>
+         *   DynamicFloat.constant(7f).plus(DynamicFloat.constant(5f));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat plus(@NonNull DynamicFloat other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_ADD)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of adding a float to this {@link
+         * DynamicFloat}; As an example, the following is equal to {@code
+         * DynamicFloat.constant(13f)}
+         *
+         * <pre>
+         *   DynamicFloat.constant(7f).plus(5f);
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat plus(float other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_ADD)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of adding a {@link DynamicInt32} to
+         * this {@link DynamicFloat}; As an example, the following is equal to {@code
+         * DynamicFloat.constant(13f)}
+         *
+         * <pre>
+         *   DynamicFloat.constant(7f).plus(DynamicInt32.constant(5));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat plus(@NonNull DynamicInt32 other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other.asFloat())
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_ADD)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of subtracting another {@link
+         * DynamicFloat} from this {@link DynamicFloat}; As an example, the following is equal to
+         * {@code DynamicFloat.constant(2f)}
+         *
+         * <pre>
+         *   DynamicFloat.constant(7f).minus(DynamicFloat.constant(5f));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat minus(@NonNull DynamicFloat other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_SUBTRACT)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of subtracting a flaot from this
+         * {@link DynamicFloat}; As an example, the following is equal to {@code
+         * DynamicFloat.constant(2f)}
+         *
+         * <pre>
+         *   DynamicFloat.constant(7f).minus(5f);
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat minus(float other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_SUBTRACT)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of subtracting a {@link
+         * DynamicInt32} from this {@link DynamicFloat}; As an example, the following is equal to
+         * {@code DynamicFloat.constant(2f)}
+         *
+         * <pre>
+         *   DynamicFloat.constant(7f).minus(DynamicInt32.constant(5));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat minus(@NonNull DynamicInt32 other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other.asFloat())
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_SUBTRACT)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of multiplying this {@link
+         * DynamicFloat} by another {@link DynamicFloat}; As an example, the following is equal to
+         * {@code DynamicFloat.constant(35f)}
+         *
+         * <pre>
+         *   DynamicFloat.constant(7f).times(DynamicFloat.constant(5f));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat times(@NonNull DynamicFloat other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MULTIPLY)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of multiplying this {@link
+         * DynamicFloat} by a flaot; As an example, the following is equal to {@code
+         * DynamicFloat.constant(35f)}
+         *
+         * <pre>
+         *   DynamicFloat.constant(7f).times(5f);
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat times(float other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MULTIPLY)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of multiplying this {@link
+         * DynamicFloat} by a {@link DynamicInt32}; As an example, the following is equal to {@code
+         * DynamicFloat.constant(35f)}
+         *
+         * <pre>
+         *   DynamicFloat.constant(7f).times(DynamicInt32.constant(5));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat times(@NonNull DynamicInt32 other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other.asFloat())
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MULTIPLY)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of dividing this {@link
+         * DynamicFloat} by another {@link DynamicFloat}; As an example, the following is equal to
+         * {@code DynamicFloat.constant(1.4f)}
+         *
+         * <pre>
+         *   DynamicFloat.constant(7f).div(DynamicFloat.constant(5f));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat div(@NonNull DynamicFloat other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_DIVIDE)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of dividing this {@link
+         * DynamicFloat} by a float; As an example, the following is equal to {@code
+         * DynamicFloat.constant(1.4f)}
+         *
+         * <pre>
+         *   DynamicFloat.constant(7f).div(5f);
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat div(float other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_DIVIDE)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the result of dividing this {@link
+         * DynamicFloat} by a {@link DynamicInt32}; As an example, the following is equal to {@code
+         * DynamicFloat.constant(1.4f)}
+         *
+         * <pre>
+         *   DynamicFloat.constant(7f).div(DynamicInt32.constant(5));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat div(@NonNull DynamicInt32 other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other.asFloat())
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_DIVIDE)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the reminder of dividing this {@link
+         * DynamicFloat} by another {@link DynamicFloat}; As an example, the following is equal to
+         * {@code DynamicFloat.constant(1.5f)}
+         *
+         * <pre>
+         *   DynamicFloat.constant(7f).rem(DynamicFloat.constant(5.5f));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat rem(@NonNull DynamicFloat other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MODULO)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the reminder of dividing this {@link
+         * DynamicFloat} by a float; As an example, the following is equal to {@code
+         * DynamicFloat.constant(1.5f)}
+         *
+         * <pre>
+         *   DynamicFloat.constant(7f).rem(5.5f);
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat rem(float other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MODULO)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicFloat} containing the reminder of dividing this {@link
+         * DynamicFloat} by a {@link DynamicInt32}; As an example, the following is equal to {@code
+         * DynamicFloat.constant(2f)}
+         *
+         * <pre>
+         *   DynamicFloat.constant(7f).rem(DynamicInt32.constant(5));
+         * </pre>
+         *
+         * The operation's evaluation order depends only on its position in the expression; no
+         * operator precedence rules are applied. See {@link DynamicFloat} for more information on
+         * operation evaluation order.
+         *
+         * @return a new instance of {@link DynamicFloat} containing the result of the operation.
+         */
+        @SuppressWarnings("KotlinOperator")
+        @NonNull
+        default DynamicFloat rem(@NonNull DynamicInt32 other) {
+            return new ArithmeticFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other.asFloat())
+                    .setOperationType(DynamicBuilders.ARITHMETIC_OP_TYPE_MODULO)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} and
+         * {@code other} are equal, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool eq(@NonNull DynamicFloat other) {
+            return new ComparisonFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_EQUALS)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} and
+         * {@code other} are equal, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool eq(float other) {
+            return new ComparisonFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_EQUALS)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} and
+         * {@code other} are not equal, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool ne(@NonNull DynamicFloat other) {
+            return new ComparisonFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_NOT_EQUALS)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} and
+         * {@code other} are not equal, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool ne(float other) {
+            return new ComparisonFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_NOT_EQUALS)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} is
+         * less than {@code other}, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool lt(@NonNull DynamicFloat other) {
+            return new ComparisonFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_LESS_THAN)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} is
+         * less than {@code other}, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool lt(float other) {
+            return new ComparisonFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_LESS_THAN)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} is
+         * less than or equal to {@code other}, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool lte(@NonNull DynamicFloat other) {
+            return new ComparisonFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_LESS_THAN_OR_EQUAL_TO)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} is
+         * less than or equal to {@code other}, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool lte(float other) {
+            return new ComparisonFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_LESS_THAN_OR_EQUAL_TO)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} is
+         * greater than {@code other}, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool gt(@NonNull DynamicFloat other) {
+            return new ComparisonFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_GREATER_THAN)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} is
+         * greater than {@code other}, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool gt(float other) {
+            return new ComparisonFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_GREATER_THAN)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} is
+         * greater than or equal to {@code other}, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool gte(@NonNull DynamicFloat other) {
+            return new ComparisonFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(other)
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_GREATER_THAN_OR_EQUAL_TO)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicFloat} is
+         * greater than or equal to {@code other}, otherwise it's false.
+         */
+        @NonNull
+        default DynamicBool gte(float other) {
+            return new ComparisonFloatOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(constant(other))
+                    .setOperationType(DynamicBuilders.COMPARISON_OP_TYPE_GREATER_THAN_OR_EQUAL_TO)
+                    .build();
+        }
+
+        /**
+         * Bind the value of this {@link DynamicFloat} to the result of a conditional expression.
+         * This will use the value given in either {@link ConditionScope#use} or {@link
+         * ConditionScopes.IfTrueScope#elseUse} depending on the value yielded from {@code
+         * condition}.
+         */
+        @NonNull
+        static ConditionScope<DynamicFloat, Float> onCondition(@NonNull DynamicBool condition) {
+            return new ConditionScopes.ConditionScope<>(
+                    (trueValue, falseValue) ->
+                            new ConditionalFloatOp.Builder()
+                                    .setCondition(condition)
+                                    .setValueIfTrue(trueValue)
+                                    .setValueIfFalse(falseValue)
+                                    .build(),
+                    DynamicFloat::constant);
+        }
+
+        /**
+         * Returns a {@link DynamicString} that contains the formatted value of this {@link
+         * DynamicFloat} (with default formatting parameters). As an example, in the English locale,
+         * the following is equal to {@code DynamicString.constant("12.346")}
+         *
+         * <pre>
+         *   DynamicFloat.constant(12.34567f).format();
+         * </pre>
+         */
+        @NonNull
+        default DynamicString format() {
+            return FloatFormatter.with().buildForInput(this);
+        }
+
+        /**
+         * Returns a {@link DynamicString} that contains the formatted value of this {@link
+         * DynamicFloat}. As an example, in the English locale, the following is equal to {@code
+         * DynamicString.constant("0,012.34")}
+         *
+         * <pre>
+         *   DynamicFloat.constant(12.345f)
+         *       .format(
+         *           FloatFormatter.with().maxFractionDigits(2).minIntegerDigits(4)
+         *                         .groupingUsed(true));
+         * </pre>
+         *
+         * @param formatter The formatting parameter.
+         */
+        @NonNull
+        default DynamicString format(@NonNull FloatFormatter formatter) {
+            return formatter.buildForInput(this);
+        }
+
+        /** Allows formatting {@link DynamicFloat} into a {@link DynamicString}. */
+        class FloatFormatter {
+            private final FloatFormatOp.Builder builder;
+
+            private FloatFormatter() {
+                builder = new FloatFormatOp.Builder();
+            }
+
+            /** Creates an instance of {@link FloatFormatter} with default configuration. */
+            @NonNull
+            public static FloatFormatter with() {
+                return new FloatFormatter();
+            }
+
+            /**
+             * Sets minimum number of fraction digits for the formatter. Defaults to zero if not
+             * specified. minimumFractionDigits must be <= maximumFractionDigits. If the condition
+             * is not satisfied, then minimumFractionDigits will be used for both fields.
+             */
+            @NonNull
+            public FloatFormatter minFractionDigits(@IntRange(from = 0) int minFractionDigits) {
+                builder.setMinFractionDigits(minFractionDigits);
+                return this;
+            }
+
+            /**
+             * Sets maximum number of fraction digits for the formatter. Defaults to three if not
+             * specified. minimumFractionDigits must be <= maximumFractionDigits. If the condition
+             * is not satisfied, then minimumFractionDigits will be used for both fields.
+             */
+            @NonNull
+            public FloatFormatter maxFractionDigits(@IntRange(from = 0) int maxFractionDigits) {
+                builder.setMaxFractionDigits(maxFractionDigits);
+                return this;
+            }
+
+            /**
+             * Sets minimum number of integer digits for the formatter. Defaults to one if not
+             * specified.
+             */
+            @NonNull
+            public FloatFormatter minIntegerDigits(@IntRange(from = 0) int minIntegerDigits) {
+                builder.setMinIntegerDigits(minIntegerDigits);
+                return this;
+            }
+
+            /**
+             * Sets whether grouping is used for the formatter. Defaults to false if not specified.
+             */
+            @NonNull
+            public FloatFormatter groupingUsed(boolean groupingUsed) {
+                builder.setGroupingUsed(groupingUsed);
+                return this;
+            }
+
+            @NonNull
+            FloatFormatOp buildForInput(@NonNull DynamicFloat dynamicFloat) {
+                return builder.setInput(dynamicFloat).build();
+            }
+        }
+
+        /** Get the fingerprint for this object or null if unknown. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        Fingerprint getFingerprint();
+
+        /** Builder to create {@link DynamicFloat} objects. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        interface Builder {
+
+            /** Builds an instance with values accumulated in this Builder. */
+            @NonNull
+            DynamicFloat build();
+        }
     }
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static AnimatableDynamicColor fromProto(@NonNull DynamicProto.AnimatableDynamicColor proto) {
-      return new AnimatableDynamicColor(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.AnimatableDynamicColor toProto() {
-      return mImpl;
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicColor toDynamicColorProto() {
-      return DynamicProto.DynamicColor.newBuilder().setAnimatableDynamic(mImpl).build();
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-      return "AnimatableDynamicColor{"
-          + "input="
-          + getInput()
-          + ", animationSpec="
-          + getAnimationSpec()
-          + "}";
-    }
-
-    /** Builder for {@link AnimatableDynamicColor}. */
-    public static final class Builder implements DynamicColor.Builder {
-      private final DynamicProto.AnimatableDynamicColor.Builder mImpl =
-          DynamicProto.AnimatableDynamicColor.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-193597422);
-
-      public Builder() {}
-
-      /**
-       * Sets the value to watch, and animate when it changes.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInput(@NonNull DynamicColor input) {
-        mImpl.setInput(input.toDynamicColorProto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      /**
-       * Sets the animation parameters for duration, delay, etc.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
-        mImpl.setAnimationSpec(animationSpec.toProto());
-        mFingerprint.recordPropertyUpdate(
-            3, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
-
-      @Override
-      @NonNull
-      public AnimatableDynamicColor build() {
-        return new AnimatableDynamicColor(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * Interface defining a dynamic color type.
-   *
-   * @since 1.2
-   */
-  public interface DynamicColor extends DynamicType {
     /**
-     * Get the protocol buffer representation of this object.
-     *
+     * Creates a new wrapper instance from the proto. Intended for testing purposes only. An object
+     * created using this method can't be added to any other wrapper.
      */
     @RestrictTo(Scope.LIBRARY_GROUP)
     @NonNull
-    DynamicProto.DynamicColor toDynamicColorProto();
-
-    /**
-     * Creates a {@link DynamicColor} from a byte array generated by {@link
-     * #toDynamicColorByteArray()}.
-     */
-    @NonNull
-    static DynamicColor fromByteArray(@NonNull byte[] byteArray) {
-      try {
-        return dynamicColorFromProto(
-            DynamicProto.DynamicColor.parseFrom(
-                byteArray, ExtensionRegistryLite.getEmptyRegistry()));
-      } catch (InvalidProtocolBufferException e) {
-        throw new IllegalArgumentException("Byte array could not be parsed into DynamicColor", e);
-      }
-    }
-
-    /** Creates a byte array that can later be used with {@link #fromByteArray(byte[])}. */
-    @NonNull
-    default byte[] toDynamicColorByteArray() {
-      return toDynamicColorProto().toByteArray();
-    }
-
-    /** Creates a constant-valued {@link DynamicColor}. */
-    @NonNull
-    static DynamicColor constant(@ColorInt int constant) {
-      return new FixedColor.Builder().setArgb(constant).build();
+    public static DynamicFloat dynamicFloatFromProto(@NonNull DynamicProto.DynamicFloat proto) {
+        if (proto.hasFixed()) {
+            return FixedFloat.fromProto(proto.getFixed());
+        }
+        if (proto.hasArithmeticOperation()) {
+            return ArithmeticFloatOp.fromProto(proto.getArithmeticOperation());
+        }
+        if (proto.hasInt32ToFloatOperation()) {
+            return Int32ToFloatOp.fromProto(proto.getInt32ToFloatOperation());
+        }
+        if (proto.hasStateSource()) {
+            return StateFloatSource.fromProto(proto.getStateSource());
+        }
+        if (proto.hasConditionalOp()) {
+            return ConditionalFloatOp.fromProto(proto.getConditionalOp());
+        }
+        if (proto.hasAnimatableFixed()) {
+            return AnimatableFixedFloat.fromProto(proto.getAnimatableFixed());
+        }
+        if (proto.hasAnimatableDynamic()) {
+            return AnimatableDynamicFloat.fromProto(proto.getAnimatableDynamic());
+        }
+        throw new IllegalStateException("Proto was not a recognised instance of DynamicFloat");
     }
 
     /**
-     * Creates a {@link DynamicColor} that is bound to the value of an item of the State.
-     *
-     * @param stateKey The key to a {@link StateEntryValue} with a color value from the provider's
-     *     state.
-     */
-    @NonNull
-    static DynamicColor fromState(@NonNull String stateKey) {
-      return new StateColorSource.Builder().setSourceKey(stateKey).build();
-    }
-
-    /**
-     * Creates a {@link DynamicColor} which will animate over the range of colors from {@code start}
-     * to {@code end}.
-     *
-     * @param start The start value of the range.
-     * @param end The end value of the range.
-     */
-    @NonNull
-    static DynamicColor animate(@ColorInt int start, @ColorInt int end) {
-      return new AnimatableFixedColor.Builder().setFromArgb(start).setToArgb(end).build();
-    }
-
-    /**
-     * Creates a {@link DynamicColor} which will animate over the range of colors from {@code start}
-     * to {@code end} with the given animation parameters.
-     *
-     * @param start The start value of the range.
-     * @param end The end value of the range.
-     * @param animationSpec The animation parameters.
-     */
-    @NonNull
-    static DynamicColor animate(
-        @ColorInt int start, @ColorInt int end, @NonNull AnimationSpec animationSpec) {
-      return new AnimatableFixedColor.Builder()
-          .setFromArgb(start)
-          .setToArgb(end)
-          .setAnimationSpec(animationSpec)
-          .build();
-    }
-
-    /**
-     * Creates a {@link DynamicColor} that is bound to the value of an item of the State. Every time
-     * the state value changes, this {@link DynamicColor} will animate from its current value to the
-     * new value (from the state).
-     *
-     * @param stateKey The key to a {@link StateEntryValue} with a color value from the provider's
-     *     state.
-     */
-    @NonNull
-    static DynamicColor animate(@NonNull String stateKey) {
-      return new AnimatableDynamicColor.Builder().setInput(fromState(stateKey)).build();
-    }
-
-    /**
-     * Creates a {@link DynamicColor} that is bound to the value of an item of the State. Every time
-     * the state value changes, this {@link DynamicColor} will animate from its current value to the
-     * new value (from the state).
-     *
-     * @param stateKey The key to a {@link StateEntryValue} with a color value from the provider's
-     *     state.
-     * @param animationSpec The animation parameters.
-     */
-    @NonNull
-    static DynamicColor animate(@NonNull String stateKey, @NonNull AnimationSpec animationSpec) {
-      return new AnimatableDynamicColor.Builder()
-          .setInput(fromState(stateKey))
-          .setAnimationSpec(animationSpec)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicColor} that is bound to the value of this {@link DynamicColor} and
-     * every time its value is changing, it animates from its current value to the new value.
-     *
-     * @param animationSpec The animation parameters.
-     */
-    @NonNull
-    default DynamicColor animate(@NonNull AnimationSpec animationSpec) {
-      return new AnimatableDynamicColor.Builder()
-          .setInput(this)
-          .setAnimationSpec(animationSpec)
-          .build();
-    }
-
-    /**
-     * Returns a {@link DynamicColor} that is bound to the value of this {@link DynamicColor} and
-     * every time its value is changing, it animates from its current value to the new value.
-     */
-    @NonNull
-    default DynamicColor animate() {
-      return new AnimatableDynamicColor.Builder().setInput(this).build();
-    }
-
-    /**
-     * Get the fingerprint for this object or null if unknown.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    Fingerprint getFingerprint();
-
-    /**
-     * Builder to create {@link DynamicColor} objects.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    interface Builder {
-
-      /** Builds an instance with values accumulated in this Builder. */
-      @NonNull
-      DynamicColor build();
-    }
-  }
-
-  /**
-   * Creates a new wrapper instance from the proto. Intended for testing purposes only. An object
-   * created using this method can't be added to any other wrapper.
-   *
-   */
-  @RestrictTo(Scope.LIBRARY_GROUP)
-  @NonNull
-  public static DynamicColor dynamicColorFromProto(@NonNull DynamicProto.DynamicColor proto) {
-    if (proto.hasFixed()) {
-      return FixedColor.fromProto(proto.getFixed());
-    }
-    if (proto.hasStateSource()) {
-      return StateColorSource.fromProto(proto.getStateSource());
-    }
-    if (proto.hasAnimatableFixed()) {
-      return AnimatableFixedColor.fromProto(proto.getAnimatableFixed());
-    }
-    if (proto.hasAnimatableDynamic()) {
-      return AnimatableDynamicColor.fromProto(proto.getAnimatableDynamic());
-    }
-    throw new IllegalStateException("Proto was not a recognised instance of DynamicColor");
-  }
-
-  /**
-   * A dynamic time instant that sources its value from the platform.
-   *
-   * @since 1.2
-   */
-  static final class PlatformTimeSource implements DynamicInstant {
-    private final DynamicProto.PlatformTimeSource mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    PlatformTimeSource(DynamicProto.PlatformTimeSource impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
-
-    @NonNull
-    static PlatformTimeSource fromProto(@NonNull DynamicProto.PlatformTimeSource proto) {
-      return new PlatformTimeSource(proto, null);
-    }
-
-    @NonNull
-    DynamicProto.PlatformTimeSource toProto() {
-      return mImpl;
-    }
-
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicInstant toDynamicInstantProto() {
-      return DynamicProto.DynamicInstant.newBuilder().setPlatformSource(mImpl).build();
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-      return "PlatformTimeSource";
-    }
-
-    /** Builder for {@link PlatformTimeSource}. */
-    public static final class Builder implements DynamicInstant.Builder {
-      private final DynamicProto.PlatformTimeSource.Builder mImpl =
-          DynamicProto.PlatformTimeSource.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-1895976938);
-
-      public Builder() {}
-
-      @Override
-      @NonNull
-      public PlatformTimeSource build() {
-        return new PlatformTimeSource(mImpl.build(), mFingerprint);
-      }
-    }
-  }
-
-  /**
-   * Interface defining a dynamic time instant type.
-   *
-   * <p> {@link DynamicInstant} precision is seconds. Thus, any time or duration operation will
-   * operate on that precision level.
-   *
-   * @since 1.2
-   */
-  public interface DynamicInstant extends DynamicType {
-    /**
-     * Get the protocol buffer representation of this object.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    DynamicProto.DynamicInstant toDynamicInstantProto();
-
-    /**
-     * Creates a {@link DynamicInstant} from a byte array generated by {@link
-     * #toDynamicInstantByteArray()}.
-     */
-    @NonNull
-    static DynamicInstant fromByteArray(@NonNull byte[] byteArray) {
-      try {
-        return dynamicInstantFromProto(
-            DynamicProto.DynamicInstant.parseFrom(
-                byteArray, ExtensionRegistryLite.getEmptyRegistry()));
-      } catch (InvalidProtocolBufferException e) {
-        throw new IllegalArgumentException("Byte array could not be parsed into DynamicInstant", e);
-      }
-    }
-
-    /** Creates a byte array that can later be used with {@link #fromByteArray(byte[])}. */
-    @NonNull
-    default byte[] toDynamicInstantByteArray() {
-      return toDynamicInstantProto().toByteArray();
-    }
-
-
-    /**
-     * Creates a constant-valued {@link DynamicInstant} from an {@link Instant}. If {@link Instant}
-     * precision is greater than seconds, then any excess precision information will be dropped.
-     */
-    @NonNull
-    static DynamicInstant withSecondsPrecision(@NonNull Instant instant) {
-      return new FixedInstant.Builder().setEpochSeconds(instant.getEpochSecond()).build();
-    }
-
-    /**
-     * Creates a {@link DynamicInstant} that updates its value periodically from the system time.
-     */
-    @NonNull
-    static DynamicInstant platformTimeWithSecondsPrecision() {
-      return new PlatformTimeSource.Builder().build();
-    }
-
-    /**
-     * Returns duration between the two {@link DynamicInstant} instances as a {@link
-     * DynamicDuration}. The resulted duration is inclusive of the start instant and exclusive of
-     * the end; As an example, the following expression yields a duration object representing 10
-     * seconds:
-     *
-     * <pre>
-     *   DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(10L))
-     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(20L)));
-     * </pre>
-     *
-     * @return a new instance of {@link DynamicDuration} containing the result of the operation.
-     */
-    @NonNull
-    default DynamicDuration durationUntil(@NonNull DynamicInstant to) {
-      return new BetweenDuration.Builder().setStartInclusive(this).setEndExclusive(to).build();
-    }
-
-    /**
-     * Get the fingerprint for this object or null if unknown.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    Fingerprint getFingerprint();
-
-    /**
-     * Builder to create {@link DynamicInstant} objects.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    interface Builder {
-
-      /** Builds an instance with values accumulated in this Builder. */
-      @NonNull
-      DynamicInstant build();
-    }
-  }
-
-  /**
-   * Creates a new wrapper instance from the proto. Intended for testing purposes only. An object
-   * created using this method can't be added to any other wrapper.
-   *
-   */
-  @RestrictTo(Scope.LIBRARY_GROUP)
-  @NonNull
-  public static DynamicInstant dynamicInstantFromProto(@NonNull DynamicProto.DynamicInstant proto) {
-    if (proto.hasFixed()) {
-      return FixedInstant.fromProto(proto.getFixed());
-    }
-    if (proto.hasPlatformSource()) {
-      return PlatformTimeSource.fromProto(proto.getPlatformSource());
-    }
-    throw new IllegalStateException("Proto was not a recognised instance of DynamicInstant");
-  }
-
-  /**
-   * A dynamic duration type that represents the duration between two dynamic time instants.
-   *
-   * @since 1.2
-   */
-  static final class BetweenDuration implements DynamicDuration {
-    private final DynamicProto.BetweenDuration mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    BetweenDuration(DynamicProto.BetweenDuration impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
-
-    /**
-     * Gets the time instant value marking the start of the duration.
+     * A dynamic boolean type which sources its data from the tile's state.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicInstant getStartInclusive() {
-      if (mImpl.hasStartInclusive()) {
-        return DynamicBuilders.dynamicInstantFromProto(mImpl.getStartInclusive());
-      } else {
-        return null;
-      }
+    static final class StateBoolSource implements DynamicBool {
+        private final DynamicProto.StateBoolSource mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        StateBoolSource(DynamicProto.StateBoolSource impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the key in the state to bind to.
+         *
+         * @since 1.2
+         */
+        @NonNull
+        public String getSourceKey() {
+            return mImpl.getSourceKey();
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static StateBoolSource fromProto(@NonNull DynamicProto.StateBoolSource proto) {
+            return new StateBoolSource(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.StateBoolSource toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicBool toDynamicBoolProto() {
+            return DynamicProto.DynamicBool.newBuilder().setStateSource(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "StateBoolSource{" + "sourceKey=" + getSourceKey() + "}";
+        }
+
+        /** Builder for {@link StateBoolSource}. */
+        public static final class Builder implements DynamicBool.Builder {
+
+            private final DynamicProto.StateBoolSource.Builder mImpl =
+                    DynamicProto.StateBoolSource.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(1818702779);
+
+            public Builder() {}
+
+            /**
+             * Sets the key in the state to bind to.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setSourceKey(@NonNull String sourceKey) {
+                mImpl.setSourceKey(sourceKey);
+                mFingerprint.recordPropertyUpdate(1, sourceKey.hashCode());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public StateBoolSource build() {
+                return new StateBoolSource(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the time instant value marking the end of the duration.
+     * A comparison operation, operating on two Int32 instances. This implements various comparison
+     * operations of the form "boolean result = LHS <op> RHS", where the available operation types
+     * are described in {@code ComparisonOpType}.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicInstant getEndExclusive() {
-      if (mImpl.hasEndExclusive()) {
-        return DynamicBuilders.dynamicInstantFromProto(mImpl.getEndExclusive());
-      } else {
-        return null;
-      }
-    }
+    static final class ComparisonInt32Op implements DynamicBool {
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
-    }
+        private final DynamicProto.ComparisonInt32Op mImpl;
+        @Nullable private final Fingerprint mFingerprint;
 
-    @NonNull
-    static BetweenDuration fromProto(@NonNull DynamicProto.BetweenDuration proto) {
-      return new BetweenDuration(proto, null);
-    }
+        ComparisonInt32Op(DynamicProto.ComparisonInt32Op impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
 
-    @NonNull
-    DynamicProto.BetweenDuration toProto() {
-      return mImpl;
-    }
+        /**
+         * Gets the left hand side of the comparison operation.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicInt32 getInputLhs() {
+            if (mImpl.hasInputLhs()) {
+                return DynamicBuilders.dynamicInt32FromProto(mImpl.getInputLhs());
+            } else {
+                return null;
+            }
+        }
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    public DynamicProto.DynamicDuration toDynamicDurationProto() {
-      return DynamicProto.DynamicDuration.newBuilder().setBetween(mImpl).build();
-    }
+        /**
+         * Gets the right hand side of the comparison operation.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicInt32 getInputRhs() {
+            if (mImpl.hasInputRhs()) {
+                return DynamicBuilders.dynamicInt32FromProto(mImpl.getInputRhs());
+            } else {
+                return null;
+            }
+        }
 
-    @Override
-    @NonNull
-    public String toString() {
-      return "BetweenDuration{"
-          + "startInclusive="
-          + getStartInclusive()
-          + ", endExclusive="
-          + getEndExclusive()
-          + "}";
-    }
+        /**
+         * Gets the type of the operation.
+         *
+         * @since 1.2
+         */
+        @ComparisonOpType
+        public int getOperationType() {
+            return mImpl.getOperationType().getNumber();
+        }
 
-    /** Builder for {@link BetweenDuration}. */
-    public static final class Builder implements DynamicDuration.Builder {
-      private final DynamicProto.BetweenDuration.Builder mImpl =
-          DynamicProto.BetweenDuration.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-1615230958);
+        /** */
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
 
-      public Builder() {}
+        @NonNull
+        static ComparisonInt32Op fromProto(@NonNull DynamicProto.ComparisonInt32Op proto) {
+            return new ComparisonInt32Op(proto, null);
+        }
 
-      /**
-       * Sets the time instant value marking the start of the duration.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setStartInclusive(@NonNull DynamicInstant startInclusive) {
-        mImpl.setStartInclusive(startInclusive.toDynamicInstantProto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(startInclusive.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
+        @NonNull
+        DynamicProto.ComparisonInt32Op toProto() {
+            return mImpl;
+        }
 
-      /**
-       * Sets the time instant value marking the end of the duration.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setEndExclusive(@NonNull DynamicInstant endExclusive) {
-        mImpl.setEndExclusive(endExclusive.toDynamicInstantProto());
-        mFingerprint.recordPropertyUpdate(
-            2, checkNotNull(endExclusive.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
+        /** */
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicBool toDynamicBoolProto() {
+            return DynamicProto.DynamicBool.newBuilder().setInt32Comparison(mImpl).build();
+        }
 
-      @Override
-      @NonNull
-      public BetweenDuration build() {
-        return new BetweenDuration(mImpl.build(), mFingerprint);
-      }
-    }
-  }
+        /** Builder for {@link ComparisonInt32Op}. */
+        public static final class Builder implements DynamicBool.Builder {
 
-  /**
-   * Interface defining a dynamic duration type.
-   *
-   * @since 1.2
-   */
-  public interface DynamicDuration extends DynamicType {
-    /**
-     * Get the protocol buffer representation of this object.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @NonNull
-    DynamicProto.DynamicDuration toDynamicDurationProto();
+            private final DynamicProto.ComparisonInt32Op.Builder mImpl =
+                    DynamicProto.ComparisonInt32Op.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(-1112207999);
 
-    /**
-     * Creates a {@link DynamicDuration} from a byte array generated by {@link
-     * #toDynamicDurationByteArray()}.
-     */
-    @NonNull
-    static DynamicDuration fromByteArray(@NonNull byte[] byteArray) {
-      try {
-        return dynamicDurationFromProto(
-            DynamicProto.DynamicDuration.parseFrom(
-                byteArray, ExtensionRegistryLite.getEmptyRegistry()));
-      } catch (InvalidProtocolBufferException e) {
-        throw new IllegalArgumentException(
-            "Byte array could not be parsed into DynamicDuration", e);
-      }
-    }
+            public Builder() {}
 
-    /** Creates a byte array that can later be used with {@link #fromByteArray(byte[])}. */
-    @NonNull
-    default byte[] toDynamicDurationByteArray() {
-      return toDynamicDurationProto().toByteArray();
-    }
+            /**
+             * Sets the left hand side of the comparison operation.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInputLhs(@NonNull DynamicInt32 inputLhs) {
+                mImpl.setInputLhs(inputLhs.toDynamicInt32Proto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(inputLhs.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
 
+            /**
+             * Sets the right hand side of the comparison operation.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInputRhs(@NonNull DynamicInt32 inputRhs) {
+                mImpl.setInputRhs(inputRhs.toDynamicInt32Proto());
+                mFingerprint.recordPropertyUpdate(
+                        2, checkNotNull(inputRhs.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
 
-    /**
-     * Returns the total number of days in a {@link DynamicDuration} as a {@link DynamicInt32}. The
-     * fraction part of the result will be truncated. This is based on the standard definition of a
-     * day as 24 hours. As an example, the following is equal to {@code DynamicInt32.constant(1)}
-     *
-     * <pre>
-     *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
-     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
-     *      .toIntDays();
-     * </pre>
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     *     Integer overflow can occur if the result of the operation is larger than {@link
-     *     Integer#MAX_VALUE}.
-     */
-    @NonNull
-    default DynamicInt32 toIntDays() {
-      return new GetDurationPartOp.Builder()
-          .setInput(this)
-          .setDurationPart(DURATION_PART_TYPE_TOTAL_DAYS)
-          .build();
+            /**
+             * Sets the type of the operation.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setOperationType(@ComparisonOpType int operationType) {
+                mImpl.setOperationType(DynamicProto.ComparisonOpType.forNumber(operationType));
+                mFingerprint.recordPropertyUpdate(3, operationType);
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public ComparisonInt32Op build() {
+                return new ComparisonInt32Op(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Returns the total number of hours in a {@link DynamicDuration} as a {@link DynamicInt32}. The
-     * fraction part of the result will be truncated. As an example, the following is equal to
-     * {@code DynamicInt32.constant(34)}
-     *
-     * <pre>
-     *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
-     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
-     *      .toIntHours();
-     * </pre>
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     *     Integer overflow can occur if the result of the operation is larger than {@link
-     *     Integer#MAX_VALUE}.
-     */
-    @NonNull
-    default DynamicInt32 toIntHours() {
-      return new GetDurationPartOp.Builder()
-          .setInput(this)
-          .setDurationPart(DURATION_PART_TYPE_TOTAL_HOURS)
-          .build();
-    }
-
-    /**
-     * Returns the total number of minutes in a {@link DynamicDuration} as a {@link DynamicInt32}.
-     * The fraction part of the result will be truncated. As an example, the following is equal to
-     * {@code DynamicInt32.constant(2057)}
-     *
-     * <pre>
-     *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
-     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
-     *      .toIntMinutes();
-     * </pre>
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     *     Integer overflow can occur if the result of the operation is larger than {@link
-     *     Integer#MAX_VALUE}.
-     */
-    @NonNull
-    default DynamicInt32 toIntMinutes() {
-      return new GetDurationPartOp.Builder()
-          .setInput(this)
-          .setDurationPart(DURATION_PART_TYPE_TOTAL_MINUTES)
-          .build();
-    }
-
-    /**
-     * Returns the total number of seconds in a {@link DynamicDuration} as a {@link DynamicInt32}.
-     * As an example, the following is equal to {@code DynamicInt32.constant(123456)}
-     *
-     * <pre>
-     *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
-     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
-     *      .toIntSeconds();
-     * </pre>
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     *     Integer overflow can occur if the result of the operation is larger than {@link
-     *     Integer#MAX_VALUE}.
-     */
-    @NonNull
-    default DynamicInt32 toIntSeconds() {
-      return new GetDurationPartOp.Builder()
-          .setInput(this)
-          .setDurationPart(DURATION_PART_TYPE_TOTAL_SECONDS)
-          .build();
-    }
-
-    /**
-     * Returns the total number of days in a duration as a {@link DynamicInt32}. This represents the
-     * absolute value of the total number of days in the duration based on the 24 hours day
-     * definition. The fraction part of the result will be truncated; As an example, the following
-     * is equal to {@code DynamicInt32.constant(1)}
-     *
-     * <pre>
-     *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
-     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
-     *      .getIntDaysPart();
-     * </pre>
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     *     Integer overflow can occur if the result of the operation is larger than {@link
-     *     Integer#MAX_VALUE}.
-     */
-    @NonNull
-    default DynamicInt32 getIntDaysPart() {
-      return new GetDurationPartOp.Builder()
-          .setInput(this)
-          .setDurationPart(DURATION_PART_TYPE_DAYS)
-          .build();
-    }
-
-    /**
-     * Returns the number of hours part in the duration as a {@link DynamicInt32}. This represents
-     * the absolute value of remaining hours when dividing total hours by hours in a day (24 hours);
-     * As an example, the following is equal to {@code DynamicInt32.constant(10)}
-     *
-     * <pre>
-     *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
-     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
-     *      .getHoursPart();
-     * </pre>
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     */
-    @NonNull
-    default DynamicInt32 getHoursPart() {
-      return new GetDurationPartOp.Builder()
-          .setInput(this)
-          .setDurationPart(DURATION_PART_TYPE_HOURS)
-          .build();
-    }
-
-    /**
-     * Returns the number of minutes part in the duration as a {@link DynamicInt32}. This represents
-     * the absolute value of remaining minutes when dividing total minutes by minutes in an hour (60
-     * minutes). As an example, the following is equal to {@code DynamicInt32.constant(17)}
-     *
-     * <pre>
-     *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
-     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
-     *      .getMinutesPart();
-     * </pre>
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     */
-    @NonNull
-    default DynamicInt32 getMinutesPart() {
-      return new GetDurationPartOp.Builder()
-          .setInput(this)
-          .setDurationPart(DURATION_PART_TYPE_MINUTES)
-          .build();
-    }
-
-    /**
-     * Returns the number of seconds part in the duration as a {@link DynamicInt32}. This represents
-     * the absolute value of remaining seconds when dividing total seconds by seconds in a minute
-     * (60 seconds); As an example, the following is equal to {@code DynamicInt32.constant(36)}
-     *
-     * <pre>
-     *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
-     *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
-     *      .getSecondsPart();
-     * </pre>
-     *
-     * @return a new instance of {@link DynamicInt32} containing the result of the operation.
-     */
-    @NonNull
-    default DynamicInt32 getSecondsPart() {
-      return new GetDurationPartOp.Builder()
-          .setInput(this)
-          .setDurationPart(DURATION_PART_TYPE_SECONDS)
-          .build();
-    }
-
-    /**
-     * Get the fingerprint for this object or null if unknown.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    Fingerprint getFingerprint();
-
-    /**
-     * Builder to create {@link DynamicDuration} objects.
-     *
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    interface Builder {
-
-      /** Builds an instance with values accumulated in this Builder. */
-      @NonNull
-      DynamicDuration build();
-    }
-  }
-
-  /**
-   * Creates a new wrapper instance from the proto. Intended for testing purposes only. An object
-   * created using this method can't be added to any other wrapper.
-   *
-   */
-  @RestrictTo(Scope.LIBRARY_GROUP)
-  @NonNull
-  public static DynamicDuration dynamicDurationFromProto(
-      @NonNull DynamicProto.DynamicDuration proto) {
-    if (proto.hasBetween()) {
-      return BetweenDuration.fromProto(proto.getBetween());
-    }
-    throw new IllegalStateException("Proto was not a recognised instance of DynamicDuration");
-  }
-
-  /**
-   * Retrieve the specified duration part of a {@link DynamicDuration} instance as a {@link
-   * DynamicInt32}.
-   *
-   * @since 1.2
-   */
-  static final class GetDurationPartOp implements DynamicInt32 {
-    private final DynamicProto.GetDurationPartOp mImpl;
-    @Nullable private final Fingerprint mFingerprint;
-
-    GetDurationPartOp(DynamicProto.GetDurationPartOp impl, @Nullable Fingerprint fingerprint) {
-      this.mImpl = impl;
-      this.mFingerprint = fingerprint;
-    }
-
-    /**
-     * Gets the duration input.
+     * A comparison operation, operating on two Float instances. This implements various comparison
+     * operations of the form "boolean result = LHS <op> RHS", where the available operation types
+     * are described in {@code ComparisonOpType}.
      *
      * @since 1.2
      */
-    @Nullable
-    public DynamicDuration getInput() {
-      if (mImpl.hasInput()) {
-        return DynamicBuilders.dynamicDurationFromProto(mImpl.getInput());
-      } else {
-        return null;
-      }
+    static final class ComparisonFloatOp implements DynamicBool {
+
+        private final DynamicProto.ComparisonFloatOp mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        ComparisonFloatOp(DynamicProto.ComparisonFloatOp impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the left hand side of the comparison operation.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicFloat getInputLhs() {
+            if (mImpl.hasInputLhs()) {
+                return DynamicBuilders.dynamicFloatFromProto(mImpl.getInputLhs());
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets the right hand side of the comparison operation.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicFloat getInputRhs() {
+            if (mImpl.hasInputRhs()) {
+                return DynamicBuilders.dynamicFloatFromProto(mImpl.getInputRhs());
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets the type of the operation.
+         *
+         * @since 1.2
+         */
+        @ComparisonOpType
+        public int getOperationType() {
+            return mImpl.getOperationType().getNumber();
+        }
+
+        /** */
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static ComparisonFloatOp fromProto(@NonNull DynamicProto.ComparisonFloatOp proto) {
+            return new ComparisonFloatOp(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.ComparisonFloatOp toProto() {
+            return mImpl;
+        }
+
+        /** */
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicBool toDynamicBoolProto() {
+            return DynamicProto.DynamicBool.newBuilder().setFloatComparison(mImpl).build();
+        }
+
+        /** Builder for {@link ComparisonFloatOp}. */
+        public static final class Builder implements DynamicBool.Builder {
+
+            private final DynamicProto.ComparisonFloatOp.Builder mImpl =
+                    DynamicProto.ComparisonFloatOp.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(-1679565270);
+
+            public Builder() {}
+
+            /**
+             * Sets the left hand side of the comparison operation.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInputLhs(@NonNull DynamicFloat inputLhs) {
+                mImpl.setInputLhs(inputLhs.toDynamicFloatProto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(inputLhs.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the right hand side of the comparison operation.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInputRhs(@NonNull DynamicFloat inputRhs) {
+                mImpl.setInputRhs(inputRhs.toDynamicFloatProto());
+                mFingerprint.recordPropertyUpdate(
+                        2, checkNotNull(inputRhs.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the type of the operation.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setOperationType(@ComparisonOpType int operationType) {
+                mImpl.setOperationType(DynamicProto.ComparisonOpType.forNumber(operationType));
+                mFingerprint.recordPropertyUpdate(3, operationType);
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public ComparisonFloatOp build() {
+                return new ComparisonFloatOp(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
     /**
-     * Gets the duration part to retrieve.
+     * A boolean operation which implements a "NOT" operator, i.e. "boolean result = !input".
      *
      * @since 1.2
      */
-    @DurationPartType
-    public int getDurationPart() {
-      return mImpl.getDurationPart().getNumber();
+    static final class NotBoolOp implements DynamicBool {
+        private final DynamicProto.NotBoolOp mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        NotBoolOp(DynamicProto.NotBoolOp impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the input, whose value to negate.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicBool getInput() {
+            if (mImpl.hasInput()) {
+                return DynamicBuilders.dynamicBoolFromProto(mImpl.getInput());
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static NotBoolOp fromProto(@NonNull DynamicProto.NotBoolOp proto) {
+            return new NotBoolOp(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.NotBoolOp toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicBool toDynamicBoolProto() {
+            return DynamicProto.DynamicBool.newBuilder().setNotOp(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "NotBoolOp{" + "input=" + getInput() + "}";
+        }
+
+        /** Builder for {@link NotBoolOp}. */
+        public static final class Builder implements DynamicBool.Builder {
+            private final DynamicProto.NotBoolOp.Builder mImpl =
+                    DynamicProto.NotBoolOp.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(91300638);
+
+            public Builder() {}
+
+            /**
+             * Sets the input, whose value to negate.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInput(@NonNull DynamicBool input) {
+                mImpl.setInput(input.toDynamicBoolProto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public NotBoolOp build() {
+                return new NotBoolOp(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
-    @Override
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Nullable
-    public Fingerprint getFingerprint() {
-      return mFingerprint;
+    /**
+     * A logical boolean operator, implementing "boolean result = LHS <op> RHS", for various boolean
+     * operators (i.e. AND/OR).
+     *
+     * @since 1.2
+     */
+    static final class LogicalBoolOp implements DynamicBool {
+        private final DynamicProto.LogicalBoolOp mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        LogicalBoolOp(DynamicProto.LogicalBoolOp impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the left hand side of the logical operation.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicBool getInputLhs() {
+            if (mImpl.hasInputLhs()) {
+                return DynamicBuilders.dynamicBoolFromProto(mImpl.getInputLhs());
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets the right hand side of the logical operation.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicBool getInputRhs() {
+            if (mImpl.hasInputRhs()) {
+                return DynamicBuilders.dynamicBoolFromProto(mImpl.getInputRhs());
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets the operation type to apply to LHS/RHS.
+         *
+         * @since 1.2
+         */
+        @LogicalOpType
+        public int getOperationType() {
+            return mImpl.getOperationType().getNumber();
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static LogicalBoolOp fromProto(@NonNull DynamicProto.LogicalBoolOp proto) {
+            return new LogicalBoolOp(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.LogicalBoolOp toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicBool toDynamicBoolProto() {
+            return DynamicProto.DynamicBool.newBuilder().setLogicalOp(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "LogicalBoolOp{"
+                    + "inputLhs="
+                    + getInputLhs()
+                    + ", inputRhs="
+                    + getInputRhs()
+                    + ", operationType="
+                    + getOperationType()
+                    + "}";
+        }
+
+        /** Builder for {@link LogicalBoolOp}. */
+        public static final class Builder implements DynamicBool.Builder {
+            private final DynamicProto.LogicalBoolOp.Builder mImpl =
+                    DynamicProto.LogicalBoolOp.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(1067523409);
+
+            public Builder() {}
+
+            /**
+             * Sets the left hand side of the logical operation.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInputLhs(@NonNull DynamicBool inputLhs) {
+                mImpl.setInputLhs(inputLhs.toDynamicBoolProto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(inputLhs.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the right hand side of the logical operation.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInputRhs(@NonNull DynamicBool inputRhs) {
+                mImpl.setInputRhs(inputRhs.toDynamicBoolProto());
+                mFingerprint.recordPropertyUpdate(
+                        2, checkNotNull(inputRhs.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the operation type to apply to LHS/RHS.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setOperationType(@LogicalOpType int operationType) {
+                mImpl.setOperationType(DynamicProto.LogicalOpType.forNumber(operationType));
+                mFingerprint.recordPropertyUpdate(3, operationType);
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public LogicalBoolOp build() {
+                return new LogicalBoolOp(mImpl.build(), mFingerprint);
+            }
+        }
     }
 
-    @NonNull
-    static GetDurationPartOp fromProto(@NonNull DynamicProto.GetDurationPartOp proto) {
-      return new GetDurationPartOp(proto, null);
+    /**
+     * Interface defining a dynamic boolean type.
+     *
+     * @since 1.2
+     */
+    public interface DynamicBool extends DynamicType {
+        /** Get the protocol buffer representation of this object. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        DynamicProto.DynamicBool toDynamicBoolProto();
+
+        /**
+         * Creates a {@link DynamicBool} from a byte array generated by {@link
+         * #toDynamicBoolByteArray()}.
+         */
+        @NonNull
+        static DynamicBool fromByteArray(@NonNull byte[] byteArray) {
+            try {
+                return dynamicBoolFromProto(
+                        DynamicProto.DynamicBool.parseFrom(
+                                byteArray, ExtensionRegistryLite.getEmptyRegistry()));
+            } catch (InvalidProtocolBufferException e) {
+                throw new IllegalArgumentException(
+                        "Byte array could not be parsed into DynamicBool", e);
+            }
+        }
+
+        /** Creates a byte array that can later be used with {@link #fromByteArray(byte[])}. */
+        @NonNull
+        default byte[] toDynamicBoolByteArray() {
+            return toDynamicBoolProto().toByteArray();
+        }
+
+        /** Creates a constant-valued {@link DynamicBool}. */
+        @NonNull
+        static DynamicBool constant(boolean constant) {
+            return new FixedBool.Builder().setValue(constant).build();
+        }
+
+        /**
+         * Creates a {@link DynamicBool} that is bound to the value of an item of the State.
+         *
+         * @param stateKey The key to a {@link StateEntryValue} with a boolean value from the
+         *     provider's state.
+         */
+        @NonNull
+        static DynamicBool fromState(@NonNull String stateKey) {
+            return new StateBoolSource.Builder().setSourceKey(stateKey).build();
+        }
+
+        /** Returns a {@link DynamicBool} that has the same value as this {@link DynamicBool}. */
+        @NonNull
+        default DynamicBool isTrue() {
+            return this;
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that has the opposite value of this {@link DynamicBool}.
+         * i.e. {code result = !this}
+         */
+        @NonNull
+        default DynamicBool isFalse() {
+            return new NotBoolOp.Builder().setInput(this).build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if this {@link DynamicBool} and {@code input}
+         * are both true, otherwise it is false. i.e. {@code boolean result = this && input}
+         *
+         * @param input The right hand operand of the "and" operation.
+         */
+        @NonNull
+        default DynamicBool and(@NonNull DynamicBool input) {
+            return new LogicalBoolOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(input)
+                    .setOperationType(DynamicBuilders.LOGICAL_OP_TYPE_AND)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicBool} that is true if this {@link DynamicBool} or {@code input}
+         * are true, otherwise it is false. i.e. {@code boolean result = this || input}
+         *
+         * @param input The right hand operand of the "or" operation.
+         */
+        @NonNull
+        default DynamicBool or(@NonNull DynamicBool input) {
+            return new LogicalBoolOp.Builder()
+                    .setInputLhs(this)
+                    .setInputRhs(input)
+                    .setOperationType(DynamicBuilders.LOGICAL_OP_TYPE_OR)
+                    .build();
+        }
+
+        /** Get the fingerprint for this object or null if unknown. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        Fingerprint getFingerprint();
+
+        /** Builder to create {@link DynamicBool} objects. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        interface Builder {
+
+            /** Builds an instance with values accumulated in this Builder. */
+            @NonNull
+            DynamicBool build();
+        }
     }
 
-    @NonNull
-    DynamicProto.GetDurationPartOp toProto() {
-      return mImpl;
-    }
-
-    @Override
+    /**
+     * Creates a new wrapper instance from the proto. Intended for testing purposes only. An object
+     * created using this method can't be added to any other wrapper.
+     */
     @RestrictTo(Scope.LIBRARY_GROUP)
     @NonNull
-    public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
-      return DynamicProto.DynamicInt32.newBuilder().setDurationPart(mImpl).build();
+    public static DynamicBool dynamicBoolFromProto(@NonNull DynamicProto.DynamicBool proto) {
+        if (proto.hasFixed()) {
+            return FixedBool.fromProto(proto.getFixed());
+        }
+        if (proto.hasStateSource()) {
+            return StateBoolSource.fromProto(proto.getStateSource());
+        }
+        if (proto.hasInt32Comparison()) {
+            return ComparisonInt32Op.fromProto(proto.getInt32Comparison());
+        }
+        if (proto.hasNotOp()) {
+            return NotBoolOp.fromProto(proto.getNotOp());
+        }
+        if (proto.hasLogicalOp()) {
+            return LogicalBoolOp.fromProto(proto.getLogicalOp());
+        }
+        if (proto.hasFloatComparison()) {
+            return ComparisonFloatOp.fromProto(proto.getFloatComparison());
+        }
+        throw new IllegalStateException("Proto was not a recognised instance of DynamicBool");
     }
 
-    @Override
+    /**
+     * A dynamic Color which sources its data from the tile's state.
+     *
+     * @since 1.2
+     */
+    static final class StateColorSource implements DynamicColor {
+        private final DynamicProto.StateColorSource mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        StateColorSource(DynamicProto.StateColorSource impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the key in the state to bind to.
+         *
+         * @since 1.2
+         */
+        @NonNull
+        public String getSourceKey() {
+            return mImpl.getSourceKey();
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static StateColorSource fromProto(@NonNull DynamicProto.StateColorSource proto) {
+            return new StateColorSource(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.StateColorSource toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicColor toDynamicColorProto() {
+            return DynamicProto.DynamicColor.newBuilder().setStateSource(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "StateColorSource{" + "sourceKey=" + getSourceKey() + "}";
+        }
+
+        /** Builder for {@link StateColorSource}. */
+        public static final class Builder implements DynamicColor.Builder {
+            private final DynamicProto.StateColorSource.Builder mImpl =
+                    DynamicProto.StateColorSource.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(1981221690);
+
+            public Builder() {}
+
+            /**
+             * Sets the key in the state to bind to.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setSourceKey(@NonNull String sourceKey) {
+                mImpl.setSourceKey(sourceKey);
+                mFingerprint.recordPropertyUpdate(1, sourceKey.hashCode());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public StateColorSource build() {
+                return new StateColorSource(mImpl.build(), mFingerprint);
+            }
+        }
+    }
+
+    /**
+     * A static interpolation node, between two fixed color values.
+     *
+     * @since 1.2
+     */
+    static final class AnimatableFixedColor implements DynamicColor {
+        private final DynamicProto.AnimatableFixedColor mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        AnimatableFixedColor(
+                DynamicProto.AnimatableFixedColor impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the color value (in ARGB format) to start animating from.
+         *
+         * @since 1.2
+         */
+        @ColorInt
+        public int getFromArgb() {
+            return mImpl.getFromArgb();
+        }
+
+        /**
+         * Gets the color value (in ARGB format) to animate to.
+         *
+         * @since 1.2
+         */
+        @ColorInt
+        public int getToArgb() {
+            return mImpl.getToArgb();
+        }
+
+        /**
+         * Gets the animation parameters for duration, delay, etc.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public AnimationSpec getAnimationSpec() {
+            if (mImpl.hasAnimationSpec()) {
+                return AnimationSpec.fromProto(mImpl.getAnimationSpec());
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static AnimatableFixedColor fromProto(@NonNull DynamicProto.AnimatableFixedColor proto) {
+            return new AnimatableFixedColor(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.AnimatableFixedColor toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicColor toDynamicColorProto() {
+            return DynamicProto.DynamicColor.newBuilder().setAnimatableFixed(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "AnimatableFixedColor{"
+                    + "fromArgb="
+                    + getFromArgb()
+                    + ", toArgb="
+                    + getToArgb()
+                    + ", animationSpec="
+                    + getAnimationSpec()
+                    + "}";
+        }
+
+        /** Builder for {@link AnimatableFixedColor}. */
+        public static final class Builder implements DynamicColor.Builder {
+            private final DynamicProto.AnimatableFixedColor.Builder mImpl =
+                    DynamicProto.AnimatableFixedColor.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(2051778294);
+
+            public Builder() {}
+
+            /**
+             * Sets the color value (in ARGB format) to start animating from.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setFromArgb(@ColorInt int fromArgb) {
+                mImpl.setFromArgb(fromArgb);
+                mFingerprint.recordPropertyUpdate(1, fromArgb);
+                return this;
+            }
+
+            /**
+             * Sets the color value (in ARGB format) to animate to.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setToArgb(@ColorInt int toArgb) {
+                mImpl.setToArgb(toArgb);
+                mFingerprint.recordPropertyUpdate(2, toArgb);
+                return this;
+            }
+
+            /**
+             * Sets the animation parameters for duration, delay, etc.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
+                mImpl.setAnimationSpec(animationSpec.toProto());
+                mFingerprint.recordPropertyUpdate(
+                        3, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public AnimatableFixedColor build() {
+                return new AnimatableFixedColor(mImpl.build(), mFingerprint);
+            }
+        }
+    }
+
+    /**
+     * A dynamic interpolation node. This will watch the value of its input and, when the first
+     * update arrives, immediately emit that value. On subsequent updates, it will animate between
+     * the old and new values.
+     *
+     * <p>If this node receives an invalid value (e.g. as a result of an upstream node having no
+     * value), then it will emit a single invalid value, and forget its "stored" value. The next
+     * valid value that arrives is then used as the "first" value again.
+     *
+     * @since 1.2
+     */
+    static final class AnimatableDynamicColor implements DynamicColor {
+        private final DynamicProto.AnimatableDynamicColor mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        AnimatableDynamicColor(
+                DynamicProto.AnimatableDynamicColor impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the value to watch, and animate when it changes.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicColor getInput() {
+            if (mImpl.hasInput()) {
+                return DynamicBuilders.dynamicColorFromProto(mImpl.getInput());
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets the animation parameters for duration, delay, etc.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public AnimationSpec getAnimationSpec() {
+            if (mImpl.hasAnimationSpec()) {
+                return AnimationSpec.fromProto(mImpl.getAnimationSpec());
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static AnimatableDynamicColor fromProto(
+                @NonNull DynamicProto.AnimatableDynamicColor proto) {
+            return new AnimatableDynamicColor(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.AnimatableDynamicColor toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicColor toDynamicColorProto() {
+            return DynamicProto.DynamicColor.newBuilder().setAnimatableDynamic(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "AnimatableDynamicColor{"
+                    + "input="
+                    + getInput()
+                    + ", animationSpec="
+                    + getAnimationSpec()
+                    + "}";
+        }
+
+        /** Builder for {@link AnimatableDynamicColor}. */
+        public static final class Builder implements DynamicColor.Builder {
+            private final DynamicProto.AnimatableDynamicColor.Builder mImpl =
+                    DynamicProto.AnimatableDynamicColor.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(-193597422);
+
+            public Builder() {}
+
+            /**
+             * Sets the value to watch, and animate when it changes.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInput(@NonNull DynamicColor input) {
+                mImpl.setInput(input.toDynamicColorProto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the animation parameters for duration, delay, etc.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setAnimationSpec(@NonNull AnimationSpec animationSpec) {
+                mImpl.setAnimationSpec(animationSpec.toProto());
+                mFingerprint.recordPropertyUpdate(
+                        3, checkNotNull(animationSpec.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public AnimatableDynamicColor build() {
+                return new AnimatableDynamicColor(mImpl.build(), mFingerprint);
+            }
+        }
+    }
+
+    /**
+     * Interface defining a dynamic color type.
+     *
+     * @since 1.2
+     */
+    public interface DynamicColor extends DynamicType {
+        /** Get the protocol buffer representation of this object. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        DynamicProto.DynamicColor toDynamicColorProto();
+
+        /**
+         * Creates a {@link DynamicColor} from a byte array generated by {@link
+         * #toDynamicColorByteArray()}.
+         */
+        @NonNull
+        static DynamicColor fromByteArray(@NonNull byte[] byteArray) {
+            try {
+                return dynamicColorFromProto(
+                        DynamicProto.DynamicColor.parseFrom(
+                                byteArray, ExtensionRegistryLite.getEmptyRegistry()));
+            } catch (InvalidProtocolBufferException e) {
+                throw new IllegalArgumentException(
+                        "Byte array could not be parsed into DynamicColor", e);
+            }
+        }
+
+        /** Creates a byte array that can later be used with {@link #fromByteArray(byte[])}. */
+        @NonNull
+        default byte[] toDynamicColorByteArray() {
+            return toDynamicColorProto().toByteArray();
+        }
+
+        /** Creates a constant-valued {@link DynamicColor}. */
+        @NonNull
+        static DynamicColor constant(@ColorInt int constant) {
+            return new FixedColor.Builder().setArgb(constant).build();
+        }
+
+        /**
+         * Creates a {@link DynamicColor} that is bound to the value of an item of the State.
+         *
+         * @param stateKey The key to a {@link StateEntryValue} with a color value from the
+         *     provider's state.
+         */
+        @NonNull
+        static DynamicColor fromState(@NonNull String stateKey) {
+            return new StateColorSource.Builder().setSourceKey(stateKey).build();
+        }
+
+        /**
+         * Creates a {@link DynamicColor} which will animate over the range of colors from {@code
+         * start} to {@code end}.
+         *
+         * @param start The start value of the range.
+         * @param end The end value of the range.
+         */
+        @NonNull
+        static DynamicColor animate(@ColorInt int start, @ColorInt int end) {
+            return new AnimatableFixedColor.Builder().setFromArgb(start).setToArgb(end).build();
+        }
+
+        /**
+         * Creates a {@link DynamicColor} which will animate over the range of colors from {@code
+         * start} to {@code end} with the given animation parameters.
+         *
+         * @param start The start value of the range.
+         * @param end The end value of the range.
+         * @param animationSpec The animation parameters.
+         */
+        @NonNull
+        static DynamicColor animate(
+                @ColorInt int start, @ColorInt int end, @NonNull AnimationSpec animationSpec) {
+            return new AnimatableFixedColor.Builder()
+                    .setFromArgb(start)
+                    .setToArgb(end)
+                    .setAnimationSpec(animationSpec)
+                    .build();
+        }
+
+        /**
+         * Creates a {@link DynamicColor} that is bound to the value of an item of the State. Every
+         * time the state value changes, this {@link DynamicColor} will animate from its current
+         * value to the new value (from the state).
+         *
+         * @param stateKey The key to a {@link StateEntryValue} with a color value from the
+         *     provider's state.
+         */
+        @NonNull
+        static DynamicColor animate(@NonNull String stateKey) {
+            return new AnimatableDynamicColor.Builder().setInput(fromState(stateKey)).build();
+        }
+
+        /**
+         * Creates a {@link DynamicColor} that is bound to the value of an item of the State. Every
+         * time the state value changes, this {@link DynamicColor} will animate from its current
+         * value to the new value (from the state).
+         *
+         * @param stateKey The key to a {@link StateEntryValue} with a color value from the
+         *     provider's state.
+         * @param animationSpec The animation parameters.
+         */
+        @NonNull
+        static DynamicColor animate(
+                @NonNull String stateKey, @NonNull AnimationSpec animationSpec) {
+            return new AnimatableDynamicColor.Builder()
+                    .setInput(fromState(stateKey))
+                    .setAnimationSpec(animationSpec)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicColor} that is bound to the value of this {@link DynamicColor}
+         * and every time its value is changing, it animates from its current value to the new
+         * value.
+         *
+         * @param animationSpec The animation parameters.
+         */
+        @NonNull
+        default DynamicColor animate(@NonNull AnimationSpec animationSpec) {
+            return new AnimatableDynamicColor.Builder()
+                    .setInput(this)
+                    .setAnimationSpec(animationSpec)
+                    .build();
+        }
+
+        /**
+         * Returns a {@link DynamicColor} that is bound to the value of this {@link DynamicColor}
+         * and every time its value is changing, it animates from its current value to the new
+         * value.
+         */
+        @NonNull
+        default DynamicColor animate() {
+            return new AnimatableDynamicColor.Builder().setInput(this).build();
+        }
+
+        /** Get the fingerprint for this object or null if unknown. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        Fingerprint getFingerprint();
+
+        /** Builder to create {@link DynamicColor} objects. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        interface Builder {
+
+            /** Builds an instance with values accumulated in this Builder. */
+            @NonNull
+            DynamicColor build();
+        }
+    }
+
+    /**
+     * Creates a new wrapper instance from the proto. Intended for testing purposes only. An object
+     * created using this method can't be added to any other wrapper.
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
     @NonNull
-    public String toString() {
-      return "GetDurationPartOp{"
-          + "input="
-          + getInput()
-          + ", durationPart="
-          + getDurationPart()
-          + "}";
+    public static DynamicColor dynamicColorFromProto(@NonNull DynamicProto.DynamicColor proto) {
+        if (proto.hasFixed()) {
+            return FixedColor.fromProto(proto.getFixed());
+        }
+        if (proto.hasStateSource()) {
+            return StateColorSource.fromProto(proto.getStateSource());
+        }
+        if (proto.hasAnimatableFixed()) {
+            return AnimatableFixedColor.fromProto(proto.getAnimatableFixed());
+        }
+        if (proto.hasAnimatableDynamic()) {
+            return AnimatableDynamicColor.fromProto(proto.getAnimatableDynamic());
+        }
+        throw new IllegalStateException("Proto was not a recognised instance of DynamicColor");
     }
 
-    /** Builder for {@link GetDurationPartOp}. */
-    public static final class Builder implements DynamicInt32.Builder {
-      private final DynamicProto.GetDurationPartOp.Builder mImpl =
-          DynamicProto.GetDurationPartOp.newBuilder();
-      private final Fingerprint mFingerprint = new Fingerprint(-225941123);
+    /**
+     * A dynamic time instant that sources its value from the platform.
+     *
+     * @since 1.2
+     */
+    static final class PlatformTimeSource implements DynamicInstant {
+        private final DynamicProto.PlatformTimeSource mImpl;
+        @Nullable private final Fingerprint mFingerprint;
 
-      public Builder() {}
+        PlatformTimeSource(
+                DynamicProto.PlatformTimeSource impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
 
-      /**
-       * Sets the duration input.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setInput(@NonNull DynamicDuration input) {
-        mImpl.setInput(input.toDynamicDurationProto());
-        mFingerprint.recordPropertyUpdate(
-            1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
-        return this;
-      }
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
 
-      /**
-       * Sets the duration part to retrieve.
-       *
-       * @since 1.2
-       */
-      @NonNull
-      public Builder setDurationPart(@DurationPartType int durationPart) {
-        mImpl.setDurationPart(DynamicProto.DurationPartType.forNumber(durationPart));
-        mFingerprint.recordPropertyUpdate(2, durationPart);
-        return this;
-      }
+        @NonNull
+        static PlatformTimeSource fromProto(@NonNull DynamicProto.PlatformTimeSource proto) {
+            return new PlatformTimeSource(proto, null);
+        }
 
-      @Override
-      @NonNull
-      public GetDurationPartOp build() {
-        return new GetDurationPartOp(mImpl.build(), mFingerprint);
-      }
+        @NonNull
+        DynamicProto.PlatformTimeSource toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicInstant toDynamicInstantProto() {
+            return DynamicProto.DynamicInstant.newBuilder().setPlatformSource(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "PlatformTimeSource";
+        }
+
+        /** Builder for {@link PlatformTimeSource}. */
+        public static final class Builder implements DynamicInstant.Builder {
+            private final DynamicProto.PlatformTimeSource.Builder mImpl =
+                    DynamicProto.PlatformTimeSource.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(-1895976938);
+
+            public Builder() {}
+
+            @Override
+            @NonNull
+            public PlatformTimeSource build() {
+                return new PlatformTimeSource(mImpl.build(), mFingerprint);
+            }
+        }
     }
-  }
 
-  /**
-   * Interface to be used as a base type for all other dynamic types. This is not consumed by any
-   * Tile elements, it exists just as a marker interface for use internally in the Tiles library.
-   */
-  public interface DynamicType {}
+    /**
+     * Interface defining a dynamic time instant type.
+     *
+     * <p>{@link DynamicInstant} precision is seconds. Thus, any time or duration operation will
+     * operate on that precision level.
+     *
+     * @since 1.2
+     */
+    public interface DynamicInstant extends DynamicType {
+        /** Get the protocol buffer representation of this object. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        DynamicProto.DynamicInstant toDynamicInstantProto();
+
+        /**
+         * Creates a {@link DynamicInstant} from a byte array generated by {@link
+         * #toDynamicInstantByteArray()}.
+         */
+        @NonNull
+        static DynamicInstant fromByteArray(@NonNull byte[] byteArray) {
+            try {
+                return dynamicInstantFromProto(
+                        DynamicProto.DynamicInstant.parseFrom(
+                                byteArray, ExtensionRegistryLite.getEmptyRegistry()));
+            } catch (InvalidProtocolBufferException e) {
+                throw new IllegalArgumentException(
+                        "Byte array could not be parsed into DynamicInstant", e);
+            }
+        }
+
+        /** Creates a byte array that can later be used with {@link #fromByteArray(byte[])}. */
+        @NonNull
+        default byte[] toDynamicInstantByteArray() {
+            return toDynamicInstantProto().toByteArray();
+        }
+
+        /**
+         * Creates a constant-valued {@link DynamicInstant} from an {@link Instant}. If {@link
+         * Instant} precision is greater than seconds, then any excess precision information will be
+         * dropped.
+         */
+        @NonNull
+        static DynamicInstant withSecondsPrecision(@NonNull Instant instant) {
+            return new FixedInstant.Builder().setEpochSeconds(instant.getEpochSecond()).build();
+        }
+
+        /**
+         * Creates a {@link DynamicInstant} that updates its value periodically from the system
+         * time.
+         */
+        @NonNull
+        static DynamicInstant platformTimeWithSecondsPrecision() {
+            return new PlatformTimeSource.Builder().build();
+        }
+
+        /**
+         * Returns duration between the two {@link DynamicInstant} instances as a {@link
+         * DynamicDuration}. The resulted duration is inclusive of the start instant and exclusive
+         * of the end; As an example, the following expression yields a duration object representing
+         * 10 seconds:
+         *
+         * <pre>
+         *   DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(10L))
+         *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(20L)));
+         * </pre>
+         *
+         * @return a new instance of {@link DynamicDuration} containing the result of the operation.
+         */
+        @NonNull
+        default DynamicDuration durationUntil(@NonNull DynamicInstant to) {
+            return new BetweenDuration.Builder()
+                    .setStartInclusive(this)
+                    .setEndExclusive(to)
+                    .build();
+        }
+
+        /** Get the fingerprint for this object or null if unknown. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        Fingerprint getFingerprint();
+
+        /** Builder to create {@link DynamicInstant} objects. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        interface Builder {
+
+            /** Builds an instance with values accumulated in this Builder. */
+            @NonNull
+            DynamicInstant build();
+        }
+    }
+
+    /**
+     * Creates a new wrapper instance from the proto. Intended for testing purposes only. An object
+     * created using this method can't be added to any other wrapper.
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @NonNull
+    public static DynamicInstant dynamicInstantFromProto(
+            @NonNull DynamicProto.DynamicInstant proto) {
+        if (proto.hasFixed()) {
+            return FixedInstant.fromProto(proto.getFixed());
+        }
+        if (proto.hasPlatformSource()) {
+            return PlatformTimeSource.fromProto(proto.getPlatformSource());
+        }
+        throw new IllegalStateException("Proto was not a recognised instance of DynamicInstant");
+    }
+
+    /**
+     * A dynamic duration type that represents the duration between two dynamic time instants.
+     *
+     * @since 1.2
+     */
+    static final class BetweenDuration implements DynamicDuration {
+        private final DynamicProto.BetweenDuration mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        BetweenDuration(DynamicProto.BetweenDuration impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the time instant value marking the start of the duration.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicInstant getStartInclusive() {
+            if (mImpl.hasStartInclusive()) {
+                return DynamicBuilders.dynamicInstantFromProto(mImpl.getStartInclusive());
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets the time instant value marking the end of the duration.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicInstant getEndExclusive() {
+            if (mImpl.hasEndExclusive()) {
+                return DynamicBuilders.dynamicInstantFromProto(mImpl.getEndExclusive());
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static BetweenDuration fromProto(@NonNull DynamicProto.BetweenDuration proto) {
+            return new BetweenDuration(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.BetweenDuration toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicDuration toDynamicDurationProto() {
+            return DynamicProto.DynamicDuration.newBuilder().setBetween(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "BetweenDuration{"
+                    + "startInclusive="
+                    + getStartInclusive()
+                    + ", endExclusive="
+                    + getEndExclusive()
+                    + "}";
+        }
+
+        /** Builder for {@link BetweenDuration}. */
+        public static final class Builder implements DynamicDuration.Builder {
+            private final DynamicProto.BetweenDuration.Builder mImpl =
+                    DynamicProto.BetweenDuration.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(-1615230958);
+
+            public Builder() {}
+
+            /**
+             * Sets the time instant value marking the start of the duration.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setStartInclusive(@NonNull DynamicInstant startInclusive) {
+                mImpl.setStartInclusive(startInclusive.toDynamicInstantProto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(startInclusive.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the time instant value marking the end of the duration.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setEndExclusive(@NonNull DynamicInstant endExclusive) {
+                mImpl.setEndExclusive(endExclusive.toDynamicInstantProto());
+                mFingerprint.recordPropertyUpdate(
+                        2, checkNotNull(endExclusive.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public BetweenDuration build() {
+                return new BetweenDuration(mImpl.build(), mFingerprint);
+            }
+        }
+    }
+
+    /**
+     * Interface defining a dynamic duration type.
+     *
+     * @since 1.2
+     */
+    public interface DynamicDuration extends DynamicType {
+        /** Get the protocol buffer representation of this object. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        DynamicProto.DynamicDuration toDynamicDurationProto();
+
+        /**
+         * Creates a {@link DynamicDuration} from a byte array generated by {@link
+         * #toDynamicDurationByteArray()}.
+         */
+        @NonNull
+        static DynamicDuration fromByteArray(@NonNull byte[] byteArray) {
+            try {
+                return dynamicDurationFromProto(
+                        DynamicProto.DynamicDuration.parseFrom(
+                                byteArray, ExtensionRegistryLite.getEmptyRegistry()));
+            } catch (InvalidProtocolBufferException e) {
+                throw new IllegalArgumentException(
+                        "Byte array could not be parsed into DynamicDuration", e);
+            }
+        }
+
+        /** Creates a byte array that can later be used with {@link #fromByteArray(byte[])}. */
+        @NonNull
+        default byte[] toDynamicDurationByteArray() {
+            return toDynamicDurationProto().toByteArray();
+        }
+
+        /**
+         * Returns the total number of days in a {@link DynamicDuration} as a {@link DynamicInt32}.
+         * The fraction part of the result will be truncated. This is based on the standard
+         * definition of a day as 24 hours. As an example, the following is equal to {@code
+         * DynamicInt32.constant(1)}
+         *
+         * <pre>
+         *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+         *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
+         *      .toIntDays();
+         * </pre>
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         *     Integer overflow can occur if the result of the operation is larger than {@link
+         *     Integer#MAX_VALUE}.
+         */
+        @NonNull
+        default DynamicInt32 toIntDays() {
+            return new GetDurationPartOp.Builder()
+                    .setInput(this)
+                    .setDurationPart(DURATION_PART_TYPE_TOTAL_DAYS)
+                    .build();
+        }
+
+        /**
+         * Returns the total number of hours in a {@link DynamicDuration} as a {@link DynamicInt32}.
+         * The fraction part of the result will be truncated. As an example, the following is equal
+         * to {@code DynamicInt32.constant(34)}
+         *
+         * <pre>
+         *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+         *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
+         *      .toIntHours();
+         * </pre>
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         *     Integer overflow can occur if the result of the operation is larger than {@link
+         *     Integer#MAX_VALUE}.
+         */
+        @NonNull
+        default DynamicInt32 toIntHours() {
+            return new GetDurationPartOp.Builder()
+                    .setInput(this)
+                    .setDurationPart(DURATION_PART_TYPE_TOTAL_HOURS)
+                    .build();
+        }
+
+        /**
+         * Returns the total number of minutes in a {@link DynamicDuration} as a {@link
+         * DynamicInt32}. The fraction part of the result will be truncated. As an example, the
+         * following is equal to {@code DynamicInt32.constant(2057)}
+         *
+         * <pre>
+         *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+         *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
+         *      .toIntMinutes();
+         * </pre>
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         *     Integer overflow can occur if the result of the operation is larger than {@link
+         *     Integer#MAX_VALUE}.
+         */
+        @NonNull
+        default DynamicInt32 toIntMinutes() {
+            return new GetDurationPartOp.Builder()
+                    .setInput(this)
+                    .setDurationPart(DURATION_PART_TYPE_TOTAL_MINUTES)
+                    .build();
+        }
+
+        /**
+         * Returns the total number of seconds in a {@link DynamicDuration} as a {@link
+         * DynamicInt32}. As an example, the following is equal to {@code
+         * DynamicInt32.constant(123456)}
+         *
+         * <pre>
+         *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+         *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
+         *      .toIntSeconds();
+         * </pre>
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         *     Integer overflow can occur if the result of the operation is larger than {@link
+         *     Integer#MAX_VALUE}.
+         */
+        @NonNull
+        default DynamicInt32 toIntSeconds() {
+            return new GetDurationPartOp.Builder()
+                    .setInput(this)
+                    .setDurationPart(DURATION_PART_TYPE_TOTAL_SECONDS)
+                    .build();
+        }
+
+        /**
+         * Returns the total number of days in a duration as a {@link DynamicInt32}. This represents
+         * the absolute value of the total number of days in the duration based on the 24 hours day
+         * definition. The fraction part of the result will be truncated; As an example, the
+         * following is equal to {@code DynamicInt32.constant(1)}
+         *
+         * <pre>
+         *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+         *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
+         *      .getIntDaysPart();
+         * </pre>
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         *     Integer overflow can occur if the result of the operation is larger than {@link
+         *     Integer#MAX_VALUE}.
+         */
+        @NonNull
+        default DynamicInt32 getIntDaysPart() {
+            return new GetDurationPartOp.Builder()
+                    .setInput(this)
+                    .setDurationPart(DURATION_PART_TYPE_DAYS)
+                    .build();
+        }
+
+        /**
+         * Returns the number of hours part in the duration as a {@link DynamicInt32}. This
+         * represents the absolute value of remaining hours when dividing total hours by hours in a
+         * day (24 hours); As an example, the following is equal to {@code
+         * DynamicInt32.constant(10)}
+         *
+         * <pre>
+         *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+         *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
+         *      .getHoursPart();
+         * </pre>
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         */
+        @NonNull
+        default DynamicInt32 getHoursPart() {
+            return new GetDurationPartOp.Builder()
+                    .setInput(this)
+                    .setDurationPart(DURATION_PART_TYPE_HOURS)
+                    .build();
+        }
+
+        /**
+         * Returns the number of minutes part in the duration as a {@link DynamicInt32}. This
+         * represents the absolute value of remaining minutes when dividing total minutes by minutes
+         * in an hour (60 minutes). As an example, the following is equal to {@code
+         * DynamicInt32.constant(17)}
+         *
+         * <pre>
+         *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+         *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
+         *      .getMinutesPart();
+         * </pre>
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         */
+        @NonNull
+        default DynamicInt32 getMinutesPart() {
+            return new GetDurationPartOp.Builder()
+                    .setInput(this)
+                    .setDurationPart(DURATION_PART_TYPE_MINUTES)
+                    .build();
+        }
+
+        /**
+         * Returns the number of seconds part in the duration as a {@link DynamicInt32}. This
+         * represents the absolute value of remaining seconds when dividing total seconds by seconds
+         * in a minute (60 seconds); As an example, the following is equal to {@code
+         * DynamicInt32.constant(36)}
+         *
+         * <pre>
+         *   DynamicInstant.withSecondsPrecision(Instant.EPOCH)
+         *      .durationUntil(DynamicInstant.withSecondsPrecision(Instant.ofEpochSecond(123456L)))
+         *      .getSecondsPart();
+         * </pre>
+         *
+         * @return a new instance of {@link DynamicInt32} containing the result of the operation.
+         */
+        @NonNull
+        default DynamicInt32 getSecondsPart() {
+            return new GetDurationPartOp.Builder()
+                    .setInput(this)
+                    .setDurationPart(DURATION_PART_TYPE_SECONDS)
+                    .build();
+        }
+
+        /** Get the fingerprint for this object or null if unknown. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        Fingerprint getFingerprint();
+
+        /** Builder to create {@link DynamicDuration} objects. */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        interface Builder {
+
+            /** Builds an instance with values accumulated in this Builder. */
+            @NonNull
+            DynamicDuration build();
+        }
+    }
+
+    /**
+     * Creates a new wrapper instance from the proto. Intended for testing purposes only. An object
+     * created using this method can't be added to any other wrapper.
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @NonNull
+    public static DynamicDuration dynamicDurationFromProto(
+            @NonNull DynamicProto.DynamicDuration proto) {
+        if (proto.hasBetween()) {
+            return BetweenDuration.fromProto(proto.getBetween());
+        }
+        throw new IllegalStateException("Proto was not a recognised instance of DynamicDuration");
+    }
+
+    /**
+     * Retrieve the specified duration part of a {@link DynamicDuration} instance as a {@link
+     * DynamicInt32}.
+     *
+     * @since 1.2
+     */
+    static final class GetDurationPartOp implements DynamicInt32 {
+        private final DynamicProto.GetDurationPartOp mImpl;
+        @Nullable private final Fingerprint mFingerprint;
+
+        GetDurationPartOp(DynamicProto.GetDurationPartOp impl, @Nullable Fingerprint fingerprint) {
+            this.mImpl = impl;
+            this.mFingerprint = fingerprint;
+        }
+
+        /**
+         * Gets the duration input.
+         *
+         * @since 1.2
+         */
+        @Nullable
+        public DynamicDuration getInput() {
+            if (mImpl.hasInput()) {
+                return DynamicBuilders.dynamicDurationFromProto(mImpl.getInput());
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets the duration part to retrieve.
+         *
+         * @since 1.2
+         */
+        @DurationPartType
+        public int getDurationPart() {
+            return mImpl.getDurationPart().getNumber();
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @Nullable
+        public Fingerprint getFingerprint() {
+            return mFingerprint;
+        }
+
+        @NonNull
+        static GetDurationPartOp fromProto(@NonNull DynamicProto.GetDurationPartOp proto) {
+            return new GetDurationPartOp(proto, null);
+        }
+
+        @NonNull
+        DynamicProto.GetDurationPartOp toProto() {
+            return mImpl;
+        }
+
+        @Override
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        public DynamicProto.DynamicInt32 toDynamicInt32Proto() {
+            return DynamicProto.DynamicInt32.newBuilder().setDurationPart(mImpl).build();
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "GetDurationPartOp{"
+                    + "input="
+                    + getInput()
+                    + ", durationPart="
+                    + getDurationPart()
+                    + "}";
+        }
+
+        /** Builder for {@link GetDurationPartOp}. */
+        public static final class Builder implements DynamicInt32.Builder {
+            private final DynamicProto.GetDurationPartOp.Builder mImpl =
+                    DynamicProto.GetDurationPartOp.newBuilder();
+            private final Fingerprint mFingerprint = new Fingerprint(-225941123);
+
+            public Builder() {}
+
+            /**
+             * Sets the duration input.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setInput(@NonNull DynamicDuration input) {
+                mImpl.setInput(input.toDynamicDurationProto());
+                mFingerprint.recordPropertyUpdate(
+                        1, checkNotNull(input.getFingerprint()).aggregateValueAsInt());
+                return this;
+            }
+
+            /**
+             * Sets the duration part to retrieve.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setDurationPart(@DurationPartType int durationPart) {
+                mImpl.setDurationPart(DynamicProto.DurationPartType.forNumber(durationPart));
+                mFingerprint.recordPropertyUpdate(2, durationPart);
+                return this;
+            }
+
+            @Override
+            @NonNull
+            public GetDurationPartOp build() {
+                return new GetDurationPartOp(mImpl.build(), mFingerprint);
+            }
+        }
+    }
+
+    /**
+     * Interface to be used as a base type for all other dynamic types. This is not consumed by any
+     * Tile elements, it exists just as a marker interface for use internally in the Tiles library.
+     */
+    public interface DynamicType {}
 }
diff --git a/wear/protolayout/protolayout-material/lint-baseline.xml b/wear/protolayout/protolayout-material/lint-baseline.xml
new file mode 100644
index 0000000..d1d66c6
--- /dev/null
+++ b/wear/protolayout/protolayout-material/lint-baseline.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
+
+    <issue
+        id="BanThreadSleep"
+        message="Uses Thread.sleep()"
+        errorLine1="            Thread.sleep(1000);"
+        errorLine2="                   ~~~~~">
+        <location
+            file="src/androidTest/java/androidx/wear/protolayout/material/RunnerUtils.java"/>
+    </issue>
+
+    <issue
+        id="BanThreadSleep"
+        message="Uses Thread.sleep()"
+        errorLine1="            Thread.sleep(1000);"
+        errorLine2="                   ~~~~~">
+        <location
+            file="src/androidTest/java/androidx/wear/protolayout/material/RunnerUtils.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.protolayout.expression.ProtoLayoutExperimental` or `@OptIn(markerClass = androidx.wear.protolayout.expression.ProtoLayoutExperimental.class)`"
+        errorLine1="                .setVariant(variant)"
+        errorLine2="                 ~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/protolayout/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.protolayout.expression.ProtoLayoutExperimental` or `@OptIn(markerClass = androidx.wear.protolayout.expression.ProtoLayoutExperimental.class)`"
+        errorLine1="                40, FONT_WEIGHT_MEDIUM, FONT_VARIANT_TITLE, 0.01f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/protolayout/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.protolayout.expression.ProtoLayoutExperimental` or `@OptIn(markerClass = androidx.wear.protolayout.expression.ProtoLayoutExperimental.class)`"
+        errorLine1="                34, FONT_WEIGHT_MEDIUM, FONT_VARIANT_TITLE, 0.03f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/protolayout/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.protolayout.expression.ProtoLayoutExperimental` or `@OptIn(markerClass = androidx.wear.protolayout.expression.ProtoLayoutExperimental.class)`"
+        errorLine1="                30, FONT_WEIGHT_MEDIUM, FONT_VARIANT_TITLE, 0.03f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/protolayout/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.protolayout.expression.ProtoLayoutExperimental` or `@OptIn(markerClass = androidx.wear.protolayout.expression.ProtoLayoutExperimental.class)`"
+        errorLine1="                24, FONT_WEIGHT_MEDIUM, FONT_VARIANT_TITLE, 0.008f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/protolayout/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.protolayout.expression.ProtoLayoutExperimental` or `@OptIn(markerClass = androidx.wear.protolayout.expression.ProtoLayoutExperimental.class)`"
+        errorLine1="                20, FONT_WEIGHT_MEDIUM, FONT_VARIANT_TITLE, 0.01f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/protolayout/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.protolayout.expression.ProtoLayoutExperimental` or `@OptIn(markerClass = androidx.wear.protolayout.expression.ProtoLayoutExperimental.class)`"
+        errorLine1="                16, FONT_WEIGHT_MEDIUM, FONT_VARIANT_TITLE, 0.01f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/protolayout/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.protolayout.expression.ProtoLayoutExperimental` or `@OptIn(markerClass = androidx.wear.protolayout.expression.ProtoLayoutExperimental.class)`"
+        errorLine1="                14, FONT_WEIGHT_MEDIUM, FONT_VARIANT_BODY, 0.01f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/protolayout/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.protolayout.expression.ProtoLayoutExperimental` or `@OptIn(markerClass = androidx.wear.protolayout.expression.ProtoLayoutExperimental.class)`"
+        errorLine1="                12, FONT_WEIGHT_MEDIUM, FONT_VARIANT_BODY, 0.01f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/protolayout/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.protolayout.expression.ProtoLayoutExperimental` or `@OptIn(markerClass = androidx.wear.protolayout.expression.ProtoLayoutExperimental.class)`"
+        errorLine1="                10, FONT_WEIGHT_MEDIUM, FONT_VARIANT_BODY, 0.01f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/protolayout/material/Typography.java"/>
+    </issue>
+
+</issues>
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Button.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Button.java
index 996cae8..494c7a21e 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Button.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Button.java
@@ -61,7 +61,7 @@
 import java.util.Map;
 
 /**
- * Tiles component {@link Button} that represents clickable button with the given content.
+ * ProtoLayout component {@link Button} that represents clickable button with the given content.
  *
  * <p>The Button is circular in shape. The recommended sizes are defined in {@link ButtonDefaults}.
  *
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ButtonColors.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ButtonColors.java
index 3ebfc62..aca78ae 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ButtonColors.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ButtonColors.java
@@ -23,7 +23,7 @@
 import androidx.wear.protolayout.ColorBuilders.ColorProp;
 
 /**
- * Represents the background and content colors used in a button Tiles component.
+ * Represents the background and content colors used in {@link Button}.
  *
  * <p>See {@link ButtonDefaults#PRIMARY_COLORS} for the default colors used in a primary styled
  * {@link Button}. See {@link ButtonDefaults#SECONDARY_COLORS} for the default colors used in a
@@ -36,10 +36,10 @@
     /**
      * Constructor for {@link ButtonColors} object.
      *
-     * @param backgroundColor The background color to be used for a button Tiles component. Should
-     *     be in ARGB format.
-     * @param contentColor The content color or tint color to be used for a button Tiles component.
+     * @param backgroundColor The background color to be used for {@link Button}.
      *     Should be in ARGB format.
+     * @param contentColor The content color or tint color to be used for {@link Button}. Should
+     *     be in ARGB format.
      */
     public ButtonColors(@ColorInt int backgroundColor, @ColorInt int contentColor) {
         mBackgroundColor = argb(backgroundColor);
@@ -75,13 +75,13 @@
         return new ButtonColors(colors.getSurface(), colors.getOnSurface());
     }
 
-    /** The background color to be used on a button Tiles components. */
+    /** The background color to be used on {@link Button}. */
     @NonNull
     public ColorProp getBackgroundColor() {
         return mBackgroundColor;
     }
 
-    /** The content or tint color to be used on a button Tiles components. */
+    /** The content or tint color to be used on {@link Button}. */
     @NonNull
     public ColorProp getContentColor() {
         return mContentColor;
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ButtonDefaults.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ButtonDefaults.java
index e98e212..0f6f057 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ButtonDefaults.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ButtonDefaults.java
@@ -23,7 +23,7 @@
 import androidx.annotation.NonNull;
 import androidx.wear.protolayout.DimensionBuilders.DpProp;
 
-/** Contains the default values used by button Tiles components. */
+/** Contains the default values used by {@link Button}. */
 public class ButtonDefaults {
     private ButtonDefaults() {}
 
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Chip.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Chip.java
index 74732d5..4683c7a 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Chip.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Chip.java
@@ -71,8 +71,8 @@
 import java.util.Map;
 
 /**
- * Tiles component {@link Chip} that represents clickable object with the text, optional label and
- * optional icon or with custom content.
+ * ProtoLayout component {@link Chip} that represents clickable object with the text, optional label
+ * and optional icon or with custom content.
  *
  * <p>The Chip is Stadium shape and has a max height designed to take no more than two lines of text
  * of {@link Typography#TYPOGRAPHY_BUTTON} style. The {@link Chip} can have an icon horizontally
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ChipColors.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ChipColors.java
index a24e6c4..8448aa5 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ChipColors.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ChipColors.java
@@ -23,7 +23,7 @@
 import androidx.wear.protolayout.ColorBuilders.ColorProp;
 
 /**
- * Represents the background and content colors used in a chip Tiles component.
+ * Represents the background and content colors used in {@link Chip}.
  *
  * <p>See {@link ChipDefaults#PRIMARY_COLORS} for the default colors used in a primary styled {@link
  * Chip}. See {@link ChipDefaults#SECONDARY_COLORS} for the default colors used in a secondary
@@ -38,14 +38,14 @@
     /**
      * Constructor for the {@link ChipColors} object.
      *
-     * @param backgroundColor The background color to be used for a chip Tiles component. Should be
-     *     in ARGB format.
-     * @param iconColor The color to be used for an icon in a chip Tiles component. Should be in
-     *     ARGB format.
-     * @param contentColor The text color to be used for a main text in a chip Tiles component.
+     * @param backgroundColor The background color to be used for {@link Chip}.
      *     Should be in ARGB format.
-     * @param secondaryContentColor The text color to be used for a label text in a chip Tiles
-     *     component. Should be in ARGB format.
+     * @param iconColor The color to be used for an icon in {@link Chip}. Should be
+     *     in ARGB format.
+     * @param contentColor The text color to be used for a main text in {@link Chip}.
+     *     Should be in ARGB format.
+     * @param secondaryContentColor The text color to be used for a label text in {@link Chip}
+     *     Should be in ARGB format.
      */
     public ChipColors(
             @ColorInt int backgroundColor,
@@ -61,9 +61,9 @@
     /**
      * Constructor for the {@link ChipColors} object.
      *
-     * @param backgroundColor The background color to be used for a chip Tiles component. Should be
-     *     in ARGB format.
-     * @param contentColor The content color to be used for all items inside a chip Tiles component.
+     * @param backgroundColor The background color to be used for {@link Chip}.
+     *     Should be in ARGB format.
+     * @param contentColor The content color to be used for all items inside {@link Chip}
      *     Should be in ARGB format.
      */
     public ChipColors(@ColorInt int backgroundColor, @ColorInt int contentColor) {
@@ -76,11 +76,10 @@
     /**
      * Constructor for the {@link ChipColors} object.
      *
-     * @param backgroundColor The background color to be used for a chip Tiles component.
-     * @param iconColor The color to be used for an icon in a chip Tiles component.
-     * @param contentColor The text color to be used for a main text in a chip Tiles component.
-     * @param secondaryContentColor The text color to be used for a label text in a chip Tiles
-     *     component.
+     * @param backgroundColor The background color to be used for {@link Chip}.
+     * @param iconColor The color to be used for an icon in {@link Chip}.
+     * @param contentColor The text color to be used for a main text in {@link Chip}.
+     * @param secondaryContentColor The text color to be used for a label text in {@link Chip}.
      */
     public ChipColors(
             @NonNull ColorProp backgroundColor,
@@ -96,8 +95,8 @@
     /**
      * Constructor for the {@link ChipColors} object.
      *
-     * @param backgroundColor The background color to be used for a chip Tiles component.
-     * @param contentColor The content color to be used for all items inside a chip Tiles component.
+     * @param backgroundColor The background color to be used for {@link Chip}.
+     * @param contentColor The content color to be used for all items inside {@link Chip}.
      */
     public ChipColors(@NonNull ColorProp backgroundColor, @NonNull ColorProp contentColor) {
         mBackgroundColor = backgroundColor;
@@ -124,25 +123,25 @@
         return new ChipColors(colors.getSurface(), colors.getOnSurface());
     }
 
-    /** The background color to be used on a chip Tiles components. */
+    /** The background color to be used on {@link Chip}. */
     @NonNull
     public ColorProp getBackgroundColor() {
         return mBackgroundColor;
     }
 
-    /** The icon color to be used on a chip Tiles components. */
+    /** The icon color to be used on {@link Chip}. */
     @NonNull
     public ColorProp getIconColor() {
         return mIconColor;
     }
 
-    /** The main text color to be used on a chip Tiles components. */
+    /** The main text color to be used on {@link Chip}. */
     @NonNull
     public ColorProp getContentColor() {
         return mContentColor;
     }
 
-    /** The label text color to be used on a chip Tiles components. */
+    /** The label text color to be used on {@link Chip}. */
     @NonNull
     public ColorProp getSecondaryContentColor() {
         return mSecondaryContentColor;
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ChipDefaults.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ChipDefaults.java
index 8059369..2139050 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ChipDefaults.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ChipDefaults.java
@@ -23,7 +23,7 @@
 import androidx.annotation.RestrictTo.Scope;
 import androidx.wear.protolayout.DimensionBuilders.DpProp;
 
-/** Contains the default values used by chip Tiles components. */
+/** Contains the default values used by {@link Chip}. */
 public class ChipDefaults {
     private ChipDefaults() {}
 
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/CircularProgressIndicator.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/CircularProgressIndicator.java
index 820be12..9a5e955 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/CircularProgressIndicator.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/CircularProgressIndicator.java
@@ -51,8 +51,9 @@
 import androidx.wear.protolayout.proto.LayoutElementProto;
 
 /**
- * Tiles component {@link CircularProgressIndicator} that represents circular progress indicator
- * which supports a gap in the circular track between startAngle and endAngle. [Progress Indicator
+ * ProtoLayout component {@link CircularProgressIndicator} that represents circular progress
+ * indicator which supports a gap in the circular track between startAngle and endAngle.
+ * [Progress Indicator
  * doc] (https://developer.android.com/training/wearables/components/progress-indicator)
  *
  * <p>The CircularProgressIndicator is a colored arc around the edge of the screen with the given
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Colors.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Colors.java
index 84026bd..b69fb56 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Colors.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Colors.java
@@ -61,7 +61,7 @@
     @ColorInt
     public static final int ON_SURFACE = 0xFFFFFFFF;
 
-    /** The default color scheme to be used in Tiles Material components. */
+    /** The default color scheme to be used in ProtoLayout Material components. */
     @NonNull
     public static final Colors DEFAULT = new Colors(PRIMARY, ON_PRIMARY, SURFACE, ON_SURFACE);
 
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/CompactChip.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/CompactChip.java
index 58bf3b8..840aa47 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/CompactChip.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/CompactChip.java
@@ -43,7 +43,7 @@
 import androidx.wear.protolayout.proto.LayoutElementProto;
 
 /**
- * Tiles component {@link CompactChip} that represents clickable object with the text.
+ * ProtoLayout component {@link CompactChip} that represents clickable object with the text.
  *
  * <p>The Chip is Stadium shape and has a max height designed to take no more than one line of text
  * of {@link Typography#TYPOGRAPHY_CAPTION1} style. Width of the chip is adjustable to the text
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Helper.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Helper.java
index 630bf29..1e87ef39 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Helper.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Helper.java
@@ -33,7 +33,7 @@
 import java.util.Collection;
 
 /**
- * Helper class used for Tiles Material.
+ * Helper class used for ProtoLayout Material.
  *
  */
 @RestrictTo(Scope.LIBRARY_GROUP)
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ProgressIndicatorColors.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ProgressIndicatorColors.java
index 668fe3e..f401e67 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ProgressIndicatorColors.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ProgressIndicatorColors.java
@@ -23,7 +23,7 @@
 import androidx.wear.protolayout.ColorBuilders.ColorProp;
 
 /**
- * Represents the indicator and track colors used in a progress indicator Tiles component.
+ * Represents the indicator and track colors used in {@link CircularProgressIndicator}.
  *
  * <p>See {@link ProgressIndicatorDefaults#DEFAULT_COLORS} for the default colors used in a {@link
  * CircularProgressIndicator}.
@@ -35,10 +35,9 @@
     /**
      * Constructor for {@link ProgressIndicatorColors} object.
      *
-     * @param indicatorColor The indicator color to be used for a progress indicator Tiles
-     *     component.
-     * @param trackColor The background track color to be used for a progress indicator Tiles
-     *     component.
+     * @param indicatorColor The indicator color to be used for {@link CircularProgressIndicator}.
+     * @param trackColor The background track color to be used for
+     * {@link CircularProgressIndicator}.
      */
     public ProgressIndicatorColors(
             @NonNull ColorProp indicatorColor, @NonNull ColorProp trackColor) {
@@ -49,10 +48,10 @@
     /**
      * Constructor for {@link ProgressIndicatorColors} object.
      *
-     * @param indicatorColor The indicator color to be used for a progress indicator Tiles
-     *     component. Should be in ARGB format.
-     * @param trackColor The background track color to be used for a progress indicator Tiles
-     *     component. Should be in ARGB format.
+     * @param indicatorColor The indicator color to be used for {@link CircularProgressIndicator}.
+     *     Should be in ARGB format.
+     * @param trackColor The background track color to be used for
+     *     {@link CircularProgressIndicator}. Should be in ARGB format.
      */
     public ProgressIndicatorColors(@ColorInt int indicatorColor, @ColorInt int trackColor) {
         this.mIndicatorColor = argb(indicatorColor);
@@ -69,13 +68,13 @@
         return new ProgressIndicatorColors(colors.getPrimary(), colors.getSurface());
     }
 
-    /** The indicator color to be used for a progress indicator Tiles component. */
+    /** The indicator color to be used for {@link CircularProgressIndicator}. */
     @NonNull
     public ColorProp getIndicatorColor() {
         return mIndicatorColor;
     }
 
-    /** The background track color to be used for a progress indicator Tiles component. */
+    /** The background track color to be used for {@link CircularProgressIndicator}. */
     @NonNull
     public ColorProp getTrackColor() {
         return mTrackColor;
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ProgressIndicatorDefaults.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ProgressIndicatorDefaults.java
index dd2f9cf..97ab540 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ProgressIndicatorDefaults.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/ProgressIndicatorDefaults.java
@@ -23,7 +23,7 @@
 import androidx.annotation.RestrictTo.Scope;
 import androidx.wear.protolayout.DimensionBuilders.DpProp;
 
-/** Contains the default values used by {@link CircularProgressIndicator} Tiles components. */
+/** Contains the default values used by {@link CircularProgressIndicator}. */
 public class ProgressIndicatorDefaults {
     private ProgressIndicatorDefaults() {}
 
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Text.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Text.java
index ed5e309..132990b 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Text.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Text.java
@@ -44,7 +44,7 @@
 import androidx.wear.protolayout.proto.LayoutElementProto;
 
 /**
- * Tiles component {@link Text} that represents text object holding any information.
+ * ProtoLayout component {@link Text} that represents text object holding any information.
  *
  * <p>There are pre-built typography styles that can be obtained from constants in {@link
  * FontStyle}.
@@ -109,8 +109,8 @@
         @NonNull
         @SuppressWarnings("MissingGetterMatchingBuilder")
         // There is getFontStyle matching getter for this setter as the serialized format of the
-        // Tiles do not allow for a direct reconstruction of the all arguments, but it has FontStyle
-        // object of that text.
+        // ProtoLayout do not allow for a direct reconstruction of the all arguments, but it has
+        // FontStyle object of that text.
         public Builder setTypography(@TypographyName int typography) {
             this.mTypographyName = typography;
             return this;
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/TitleChip.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/TitleChip.java
index 009dd8c..dc7ee6e 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/TitleChip.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/TitleChip.java
@@ -42,7 +42,7 @@
 import androidx.wear.protolayout.proto.LayoutElementProto;
 
 /**
- * Tiles component {@link TitleChip} that represents clickable object with the text.
+ * ProtoLayout component {@link TitleChip} that represents clickable object with the text.
  *
  * <p>The Title Chip is Stadium shaped object with a larger height then standard Chip and it will
  * take one line of text of {@link Typography#TYPOGRAPHY_TITLE2} style.
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/EdgeContentLayout.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/EdgeContentLayout.java
index e3e78d2..ebd0b97 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/EdgeContentLayout.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/EdgeContentLayout.java
@@ -54,13 +54,10 @@
 import java.util.List;
 
 /**
- * Tiles layout that represents the suggested layout style for Material Tiles, which has content
- * around the edge of the screen (e.g. a ProgressIndicator) and the given content inside of it with
- * the recommended margin and padding applied. Optional primary or secondary label can be added
- * above and below the main content, respectively.
- *
- * <p>For additional examples and suggested layouts see <a
- * href="/training/wearables/design/tiles-design-system">Tiles Design System</a>.
+ * ProtoLayout layout that represents the suggested layout style for Material ProtoLayout, which has
+ * content around the edge of the screen (e.g. a ProgressIndicator) and the given content inside
+ * of it with the recommended margin and padding applied. Optional primary or secondary label can
+ * be added above and below the main content, respectively.
  *
  * <p>When accessing the contents of a container for testing, note that this element can't be simply
  * casted back to the original type, i.e.:
@@ -82,6 +79,7 @@
  *   EdgeContentLayout.fromLayoutElement(box.getContents().get(0));
  * }</pre>
  */
+// TODO(b/274916652): Link visuals once they are available.
 public class EdgeContentLayout implements LayoutElement {
     /**
      * Prefix tool tag for Metadata in Modifiers, so we know that Box is actually a
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/LayoutDefaults.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/LayoutDefaults.java
index 42a3381..b43b43c 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/LayoutDefaults.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/LayoutDefaults.java
@@ -21,7 +21,7 @@
 import androidx.wear.protolayout.DimensionBuilders.DpProp;
 import androidx.wear.protolayout.material.ButtonDefaults;
 
-/** Contains the default values used by layout templates for Tiles. */
+/** Contains the default values used by layout templates for ProtoLayout. */
 public class LayoutDefaults {
     private LayoutDefaults() {}
 
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/MultiButtonLayout.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/MultiButtonLayout.java
index e4186c5..2267c1a 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/MultiButtonLayout.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/MultiButtonLayout.java
@@ -51,14 +51,11 @@
 import java.util.List;
 
 /**
- * Opinionated Tiles layout, that can contain between 1 and {@link
+ * Opinionated ProtoLayout layout, that can contain between 1 and {@link
  * LayoutDefaults#MULTI_BUTTON_MAX_NUMBER} number of buttons arranged inline with the Material
  * guidelines. Can be used as a content passed in to the {@link PrimaryLayout}, but if there is
  * {@link LayoutDefaults#MULTI_BUTTON_MAX_NUMBER} buttons it should be used on its own.
  *
- * <p>For additional examples and suggested layouts see <a
- * href="/training/wearables/design/tiles-design-system">Tiles Design System</a>.
- *
  * <p>When accessing the contents of a container for testing, note that this element can't be simply
  * casted back to the original type, i.e.:
  *
@@ -78,6 +75,7 @@
  * MultiButtonLayout myMbl = MultiButtonLayout.fromLayoutElement(box.getContents().get(0));
  * }</pre>
  */
+// TODO(b/274916652): Link visuals once they are available.
 public class MultiButtonLayout implements LayoutElement {
     /** Tool tag for Metadata in Modifiers, so we know that Box is actually a MultiButtonLayout. */
     static final String METADATA_TAG = "MBL";
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/MultiSlotLayout.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/MultiSlotLayout.java
index 8f9e903..e76baa3 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/MultiSlotLayout.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/MultiSlotLayout.java
@@ -48,16 +48,14 @@
 import java.util.List;
 
 /**
- * Opinionated Tiles layout, row like style with horizontally aligned and spaced slots (for icons or
- * other small content). Should be used as a content passed in to the {@link PrimaryLayout}.
+ * Opinionated ProtoLayout layout, row like style with horizontally aligned and spaced slots (for
+ * icons or other small content). Should be used as a content passed in to the
+ * {@link PrimaryLayout}.
  *
  * <p>Recommended number of added slots is 1 to 3. Their width will be the width of an element
  * passed in, with the {@link LayoutDefaults#MULTI_SLOT_LAYOUT_HORIZONTAL_SPACER_WIDTH} space
  * between.
  *
- * <p>For additional examples and suggested layouts see <a
- * href="/training/wearables/design/tiles-design-system">Tiles Design System</a>.
- *
  * <p>When accessing the contents of a container for testing, note that this element can't be simply
  * casted back to the original type, i.e.:
  *
@@ -77,6 +75,7 @@
  * MultiSlotLayout myMsl = MultiSlotLayout.fromLayoutElement(box.getContents().get(0));
  * }</pre>
  */
+// TODO(b/274916652): Link visuals once they are available.
 public class MultiSlotLayout implements LayoutElement {
     /** Tool tag for Metadata in Modifiers, so we know that Row is actually a MultiSlotLayout. */
     static final String METADATA_TAG = "MSL";
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/PrimaryLayout.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/PrimaryLayout.java
index 2bbbac5..800606d 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/PrimaryLayout.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/layouts/PrimaryLayout.java
@@ -67,18 +67,15 @@
 import java.util.List;
 
 /**
- * Tiles layout that represents a suggested layout style for Material Tiles with the primary
- * (compact) chip at the bottom with the given content in the center and the recommended margin and
- * padding applied. There is a fixed slot for an optional primary label above or optional secondary
- * label below the main content area.
+ * ProtoLayout layout that represents a suggested layout style for Material ProtoLayout with the
+ * primary (compact) chip at the bottom with the given content in the center and the recommended
+ * margin and padding applied. There is a fixed slot for an optional primary label above or
+ * optional secondary label below the main content area.
  *
  * <p>It is highly recommended that main content has max lines between 2 and 4 (dependant on labels
  * present), i.e.: * No labels are present: content with max 4 lines, * 1 label is present: content
  * with max 3 lines, * 2 labels are present: content with max 2 lines.
  *
- * <p>For additional examples and suggested layouts see <a
- * href="/training/wearables/design/tiles-design-system">Tiles Design System</a>.
- *
  * <p>When accessing the contents of a container for testing, note that this element can't be simply
  * casted back to the original type, i.e.:
  *
@@ -98,6 +95,7 @@
  * PrimaryLayout myPl = PrimaryLayout.fromLayoutElement(box.getContents().get(0));
  * }</pre>
  */
+// TODO(b/274916652): Link visuals once they are available.
 public class PrimaryLayout implements LayoutElement {
     /**
      * Prefix tool tag for Metadata in Modifiers, so we know that Box is actually a PrimaryLayout.
diff --git a/wear/protolayout/protolayout/build.gradle b/wear/protolayout/protolayout/build.gradle
index 0cc935b..bc93416 100644
--- a/wear/protolayout/protolayout/build.gradle
+++ b/wear/protolayout/protolayout/build.gradle
@@ -25,7 +25,7 @@
     annotationProcessor(libs.nullaway)
     api("androidx.annotation:annotation:1.2.0")
 
-    implementation("androidx.annotation:annotation-experimental:1.2.0")
+    implementation("androidx.annotation:annotation-experimental:1.3.0")
     implementation(project(path: ":wear:protolayout:protolayout-proto", configuration: "shadow"))
     implementation(project(":wear:protolayout:protolayout-expression"))
 
diff --git a/wear/protolayout/protolayout/lint-baseline.xml b/wear/protolayout/protolayout/lint-baseline.xml
new file mode 100644
index 0000000..d2cf132
--- /dev/null
+++ b/wear/protolayout/protolayout/lint-baseline.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.protolayout.expression.ProtoLayoutExperimental` or `@OptIn(markerClass = androidx.wear.protolayout.expression.ProtoLayoutExperimental.class)`"
+        errorLine1="    @IntDef({FONT_WEIGHT_UNDEFINED, FONT_WEIGHT_NORMAL, FONT_WEIGHT_MEDIUM, FONT_WEIGHT_BOLD})"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java"/>
+    </issue>
+
+</issues>
diff --git a/wear/tiles/tiles-material/lint-baseline.xml b/wear/tiles/tiles-material/lint-baseline.xml
index 0faeeff..39bc7f8 100644
--- a/wear/tiles/tiles-material/lint-baseline.xml
+++ b/wear/tiles/tiles-material/lint-baseline.xml
@@ -19,4 +19,94 @@
             file="src/androidTest/java/androidx/wear/tiles/material/RunnerUtils.java"/>
     </issue>
 
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.tiles.TilesExperimental` or `@OptIn(markerClass = androidx.wear.tiles.TilesExperimental.class)`"
+        errorLine1="                .setVariant(variant)"
+        errorLine2="                 ~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/tiles/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.tiles.TilesExperimental` or `@OptIn(markerClass = androidx.wear.tiles.TilesExperimental.class)`"
+        errorLine1="                40, FONT_WEIGHT_MEDIUM, FONT_VARIANT_TITLE, 0.01f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/tiles/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.tiles.TilesExperimental` or `@OptIn(markerClass = androidx.wear.tiles.TilesExperimental.class)`"
+        errorLine1="                34, FONT_WEIGHT_MEDIUM, FONT_VARIANT_TITLE, 0.03f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/tiles/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.tiles.TilesExperimental` or `@OptIn(markerClass = androidx.wear.tiles.TilesExperimental.class)`"
+        errorLine1="                30, FONT_WEIGHT_MEDIUM, FONT_VARIANT_TITLE, 0.03f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/tiles/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.tiles.TilesExperimental` or `@OptIn(markerClass = androidx.wear.tiles.TilesExperimental.class)`"
+        errorLine1="                24, FONT_WEIGHT_MEDIUM, FONT_VARIANT_TITLE, 0.008f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/tiles/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.tiles.TilesExperimental` or `@OptIn(markerClass = androidx.wear.tiles.TilesExperimental.class)`"
+        errorLine1="                20, FONT_WEIGHT_MEDIUM, FONT_VARIANT_TITLE, 0.01f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/tiles/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.tiles.TilesExperimental` or `@OptIn(markerClass = androidx.wear.tiles.TilesExperimental.class)`"
+        errorLine1="                16, FONT_WEIGHT_MEDIUM, FONT_VARIANT_TITLE, 0.01f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/tiles/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.tiles.TilesExperimental` or `@OptIn(markerClass = androidx.wear.tiles.TilesExperimental.class)`"
+        errorLine1="                14, FONT_WEIGHT_MEDIUM, FONT_VARIANT_BODY, 0.01f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/tiles/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.tiles.TilesExperimental` or `@OptIn(markerClass = androidx.wear.tiles.TilesExperimental.class)`"
+        errorLine1="                12, FONT_WEIGHT_MEDIUM, FONT_VARIANT_BODY, 0.01f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/tiles/material/Typography.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.tiles.TilesExperimental` or `@OptIn(markerClass = androidx.wear.tiles.TilesExperimental.class)`"
+        errorLine1="                10, FONT_WEIGHT_MEDIUM, FONT_VARIANT_BODY, 0.01f, isScalable, context);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/tiles/material/Typography.java"/>
+    </issue>
+
 </issues>
diff --git a/wear/tiles/tiles-renderer/lint-baseline.xml b/wear/tiles/tiles-renderer/lint-baseline.xml
new file mode 100644
index 0000000..5a7fd53
--- /dev/null
+++ b/wear/tiles/tiles-renderer/lint-baseline.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.tiles.TilesExperimental` or `@OptIn(markerClass = androidx.wear.tiles.TilesExperimental.class)`"
+        errorLine1="                        .fromByteArray(resources.toByteArray())).toProto();"
+        errorLine2="                         ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/tiles/renderer/TileRenderer.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.tiles.TilesExperimental` or `@OptIn(markerClass = androidx.wear.tiles.TilesExperimental.class)`"
+        errorLine1="                        .fromByteArray(resources.toByteArray())).toProto();"
+        errorLine2="                                                 ~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/tiles/renderer/TileRenderer.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.protolayout.expression.ProtoLayoutExperimental` or `@OptIn(markerClass = androidx.wear.protolayout.expression.ProtoLayoutExperimental.class)`"
+        errorLine1="                        .fromByteArray(layout.toByteArray())).toProto();"
+        errorLine2="                         ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/tiles/renderer/TileRenderer.java"/>
+    </issue>
+
+    <issue
+        id="UnsafeOptInUsageError"
+        message="This declaration is opt-in and its usage should be marked with `@androidx.wear.tiles.TilesExperimental` or `@OptIn(markerClass = androidx.wear.tiles.TilesExperimental.class)`"
+        errorLine1="                        .fromByteArray(layout.toByteArray())).toProto();"
+        errorLine2="                                              ~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/tiles/renderer/TileRenderer.java"/>
+    </issue>
+
+</issues>
diff --git a/wear/tiles/tiles/build.gradle b/wear/tiles/tiles/build.gradle
index ef02109..8b13595 100644
--- a/wear/tiles/tiles/build.gradle
+++ b/wear/tiles/tiles/build.gradle
@@ -28,7 +28,7 @@
     api(project(":wear:protolayout:protolayout-expression"))
     api(libs.guavaListenableFuture)
 
-    implementation("androidx.annotation:annotation-experimental:1.2.0")
+    implementation("androidx.annotation:annotation-experimental:1.3.0")
     implementation("androidx.concurrent:concurrent-futures:1.1.0")
     implementation(project(path: ":wear:tiles:tiles-proto"))
 
diff --git a/wear/watchface/watchface-complications-rendering/build.gradle b/wear/watchface/watchface-complications-rendering/build.gradle
index c79c2e2..fa03502 100644
--- a/wear/watchface/watchface-complications-rendering/build.gradle
+++ b/wear/watchface/watchface-complications-rendering/build.gradle
@@ -52,6 +52,9 @@
     defaultConfig {
         minSdkVersion 26
     }
+    lintOptions {
+        disable 'NullabilityAnnotationsDetector' // False alarm on transformed files.
+    }
 
     // Use Robolectric 4.+
     testOptions.unitTests.includeAndroidResources = true
diff --git a/wear/watchface/watchface-editor/samples/src/main/java/androidx/wear/watchface/editor/sample/StyleConfigFragment.kt b/wear/watchface/watchface-editor/samples/src/main/java/androidx/wear/watchface/editor/sample/StyleConfigFragment.kt
index 924ec20..9d0825c 100644
--- a/wear/watchface/watchface-editor/samples/src/main/java/androidx/wear/watchface/editor/sample/StyleConfigFragment.kt
+++ b/wear/watchface/watchface-editor/samples/src/main/java/androidx/wear/watchface/editor/sample/StyleConfigFragment.kt
@@ -40,7 +40,7 @@
 import androidx.wear.watchface.style.UserStyleSetting.ComplicationSlotsUserStyleSetting
 import androidx.wear.watchface.style.UserStyleSetting.ComplicationSlotsUserStyleSetting.ComplicationSlotsOption
 import androidx.wear.watchface.style.UserStyleSetting.CustomValueUserStyleSetting
-import androidx.wear.watchface.style.UserStyleSetting.CustomValueUserStyleSetting2
+import androidx.wear.watchface.style.UserStyleSetting.LargeCustomValueUserStyleSetting
 import androidx.wear.watchface.style.UserStyleSetting.DoubleRangeUserStyleSetting
 import androidx.wear.watchface.style.UserStyleSetting.DoubleRangeUserStyleSetting.DoubleRangeOption
 import androidx.wear.watchface.style.UserStyleSetting.ListUserStyleSetting
@@ -132,7 +132,7 @@
             is CustomValueUserStyleSetting -> {
                 // Not supported, ignore.
             }
-            is CustomValueUserStyleSetting2 -> {
+            is LargeCustomValueUserStyleSetting -> {
                 // Not supported, ignore.
             }
             is DoubleRangeUserStyleSetting -> {
diff --git a/wear/watchface/watchface-style/api/current.txt b/wear/watchface/watchface-style/api/current.txt
index 5d515cf..fb68cef 100644
--- a/wear/watchface/watchface-style/api/current.txt
+++ b/wear/watchface/watchface-style/api/current.txt
@@ -183,21 +183,6 @@
     property public final byte[] customValue;
   }
 
-  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class UserStyleSetting.CustomValueUserStyleSetting2 extends androidx.wear.watchface.style.UserStyleSetting {
-    ctor public UserStyleSetting.CustomValueUserStyleSetting2(java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, byte[] defaultValue);
-  }
-
-  public static final class UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption extends androidx.wear.watchface.style.UserStyleSetting.Option {
-    ctor public UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption(byte[] customValue);
-    method public byte[] getCustomValue();
-    property public final byte[] customValue;
-    field public static final androidx.wear.watchface.style.UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption.Companion Companion;
-    field public static final int MAX_SIZE = 125000; // 0x1e848
-  }
-
-  public static final class UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption.Companion {
-  }
-
   public static final class UserStyleSetting.DoubleRangeUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
     ctor public UserStyleSetting.DoubleRangeUserStyleSetting(androidx.wear.watchface.style.UserStyleSetting.Id id, android.content.res.Resources resources, @StringRes int displayNameResourceId, @StringRes int descriptionResourceId, android.graphics.drawable.Icon? icon, double minimumValue, double maximumValue, java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, double defaultValue, optional androidx.wear.watchface.style.UserStyleSetting.WatchFaceEditorData? watchFaceEditorData);
     ctor public UserStyleSetting.DoubleRangeUserStyleSetting(androidx.wear.watchface.style.UserStyleSetting.Id id, android.content.res.Resources resources, @StringRes int displayNameResourceId, @StringRes int descriptionResourceId, android.graphics.drawable.Icon? icon, double minimumValue, double maximumValue, java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, double defaultValue);
@@ -226,6 +211,21 @@
   public static final class UserStyleSetting.Id.Companion {
   }
 
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class UserStyleSetting.LargeCustomValueUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
+    ctor public UserStyleSetting.LargeCustomValueUserStyleSetting(java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, byte[] defaultValue);
+  }
+
+  public static final class UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption extends androidx.wear.watchface.style.UserStyleSetting.Option {
+    ctor public UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption(byte[] customValue);
+    method public byte[] getCustomValue();
+    property public final byte[] customValue;
+    field public static final androidx.wear.watchface.style.UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption.Companion Companion;
+    field public static final int MAX_SIZE = 125000; // 0x1e848
+  }
+
+  public static final class UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption.Companion {
+  }
+
   public static class UserStyleSetting.ListUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
     ctor public UserStyleSetting.ListUserStyleSetting(androidx.wear.watchface.style.UserStyleSetting.Id id, android.content.res.Resources resources, @StringRes int displayNameResourceId, @StringRes int descriptionResourceId, android.graphics.drawable.Icon? icon, java.util.List<androidx.wear.watchface.style.UserStyleSetting.ListUserStyleSetting.ListOption> options, java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, optional androidx.wear.watchface.style.UserStyleSetting.ListUserStyleSetting.ListOption defaultOption, optional androidx.wear.watchface.style.UserStyleSetting.WatchFaceEditorData? watchFaceEditorData);
     ctor public UserStyleSetting.ListUserStyleSetting(androidx.wear.watchface.style.UserStyleSetting.Id id, android.content.res.Resources resources, @StringRes int displayNameResourceId, @StringRes int descriptionResourceId, android.graphics.drawable.Icon? icon, java.util.List<androidx.wear.watchface.style.UserStyleSetting.ListUserStyleSetting.ListOption> options, java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, optional androidx.wear.watchface.style.UserStyleSetting.ListUserStyleSetting.ListOption defaultOption);
diff --git a/wear/watchface/watchface-style/api/public_plus_experimental_current.txt b/wear/watchface/watchface-style/api/public_plus_experimental_current.txt
index 5d515cf..fb68cef 100644
--- a/wear/watchface/watchface-style/api/public_plus_experimental_current.txt
+++ b/wear/watchface/watchface-style/api/public_plus_experimental_current.txt
@@ -183,21 +183,6 @@
     property public final byte[] customValue;
   }
 
-  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class UserStyleSetting.CustomValueUserStyleSetting2 extends androidx.wear.watchface.style.UserStyleSetting {
-    ctor public UserStyleSetting.CustomValueUserStyleSetting2(java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, byte[] defaultValue);
-  }
-
-  public static final class UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption extends androidx.wear.watchface.style.UserStyleSetting.Option {
-    ctor public UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption(byte[] customValue);
-    method public byte[] getCustomValue();
-    property public final byte[] customValue;
-    field public static final androidx.wear.watchface.style.UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption.Companion Companion;
-    field public static final int MAX_SIZE = 125000; // 0x1e848
-  }
-
-  public static final class UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption.Companion {
-  }
-
   public static final class UserStyleSetting.DoubleRangeUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
     ctor public UserStyleSetting.DoubleRangeUserStyleSetting(androidx.wear.watchface.style.UserStyleSetting.Id id, android.content.res.Resources resources, @StringRes int displayNameResourceId, @StringRes int descriptionResourceId, android.graphics.drawable.Icon? icon, double minimumValue, double maximumValue, java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, double defaultValue, optional androidx.wear.watchface.style.UserStyleSetting.WatchFaceEditorData? watchFaceEditorData);
     ctor public UserStyleSetting.DoubleRangeUserStyleSetting(androidx.wear.watchface.style.UserStyleSetting.Id id, android.content.res.Resources resources, @StringRes int displayNameResourceId, @StringRes int descriptionResourceId, android.graphics.drawable.Icon? icon, double minimumValue, double maximumValue, java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, double defaultValue);
@@ -226,6 +211,21 @@
   public static final class UserStyleSetting.Id.Companion {
   }
 
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class UserStyleSetting.LargeCustomValueUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
+    ctor public UserStyleSetting.LargeCustomValueUserStyleSetting(java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, byte[] defaultValue);
+  }
+
+  public static final class UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption extends androidx.wear.watchface.style.UserStyleSetting.Option {
+    ctor public UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption(byte[] customValue);
+    method public byte[] getCustomValue();
+    property public final byte[] customValue;
+    field public static final androidx.wear.watchface.style.UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption.Companion Companion;
+    field public static final int MAX_SIZE = 125000; // 0x1e848
+  }
+
+  public static final class UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption.Companion {
+  }
+
   public static class UserStyleSetting.ListUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
     ctor public UserStyleSetting.ListUserStyleSetting(androidx.wear.watchface.style.UserStyleSetting.Id id, android.content.res.Resources resources, @StringRes int displayNameResourceId, @StringRes int descriptionResourceId, android.graphics.drawable.Icon? icon, java.util.List<androidx.wear.watchface.style.UserStyleSetting.ListUserStyleSetting.ListOption> options, java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, optional androidx.wear.watchface.style.UserStyleSetting.ListUserStyleSetting.ListOption defaultOption, optional androidx.wear.watchface.style.UserStyleSetting.WatchFaceEditorData? watchFaceEditorData);
     ctor public UserStyleSetting.ListUserStyleSetting(androidx.wear.watchface.style.UserStyleSetting.Id id, android.content.res.Resources resources, @StringRes int displayNameResourceId, @StringRes int descriptionResourceId, android.graphics.drawable.Icon? icon, java.util.List<androidx.wear.watchface.style.UserStyleSetting.ListUserStyleSetting.ListOption> options, java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, optional androidx.wear.watchface.style.UserStyleSetting.ListUserStyleSetting.ListOption defaultOption);
diff --git a/wear/watchface/watchface-style/api/restricted_current.txt b/wear/watchface/watchface-style/api/restricted_current.txt
index 5d515cf..fb68cef 100644
--- a/wear/watchface/watchface-style/api/restricted_current.txt
+++ b/wear/watchface/watchface-style/api/restricted_current.txt
@@ -183,21 +183,6 @@
     property public final byte[] customValue;
   }
 
-  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class UserStyleSetting.CustomValueUserStyleSetting2 extends androidx.wear.watchface.style.UserStyleSetting {
-    ctor public UserStyleSetting.CustomValueUserStyleSetting2(java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, byte[] defaultValue);
-  }
-
-  public static final class UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption extends androidx.wear.watchface.style.UserStyleSetting.Option {
-    ctor public UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption(byte[] customValue);
-    method public byte[] getCustomValue();
-    property public final byte[] customValue;
-    field public static final androidx.wear.watchface.style.UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption.Companion Companion;
-    field public static final int MAX_SIZE = 125000; // 0x1e848
-  }
-
-  public static final class UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption.Companion {
-  }
-
   public static final class UserStyleSetting.DoubleRangeUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
     ctor public UserStyleSetting.DoubleRangeUserStyleSetting(androidx.wear.watchface.style.UserStyleSetting.Id id, android.content.res.Resources resources, @StringRes int displayNameResourceId, @StringRes int descriptionResourceId, android.graphics.drawable.Icon? icon, double minimumValue, double maximumValue, java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, double defaultValue, optional androidx.wear.watchface.style.UserStyleSetting.WatchFaceEditorData? watchFaceEditorData);
     ctor public UserStyleSetting.DoubleRangeUserStyleSetting(androidx.wear.watchface.style.UserStyleSetting.Id id, android.content.res.Resources resources, @StringRes int displayNameResourceId, @StringRes int descriptionResourceId, android.graphics.drawable.Icon? icon, double minimumValue, double maximumValue, java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, double defaultValue);
@@ -226,6 +211,21 @@
   public static final class UserStyleSetting.Id.Companion {
   }
 
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class UserStyleSetting.LargeCustomValueUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
+    ctor public UserStyleSetting.LargeCustomValueUserStyleSetting(java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, byte[] defaultValue);
+  }
+
+  public static final class UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption extends androidx.wear.watchface.style.UserStyleSetting.Option {
+    ctor public UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption(byte[] customValue);
+    method public byte[] getCustomValue();
+    property public final byte[] customValue;
+    field public static final androidx.wear.watchface.style.UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption.Companion Companion;
+    field public static final int MAX_SIZE = 125000; // 0x1e848
+  }
+
+  public static final class UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption.Companion {
+  }
+
   public static class UserStyleSetting.ListUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
     ctor public UserStyleSetting.ListUserStyleSetting(androidx.wear.watchface.style.UserStyleSetting.Id id, android.content.res.Resources resources, @StringRes int displayNameResourceId, @StringRes int descriptionResourceId, android.graphics.drawable.Icon? icon, java.util.List<androidx.wear.watchface.style.UserStyleSetting.ListUserStyleSetting.ListOption> options, java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, optional androidx.wear.watchface.style.UserStyleSetting.ListUserStyleSetting.ListOption defaultOption, optional androidx.wear.watchface.style.UserStyleSetting.WatchFaceEditorData? watchFaceEditorData);
     ctor public UserStyleSetting.ListUserStyleSetting(androidx.wear.watchface.style.UserStyleSetting.Id id, android.content.res.Resources resources, @StringRes int displayNameResourceId, @StringRes int descriptionResourceId, android.graphics.drawable.Icon? icon, java.util.List<androidx.wear.watchface.style.UserStyleSetting.ListUserStyleSetting.ListOption> options, java.util.Collection<? extends androidx.wear.watchface.style.WatchFaceLayer> affectsWatchFaceLayers, optional androidx.wear.watchface.style.UserStyleSetting.ListUserStyleSetting.ListOption defaultOption);
diff --git a/wear/watchface/watchface-style/src/main/java/androidx/wear/watchface/style/CurrentUserStyleRepository.kt b/wear/watchface/watchface-style/src/main/java/androidx/wear/watchface/style/CurrentUserStyleRepository.kt
index a7528bc..6fd3d02 100644
--- a/wear/watchface/watchface-style/src/main/java/androidx/wear/watchface/style/CurrentUserStyleRepository.kt
+++ b/wear/watchface/watchface-style/src/main/java/androidx/wear/watchface/style/CurrentUserStyleRepository.kt
@@ -530,7 +530,7 @@
                     complicationSlotsUserStyleSettingCount++
                 is UserStyleSetting.CustomValueUserStyleSetting ->
                     customValueUserStyleSettingCount++
-                is UserStyleSetting.CustomValueUserStyleSetting2 ->
+                is UserStyleSetting.LargeCustomValueUserStyleSetting ->
                     customValueUserStyleSettingCount++
                 else -> {
                     // Nothing
diff --git a/wear/watchface/watchface-style/src/main/java/androidx/wear/watchface/style/UserStyleSetting.kt b/wear/watchface/watchface-style/src/main/java/androidx/wear/watchface/style/UserStyleSetting.kt
index 3341e85..8ce3c6c 100644
--- a/wear/watchface/watchface-style/src/main/java/androidx/wear/watchface/style/UserStyleSetting.kt
+++ b/wear/watchface/watchface-style/src/main/java/androidx/wear/watchface/style/UserStyleSetting.kt
@@ -312,7 +312,7 @@
     }
 
     public companion object {
-        @Suppress("NewApi") // CustomValueUserStyleSetting2
+        @Suppress("NewApi") // LargeCustomValueUserStyleSetting
         internal fun createFromWireFormat(
             wireFormat: UserStyleSettingWireFormat
         ): UserStyleSetting =
@@ -322,7 +322,7 @@
                     ComplicationSlotsUserStyleSetting(wireFormat)
                 is CustomValueUserStyleSettingWireFormat -> CustomValueUserStyleSetting(wireFormat)
                 is CustomValueUserStyleSetting2WireFormat ->
-                    CustomValueUserStyleSetting2(wireFormat)
+                    LargeCustomValueUserStyleSetting(wireFormat)
                 is DoubleRangeUserStyleSettingWireFormat -> DoubleRangeUserStyleSetting(wireFormat)
                 is ListUserStyleSettingWireFormat -> ListUserStyleSetting(wireFormat)
                 is LongRangeUserStyleSettingWireFormat -> LongRangeUserStyleSetting(wireFormat)
@@ -659,7 +659,7 @@
                     is CustomValueOptionWireFormat ->
                         CustomValueUserStyleSetting.CustomValueOption(wireFormat)
                     is CustomValueOption2WireFormat ->
-                        CustomValueUserStyleSetting2.CustomValueOption(wireFormat)
+                        LargeCustomValueUserStyleSetting.CustomValueOption(wireFormat)
                     is DoubleRangeOptionWireFormat ->
                         DoubleRangeUserStyleSetting.DoubleRangeOption(wireFormat)
                     is ListOptionWireFormat -> ListUserStyleSetting.ListOption(wireFormat)
@@ -2817,11 +2817,11 @@
     /**
      * An application specific style setting. This style is ignored by the system editor. This is
      * expected to be used in conjunction with an on watch face editor. Only a single
-     * [ComplicationSlotsUserStyleSetting] or [CustomValueUserStyleSetting2] is permitted in the
+     * [ComplicationSlotsUserStyleSetting] or [LargeCustomValueUserStyleSetting] is permitted in the
      * [UserStyleSchema].
      *
      * The [CustomValueOption] can store at most [Option.Id.MAX_LENGTH] bytes. If you need more
-     * storage, consider using [CustomValueUserStyleSetting2].
+     * storage, consider using [LargeCustomValueUserStyleSetting].
      */
     public class CustomValueUserStyleSetting : UserStyleSetting {
         internal companion object {
@@ -2909,19 +2909,19 @@
      * An application specific style setting which supports a larger maximum size than
      * [CustomValueUserStyleSetting]. This style is ignored by the system editor. This is expected
      * to be used in conjunction with an on watch face editor. Only a single
-     * [ComplicationSlotsUserStyleSetting] or [CustomValueUserStyleSetting2] is permitted in the
+     * [ComplicationSlotsUserStyleSetting] or [LargeCustomValueUserStyleSetting] is permitted in the
      * [UserStyleSchema].
      *
      * The [CustomValueOption] can store at most [Option.Id.MAX_LENGTH] bytes.
      */
     @RequiresApi(Build.VERSION_CODES.TIRAMISU)
-    public class CustomValueUserStyleSetting2 : UserStyleSetting {
+    public class LargeCustomValueUserStyleSetting : UserStyleSetting {
         internal companion object {
             internal const val CUSTOM_VALUE_USER_STYLE_SETTING_ID = "CustomValue"
         }
 
         /**
-         * Constructs a CustomValueUserStyleSetting2.
+         * Constructs a LargeCustomValueUserStyleSetting.
          *
          * @param affectsWatchFaceLayers Used by the style configuration UI. Describes which watch
          *   face rendering layers this style affects.
@@ -2981,7 +2981,7 @@
             ) : super(Id(wireFormat.mId), emptyList())
 
             internal override fun getUserStyleSettingClass(): Class<out UserStyleSetting> =
-                CustomValueUserStyleSetting2::class.java
+                LargeCustomValueUserStyleSetting::class.java
 
             @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
             override fun toWireFormat(): CustomValueOption2WireFormat =
diff --git a/wear/watchface/watchface-style/src/test/java/androidx/wear/watchface/style/StyleParcelableTest.kt b/wear/watchface/watchface-style/src/test/java/androidx/wear/watchface/style/StyleParcelableTest.kt
index 9159324..1a449b9 100644
--- a/wear/watchface/watchface-style/src/test/java/androidx/wear/watchface/style/StyleParcelableTest.kt
+++ b/wear/watchface/watchface-style/src/test/java/androidx/wear/watchface/style/StyleParcelableTest.kt
@@ -26,7 +26,7 @@
 import androidx.wear.watchface.style.UserStyleSetting.BooleanUserStyleSetting
 import androidx.wear.watchface.style.UserStyleSetting.ComplicationSlotsUserStyleSetting
 import androidx.wear.watchface.style.UserStyleSetting.CustomValueUserStyleSetting
-import androidx.wear.watchface.style.UserStyleSetting.CustomValueUserStyleSetting2
+import androidx.wear.watchface.style.UserStyleSetting.LargeCustomValueUserStyleSetting
 import androidx.wear.watchface.style.UserStyleSetting.DoubleRangeUserStyleSetting
 import androidx.wear.watchface.style.UserStyleSetting.ListUserStyleSetting
 import androidx.wear.watchface.style.UserStyleSetting.ListUserStyleSetting.ListOption
@@ -194,8 +194,10 @@
                 listOf(WatchFaceLayer.BASE),
                 true
             )
-        val styleSetting4 =
-            CustomValueUserStyleSetting2(listOf(WatchFaceLayer.BASE), "default".encodeToByteArray())
+        val styleSetting4 = LargeCustomValueUserStyleSetting(
+            listOf(WatchFaceLayer.BASE),
+            "default".encodeToByteArray()
+        )
         val srcSchema =
             UserStyleSchema(listOf(styleSetting1, styleSetting2, styleSetting3, styleSetting4))
 
@@ -263,7 +265,7 @@
         assertThat(schema.userStyleSettings[2].affectedWatchFaceLayers.first())
             .isEqualTo(WatchFaceLayer.BASE)
 
-        assertThat(schema.userStyleSettings[3] is CustomValueUserStyleSetting2).isTrue()
+        assertThat(schema.userStyleSettings[3] is LargeCustomValueUserStyleSetting).isTrue()
         assertThat(schema.userStyleSettings[3].defaultOption.id.value.decodeToString())
             .isEqualTo("default")
         assertThat(schema.userStyleSettings[3].affectedWatchFaceLayers.size).isEqualTo(1)
diff --git a/wear/watchface/watchface-style/src/test/java/androidx/wear/watchface/style/UserStyleSettingTest.kt b/wear/watchface/watchface-style/src/test/java/androidx/wear/watchface/style/UserStyleSettingTest.kt
index 5fa5892..ff25cdc 100644
--- a/wear/watchface/watchface-style/src/test/java/androidx/wear/watchface/style/UserStyleSettingTest.kt
+++ b/wear/watchface/watchface-style/src/test/java/androidx/wear/watchface/style/UserStyleSettingTest.kt
@@ -193,19 +193,19 @@
     @Test
     public fun maximumCustomValueOption2Size() {
         // OK.
-        UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption(
+        UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption(
             ByteArray(Option.Id.MAX_LENGTH + 1)
         )
 
-        UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption(
-            ByteArray(UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption.MAX_SIZE)
+        UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption(
+            ByteArray(UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption.MAX_SIZE)
         )
 
         try {
             // Not OK.
-            UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption(
+            UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption(
                 ByteArray(
-                    UserStyleSetting.CustomValueUserStyleSetting2.CustomValueOption.MAX_SIZE + 1
+                    UserStyleSetting.LargeCustomValueUserStyleSetting.CustomValueOption.MAX_SIZE + 1
                 )
             )
             fail("Should have thrown an exception")
diff --git a/wear/watchface/watchface/lint-baseline.xml b/wear/watchface/watchface/lint-baseline.xml
index 3e45aa6..54a3726 100644
--- a/wear/watchface/watchface/lint-baseline.xml
+++ b/wear/watchface/watchface/lint-baseline.xml
@@ -4,7 +4,7 @@
     <issue
         id="SupportAnnotationUsage"
         message="Did you mean `@get:RestrictTo`? Without `get:` this annotates the constructor parameter itself instead of the associated getter."
-        errorLine1="    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)"
+        errorLine1="    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) public val boundingArc: BoundingArc?"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="src/main/java/androidx/wear/watchface/ComplicationSlot.kt"/>
diff --git a/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/ComplicationHelperActivityTest.kt b/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/ComplicationHelperActivityTest.kt
index bade28d..6550522 100644
--- a/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/ComplicationHelperActivityTest.kt
+++ b/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/ComplicationHelperActivityTest.kt
@@ -29,10 +29,10 @@
 import androidx.wear.watchface.complications.data.ComplicationType.MONOCHROMATIC_IMAGE
 import androidx.wear.watchface.complications.data.ComplicationType.SHORT_TEXT
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.doReturn
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.never
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.TimeUnit
 import org.junit.Test
diff --git a/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/test/XmlDefinedUserStyleSchemaAndComplicationSlotsTest.kt b/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/test/XmlDefinedUserStyleSchemaAndComplicationSlotsTest.kt
index f375f2a..c3acedb 100644
--- a/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/test/XmlDefinedUserStyleSchemaAndComplicationSlotsTest.kt
+++ b/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/test/XmlDefinedUserStyleSchemaAndComplicationSlotsTest.kt
@@ -67,6 +67,7 @@
 import org.junit.Assert
 import org.junit.Assume
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
@@ -215,6 +216,7 @@
         assertThat(existingInstance).isNull()
     }
 
+    @Ignore // b/275354644
     @Test
     @Suppress("Deprecation", "NewApi") // userStyleSettings
     public fun staticSchemaAndComplicationsRead() {
diff --git a/wear/wear/lint-baseline.xml b/wear/wear/lint-baseline.xml
index 38571b3..d2d3f5c 100644
--- a/wear/wear/lint-baseline.xml
+++ b/wear/wear/lint-baseline.xml
@@ -124,87 +124,6 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="        AmbientCallback getAmbientCallback();"
-        errorLine2="        ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/wear/ambient/AmbientModeSupport.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="        public void onEnterAmbient(Bundle ambientDetails) {}"
-        errorLine2="                                   ~~~~~~">
-        <location
-            file="src/main/java/androidx/wear/ambient/AmbientModeSupport.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public void onAttach(Context context) {"
-        errorLine2="                         ~~~~~~~">
-        <location
-            file="src/main/java/androidx/wear/ambient/AmbientModeSupport.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public void onCreate(Bundle savedInstanceState) {"
-        errorLine2="                         ~~~~~~">
-        <location
-            file="src/main/java/androidx/wear/ambient/AmbientModeSupport.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public static &lt;T extends FragmentActivity> AmbientController attach(T activity) {"
-        errorLine2="                                               ~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/wear/ambient/AmbientModeSupport.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {"
-        errorLine2="                     ~~~~~~">
-        <location
-            file="src/main/java/androidx/wear/ambient/AmbientModeSupport.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {"
-        errorLine2="                                    ~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/wear/ambient/AmbientModeSupport.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {"
-        errorLine2="                                                       ~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/wear/ambient/AmbientModeSupport.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {"
-        errorLine2="                                                                           ~~~~~~~~">
-        <location
-            file="src/main/java/androidx/wear/ambient/AmbientModeSupport.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
         errorLine1="    public CircledImageView(Context context) {"
         errorLine2="                            ~~~~~~~">
         <location
diff --git a/webkit/webkit/lint-baseline.xml b/webkit/webkit/lint-baseline.xml
deleted file mode 100644
index 20d81ba..0000000
--- a/webkit/webkit/lint-baseline.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-alpha05" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-alpha05)" variant="all" version="8.0.0-alpha05">
-
-    <issue
-        id="NewApi"
-        message="Multi-catch with these reflection exceptions requires API level 19 (current min is 14) because they get compiled to the common but new super type `ReflectiveOperationException`. As a workaround either create individual catch statements, or catch `Exception`."
-        errorLine1="            } catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException"
-        errorLine2="                     ^">
-        <location
-            file="src/main/java/androidx/webkit/WebViewCompat.java"/>
-    </issue>
-
-</issues>
diff --git a/window/window-java/src/androidTest/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapterTest.kt b/window/window-java/src/androidTest/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapterTest.kt
index bd6ae04..ccf2fc5 100644
--- a/window/window-java/src/androidTest/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapterTest.kt
+++ b/window/window-java/src/androidTest/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapterTest.kt
@@ -23,8 +23,8 @@
 import androidx.window.layout.FoldingFeature
 import androidx.window.layout.WindowInfoTracker
 import androidx.window.layout.WindowLayoutInfo
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.whenever
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
 import kotlinx.coroutines.channels.Channel
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.receiveAsFlow
diff --git a/window/window-rxjava2/src/androidTest/java/androidx/window/rxjava2/layout/WindowInfoTrackerRxTest.kt b/window/window-rxjava2/src/androidTest/java/androidx/window/rxjava2/layout/WindowInfoTrackerRxTest.kt
index 038ad11..7415e37 100644
--- a/window/window-rxjava2/src/androidTest/java/androidx/window/rxjava2/layout/WindowInfoTrackerRxTest.kt
+++ b/window/window-rxjava2/src/androidTest/java/androidx/window/rxjava2/layout/WindowInfoTrackerRxTest.kt
@@ -22,8 +22,8 @@
 import androidx.window.layout.FoldingFeature
 import androidx.window.layout.WindowInfoTracker
 import androidx.window.layout.WindowLayoutInfo
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.whenever
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
 import kotlinx.coroutines.flow.flowOf
 import org.junit.Test
 
diff --git a/window/window-rxjava3/src/androidTest/java/androidx/window/rxjava3/layout/WindowInfoTrackerRxTest.kt b/window/window-rxjava3/src/androidTest/java/androidx/window/rxjava3/layout/WindowInfoTrackerRxTest.kt
index 8630cc6..b32bfa0 100644
--- a/window/window-rxjava3/src/androidTest/java/androidx/window/rxjava3/layout/WindowInfoTrackerRxTest.kt
+++ b/window/window-rxjava3/src/androidTest/java/androidx/window/rxjava3/layout/WindowInfoTrackerRxTest.kt
@@ -22,8 +22,8 @@
 import androidx.window.layout.FoldingFeature
 import androidx.window.layout.WindowInfoTracker
 import androidx.window.layout.WindowLayoutInfo
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.whenever
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
 import kotlinx.coroutines.flow.flowOf
 import org.junit.Test
 
diff --git a/window/window/src/androidTest/java/androidx/window/embedding/ActivityFilterTest.kt b/window/window/src/androidTest/java/androidx/window/embedding/ActivityFilterTest.kt
index 44e9c5b..ec34298 100644
--- a/window/window/src/androidTest/java/androidx/window/embedding/ActivityFilterTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/embedding/ActivityFilterTest.kt
@@ -20,9 +20,9 @@
 import android.content.ComponentName
 import android.content.Intent
 import com.google.common.truth.Truth.assertWithMessage
-import com.nhaarman.mockitokotlin2.doReturn
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.whenever
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
 import org.junit.Assert.assertEquals
 import org.junit.Before
 import org.junit.Test
diff --git a/window/window/src/androidTest/java/androidx/window/embedding/EmbeddingAdapterTest.kt b/window/window/src/androidTest/java/androidx/window/embedding/EmbeddingAdapterTest.kt
index c3afe8f..9d0aaba 100644
--- a/window/window/src/androidTest/java/androidx/window/embedding/EmbeddingAdapterTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/embedding/EmbeddingAdapterTest.kt
@@ -28,8 +28,8 @@
 import androidx.window.extensions.WindowExtensions
 import androidx.window.extensions.embedding.SplitAttributes.LayoutDirection.TOP_TO_BOTTOM
 import androidx.window.extensions.embedding.SplitAttributes.SplitType.RatioSplitType
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.whenever
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
 import org.junit.Assert.assertEquals
 import org.junit.Before
 import org.junit.Test
diff --git a/window/window/src/androidTest/java/androidx/window/layout/adapter/extensions/ExtensionWindowLayoutInfoBackendTest.kt b/window/window/src/androidTest/java/androidx/window/layout/adapter/extensions/ExtensionWindowLayoutInfoBackendTest.kt
index 2b80d87..ff28be7 100644
--- a/window/window/src/androidTest/java/androidx/window/layout/adapter/extensions/ExtensionWindowLayoutInfoBackendTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/layout/adapter/extensions/ExtensionWindowLayoutInfoBackendTest.kt
@@ -43,13 +43,13 @@
 import androidx.window.layout.WindowLayoutInfo
 import androidx.window.layout.WindowMetricsCalculatorCompat
 import androidx.window.layout.adapter.extensions.ExtensionsWindowLayoutInfoAdapter.translate
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.argumentCaptor
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
-import com.nhaarman.mockitokotlin2.whenever
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
diff --git a/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarCompatDeviceTest.kt b/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarCompatDeviceTest.kt
index 783c535..8d3873e 100644
--- a/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarCompatDeviceTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarCompatDeviceTest.kt
@@ -35,12 +35,12 @@
 import androidx.window.layout.WindowLayoutInfo
 import androidx.window.sidecar.SidecarDisplayFeature
 import androidx.window.sidecar.SidecarWindowLayoutInfo
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.argThat
-import com.nhaarman.mockitokotlin2.atLeastOnce
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argThat
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
diff --git a/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarCompatTest.kt b/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarCompatTest.kt
index 0772127..305c4f8 100644
--- a/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarCompatTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarCompatTest.kt
@@ -44,19 +44,19 @@
 import androidx.window.sidecar.SidecarInterface
 import androidx.window.sidecar.SidecarInterface.SidecarCallback
 import androidx.window.sidecar.SidecarWindowLayoutInfo
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.argThat
-import com.nhaarman.mockitokotlin2.argumentCaptor
-import com.nhaarman.mockitokotlin2.atLeastOnce
-import com.nhaarman.mockitokotlin2.doAnswer
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.reset
-import com.nhaarman.mockitokotlin2.spy
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
-import com.nhaarman.mockitokotlin2.verifyZeroInteractions
-import com.nhaarman.mockitokotlin2.whenever
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argThat
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.doAnswer
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.reset
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.verifyZeroInteractions
+import org.mockito.kotlin.whenever
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertNotNull
 import org.junit.Assert.assertTrue
diff --git a/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendIntegrationTest.kt b/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendIntegrationTest.kt
index bde27e9..9ec6aa3 100644
--- a/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendIntegrationTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendIntegrationTest.kt
@@ -37,11 +37,11 @@
 import androidx.window.layout.WindowLayoutInfo
 import androidx.window.layout.WindowMetricsCalculator
 import androidx.window.layout.adapter.sidecar.ExtensionInterfaceCompat.ExtensionCallbackInterface
-import com.nhaarman.mockitokotlin2.any
-import com.nhaarman.mockitokotlin2.argThat
-import com.nhaarman.mockitokotlin2.atLeastOnce
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argThat
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertTrue
 import org.junit.Assume
diff --git a/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendTest.kt b/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendTest.kt
index 4cd3c48..434cc92 100644
--- a/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendTest.kt
@@ -30,10 +30,10 @@
 import androidx.window.layout.HardwareFoldingFeature.Type.Companion.HINGE
 import androidx.window.layout.WindowLayoutInfo
 import com.google.common.util.concurrent.MoreExecutors
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertNotNull
 import org.junit.Assert.assertTrue