Merge "Run EntityParser tests with KSP" into androidx-main
diff --git a/activity/activity-compose/api/current.txt b/activity/activity-compose/api/current.txt
index d593ffc..0eb5edc 100644
--- a/activity/activity-compose/api/current.txt
+++ b/activity/activity-compose/api/current.txt
@@ -17,15 +17,15 @@
   }
 
   public final class LocalActivityResultRegistryOwner {
-    method public androidx.compose.runtime.ProvidableCompositionLocal<androidx.activity.result.ActivityResultRegistryOwner> asProvidableCompositionLocal();
     method @androidx.compose.runtime.Composable public androidx.activity.result.ActivityResultRegistryOwner getCurrent();
+    method public infix androidx.compose.runtime.ProvidedValue<androidx.activity.result.ActivityResultRegistryOwner> provides(androidx.activity.result.ActivityResultRegistryOwner registryOwner);
     property @androidx.compose.runtime.Composable public final androidx.activity.result.ActivityResultRegistryOwner current;
     field public static final androidx.activity.compose.LocalActivityResultRegistryOwner INSTANCE;
   }
 
   public final class LocalOnBackPressedDispatcherOwner {
-    method public androidx.compose.runtime.ProvidableCompositionLocal<androidx.activity.OnBackPressedDispatcherOwner> asProvidableCompositionLocal();
     method @androidx.compose.runtime.Composable public androidx.activity.OnBackPressedDispatcherOwner getCurrent();
+    method public infix androidx.compose.runtime.ProvidedValue<androidx.activity.OnBackPressedDispatcherOwner> provides(androidx.activity.OnBackPressedDispatcherOwner dispatcherOwner);
     property @androidx.compose.runtime.Composable public final androidx.activity.OnBackPressedDispatcherOwner current;
     field public static final androidx.activity.compose.LocalOnBackPressedDispatcherOwner INSTANCE;
   }
diff --git a/activity/activity-compose/api/public_plus_experimental_current.txt b/activity/activity-compose/api/public_plus_experimental_current.txt
index d593ffc..0eb5edc 100644
--- a/activity/activity-compose/api/public_plus_experimental_current.txt
+++ b/activity/activity-compose/api/public_plus_experimental_current.txt
@@ -17,15 +17,15 @@
   }
 
   public final class LocalActivityResultRegistryOwner {
-    method public androidx.compose.runtime.ProvidableCompositionLocal<androidx.activity.result.ActivityResultRegistryOwner> asProvidableCompositionLocal();
     method @androidx.compose.runtime.Composable public androidx.activity.result.ActivityResultRegistryOwner getCurrent();
+    method public infix androidx.compose.runtime.ProvidedValue<androidx.activity.result.ActivityResultRegistryOwner> provides(androidx.activity.result.ActivityResultRegistryOwner registryOwner);
     property @androidx.compose.runtime.Composable public final androidx.activity.result.ActivityResultRegistryOwner current;
     field public static final androidx.activity.compose.LocalActivityResultRegistryOwner INSTANCE;
   }
 
   public final class LocalOnBackPressedDispatcherOwner {
-    method public androidx.compose.runtime.ProvidableCompositionLocal<androidx.activity.OnBackPressedDispatcherOwner> asProvidableCompositionLocal();
     method @androidx.compose.runtime.Composable public androidx.activity.OnBackPressedDispatcherOwner getCurrent();
+    method public infix androidx.compose.runtime.ProvidedValue<androidx.activity.OnBackPressedDispatcherOwner> provides(androidx.activity.OnBackPressedDispatcherOwner dispatcherOwner);
     property @androidx.compose.runtime.Composable public final androidx.activity.OnBackPressedDispatcherOwner current;
     field public static final androidx.activity.compose.LocalOnBackPressedDispatcherOwner INSTANCE;
   }
diff --git a/activity/activity-compose/api/restricted_current.txt b/activity/activity-compose/api/restricted_current.txt
index d593ffc..0eb5edc 100644
--- a/activity/activity-compose/api/restricted_current.txt
+++ b/activity/activity-compose/api/restricted_current.txt
@@ -17,15 +17,15 @@
   }
 
   public final class LocalActivityResultRegistryOwner {
-    method public androidx.compose.runtime.ProvidableCompositionLocal<androidx.activity.result.ActivityResultRegistryOwner> asProvidableCompositionLocal();
     method @androidx.compose.runtime.Composable public androidx.activity.result.ActivityResultRegistryOwner getCurrent();
+    method public infix androidx.compose.runtime.ProvidedValue<androidx.activity.result.ActivityResultRegistryOwner> provides(androidx.activity.result.ActivityResultRegistryOwner registryOwner);
     property @androidx.compose.runtime.Composable public final androidx.activity.result.ActivityResultRegistryOwner current;
     field public static final androidx.activity.compose.LocalActivityResultRegistryOwner INSTANCE;
   }
 
   public final class LocalOnBackPressedDispatcherOwner {
-    method public androidx.compose.runtime.ProvidableCompositionLocal<androidx.activity.OnBackPressedDispatcherOwner> asProvidableCompositionLocal();
     method @androidx.compose.runtime.Composable public androidx.activity.OnBackPressedDispatcherOwner getCurrent();
+    method public infix androidx.compose.runtime.ProvidedValue<androidx.activity.OnBackPressedDispatcherOwner> provides(androidx.activity.OnBackPressedDispatcherOwner dispatcherOwner);
     property @androidx.compose.runtime.Composable public final androidx.activity.OnBackPressedDispatcherOwner current;
     field public static final androidx.activity.compose.LocalOnBackPressedDispatcherOwner INSTANCE;
   }
diff --git a/activity/activity-compose/src/androidTest/java/androidx/activity/compose/ActivityResultRegistryTest.kt b/activity/activity-compose/src/androidTest/java/androidx/activity/compose/ActivityResultRegistryTest.kt
index 6d22c1d..84d3ec1 100644
--- a/activity/activity-compose/src/androidTest/java/androidx/activity/compose/ActivityResultRegistryTest.kt
+++ b/activity/activity-compose/src/androidTest/java/androidx/activity/compose/ActivityResultRegistryTest.kt
@@ -64,8 +64,7 @@
         var launcher: ActivityResultLauncher<Intent>? by mutableStateOf(null)
         composeTestRule.setContent {
             CompositionLocalProvider(
-                LocalActivityResultRegistryOwner.asProvidableCompositionLocal()
-                    provides registryOwner
+                LocalActivityResultRegistryOwner provides registryOwner
             ) {
                 launcher = registerForActivityResult(
                     ActivityResultContracts.StartActivityForResult()
@@ -92,8 +91,7 @@
         activityScenario.onActivity { activity ->
             (activity as ComponentActivity).setContent {
                 CompositionLocalProvider(
-                    LocalActivityResultRegistryOwner.asProvidableCompositionLocal()
-                        provides registryOwner
+                    LocalActivityResultRegistryOwner provides registryOwner
                 ) {
                     launcher = registerForActivityResult(
                         ActivityResultContracts.StartActivityForResult()
diff --git a/activity/activity-compose/src/androidTest/java/androidx/activity/compose/BackPressedDispatcherOwnerTest.kt b/activity/activity-compose/src/androidTest/java/androidx/activity/compose/BackPressedDispatcherOwnerTest.kt
index f3f93ac..bf7dab0 100644
--- a/activity/activity-compose/src/androidTest/java/androidx/activity/compose/BackPressedDispatcherOwnerTest.kt
+++ b/activity/activity-compose/src/androidTest/java/androidx/activity/compose/BackPressedDispatcherOwnerTest.kt
@@ -69,8 +69,7 @@
 
         composeTestRule.setContent {
             CompositionLocalProvider(
-                LocalOnBackPressedDispatcherOwner.asProvidableCompositionLocal()
-                    provides testDispatcherOwner
+                LocalOnBackPressedDispatcherOwner provides testDispatcherOwner
             ) {
                 innerDispatcherOwner = LocalOnBackPressedDispatcherOwner.current
             }
diff --git a/activity/activity-compose/src/main/java/androidx/activity/compose/ActivityResultRegistry.kt b/activity/activity-compose/src/main/java/androidx/activity/compose/ActivityResultRegistry.kt
index 782e223..a2d42a9 100644
--- a/activity/activity-compose/src/main/java/androidx/activity/compose/ActivityResultRegistry.kt
+++ b/activity/activity-compose/src/main/java/androidx/activity/compose/ActivityResultRegistry.kt
@@ -21,7 +21,7 @@
 import androidx.activity.result.contract.ActivityResultContract
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
-import androidx.compose.runtime.ProvidableCompositionLocal
+import androidx.compose.runtime.ProvidedValue
 import androidx.compose.runtime.compositionLocalOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberUpdatedState
@@ -47,11 +47,13 @@
             ?: error("No ActivityResultRegisterOwner has been provided")
 
     /**
-     * Returns a [ProvidableCompositionLocal] which you can use to override the value for the
-     * subtree.
+     * Associates a [LocalActivityResultRegistryOwner] key to a value in a call to
+     * [CompositionLocalProvider].
      */
-    public fun asProvidableCompositionLocal():
-        ProvidableCompositionLocal<ActivityResultRegistryOwner?> = LocalComposition
+    public infix fun provides(registryOwner: ActivityResultRegistryOwner):
+        ProvidedValue<ActivityResultRegistryOwner?> {
+            return LocalComposition.provides(registryOwner)
+        }
 }
 
 /**
diff --git a/activity/activity-compose/src/main/java/androidx/activity/compose/BackHandler.kt b/activity/activity-compose/src/main/java/androidx/activity/compose/BackHandler.kt
index 28bcdde..1e39ad5 100644
--- a/activity/activity-compose/src/main/java/androidx/activity/compose/BackHandler.kt
+++ b/activity/activity-compose/src/main/java/androidx/activity/compose/BackHandler.kt
@@ -21,7 +21,7 @@
 import androidx.activity.OnBackPressedDispatcherOwner
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
-import androidx.compose.runtime.ProvidableCompositionLocal
+import androidx.compose.runtime.ProvidedValue
 import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.compositionLocalOf
 import androidx.compose.runtime.remember
@@ -42,9 +42,14 @@
             ?: findOwner<OnBackPressedDispatcherOwner>(LocalContext.current)
             ?: error("No Back Dispatcher provided")
 
-    public fun asProvidableCompositionLocal():
-        ProvidableCompositionLocal<OnBackPressedDispatcherOwner?> =
-            LocalOnBackPressedDispatcherOwner
+    /**
+     * Associates a [LocalOnBackPressedDispatcherOwner] key to a value in a call to
+     * [CompositionLocalProvider].
+     */
+    public infix fun provides(dispatcherOwner: OnBackPressedDispatcherOwner):
+        ProvidedValue<OnBackPressedDispatcherOwner?> {
+            return LocalOnBackPressedDispatcherOwner.provides(dispatcherOwner)
+        }
 }
 
 /**
diff --git a/activity/activity-compose/src/main/java/androidx/activity/compose/ComponentActivity.kt b/activity/activity-compose/src/main/java/androidx/activity/compose/ComponentActivity.kt
index 371955a..9516dd8 100644
--- a/activity/activity-compose/src/main/java/androidx/activity/compose/ComponentActivity.kt
+++ b/activity/activity-compose/src/main/java/androidx/activity/compose/ComponentActivity.kt
@@ -26,6 +26,18 @@
  * Composes the given composable into the given activity. The [content] will become the root view
  * of the given activity.
  *
+ * This is roughly equivalent to calling [setContentView] with a [ComposeView] i.e.:
+ *
+ * ```
+ * setContentView(
+ *   ComposeView(this).apply {
+ *     setContent {
+ *       MyComposableContent()
+ *     }
+ *   }
+ * )
+ * ```
+ *
  * @param parent The parent composition reference to coordinate scheduling of composition updates
  * @param content A `@Composable` function declaring the UI contents
  */
diff --git a/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.java b/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.java
index de13a11..e3d52e1 100644
--- a/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.java
+++ b/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.java
@@ -223,6 +223,7 @@
 
         @NonNull
         @Override
+        @SuppressWarnings("MixedMutabilityReturnType")
         public Map<String, Boolean> parseResult(int resultCode,
                 @Nullable Intent intent) {
             if (resultCode != Activity.RESULT_OK) return emptyMap();
@@ -485,6 +486,7 @@
         }
 
         @NonNull
+        @SuppressWarnings("MixedMutabilityReturnType")
         static List<Uri> getClipDataUris(@NonNull Intent intent) {
             // Use a LinkedHashSet to maintain any ordering that may be
             // present in the ClipData
diff --git a/activity/settings.gradle b/activity/settings.gradle
index 4213c9a..9975849 100644
--- a/activity/settings.gradle
+++ b/activity/settings.gradle
@@ -22,6 +22,7 @@
     if (name.startsWith(":activity")) return true
     if (name == ":annotation:annotation-sampled") return true
     if (name.startsWith(":internal-testutils-runtime")) return true
+    if (name == ":compose:internal-lint-checks") return true
     return false
 })
 
diff --git a/ads/ads-identifier-common/src/main/java/androidx/ads/identifier/AdvertisingIdUtils.java b/ads/ads-identifier-common/src/main/java/androidx/ads/identifier/AdvertisingIdUtils.java
index f73f579..ae660f2 100644
--- a/ads/ads-identifier-common/src/main/java/androidx/ads/identifier/AdvertisingIdUtils.java
+++ b/ads/ads-identifier-common/src/main/java/androidx/ads/identifier/AdvertisingIdUtils.java
@@ -66,6 +66,7 @@
      * <p>Only system-level providers will be returned.
      */
     @NonNull
+    @SuppressWarnings("MixedMutabilityReturnType")
     public static List<ServiceInfo> getAdvertisingIdProviderServices(
             @NonNull PackageManager packageManager) {
         Intent intent = new Intent(GET_AD_ID_ACTION);
diff --git a/ads/ads-identifier-provider/src/main/java/androidx/ads/identifier/provider/AdvertisingIdProviderManager.java b/ads/ads-identifier-provider/src/main/java/androidx/ads/identifier/provider/AdvertisingIdProviderManager.java
index b946758..da66c33 100644
--- a/ads/ads-identifier-provider/src/main/java/androidx/ads/identifier/provider/AdvertisingIdProviderManager.java
+++ b/ads/ads-identifier-provider/src/main/java/androidx/ads/identifier/provider/AdvertisingIdProviderManager.java
@@ -105,6 +105,7 @@
      * user of the device can manager all the providers' settings together.
      */
     @NonNull
+    @SuppressWarnings("MixedMutabilityReturnType")
     public static List<AdvertisingIdProviderInfo> getAdvertisingIdProviders(
             @NonNull Context context) {
         PackageManager packageManager = context.getPackageManager();
@@ -142,6 +143,7 @@
      * <p>This is achieved by looking up which activities can handle {@link #OPEN_SETTINGS_ACTION}
      * intent action.
      */
+    @SuppressWarnings("MixedMutabilityReturnType")
     private static Map<String, String> getOpenSettingsActivities(PackageManager packageManager) {
         Intent settingsIntent = new Intent(OPEN_SETTINGS_ACTION);
         List<ResolveInfo> settingsResolveInfos = packageManager.queryIntentActivities(
diff --git a/appcompat/appcompat-resources/api/1.3.0-beta02.txt b/appcompat/appcompat-resources/api/1.3.0-beta02.txt
new file mode 100644
index 0000000..b0256cf
--- /dev/null
+++ b/appcompat/appcompat-resources/api/1.3.0-beta02.txt
@@ -0,0 +1,35 @@
+// Signature format: 4.0
+package androidx.appcompat.content.res {
+
+  public final class AppCompatResources {
+    method public static android.content.res.ColorStateList! getColorStateList(android.content.Context, @ColorRes int);
+    method public static android.graphics.drawable.Drawable? getDrawable(android.content.Context, @DrawableRes int);
+  }
+
+}
+
+package androidx.appcompat.graphics.drawable {
+
+  public class AnimatedStateListDrawableCompat extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
+    ctor public AnimatedStateListDrawableCompat();
+    method public void addState(int[], android.graphics.drawable.Drawable, int);
+    method public void addState(int[]!, android.graphics.drawable.Drawable!);
+    method public <T extends android.graphics.drawable.Drawable & android.graphics.drawable.Animatable> void addTransition(int, int, T, boolean);
+    method public static androidx.appcompat.graphics.drawable.AnimatedStateListDrawableCompat? create(android.content.Context, @DrawableRes int, android.content.res.Resources.Theme?);
+    method public static androidx.appcompat.graphics.drawable.AnimatedStateListDrawableCompat! createFromXmlInner(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme?) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public void draw(android.graphics.Canvas);
+    method public final android.graphics.drawable.Drawable.ConstantState! getConstantState();
+    method public int getOpacity();
+    method public void inflate(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme?) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public void invalidateDrawable(android.graphics.drawable.Drawable);
+    method public void scheduleDrawable(android.graphics.drawable.Drawable, Runnable, long);
+    method public void setAlpha(int);
+    method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setDither(boolean);
+    method public void setEnterFadeDuration(int);
+    method public void setExitFadeDuration(int);
+    method public void unscheduleDrawable(android.graphics.drawable.Drawable, Runnable);
+  }
+
+}
+
diff --git a/appcompat/appcompat-resources/api/public_plus_experimental_1.3.0-beta02.txt b/appcompat/appcompat-resources/api/public_plus_experimental_1.3.0-beta02.txt
new file mode 100644
index 0000000..fdef64c
--- /dev/null
+++ b/appcompat/appcompat-resources/api/public_plus_experimental_1.3.0-beta02.txt
@@ -0,0 +1,35 @@
+// Signature format: 4.0
+package androidx.appcompat.content.res {
+
+  public final class AppCompatResources {
+    method public static android.content.res.ColorStateList! getColorStateList(android.content.Context, @ColorRes int);
+    method public static android.graphics.drawable.Drawable? getDrawable(android.content.Context, @DrawableRes int);
+  }
+
+}
+
+package androidx.appcompat.graphics.drawable {
+
+  public class AnimatedStateListDrawableCompat extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback androidx.core.graphics.drawable.TintAwareDrawable {
+    ctor public AnimatedStateListDrawableCompat();
+    method public void addState(int[], android.graphics.drawable.Drawable, int);
+    method public void addState(int[]!, android.graphics.drawable.Drawable!);
+    method public <T extends android.graphics.drawable.Drawable & android.graphics.drawable.Animatable> void addTransition(int, int, T, boolean);
+    method public static androidx.appcompat.graphics.drawable.AnimatedStateListDrawableCompat? create(android.content.Context, @DrawableRes int, android.content.res.Resources.Theme?);
+    method public static androidx.appcompat.graphics.drawable.AnimatedStateListDrawableCompat! createFromXmlInner(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme?) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public void draw(android.graphics.Canvas);
+    method public final android.graphics.drawable.Drawable.ConstantState! getConstantState();
+    method public int getOpacity();
+    method public void inflate(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme?) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public void invalidateDrawable(android.graphics.drawable.Drawable);
+    method public void scheduleDrawable(android.graphics.drawable.Drawable, Runnable, long);
+    method public void setAlpha(int);
+    method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setDither(boolean);
+    method public void setEnterFadeDuration(int);
+    method public void setExitFadeDuration(int);
+    method public void unscheduleDrawable(android.graphics.drawable.Drawable, Runnable);
+  }
+
+}
+
diff --git a/appcompat/appcompat-resources/api/res-1.3.0-beta02.txt b/appcompat/appcompat-resources/api/res-1.3.0-beta02.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/appcompat/appcompat-resources/api/res-1.3.0-beta02.txt
diff --git a/appcompat/appcompat-resources/api/restricted_1.3.0-beta02.txt b/appcompat/appcompat-resources/api/restricted_1.3.0-beta02.txt
new file mode 100644
index 0000000..84adee2
--- /dev/null
+++ b/appcompat/appcompat-resources/api/restricted_1.3.0-beta02.txt
@@ -0,0 +1,98 @@
+// Signature format: 4.0
+package androidx.appcompat.content.res {
+
+  public final class AppCompatResources {
+    method public static android.content.res.ColorStateList! getColorStateList(android.content.Context, @ColorRes int);
+    method public static android.graphics.drawable.Drawable? getDrawable(android.content.Context, @DrawableRes int);
+  }
+
+}
+
+package androidx.appcompat.graphics.drawable {
+
+  public class AnimatedStateListDrawableCompat extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback androidx.core.graphics.drawable.TintAwareDrawable {
+    ctor public AnimatedStateListDrawableCompat();
+    method public void addState(int[], android.graphics.drawable.Drawable, int);
+    method public void addState(int[]!, android.graphics.drawable.Drawable!);
+    method public <T extends android.graphics.drawable.Drawable & android.graphics.drawable.Animatable> void addTransition(int, int, T, boolean);
+    method public static androidx.appcompat.graphics.drawable.AnimatedStateListDrawableCompat? create(android.content.Context, @DrawableRes int, android.content.res.Resources.Theme?);
+    method public static androidx.appcompat.graphics.drawable.AnimatedStateListDrawableCompat! createFromXmlInner(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme?) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public void draw(android.graphics.Canvas);
+    method public final android.graphics.drawable.Drawable.ConstantState! getConstantState();
+    method public int getOpacity();
+    method public void inflate(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme?) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public void invalidateDrawable(android.graphics.drawable.Drawable);
+    method public void scheduleDrawable(android.graphics.drawable.Drawable, Runnable, long);
+    method public void setAlpha(int);
+    method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setDither(boolean);
+    method public void setEnterFadeDuration(int);
+    method public void setExitFadeDuration(int);
+    method public void unscheduleDrawable(android.graphics.drawable.Drawable, Runnable);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class DrawableWrapper extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
+    ctor public DrawableWrapper(android.graphics.drawable.Drawable!);
+    method public void draw(android.graphics.Canvas!);
+    method public int getOpacity();
+    method public android.graphics.drawable.Drawable! getWrappedDrawable();
+    method public void invalidateDrawable(android.graphics.drawable.Drawable!);
+    method public void scheduleDrawable(android.graphics.drawable.Drawable!, Runnable!, long);
+    method public void setAlpha(int);
+    method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setDither(boolean);
+    method public void setWrappedDrawable(android.graphics.drawable.Drawable!);
+    method public void unscheduleDrawable(android.graphics.drawable.Drawable!, Runnable!);
+  }
+
+}
+
+package androidx.appcompat.widget {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class DrawableUtils {
+    method public static boolean canSafelyMutateDrawable(android.graphics.drawable.Drawable);
+    method public static android.graphics.Rect! getOpticalBounds(android.graphics.drawable.Drawable!);
+    method public static android.graphics.PorterDuff.Mode! parseTintMode(int, android.graphics.PorterDuff.Mode!);
+    field public static final android.graphics.Rect! INSETS_NONE;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class ResourceManagerInternal {
+    ctor public ResourceManagerInternal();
+    method public static androidx.appcompat.widget.ResourceManagerInternal! get();
+    method public android.graphics.drawable.Drawable! getDrawable(android.content.Context, @DrawableRes int);
+    method public static android.graphics.PorterDuffColorFilter! getPorterDuffColorFilter(int, android.graphics.PorterDuff.Mode!);
+    method public void onConfigurationChanged(android.content.Context);
+    method public void setHooks(androidx.appcompat.widget.ResourceManagerInternal.ResourceManagerHooks!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static interface ResourceManagerInternal.ResourceManagerHooks {
+    method public android.graphics.drawable.Drawable? createDrawableFor(androidx.appcompat.widget.ResourceManagerInternal, android.content.Context, @DrawableRes int);
+    method public android.content.res.ColorStateList? getTintListForDrawableRes(android.content.Context, @DrawableRes int);
+    method public android.graphics.PorterDuff.Mode? getTintModeForDrawableRes(int);
+    method public boolean tintDrawable(android.content.Context, @DrawableRes int, android.graphics.drawable.Drawable);
+    method public boolean tintDrawableUsingColorFilter(android.content.Context, @DrawableRes int, android.graphics.drawable.Drawable);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class TintContextWrapper extends android.content.ContextWrapper {
+    method public static android.content.Context! wrap(android.content.Context);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class TintInfo {
+    ctor public TintInfo();
+    field public boolean mHasTintList;
+    field public boolean mHasTintMode;
+    field public android.content.res.ColorStateList! mTintList;
+    field public android.graphics.PorterDuff.Mode! mTintMode;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class VectorEnabledTintResources extends android.content.res.Resources {
+    ctor public VectorEnabledTintResources(android.content.Context, android.content.res.Resources);
+    method public android.graphics.drawable.Drawable! getDrawable(int) throws android.content.res.Resources.NotFoundException;
+    method public static boolean isCompatVectorFromResourcesEnabled();
+    method public static void setCompatVectorFromResourcesEnabled(boolean);
+    method public static boolean shouldBeUsed();
+    field public static final int MAX_SDK_WHERE_REQUIRED = 20; // 0x14
+  }
+
+}
+
diff --git a/appcompat/appcompat/api/1.3.0-beta02.txt b/appcompat/appcompat/api/1.3.0-beta02.txt
new file mode 100644
index 0000000..6b91606
--- /dev/null
+++ b/appcompat/appcompat/api/1.3.0-beta02.txt
@@ -0,0 +1,981 @@
+// Signature format: 4.0
+package androidx.appcompat.app {
+
+  public abstract class ActionBar {
+    ctor public ActionBar();
+    method public abstract void addOnMenuVisibilityListener(androidx.appcompat.app.ActionBar.OnMenuVisibilityListener!);
+    method @Deprecated public abstract void addTab(androidx.appcompat.app.ActionBar.Tab!);
+    method @Deprecated public abstract void addTab(androidx.appcompat.app.ActionBar.Tab!, boolean);
+    method @Deprecated public abstract void addTab(androidx.appcompat.app.ActionBar.Tab!, int);
+    method @Deprecated public abstract void addTab(androidx.appcompat.app.ActionBar.Tab!, int, boolean);
+    method public abstract android.view.View! getCustomView();
+    method public abstract int getDisplayOptions();
+    method public float getElevation();
+    method public abstract int getHeight();
+    method public int getHideOffset();
+    method @Deprecated public abstract int getNavigationItemCount();
+    method @Deprecated public abstract int getNavigationMode();
+    method @Deprecated public abstract int getSelectedNavigationIndex();
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab? getSelectedTab();
+    method public abstract CharSequence? getSubtitle();
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! getTabAt(int);
+    method @Deprecated public abstract int getTabCount();
+    method public android.content.Context! getThemedContext();
+    method public abstract CharSequence? getTitle();
+    method public abstract void hide();
+    method public boolean isHideOnContentScrollEnabled();
+    method public abstract boolean isShowing();
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! newTab();
+    method @Deprecated public abstract void removeAllTabs();
+    method public abstract void removeOnMenuVisibilityListener(androidx.appcompat.app.ActionBar.OnMenuVisibilityListener!);
+    method @Deprecated public abstract void removeTab(androidx.appcompat.app.ActionBar.Tab!);
+    method @Deprecated public abstract void removeTabAt(int);
+    method @Deprecated public abstract void selectTab(androidx.appcompat.app.ActionBar.Tab!);
+    method public abstract void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method public abstract void setCustomView(android.view.View!);
+    method public abstract void setCustomView(android.view.View!, androidx.appcompat.app.ActionBar.LayoutParams!);
+    method public abstract void setCustomView(int);
+    method public abstract void setDisplayHomeAsUpEnabled(boolean);
+    method public abstract void setDisplayOptions(int);
+    method public abstract void setDisplayOptions(int, int);
+    method public abstract void setDisplayShowCustomEnabled(boolean);
+    method public abstract void setDisplayShowHomeEnabled(boolean);
+    method public abstract void setDisplayShowTitleEnabled(boolean);
+    method public abstract void setDisplayUseLogoEnabled(boolean);
+    method public void setElevation(float);
+    method public void setHideOffset(int);
+    method public void setHideOnContentScrollEnabled(boolean);
+    method public void setHomeActionContentDescription(CharSequence?);
+    method public void setHomeActionContentDescription(@StringRes int);
+    method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable?);
+    method public void setHomeAsUpIndicator(@DrawableRes int);
+    method public void setHomeButtonEnabled(boolean);
+    method public abstract void setIcon(@DrawableRes int);
+    method public abstract void setIcon(android.graphics.drawable.Drawable!);
+    method @Deprecated public abstract void setListNavigationCallbacks(android.widget.SpinnerAdapter!, androidx.appcompat.app.ActionBar.OnNavigationListener!);
+    method public abstract void setLogo(@DrawableRes int);
+    method public abstract void setLogo(android.graphics.drawable.Drawable!);
+    method @Deprecated public abstract void setNavigationMode(int);
+    method @Deprecated public abstract void setSelectedNavigationItem(int);
+    method public void setSplitBackgroundDrawable(android.graphics.drawable.Drawable!);
+    method public void setStackedBackgroundDrawable(android.graphics.drawable.Drawable!);
+    method public abstract void setSubtitle(CharSequence!);
+    method public abstract void setSubtitle(int);
+    method public abstract void setTitle(CharSequence!);
+    method public abstract void setTitle(@StringRes int);
+    method public abstract void show();
+    field public static final int DISPLAY_HOME_AS_UP = 4; // 0x4
+    field public static final int DISPLAY_SHOW_CUSTOM = 16; // 0x10
+    field public static final int DISPLAY_SHOW_HOME = 2; // 0x2
+    field public static final int DISPLAY_SHOW_TITLE = 8; // 0x8
+    field public static final int DISPLAY_USE_LOGO = 1; // 0x1
+    field @Deprecated public static final int NAVIGATION_MODE_LIST = 1; // 0x1
+    field @Deprecated public static final int NAVIGATION_MODE_STANDARD = 0; // 0x0
+    field @Deprecated public static final int NAVIGATION_MODE_TABS = 2; // 0x2
+  }
+
+  public static class ActionBar.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+    ctor public ActionBar.LayoutParams(android.content.Context, android.util.AttributeSet!);
+    ctor public ActionBar.LayoutParams(int, int);
+    ctor public ActionBar.LayoutParams(int, int, int);
+    ctor public ActionBar.LayoutParams(int);
+    ctor public ActionBar.LayoutParams(androidx.appcompat.app.ActionBar.LayoutParams!);
+    ctor public ActionBar.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    field public int gravity;
+  }
+
+  public static interface ActionBar.OnMenuVisibilityListener {
+    method public void onMenuVisibilityChanged(boolean);
+  }
+
+  @Deprecated public static interface ActionBar.OnNavigationListener {
+    method @Deprecated public boolean onNavigationItemSelected(int, long);
+  }
+
+  @Deprecated public abstract static class ActionBar.Tab {
+    ctor @Deprecated public ActionBar.Tab();
+    method @Deprecated public abstract CharSequence! getContentDescription();
+    method @Deprecated public abstract android.view.View! getCustomView();
+    method @Deprecated public abstract android.graphics.drawable.Drawable! getIcon();
+    method @Deprecated public abstract int getPosition();
+    method @Deprecated public abstract Object! getTag();
+    method @Deprecated public abstract CharSequence! getText();
+    method @Deprecated public abstract void select();
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setContentDescription(@StringRes int);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setContentDescription(CharSequence!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setCustomView(android.view.View!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setCustomView(int);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setIcon(android.graphics.drawable.Drawable!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setIcon(@DrawableRes int);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setTabListener(androidx.appcompat.app.ActionBar.TabListener!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setTag(Object!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setText(CharSequence!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setText(int);
+    field @Deprecated public static final int INVALID_POSITION = -1; // 0xffffffff
+  }
+
+  @Deprecated public static interface ActionBar.TabListener {
+    method @Deprecated public void onTabReselected(androidx.appcompat.app.ActionBar.Tab!, androidx.fragment.app.FragmentTransaction!);
+    method @Deprecated public void onTabSelected(androidx.appcompat.app.ActionBar.Tab!, androidx.fragment.app.FragmentTransaction!);
+    method @Deprecated public void onTabUnselected(androidx.appcompat.app.ActionBar.Tab!, androidx.fragment.app.FragmentTransaction!);
+  }
+
+  public class ActionBarDrawerToggle implements androidx.drawerlayout.widget.DrawerLayout.DrawerListener {
+    ctor public ActionBarDrawerToggle(android.app.Activity!, androidx.drawerlayout.widget.DrawerLayout!, @StringRes int, @StringRes int);
+    ctor public ActionBarDrawerToggle(android.app.Activity!, androidx.drawerlayout.widget.DrawerLayout!, androidx.appcompat.widget.Toolbar!, @StringRes int, @StringRes int);
+    method public androidx.appcompat.graphics.drawable.DrawerArrowDrawable getDrawerArrowDrawable();
+    method public android.view.View.OnClickListener! getToolbarNavigationClickListener();
+    method public boolean isDrawerIndicatorEnabled();
+    method public boolean isDrawerSlideAnimationEnabled();
+    method public void onConfigurationChanged(android.content.res.Configuration!);
+    method public void onDrawerClosed(android.view.View!);
+    method public void onDrawerOpened(android.view.View!);
+    method public void onDrawerSlide(android.view.View!, float);
+    method public void onDrawerStateChanged(int);
+    method public boolean onOptionsItemSelected(android.view.MenuItem!);
+    method public void setDrawerArrowDrawable(androidx.appcompat.graphics.drawable.DrawerArrowDrawable);
+    method public void setDrawerIndicatorEnabled(boolean);
+    method public void setDrawerSlideAnimationEnabled(boolean);
+    method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable!);
+    method public void setHomeAsUpIndicator(int);
+    method public void setToolbarNavigationClickListener(android.view.View.OnClickListener!);
+    method public void syncState();
+  }
+
+  public static interface ActionBarDrawerToggle.Delegate {
+    method public android.content.Context! getActionBarThemedContext();
+    method public android.graphics.drawable.Drawable! getThemeUpIndicator();
+    method public boolean isNavigationVisible();
+    method public void setActionBarDescription(@StringRes int);
+    method public void setActionBarUpIndicator(android.graphics.drawable.Drawable!, @StringRes int);
+  }
+
+  public static interface ActionBarDrawerToggle.DelegateProvider {
+    method public androidx.appcompat.app.ActionBarDrawerToggle.Delegate? getDrawerToggleDelegate();
+  }
+
+  public class AlertDialog extends androidx.appcompat.app.AppCompatDialog implements android.content.DialogInterface {
+    ctor protected AlertDialog(android.content.Context);
+    ctor protected AlertDialog(android.content.Context, @StyleRes int);
+    ctor protected AlertDialog(android.content.Context, boolean, android.content.DialogInterface.OnCancelListener?);
+    method public android.widget.Button! getButton(int);
+    method public android.widget.ListView! getListView();
+    method public void setButton(int, CharSequence!, android.os.Message!);
+    method public void setButton(int, CharSequence!, android.content.DialogInterface.OnClickListener!);
+    method public void setButton(int, CharSequence!, android.graphics.drawable.Drawable!, android.content.DialogInterface.OnClickListener!);
+    method public void setCustomTitle(android.view.View!);
+    method public void setIcon(int);
+    method public void setIcon(android.graphics.drawable.Drawable!);
+    method public void setIconAttribute(int);
+    method public void setMessage(CharSequence!);
+    method public void setView(android.view.View!);
+    method public void setView(android.view.View!, int, int, int, int);
+  }
+
+  public static class AlertDialog.Builder {
+    ctor public AlertDialog.Builder(android.content.Context);
+    ctor public AlertDialog.Builder(android.content.Context, @StyleRes int);
+    method public androidx.appcompat.app.AlertDialog create();
+    method public android.content.Context getContext();
+    method public androidx.appcompat.app.AlertDialog.Builder! setAdapter(android.widget.ListAdapter!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setCancelable(boolean);
+    method public androidx.appcompat.app.AlertDialog.Builder! setCursor(android.database.Cursor!, android.content.DialogInterface.OnClickListener!, String!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setCustomTitle(android.view.View?);
+    method public androidx.appcompat.app.AlertDialog.Builder! setIcon(@DrawableRes int);
+    method public androidx.appcompat.app.AlertDialog.Builder! setIcon(android.graphics.drawable.Drawable?);
+    method public androidx.appcompat.app.AlertDialog.Builder! setIconAttribute(@AttrRes int);
+    method @Deprecated public androidx.appcompat.app.AlertDialog.Builder! setInverseBackgroundForced(boolean);
+    method public androidx.appcompat.app.AlertDialog.Builder! setItems(@ArrayRes int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setItems(CharSequence![]!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setMessage(@StringRes int);
+    method public androidx.appcompat.app.AlertDialog.Builder! setMessage(CharSequence?);
+    method public androidx.appcompat.app.AlertDialog.Builder! setMultiChoiceItems(@ArrayRes int, boolean[]!, android.content.DialogInterface.OnMultiChoiceClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setMultiChoiceItems(CharSequence![]!, boolean[]!, android.content.DialogInterface.OnMultiChoiceClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setMultiChoiceItems(android.database.Cursor!, String!, String!, android.content.DialogInterface.OnMultiChoiceClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNegativeButton(@StringRes int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNegativeButton(CharSequence!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNegativeButtonIcon(android.graphics.drawable.Drawable!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNeutralButton(@StringRes int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNeutralButton(CharSequence!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNeutralButtonIcon(android.graphics.drawable.Drawable!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setOnCancelListener(android.content.DialogInterface.OnCancelListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setOnDismissListener(android.content.DialogInterface.OnDismissListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setOnKeyListener(android.content.DialogInterface.OnKeyListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setPositiveButton(@StringRes int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setPositiveButton(CharSequence!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setPositiveButtonIcon(android.graphics.drawable.Drawable!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setSingleChoiceItems(@ArrayRes int, int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setSingleChoiceItems(android.database.Cursor!, int, String!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setSingleChoiceItems(CharSequence![]!, int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setSingleChoiceItems(android.widget.ListAdapter!, int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setTitle(@StringRes int);
+    method public androidx.appcompat.app.AlertDialog.Builder! setTitle(CharSequence?);
+    method public androidx.appcompat.app.AlertDialog.Builder! setView(int);
+    method public androidx.appcompat.app.AlertDialog.Builder! setView(android.view.View!);
+    method public androidx.appcompat.app.AlertDialog! show();
+  }
+
+  public class AppCompatActivity extends androidx.fragment.app.FragmentActivity implements androidx.appcompat.app.ActionBarDrawerToggle.DelegateProvider androidx.appcompat.app.AppCompatCallback androidx.lifecycle.LifecycleOwner androidx.core.app.TaskStackBuilder.SupportParentable {
+    ctor public AppCompatActivity();
+    ctor @ContentView public AppCompatActivity(@LayoutRes int);
+    method public androidx.appcompat.app.AppCompatDelegate getDelegate();
+    method public androidx.appcompat.app.ActionBarDrawerToggle.Delegate? getDrawerToggleDelegate();
+    method public androidx.appcompat.app.ActionBar? getSupportActionBar();
+    method public android.content.Intent? getSupportParentActivityIntent();
+    method public void onCreateSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder);
+    method public final boolean onMenuItemSelected(int, android.view.MenuItem);
+    method protected void onNightModeChanged(int);
+    method public void onPrepareSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder);
+    method @CallSuper public void onSupportActionModeFinished(androidx.appcompat.view.ActionMode);
+    method @CallSuper public void onSupportActionModeStarted(androidx.appcompat.view.ActionMode);
+    method @Deprecated public void onSupportContentChanged();
+    method public boolean onSupportNavigateUp();
+    method public androidx.appcompat.view.ActionMode? onWindowStartingSupportActionMode(androidx.appcompat.view.ActionMode.Callback);
+    method public void setSupportActionBar(androidx.appcompat.widget.Toolbar?);
+    method @Deprecated public void setSupportProgress(int);
+    method @Deprecated public void setSupportProgressBarIndeterminate(boolean);
+    method @Deprecated public void setSupportProgressBarIndeterminateVisibility(boolean);
+    method @Deprecated public void setSupportProgressBarVisibility(boolean);
+    method public androidx.appcompat.view.ActionMode? startSupportActionMode(androidx.appcompat.view.ActionMode.Callback);
+    method public void supportInvalidateOptionsMenu();
+    method public void supportNavigateUpTo(android.content.Intent);
+    method public boolean supportRequestWindowFeature(int);
+    method public boolean supportShouldUpRecreateTask(android.content.Intent);
+  }
+
+  public interface AppCompatCallback {
+    method public void onSupportActionModeFinished(androidx.appcompat.view.ActionMode!);
+    method public void onSupportActionModeStarted(androidx.appcompat.view.ActionMode!);
+    method public androidx.appcompat.view.ActionMode? onWindowStartingSupportActionMode(androidx.appcompat.view.ActionMode.Callback!);
+  }
+
+  public abstract class AppCompatDelegate {
+    method public abstract void addContentView(android.view.View!, android.view.ViewGroup.LayoutParams!);
+    method public abstract boolean applyDayNight();
+    method @Deprecated public void attachBaseContext(android.content.Context!);
+    method @CallSuper public android.content.Context attachBaseContext2(android.content.Context);
+    method public static androidx.appcompat.app.AppCompatDelegate create(android.app.Activity, androidx.appcompat.app.AppCompatCallback?);
+    method public static androidx.appcompat.app.AppCompatDelegate create(android.app.Dialog, androidx.appcompat.app.AppCompatCallback?);
+    method public static androidx.appcompat.app.AppCompatDelegate create(android.content.Context, android.view.Window, androidx.appcompat.app.AppCompatCallback?);
+    method public static androidx.appcompat.app.AppCompatDelegate create(android.content.Context, android.app.Activity, androidx.appcompat.app.AppCompatCallback?);
+    method public abstract android.view.View! createView(android.view.View?, String!, android.content.Context, android.util.AttributeSet);
+    method public abstract <T extends android.view.View> T! findViewById(@IdRes int);
+    method public static int getDefaultNightMode();
+    method public abstract androidx.appcompat.app.ActionBarDrawerToggle.Delegate? getDrawerToggleDelegate();
+    method public int getLocalNightMode();
+    method public abstract android.view.MenuInflater! getMenuInflater();
+    method public abstract androidx.appcompat.app.ActionBar? getSupportActionBar();
+    method public abstract boolean hasWindowFeature(int);
+    method public abstract void installViewFactory();
+    method public abstract void invalidateOptionsMenu();
+    method public static boolean isCompatVectorFromResourcesEnabled();
+    method public abstract boolean isHandleNativeActionModesEnabled();
+    method public abstract void onConfigurationChanged(android.content.res.Configuration!);
+    method public abstract void onCreate(android.os.Bundle!);
+    method public abstract void onDestroy();
+    method public abstract void onPostCreate(android.os.Bundle!);
+    method public abstract void onPostResume();
+    method public abstract void onSaveInstanceState(android.os.Bundle!);
+    method public abstract void onStart();
+    method public abstract void onStop();
+    method public abstract boolean requestWindowFeature(int);
+    method public static void setCompatVectorFromResourcesEnabled(boolean);
+    method public abstract void setContentView(android.view.View!);
+    method public abstract void setContentView(@LayoutRes int);
+    method public abstract void setContentView(android.view.View!, android.view.ViewGroup.LayoutParams!);
+    method public static void setDefaultNightMode(int);
+    method public abstract void setHandleNativeActionModesEnabled(boolean);
+    method @RequiresApi(17) public abstract void setLocalNightMode(int);
+    method public abstract void setSupportActionBar(androidx.appcompat.widget.Toolbar?);
+    method public void setTheme(@StyleRes int);
+    method public abstract void setTitle(CharSequence?);
+    method public abstract androidx.appcompat.view.ActionMode? startSupportActionMode(androidx.appcompat.view.ActionMode.Callback);
+    field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+    field public static final int FEATURE_SUPPORT_ACTION_BAR = 108; // 0x6c
+    field public static final int FEATURE_SUPPORT_ACTION_BAR_OVERLAY = 109; // 0x6d
+    field @Deprecated public static final int MODE_NIGHT_AUTO = 0; // 0x0
+    field public static final int MODE_NIGHT_AUTO_BATTERY = 3; // 0x3
+    field @Deprecated public static final int MODE_NIGHT_AUTO_TIME = 0; // 0x0
+    field public static final int MODE_NIGHT_FOLLOW_SYSTEM = -1; // 0xffffffff
+    field public static final int MODE_NIGHT_NO = 1; // 0x1
+    field public static final int MODE_NIGHT_UNSPECIFIED = -100; // 0xffffff9c
+    field public static final int MODE_NIGHT_YES = 2; // 0x2
+  }
+
+  public class AppCompatDialog extends android.app.Dialog implements androidx.appcompat.app.AppCompatCallback {
+    ctor public AppCompatDialog(android.content.Context!);
+    ctor public AppCompatDialog(android.content.Context!, int);
+    ctor protected AppCompatDialog(android.content.Context!, boolean, android.content.DialogInterface.OnCancelListener!);
+    method public androidx.appcompat.app.AppCompatDelegate! getDelegate();
+    method public androidx.appcompat.app.ActionBar! getSupportActionBar();
+    method public void onSupportActionModeFinished(androidx.appcompat.view.ActionMode!);
+    method public void onSupportActionModeStarted(androidx.appcompat.view.ActionMode!);
+    method public androidx.appcompat.view.ActionMode? onWindowStartingSupportActionMode(androidx.appcompat.view.ActionMode.Callback!);
+    method public boolean supportRequestWindowFeature(int);
+  }
+
+  public class AppCompatDialogFragment extends androidx.fragment.app.DialogFragment {
+    ctor public AppCompatDialogFragment();
+  }
+
+  public class AppCompatViewInflater {
+    ctor public AppCompatViewInflater();
+    method protected androidx.appcompat.widget.AppCompatAutoCompleteTextView createAutoCompleteTextView(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatButton createButton(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatCheckBox createCheckBox(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatCheckedTextView createCheckedTextView(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatEditText createEditText(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatImageButton createImageButton(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatImageView createImageView(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatMultiAutoCompleteTextView createMultiAutoCompleteTextView(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatRadioButton createRadioButton(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatRatingBar createRatingBar(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatSeekBar createSeekBar(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatSpinner createSpinner(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatTextView createTextView(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatToggleButton createToggleButton(android.content.Context!, android.util.AttributeSet!);
+    method protected android.view.View? createView(android.content.Context!, String!, android.util.AttributeSet!);
+  }
+
+}
+
+package androidx.appcompat.graphics.drawable {
+
+  public class DrawerArrowDrawable extends android.graphics.drawable.Drawable {
+    ctor public DrawerArrowDrawable(android.content.Context!);
+    method public void draw(android.graphics.Canvas!);
+    method public float getArrowHeadLength();
+    method public float getArrowShaftLength();
+    method public float getBarLength();
+    method public float getBarThickness();
+    method @ColorInt public int getColor();
+    method public int getDirection();
+    method public float getGapSize();
+    method public int getOpacity();
+    method public final android.graphics.Paint! getPaint();
+    method @FloatRange(from=0.0, to=1.0) public float getProgress();
+    method public boolean isSpinEnabled();
+    method public void setAlpha(int);
+    method public void setArrowHeadLength(float);
+    method public void setArrowShaftLength(float);
+    method public void setBarLength(float);
+    method public void setBarThickness(float);
+    method public void setColor(@ColorInt int);
+    method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setDirection(int);
+    method public void setGapSize(float);
+    method public void setProgress(@FloatRange(from=0.0, to=1.0) float);
+    method public void setSpinEnabled(boolean);
+    method public void setVerticalMirror(boolean);
+    field public static final int ARROW_DIRECTION_END = 3; // 0x3
+    field public static final int ARROW_DIRECTION_LEFT = 0; // 0x0
+    field public static final int ARROW_DIRECTION_RIGHT = 1; // 0x1
+    field public static final int ARROW_DIRECTION_START = 2; // 0x2
+  }
+
+}
+
+package androidx.appcompat.view {
+
+  public abstract class ActionMode {
+    ctor public ActionMode();
+    method public abstract void finish();
+    method public abstract android.view.View! getCustomView();
+    method public abstract android.view.Menu! getMenu();
+    method public abstract android.view.MenuInflater! getMenuInflater();
+    method public abstract CharSequence! getSubtitle();
+    method public Object! getTag();
+    method public abstract CharSequence! getTitle();
+    method public boolean getTitleOptionalHint();
+    method public abstract void invalidate();
+    method public boolean isTitleOptional();
+    method public abstract void setCustomView(android.view.View!);
+    method public abstract void setSubtitle(CharSequence!);
+    method public abstract void setSubtitle(int);
+    method public void setTag(Object!);
+    method public abstract void setTitle(CharSequence!);
+    method public abstract void setTitle(int);
+    method public void setTitleOptionalHint(boolean);
+  }
+
+  public static interface ActionMode.Callback {
+    method public boolean onActionItemClicked(androidx.appcompat.view.ActionMode!, android.view.MenuItem!);
+    method public boolean onCreateActionMode(androidx.appcompat.view.ActionMode!, android.view.Menu!);
+    method public void onDestroyActionMode(androidx.appcompat.view.ActionMode!);
+    method public boolean onPrepareActionMode(androidx.appcompat.view.ActionMode!, android.view.Menu!);
+  }
+
+  @Deprecated public interface CollapsibleActionView {
+    method @Deprecated public void onActionViewCollapsed();
+    method @Deprecated public void onActionViewExpanded();
+  }
+
+  public class ContextThemeWrapper extends android.content.ContextWrapper {
+    ctor public ContextThemeWrapper();
+    ctor public ContextThemeWrapper(android.content.Context!, @StyleRes int);
+    ctor public ContextThemeWrapper(android.content.Context!, android.content.res.Resources.Theme!);
+    method public void applyOverrideConfiguration(android.content.res.Configuration!);
+    method public int getThemeResId();
+    method protected void onApplyThemeResource(android.content.res.Resources.Theme!, int, boolean);
+  }
+
+}
+
+package androidx.appcompat.widget {
+
+  public class ActionMenuView extends androidx.appcompat.widget.LinearLayoutCompat {
+    ctor public ActionMenuView(android.content.Context);
+    ctor public ActionMenuView(android.content.Context, android.util.AttributeSet?);
+    method public void dismissPopupMenus();
+    method protected androidx.appcompat.widget.ActionMenuView.LayoutParams! generateDefaultLayoutParams();
+    method public androidx.appcompat.widget.ActionMenuView.LayoutParams! generateLayoutParams(android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.ActionMenuView.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+    method public android.view.Menu! getMenu();
+    method public android.graphics.drawable.Drawable? getOverflowIcon();
+    method public int getPopupTheme();
+    method public boolean hideOverflowMenu();
+    method public boolean isOverflowMenuShowing();
+    method public void onConfigurationChanged(android.content.res.Configuration!);
+    method public void onDetachedFromWindow();
+    method public void setOnMenuItemClickListener(androidx.appcompat.widget.ActionMenuView.OnMenuItemClickListener!);
+    method public void setOverflowIcon(android.graphics.drawable.Drawable?);
+    method public void setPopupTheme(@StyleRes int);
+    method public boolean showOverflowMenu();
+  }
+
+  public static class ActionMenuView.LayoutParams extends androidx.appcompat.widget.LinearLayoutCompat.LayoutParams {
+    ctor public ActionMenuView.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public ActionMenuView.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public ActionMenuView.LayoutParams(androidx.appcompat.widget.ActionMenuView.LayoutParams!);
+    ctor public ActionMenuView.LayoutParams(int, int);
+    field public int cellsUsed;
+    field public boolean expandable;
+    field public int extraPixels;
+    field public boolean isOverflowButton;
+    field public boolean preventEdgeOffset;
+  }
+
+  public static interface ActionMenuView.OnMenuItemClickListener {
+    method public boolean onMenuItemClick(android.view.MenuItem!);
+  }
+
+  public class AppCompatAutoCompleteTextView extends android.widget.AutoCompleteTextView implements androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatAutoCompleteTextView(android.content.Context);
+    ctor public AppCompatAutoCompleteTextView(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatAutoCompleteTextView(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTextAppearance(android.content.Context!, int);
+  }
+
+  public class AppCompatButton extends android.widget.Button implements androidx.core.view.TintableBackgroundView androidx.core.widget.TintableCompoundDrawablesView {
+    ctor public AppCompatButton(android.content.Context);
+    ctor public AppCompatButton(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatButton(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportCompoundDrawablesTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportCompoundDrawablesTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setAutoSizeTextTypeUniformWithConfiguration(int, int, int, int) throws java.lang.IllegalArgumentException;
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setAutoSizeTextTypeUniformWithPresetSizes(int[], int) throws java.lang.IllegalArgumentException;
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method public void setSupportAllCaps(boolean);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportCompoundDrawablesTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportCompoundDrawablesTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTextAppearance(android.content.Context!, int);
+  }
+
+  public class AppCompatCheckBox extends android.widget.CheckBox implements androidx.core.view.TintableBackgroundView androidx.core.widget.TintableCompoundButton {
+    ctor public AppCompatCheckBox(android.content.Context);
+    ctor public AppCompatCheckBox(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatCheckBox(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportButtonTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportButtonTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportButtonTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public class AppCompatCheckedTextView extends android.widget.CheckedTextView {
+    ctor public AppCompatCheckedTextView(android.content.Context);
+    ctor public AppCompatCheckedTextView(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatCheckedTextView(android.content.Context, android.util.AttributeSet?, int);
+    method public void setTextAppearance(android.content.Context!, int);
+  }
+
+  public class AppCompatEditText extends android.widget.EditText implements androidx.core.view.OnReceiveContentViewBehavior androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatEditText(android.content.Context);
+    ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public androidx.core.view.ContentInfoCompat? onReceiveContent(androidx.core.view.ContentInfoCompat);
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTextAppearance(android.content.Context!, int);
+  }
+
+  public class AppCompatImageButton extends android.widget.ImageButton implements androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatImageButton(android.content.Context);
+    ctor public AppCompatImageButton(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatImageButton(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public class AppCompatImageView extends android.widget.ImageView implements androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatImageView(android.content.Context);
+    ctor public AppCompatImageView(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatImageView(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public class AppCompatMultiAutoCompleteTextView extends android.widget.MultiAutoCompleteTextView implements androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatMultiAutoCompleteTextView(android.content.Context);
+    ctor public AppCompatMultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatMultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTextAppearance(android.content.Context!, int);
+  }
+
+  public class AppCompatRadioButton extends android.widget.RadioButton implements androidx.core.view.TintableBackgroundView androidx.core.widget.TintableCompoundButton {
+    ctor public AppCompatRadioButton(android.content.Context!);
+    ctor public AppCompatRadioButton(android.content.Context!, android.util.AttributeSet?);
+    ctor public AppCompatRadioButton(android.content.Context!, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportButtonTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportButtonTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportButtonTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public class AppCompatRatingBar extends android.widget.RatingBar {
+    ctor public AppCompatRatingBar(android.content.Context);
+    ctor public AppCompatRatingBar(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatRatingBar(android.content.Context, android.util.AttributeSet?, int);
+  }
+
+  public class AppCompatSeekBar extends android.widget.SeekBar {
+    ctor public AppCompatSeekBar(android.content.Context);
+    ctor public AppCompatSeekBar(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatSeekBar(android.content.Context, android.util.AttributeSet?, int);
+  }
+
+  public class AppCompatSpinner extends android.widget.Spinner implements androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatSpinner(android.content.Context);
+    ctor public AppCompatSpinner(android.content.Context, int);
+    ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet?, int);
+    ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet?, int, int);
+    ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet?, int, int, android.content.res.Resources.Theme!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public class AppCompatTextView extends android.widget.TextView implements androidx.core.view.TintableBackgroundView androidx.core.widget.TintableCompoundDrawablesView {
+    ctor public AppCompatTextView(android.content.Context);
+    ctor public AppCompatTextView(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatTextView(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportCompoundDrawablesTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportCompoundDrawablesTintMode();
+    method public androidx.core.text.PrecomputedTextCompat.Params getTextMetricsParamsCompat();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setAutoSizeTextTypeUniformWithConfiguration(int, int, int, int) throws java.lang.IllegalArgumentException;
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setAutoSizeTextTypeUniformWithPresetSizes(int[], int) throws java.lang.IllegalArgumentException;
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method public void setPrecomputedText(androidx.core.text.PrecomputedTextCompat);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportCompoundDrawablesTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportCompoundDrawablesTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTextAppearance(android.content.Context!, int);
+    method public void setTextFuture(java.util.concurrent.Future<androidx.core.text.PrecomputedTextCompat!>?);
+    method public void setTextMetricsParamsCompat(androidx.core.text.PrecomputedTextCompat.Params);
+  }
+
+  public class AppCompatToggleButton extends android.widget.ToggleButton implements androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatToggleButton(android.content.Context);
+    ctor public AppCompatToggleButton(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatToggleButton(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public class LinearLayoutCompat extends android.view.ViewGroup {
+    ctor public LinearLayoutCompat(android.content.Context);
+    ctor public LinearLayoutCompat(android.content.Context, android.util.AttributeSet?);
+    ctor public LinearLayoutCompat(android.content.Context, android.util.AttributeSet?, int);
+    method protected androidx.appcompat.widget.LinearLayoutCompat.LayoutParams! generateDefaultLayoutParams();
+    method public androidx.appcompat.widget.LinearLayoutCompat.LayoutParams! generateLayoutParams(android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.LinearLayoutCompat.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+    method public int getBaselineAlignedChildIndex();
+    method public android.graphics.drawable.Drawable! getDividerDrawable();
+    method public int getDividerPadding();
+    method public int getGravity();
+    method public int getOrientation();
+    method public int getShowDividers();
+    method public float getWeightSum();
+    method public boolean isBaselineAligned();
+    method public boolean isMeasureWithLargestChildEnabled();
+    method public void setBaselineAligned(boolean);
+    method public void setBaselineAlignedChildIndex(int);
+    method public void setDividerDrawable(android.graphics.drawable.Drawable!);
+    method public void setDividerPadding(int);
+    method public void setGravity(int);
+    method public void setHorizontalGravity(int);
+    method public void setMeasureWithLargestChildEnabled(boolean);
+    method public void setOrientation(int);
+    method public void setShowDividers(int);
+    method public void setVerticalGravity(int);
+    method public void setWeightSum(float);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int SHOW_DIVIDER_BEGINNING = 1; // 0x1
+    field public static final int SHOW_DIVIDER_END = 4; // 0x4
+    field public static final int SHOW_DIVIDER_MIDDLE = 2; // 0x2
+    field public static final int SHOW_DIVIDER_NONE = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public static class LinearLayoutCompat.LayoutParams extends android.widget.LinearLayout.LayoutParams {
+    ctor public LinearLayoutCompat.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public LinearLayoutCompat.LayoutParams(int, int);
+    ctor public LinearLayoutCompat.LayoutParams(int, int, float);
+    ctor public LinearLayoutCompat.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public LinearLayoutCompat.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+  }
+
+  public class ListPopupWindow {
+    ctor public ListPopupWindow(android.content.Context);
+    ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet?);
+    ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet?, @AttrRes int);
+    ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet?, @AttrRes int, @StyleRes int);
+    method public void clearListSelection();
+    method public android.view.View.OnTouchListener! createDragToOpenListener(android.view.View!);
+    method public void dismiss();
+    method public android.view.View? getAnchorView();
+    method @StyleRes public int getAnimationStyle();
+    method public android.graphics.drawable.Drawable? getBackground();
+    method public android.graphics.Rect? getEpicenterBounds();
+    method public int getHeight();
+    method public int getHorizontalOffset();
+    method public int getInputMethodMode();
+    method public android.widget.ListView? getListView();
+    method public int getPromptPosition();
+    method public Object? getSelectedItem();
+    method public long getSelectedItemId();
+    method public int getSelectedItemPosition();
+    method public android.view.View? getSelectedView();
+    method public int getSoftInputMode();
+    method public int getVerticalOffset();
+    method public int getWidth();
+    method public boolean isInputMethodNotNeeded();
+    method public boolean isModal();
+    method public boolean isShowing();
+    method public boolean onKeyDown(int, android.view.KeyEvent);
+    method public boolean onKeyPreIme(int, android.view.KeyEvent);
+    method public boolean onKeyUp(int, android.view.KeyEvent);
+    method public boolean performItemClick(int);
+    method public void postShow();
+    method public void setAdapter(android.widget.ListAdapter?);
+    method public void setAnchorView(android.view.View?);
+    method public void setAnimationStyle(@StyleRes int);
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method public void setContentWidth(int);
+    method public void setDropDownGravity(int);
+    method public void setEpicenterBounds(android.graphics.Rect?);
+    method public void setHeight(int);
+    method public void setHorizontalOffset(int);
+    method public void setInputMethodMode(int);
+    method public void setListSelector(android.graphics.drawable.Drawable!);
+    method public void setModal(boolean);
+    method public void setOnDismissListener(android.widget.PopupWindow.OnDismissListener?);
+    method public void setOnItemClickListener(android.widget.AdapterView.OnItemClickListener?);
+    method public void setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener?);
+    method public void setPromptPosition(int);
+    method public void setPromptView(android.view.View?);
+    method public void setSelection(int);
+    method public void setSoftInputMode(int);
+    method public void setVerticalOffset(int);
+    method public void setWidth(int);
+    method public void setWindowLayoutType(int);
+    method public void show();
+    field public static final int INPUT_METHOD_FROM_FOCUSABLE = 0; // 0x0
+    field public static final int INPUT_METHOD_NEEDED = 1; // 0x1
+    field public static final int INPUT_METHOD_NOT_NEEDED = 2; // 0x2
+    field public static final int MATCH_PARENT = -1; // 0xffffffff
+    field public static final int POSITION_PROMPT_ABOVE = 0; // 0x0
+    field public static final int POSITION_PROMPT_BELOW = 1; // 0x1
+    field public static final int WRAP_CONTENT = -2; // 0xfffffffe
+  }
+
+  public class PopupMenu {
+    ctor public PopupMenu(android.content.Context, android.view.View);
+    ctor public PopupMenu(android.content.Context, android.view.View, int);
+    ctor public PopupMenu(android.content.Context, android.view.View, int, @AttrRes int, @StyleRes int);
+    method public void dismiss();
+    method public android.view.View.OnTouchListener getDragToOpenListener();
+    method public int getGravity();
+    method public android.view.Menu getMenu();
+    method public android.view.MenuInflater getMenuInflater();
+    method public void inflate(@MenuRes int);
+    method public void setGravity(int);
+    method public void setOnDismissListener(androidx.appcompat.widget.PopupMenu.OnDismissListener?);
+    method public void setOnMenuItemClickListener(androidx.appcompat.widget.PopupMenu.OnMenuItemClickListener?);
+    method public void show();
+  }
+
+  public static interface PopupMenu.OnDismissListener {
+    method public void onDismiss(androidx.appcompat.widget.PopupMenu!);
+  }
+
+  public static interface PopupMenu.OnMenuItemClickListener {
+    method public boolean onMenuItemClick(android.view.MenuItem!);
+  }
+
+  public class SearchView extends androidx.appcompat.widget.LinearLayoutCompat implements androidx.appcompat.view.CollapsibleActionView {
+    ctor public SearchView(android.content.Context);
+    ctor public SearchView(android.content.Context, android.util.AttributeSet?);
+    ctor public SearchView(android.content.Context, android.util.AttributeSet?, int);
+    method public int getImeOptions();
+    method public int getInputType();
+    method public int getMaxWidth();
+    method public CharSequence! getQuery();
+    method public CharSequence? getQueryHint();
+    method public androidx.cursoradapter.widget.CursorAdapter! getSuggestionsAdapter();
+    method public boolean isIconfiedByDefault();
+    method public boolean isIconified();
+    method public boolean isQueryRefinementEnabled();
+    method public boolean isSubmitButtonEnabled();
+    method public void onActionViewCollapsed();
+    method public void onActionViewExpanded();
+    method public void setIconified(boolean);
+    method public void setIconifiedByDefault(boolean);
+    method public void setImeOptions(int);
+    method public void setInputType(int);
+    method public void setMaxWidth(int);
+    method public void setOnCloseListener(androidx.appcompat.widget.SearchView.OnCloseListener!);
+    method public void setOnQueryTextFocusChangeListener(android.view.View.OnFocusChangeListener!);
+    method public void setOnQueryTextListener(androidx.appcompat.widget.SearchView.OnQueryTextListener!);
+    method public void setOnSearchClickListener(android.view.View.OnClickListener!);
+    method public void setOnSuggestionListener(androidx.appcompat.widget.SearchView.OnSuggestionListener!);
+    method public void setQuery(CharSequence!, boolean);
+    method public void setQueryHint(CharSequence?);
+    method public void setQueryRefinementEnabled(boolean);
+    method public void setSearchableInfo(android.app.SearchableInfo!);
+    method public void setSubmitButtonEnabled(boolean);
+    method public void setSuggestionsAdapter(androidx.cursoradapter.widget.CursorAdapter!);
+  }
+
+  public static interface SearchView.OnCloseListener {
+    method public boolean onClose();
+  }
+
+  public static interface SearchView.OnQueryTextListener {
+    method public boolean onQueryTextChange(String!);
+    method public boolean onQueryTextSubmit(String!);
+  }
+
+  public static interface SearchView.OnSuggestionListener {
+    method public boolean onSuggestionClick(int);
+    method public boolean onSuggestionSelect(int);
+  }
+
+  public class ShareActionProvider extends androidx.core.view.ActionProvider {
+    ctor public ShareActionProvider(android.content.Context!);
+    method public android.view.View! onCreateActionView();
+    method public void setOnShareTargetSelectedListener(androidx.appcompat.widget.ShareActionProvider.OnShareTargetSelectedListener!);
+    method public void setShareHistoryFileName(String!);
+    method public void setShareIntent(android.content.Intent!);
+    field public static final String DEFAULT_SHARE_HISTORY_FILE_NAME = "share_history.xml";
+  }
+
+  public static interface ShareActionProvider.OnShareTargetSelectedListener {
+    method public boolean onShareTargetSelected(androidx.appcompat.widget.ShareActionProvider!, android.content.Intent!);
+  }
+
+  public class SwitchCompat extends android.widget.CompoundButton {
+    ctor public SwitchCompat(android.content.Context);
+    ctor public SwitchCompat(android.content.Context, android.util.AttributeSet?);
+    ctor public SwitchCompat(android.content.Context, android.util.AttributeSet?, int);
+    method public boolean getShowText();
+    method public boolean getSplitTrack();
+    method public int getSwitchMinWidth();
+    method public int getSwitchPadding();
+    method public CharSequence! getTextOff();
+    method public CharSequence! getTextOn();
+    method public android.graphics.drawable.Drawable! getThumbDrawable();
+    method public int getThumbTextPadding();
+    method public android.content.res.ColorStateList? getThumbTintList();
+    method public android.graphics.PorterDuff.Mode? getThumbTintMode();
+    method public android.graphics.drawable.Drawable! getTrackDrawable();
+    method public android.content.res.ColorStateList? getTrackTintList();
+    method public android.graphics.PorterDuff.Mode? getTrackTintMode();
+    method public void onMeasure(int, int);
+    method public void setShowText(boolean);
+    method public void setSplitTrack(boolean);
+    method public void setSwitchMinWidth(int);
+    method public void setSwitchPadding(int);
+    method public void setSwitchTextAppearance(android.content.Context!, int);
+    method public void setSwitchTypeface(android.graphics.Typeface!, int);
+    method public void setSwitchTypeface(android.graphics.Typeface!);
+    method public void setTextOff(CharSequence!);
+    method public void setTextOn(CharSequence!);
+    method public void setThumbDrawable(android.graphics.drawable.Drawable!);
+    method public void setThumbResource(int);
+    method public void setThumbTextPadding(int);
+    method public void setThumbTintList(android.content.res.ColorStateList?);
+    method public void setThumbTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTrackDrawable(android.graphics.drawable.Drawable!);
+    method public void setTrackResource(int);
+    method public void setTrackTintList(android.content.res.ColorStateList?);
+    method public void setTrackTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public interface ThemedSpinnerAdapter extends android.widget.SpinnerAdapter {
+    method public android.content.res.Resources.Theme? getDropDownViewTheme();
+    method public void setDropDownViewTheme(android.content.res.Resources.Theme?);
+  }
+
+  public static final class ThemedSpinnerAdapter.Helper {
+    ctor public ThemedSpinnerAdapter.Helper(android.content.Context);
+    method public android.view.LayoutInflater getDropDownViewInflater();
+    method public android.content.res.Resources.Theme? getDropDownViewTheme();
+    method public void setDropDownViewTheme(android.content.res.Resources.Theme?);
+  }
+
+  public class Toolbar extends android.view.ViewGroup {
+    ctor public Toolbar(android.content.Context);
+    ctor public Toolbar(android.content.Context, android.util.AttributeSet?);
+    ctor public Toolbar(android.content.Context, android.util.AttributeSet?, int);
+    method public void collapseActionView();
+    method public void dismissPopupMenus();
+    method protected androidx.appcompat.widget.Toolbar.LayoutParams! generateDefaultLayoutParams();
+    method public androidx.appcompat.widget.Toolbar.LayoutParams! generateLayoutParams(android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.Toolbar.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+    method public CharSequence? getCollapseContentDescription();
+    method public android.graphics.drawable.Drawable? getCollapseIcon();
+    method public int getContentInsetEnd();
+    method public int getContentInsetEndWithActions();
+    method public int getContentInsetLeft();
+    method public int getContentInsetRight();
+    method public int getContentInsetStart();
+    method public int getContentInsetStartWithNavigation();
+    method public int getCurrentContentInsetEnd();
+    method public int getCurrentContentInsetLeft();
+    method public int getCurrentContentInsetRight();
+    method public int getCurrentContentInsetStart();
+    method public android.graphics.drawable.Drawable! getLogo();
+    method public CharSequence! getLogoDescription();
+    method public android.view.Menu! getMenu();
+    method public CharSequence? getNavigationContentDescription();
+    method public android.graphics.drawable.Drawable? getNavigationIcon();
+    method public android.graphics.drawable.Drawable? getOverflowIcon();
+    method public int getPopupTheme();
+    method public CharSequence! getSubtitle();
+    method public CharSequence! getTitle();
+    method public int getTitleMarginBottom();
+    method public int getTitleMarginEnd();
+    method public int getTitleMarginStart();
+    method public int getTitleMarginTop();
+    method public boolean hasExpandedActionView();
+    method public boolean hideOverflowMenu();
+    method public void inflateMenu(@MenuRes int);
+    method public boolean isOverflowMenuShowing();
+    method public void setCollapseContentDescription(@StringRes int);
+    method public void setCollapseContentDescription(CharSequence?);
+    method public void setCollapseIcon(@DrawableRes int);
+    method public void setCollapseIcon(android.graphics.drawable.Drawable?);
+    method public void setContentInsetEndWithActions(int);
+    method public void setContentInsetStartWithNavigation(int);
+    method public void setContentInsetsAbsolute(int, int);
+    method public void setContentInsetsRelative(int, int);
+    method public void setLogo(@DrawableRes int);
+    method public void setLogo(android.graphics.drawable.Drawable!);
+    method public void setLogoDescription(@StringRes int);
+    method public void setLogoDescription(CharSequence!);
+    method public void setNavigationContentDescription(@StringRes int);
+    method public void setNavigationContentDescription(CharSequence?);
+    method public void setNavigationIcon(@DrawableRes int);
+    method public void setNavigationIcon(android.graphics.drawable.Drawable?);
+    method public void setNavigationOnClickListener(android.view.View.OnClickListener!);
+    method public void setOnMenuItemClickListener(androidx.appcompat.widget.Toolbar.OnMenuItemClickListener!);
+    method public void setOverflowIcon(android.graphics.drawable.Drawable?);
+    method public void setPopupTheme(@StyleRes int);
+    method public void setSubtitle(@StringRes int);
+    method public void setSubtitle(CharSequence!);
+    method public void setSubtitleTextAppearance(android.content.Context!, @StyleRes int);
+    method public void setSubtitleTextColor(@ColorInt int);
+    method public void setSubtitleTextColor(android.content.res.ColorStateList);
+    method public void setTitle(@StringRes int);
+    method public void setTitle(CharSequence!);
+    method public void setTitleMargin(int, int, int, int);
+    method public void setTitleMarginBottom(int);
+    method public void setTitleMarginEnd(int);
+    method public void setTitleMarginStart(int);
+    method public void setTitleMarginTop(int);
+    method public void setTitleTextAppearance(android.content.Context!, @StyleRes int);
+    method public void setTitleTextColor(@ColorInt int);
+    method public void setTitleTextColor(android.content.res.ColorStateList);
+    method public boolean showOverflowMenu();
+  }
+
+  public static class Toolbar.LayoutParams extends androidx.appcompat.app.ActionBar.LayoutParams {
+    ctor public Toolbar.LayoutParams(android.content.Context, android.util.AttributeSet!);
+    ctor public Toolbar.LayoutParams(int, int);
+    ctor public Toolbar.LayoutParams(int, int, int);
+    ctor public Toolbar.LayoutParams(int);
+    ctor public Toolbar.LayoutParams(androidx.appcompat.widget.Toolbar.LayoutParams!);
+    ctor public Toolbar.LayoutParams(androidx.appcompat.app.ActionBar.LayoutParams!);
+    ctor public Toolbar.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public Toolbar.LayoutParams(android.view.ViewGroup.LayoutParams!);
+  }
+
+  public static interface Toolbar.OnMenuItemClickListener {
+    method public boolean onMenuItemClick(android.view.MenuItem!);
+  }
+
+  public static class Toolbar.SavedState extends androidx.customview.view.AbsSavedState {
+    ctor public Toolbar.SavedState(android.os.Parcel!);
+    ctor public Toolbar.SavedState(android.os.Parcel!, ClassLoader!);
+    ctor public Toolbar.SavedState(android.os.Parcelable!);
+    field public static final android.os.Parcelable.Creator<androidx.appcompat.widget.Toolbar.SavedState!>! CREATOR;
+  }
+
+  public class TooltipCompat {
+    method public static void setTooltipText(android.view.View, CharSequence?);
+  }
+
+}
+
diff --git a/appcompat/appcompat/api/public_plus_experimental_1.3.0-beta02.txt b/appcompat/appcompat/api/public_plus_experimental_1.3.0-beta02.txt
new file mode 100644
index 0000000..8886644
--- /dev/null
+++ b/appcompat/appcompat/api/public_plus_experimental_1.3.0-beta02.txt
@@ -0,0 +1,989 @@
+// Signature format: 4.0
+package androidx.appcompat.app {
+
+  public abstract class ActionBar {
+    ctor public ActionBar();
+    method public abstract void addOnMenuVisibilityListener(androidx.appcompat.app.ActionBar.OnMenuVisibilityListener!);
+    method @Deprecated public abstract void addTab(androidx.appcompat.app.ActionBar.Tab!);
+    method @Deprecated public abstract void addTab(androidx.appcompat.app.ActionBar.Tab!, boolean);
+    method @Deprecated public abstract void addTab(androidx.appcompat.app.ActionBar.Tab!, int);
+    method @Deprecated public abstract void addTab(androidx.appcompat.app.ActionBar.Tab!, int, boolean);
+    method public abstract android.view.View! getCustomView();
+    method public abstract int getDisplayOptions();
+    method public float getElevation();
+    method public abstract int getHeight();
+    method public int getHideOffset();
+    method @Deprecated public abstract int getNavigationItemCount();
+    method @Deprecated public abstract int getNavigationMode();
+    method @Deprecated public abstract int getSelectedNavigationIndex();
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab? getSelectedTab();
+    method public abstract CharSequence? getSubtitle();
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! getTabAt(int);
+    method @Deprecated public abstract int getTabCount();
+    method public android.content.Context! getThemedContext();
+    method public abstract CharSequence? getTitle();
+    method public abstract void hide();
+    method public boolean isHideOnContentScrollEnabled();
+    method public abstract boolean isShowing();
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! newTab();
+    method @Deprecated public abstract void removeAllTabs();
+    method public abstract void removeOnMenuVisibilityListener(androidx.appcompat.app.ActionBar.OnMenuVisibilityListener!);
+    method @Deprecated public abstract void removeTab(androidx.appcompat.app.ActionBar.Tab!);
+    method @Deprecated public abstract void removeTabAt(int);
+    method @Deprecated public abstract void selectTab(androidx.appcompat.app.ActionBar.Tab!);
+    method public abstract void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method public abstract void setCustomView(android.view.View!);
+    method public abstract void setCustomView(android.view.View!, androidx.appcompat.app.ActionBar.LayoutParams!);
+    method public abstract void setCustomView(int);
+    method public abstract void setDisplayHomeAsUpEnabled(boolean);
+    method public abstract void setDisplayOptions(int);
+    method public abstract void setDisplayOptions(int, int);
+    method public abstract void setDisplayShowCustomEnabled(boolean);
+    method public abstract void setDisplayShowHomeEnabled(boolean);
+    method public abstract void setDisplayShowTitleEnabled(boolean);
+    method public abstract void setDisplayUseLogoEnabled(boolean);
+    method public void setElevation(float);
+    method public void setHideOffset(int);
+    method public void setHideOnContentScrollEnabled(boolean);
+    method public void setHomeActionContentDescription(CharSequence?);
+    method public void setHomeActionContentDescription(@StringRes int);
+    method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable?);
+    method public void setHomeAsUpIndicator(@DrawableRes int);
+    method public void setHomeButtonEnabled(boolean);
+    method public abstract void setIcon(@DrawableRes int);
+    method public abstract void setIcon(android.graphics.drawable.Drawable!);
+    method @Deprecated public abstract void setListNavigationCallbacks(android.widget.SpinnerAdapter!, androidx.appcompat.app.ActionBar.OnNavigationListener!);
+    method public abstract void setLogo(@DrawableRes int);
+    method public abstract void setLogo(android.graphics.drawable.Drawable!);
+    method @Deprecated public abstract void setNavigationMode(int);
+    method @Deprecated public abstract void setSelectedNavigationItem(int);
+    method public void setSplitBackgroundDrawable(android.graphics.drawable.Drawable!);
+    method public void setStackedBackgroundDrawable(android.graphics.drawable.Drawable!);
+    method public abstract void setSubtitle(CharSequence!);
+    method public abstract void setSubtitle(int);
+    method public abstract void setTitle(CharSequence!);
+    method public abstract void setTitle(@StringRes int);
+    method public abstract void show();
+    field public static final int DISPLAY_HOME_AS_UP = 4; // 0x4
+    field public static final int DISPLAY_SHOW_CUSTOM = 16; // 0x10
+    field public static final int DISPLAY_SHOW_HOME = 2; // 0x2
+    field public static final int DISPLAY_SHOW_TITLE = 8; // 0x8
+    field public static final int DISPLAY_USE_LOGO = 1; // 0x1
+    field @Deprecated public static final int NAVIGATION_MODE_LIST = 1; // 0x1
+    field @Deprecated public static final int NAVIGATION_MODE_STANDARD = 0; // 0x0
+    field @Deprecated public static final int NAVIGATION_MODE_TABS = 2; // 0x2
+  }
+
+  public static class ActionBar.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+    ctor public ActionBar.LayoutParams(android.content.Context, android.util.AttributeSet!);
+    ctor public ActionBar.LayoutParams(int, int);
+    ctor public ActionBar.LayoutParams(int, int, int);
+    ctor public ActionBar.LayoutParams(int);
+    ctor public ActionBar.LayoutParams(androidx.appcompat.app.ActionBar.LayoutParams!);
+    ctor public ActionBar.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    field public int gravity;
+  }
+
+  public static interface ActionBar.OnMenuVisibilityListener {
+    method public void onMenuVisibilityChanged(boolean);
+  }
+
+  @Deprecated public static interface ActionBar.OnNavigationListener {
+    method @Deprecated public boolean onNavigationItemSelected(int, long);
+  }
+
+  @Deprecated public abstract static class ActionBar.Tab {
+    ctor @Deprecated public ActionBar.Tab();
+    method @Deprecated public abstract CharSequence! getContentDescription();
+    method @Deprecated public abstract android.view.View! getCustomView();
+    method @Deprecated public abstract android.graphics.drawable.Drawable! getIcon();
+    method @Deprecated public abstract int getPosition();
+    method @Deprecated public abstract Object! getTag();
+    method @Deprecated public abstract CharSequence! getText();
+    method @Deprecated public abstract void select();
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setContentDescription(@StringRes int);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setContentDescription(CharSequence!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setCustomView(android.view.View!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setCustomView(int);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setIcon(android.graphics.drawable.Drawable!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setIcon(@DrawableRes int);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setTabListener(androidx.appcompat.app.ActionBar.TabListener!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setTag(Object!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setText(CharSequence!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setText(int);
+    field @Deprecated public static final int INVALID_POSITION = -1; // 0xffffffff
+  }
+
+  @Deprecated public static interface ActionBar.TabListener {
+    method @Deprecated public void onTabReselected(androidx.appcompat.app.ActionBar.Tab!, androidx.fragment.app.FragmentTransaction!);
+    method @Deprecated public void onTabSelected(androidx.appcompat.app.ActionBar.Tab!, androidx.fragment.app.FragmentTransaction!);
+    method @Deprecated public void onTabUnselected(androidx.appcompat.app.ActionBar.Tab!, androidx.fragment.app.FragmentTransaction!);
+  }
+
+  public class ActionBarDrawerToggle implements androidx.drawerlayout.widget.DrawerLayout.DrawerListener {
+    ctor public ActionBarDrawerToggle(android.app.Activity!, androidx.drawerlayout.widget.DrawerLayout!, @StringRes int, @StringRes int);
+    ctor public ActionBarDrawerToggle(android.app.Activity!, androidx.drawerlayout.widget.DrawerLayout!, androidx.appcompat.widget.Toolbar!, @StringRes int, @StringRes int);
+    method public androidx.appcompat.graphics.drawable.DrawerArrowDrawable getDrawerArrowDrawable();
+    method public android.view.View.OnClickListener! getToolbarNavigationClickListener();
+    method public boolean isDrawerIndicatorEnabled();
+    method public boolean isDrawerSlideAnimationEnabled();
+    method public void onConfigurationChanged(android.content.res.Configuration!);
+    method public void onDrawerClosed(android.view.View!);
+    method public void onDrawerOpened(android.view.View!);
+    method public void onDrawerSlide(android.view.View!, float);
+    method public void onDrawerStateChanged(int);
+    method public boolean onOptionsItemSelected(android.view.MenuItem!);
+    method public void setDrawerArrowDrawable(androidx.appcompat.graphics.drawable.DrawerArrowDrawable);
+    method public void setDrawerIndicatorEnabled(boolean);
+    method public void setDrawerSlideAnimationEnabled(boolean);
+    method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable!);
+    method public void setHomeAsUpIndicator(int);
+    method public void setToolbarNavigationClickListener(android.view.View.OnClickListener!);
+    method public void syncState();
+  }
+
+  public static interface ActionBarDrawerToggle.Delegate {
+    method public android.content.Context! getActionBarThemedContext();
+    method public android.graphics.drawable.Drawable! getThemeUpIndicator();
+    method public boolean isNavigationVisible();
+    method public void setActionBarDescription(@StringRes int);
+    method public void setActionBarUpIndicator(android.graphics.drawable.Drawable!, @StringRes int);
+  }
+
+  public static interface ActionBarDrawerToggle.DelegateProvider {
+    method public androidx.appcompat.app.ActionBarDrawerToggle.Delegate? getDrawerToggleDelegate();
+  }
+
+  public class AlertDialog extends androidx.appcompat.app.AppCompatDialog implements android.content.DialogInterface {
+    ctor protected AlertDialog(android.content.Context);
+    ctor protected AlertDialog(android.content.Context, @StyleRes int);
+    ctor protected AlertDialog(android.content.Context, boolean, android.content.DialogInterface.OnCancelListener?);
+    method public android.widget.Button! getButton(int);
+    method public android.widget.ListView! getListView();
+    method public void setButton(int, CharSequence!, android.os.Message!);
+    method public void setButton(int, CharSequence!, android.content.DialogInterface.OnClickListener!);
+    method public void setButton(int, CharSequence!, android.graphics.drawable.Drawable!, android.content.DialogInterface.OnClickListener!);
+    method public void setCustomTitle(android.view.View!);
+    method public void setIcon(int);
+    method public void setIcon(android.graphics.drawable.Drawable!);
+    method public void setIconAttribute(int);
+    method public void setMessage(CharSequence!);
+    method public void setView(android.view.View!);
+    method public void setView(android.view.View!, int, int, int, int);
+  }
+
+  public static class AlertDialog.Builder {
+    ctor public AlertDialog.Builder(android.content.Context);
+    ctor public AlertDialog.Builder(android.content.Context, @StyleRes int);
+    method public androidx.appcompat.app.AlertDialog create();
+    method public android.content.Context getContext();
+    method public androidx.appcompat.app.AlertDialog.Builder! setAdapter(android.widget.ListAdapter!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setCancelable(boolean);
+    method public androidx.appcompat.app.AlertDialog.Builder! setCursor(android.database.Cursor!, android.content.DialogInterface.OnClickListener!, String!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setCustomTitle(android.view.View?);
+    method public androidx.appcompat.app.AlertDialog.Builder! setIcon(@DrawableRes int);
+    method public androidx.appcompat.app.AlertDialog.Builder! setIcon(android.graphics.drawable.Drawable?);
+    method public androidx.appcompat.app.AlertDialog.Builder! setIconAttribute(@AttrRes int);
+    method @Deprecated public androidx.appcompat.app.AlertDialog.Builder! setInverseBackgroundForced(boolean);
+    method public androidx.appcompat.app.AlertDialog.Builder! setItems(@ArrayRes int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setItems(CharSequence![]!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setMessage(@StringRes int);
+    method public androidx.appcompat.app.AlertDialog.Builder! setMessage(CharSequence?);
+    method public androidx.appcompat.app.AlertDialog.Builder! setMultiChoiceItems(@ArrayRes int, boolean[]!, android.content.DialogInterface.OnMultiChoiceClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setMultiChoiceItems(CharSequence![]!, boolean[]!, android.content.DialogInterface.OnMultiChoiceClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setMultiChoiceItems(android.database.Cursor!, String!, String!, android.content.DialogInterface.OnMultiChoiceClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNegativeButton(@StringRes int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNegativeButton(CharSequence!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNegativeButtonIcon(android.graphics.drawable.Drawable!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNeutralButton(@StringRes int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNeutralButton(CharSequence!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNeutralButtonIcon(android.graphics.drawable.Drawable!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setOnCancelListener(android.content.DialogInterface.OnCancelListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setOnDismissListener(android.content.DialogInterface.OnDismissListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setOnKeyListener(android.content.DialogInterface.OnKeyListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setPositiveButton(@StringRes int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setPositiveButton(CharSequence!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setPositiveButtonIcon(android.graphics.drawable.Drawable!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setSingleChoiceItems(@ArrayRes int, int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setSingleChoiceItems(android.database.Cursor!, int, String!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setSingleChoiceItems(CharSequence![]!, int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setSingleChoiceItems(android.widget.ListAdapter!, int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setTitle(@StringRes int);
+    method public androidx.appcompat.app.AlertDialog.Builder! setTitle(CharSequence?);
+    method public androidx.appcompat.app.AlertDialog.Builder! setView(int);
+    method public androidx.appcompat.app.AlertDialog.Builder! setView(android.view.View!);
+    method public androidx.appcompat.app.AlertDialog! show();
+  }
+
+  public class AppCompatActivity extends androidx.fragment.app.FragmentActivity implements androidx.appcompat.app.ActionBarDrawerToggle.DelegateProvider androidx.appcompat.app.AppCompatCallback androidx.core.app.TaskStackBuilder.SupportParentable {
+    ctor public AppCompatActivity();
+    ctor @ContentView public AppCompatActivity(@LayoutRes int);
+    method public androidx.appcompat.app.AppCompatDelegate getDelegate();
+    method public androidx.appcompat.app.ActionBarDrawerToggle.Delegate? getDrawerToggleDelegate();
+    method public androidx.appcompat.app.ActionBar? getSupportActionBar();
+    method public android.content.Intent? getSupportParentActivityIntent();
+    method public void onCreateSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder);
+    method public final boolean onMenuItemSelected(int, android.view.MenuItem);
+    method protected void onNightModeChanged(int);
+    method public void onPrepareSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder);
+    method @CallSuper public void onSupportActionModeFinished(androidx.appcompat.view.ActionMode);
+    method @CallSuper public void onSupportActionModeStarted(androidx.appcompat.view.ActionMode);
+    method @Deprecated public void onSupportContentChanged();
+    method public boolean onSupportNavigateUp();
+    method public androidx.appcompat.view.ActionMode? onWindowStartingSupportActionMode(androidx.appcompat.view.ActionMode.Callback);
+    method public void setSupportActionBar(androidx.appcompat.widget.Toolbar?);
+    method @Deprecated public void setSupportProgress(int);
+    method @Deprecated public void setSupportProgressBarIndeterminate(boolean);
+    method @Deprecated public void setSupportProgressBarIndeterminateVisibility(boolean);
+    method @Deprecated public void setSupportProgressBarVisibility(boolean);
+    method public androidx.appcompat.view.ActionMode? startSupportActionMode(androidx.appcompat.view.ActionMode.Callback);
+    method public void supportInvalidateOptionsMenu();
+    method public void supportNavigateUpTo(android.content.Intent);
+    method public boolean supportRequestWindowFeature(int);
+    method public boolean supportShouldUpRecreateTask(android.content.Intent);
+  }
+
+  public interface AppCompatCallback {
+    method public void onSupportActionModeFinished(androidx.appcompat.view.ActionMode!);
+    method public void onSupportActionModeStarted(androidx.appcompat.view.ActionMode!);
+    method public androidx.appcompat.view.ActionMode? onWindowStartingSupportActionMode(androidx.appcompat.view.ActionMode.Callback!);
+  }
+
+  public abstract class AppCompatDelegate {
+    method public abstract void addContentView(android.view.View!, android.view.ViewGroup.LayoutParams!);
+    method public abstract boolean applyDayNight();
+    method @Deprecated public void attachBaseContext(android.content.Context!);
+    method @CallSuper public android.content.Context attachBaseContext2(android.content.Context);
+    method public static androidx.appcompat.app.AppCompatDelegate create(android.app.Activity, androidx.appcompat.app.AppCompatCallback?);
+    method public static androidx.appcompat.app.AppCompatDelegate create(android.app.Dialog, androidx.appcompat.app.AppCompatCallback?);
+    method public static androidx.appcompat.app.AppCompatDelegate create(android.content.Context, android.view.Window, androidx.appcompat.app.AppCompatCallback?);
+    method public static androidx.appcompat.app.AppCompatDelegate create(android.content.Context, android.app.Activity, androidx.appcompat.app.AppCompatCallback?);
+    method public abstract android.view.View! createView(android.view.View?, String!, android.content.Context, android.util.AttributeSet);
+    method public abstract <T extends android.view.View> T! findViewById(@IdRes int);
+    method public static int getDefaultNightMode();
+    method public abstract androidx.appcompat.app.ActionBarDrawerToggle.Delegate? getDrawerToggleDelegate();
+    method public int getLocalNightMode();
+    method public abstract android.view.MenuInflater! getMenuInflater();
+    method public abstract androidx.appcompat.app.ActionBar? getSupportActionBar();
+    method public abstract boolean hasWindowFeature(int);
+    method public abstract void installViewFactory();
+    method public abstract void invalidateOptionsMenu();
+    method public static boolean isCompatVectorFromResourcesEnabled();
+    method public abstract boolean isHandleNativeActionModesEnabled();
+    method public abstract void onConfigurationChanged(android.content.res.Configuration!);
+    method public abstract void onCreate(android.os.Bundle!);
+    method public abstract void onDestroy();
+    method public abstract void onPostCreate(android.os.Bundle!);
+    method public abstract void onPostResume();
+    method public abstract void onSaveInstanceState(android.os.Bundle!);
+    method public abstract void onStart();
+    method public abstract void onStop();
+    method public abstract boolean requestWindowFeature(int);
+    method public static void setCompatVectorFromResourcesEnabled(boolean);
+    method public abstract void setContentView(android.view.View!);
+    method public abstract void setContentView(@LayoutRes int);
+    method public abstract void setContentView(android.view.View!, android.view.ViewGroup.LayoutParams!);
+    method public static void setDefaultNightMode(int);
+    method public abstract void setHandleNativeActionModesEnabled(boolean);
+    method @RequiresApi(17) public abstract void setLocalNightMode(int);
+    method public abstract void setSupportActionBar(androidx.appcompat.widget.Toolbar?);
+    method public void setTheme(@StyleRes int);
+    method public abstract void setTitle(CharSequence?);
+    method public abstract androidx.appcompat.view.ActionMode? startSupportActionMode(androidx.appcompat.view.ActionMode.Callback);
+    field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+    field public static final int FEATURE_SUPPORT_ACTION_BAR = 108; // 0x6c
+    field public static final int FEATURE_SUPPORT_ACTION_BAR_OVERLAY = 109; // 0x6d
+    field @Deprecated public static final int MODE_NIGHT_AUTO = 0; // 0x0
+    field public static final int MODE_NIGHT_AUTO_BATTERY = 3; // 0x3
+    field @Deprecated public static final int MODE_NIGHT_AUTO_TIME = 0; // 0x0
+    field public static final int MODE_NIGHT_FOLLOW_SYSTEM = -1; // 0xffffffff
+    field public static final int MODE_NIGHT_NO = 1; // 0x1
+    field public static final int MODE_NIGHT_UNSPECIFIED = -100; // 0xffffff9c
+    field public static final int MODE_NIGHT_YES = 2; // 0x2
+  }
+
+  public class AppCompatDialog extends android.app.Dialog implements androidx.appcompat.app.AppCompatCallback {
+    ctor public AppCompatDialog(android.content.Context!);
+    ctor public AppCompatDialog(android.content.Context!, int);
+    ctor protected AppCompatDialog(android.content.Context!, boolean, android.content.DialogInterface.OnCancelListener!);
+    method public androidx.appcompat.app.AppCompatDelegate! getDelegate();
+    method public androidx.appcompat.app.ActionBar! getSupportActionBar();
+    method public void onSupportActionModeFinished(androidx.appcompat.view.ActionMode!);
+    method public void onSupportActionModeStarted(androidx.appcompat.view.ActionMode!);
+    method public androidx.appcompat.view.ActionMode? onWindowStartingSupportActionMode(androidx.appcompat.view.ActionMode.Callback!);
+    method public boolean supportRequestWindowFeature(int);
+  }
+
+  public class AppCompatDialogFragment extends androidx.fragment.app.DialogFragment {
+    ctor public AppCompatDialogFragment();
+  }
+
+  public class AppCompatViewInflater {
+    ctor public AppCompatViewInflater();
+    method protected androidx.appcompat.widget.AppCompatAutoCompleteTextView createAutoCompleteTextView(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatButton createButton(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatCheckBox createCheckBox(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatCheckedTextView createCheckedTextView(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatEditText createEditText(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatImageButton createImageButton(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatImageView createImageView(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatMultiAutoCompleteTextView createMultiAutoCompleteTextView(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatRadioButton createRadioButton(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatRatingBar createRatingBar(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatSeekBar createSeekBar(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatSpinner createSpinner(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatTextView createTextView(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatToggleButton createToggleButton(android.content.Context!, android.util.AttributeSet!);
+    method protected android.view.View? createView(android.content.Context!, String!, android.util.AttributeSet!);
+  }
+
+}
+
+package androidx.appcompat.graphics.drawable {
+
+  public class DrawerArrowDrawable extends android.graphics.drawable.Drawable {
+    ctor public DrawerArrowDrawable(android.content.Context!);
+    method public void draw(android.graphics.Canvas!);
+    method public float getArrowHeadLength();
+    method public float getArrowShaftLength();
+    method public float getBarLength();
+    method public float getBarThickness();
+    method @ColorInt public int getColor();
+    method public int getDirection();
+    method public float getGapSize();
+    method public int getOpacity();
+    method public final android.graphics.Paint! getPaint();
+    method @FloatRange(from=0.0, to=1.0) public float getProgress();
+    method public boolean isSpinEnabled();
+    method public void setAlpha(int);
+    method public void setArrowHeadLength(float);
+    method public void setArrowShaftLength(float);
+    method public void setBarLength(float);
+    method public void setBarThickness(float);
+    method public void setColor(@ColorInt int);
+    method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setDirection(int);
+    method public void setGapSize(float);
+    method public void setProgress(@FloatRange(from=0.0, to=1.0) float);
+    method public void setSpinEnabled(boolean);
+    method public void setVerticalMirror(boolean);
+    field public static final int ARROW_DIRECTION_END = 3; // 0x3
+    field public static final int ARROW_DIRECTION_LEFT = 0; // 0x0
+    field public static final int ARROW_DIRECTION_RIGHT = 1; // 0x1
+    field public static final int ARROW_DIRECTION_START = 2; // 0x2
+  }
+
+}
+
+package androidx.appcompat.view {
+
+  public abstract class ActionMode {
+    ctor public ActionMode();
+    method public abstract void finish();
+    method public abstract android.view.View! getCustomView();
+    method public abstract android.view.Menu! getMenu();
+    method public abstract android.view.MenuInflater! getMenuInflater();
+    method public abstract CharSequence! getSubtitle();
+    method public Object! getTag();
+    method public abstract CharSequence! getTitle();
+    method public boolean getTitleOptionalHint();
+    method public abstract void invalidate();
+    method public boolean isTitleOptional();
+    method public abstract void setCustomView(android.view.View!);
+    method public abstract void setSubtitle(CharSequence!);
+    method public abstract void setSubtitle(int);
+    method public void setTag(Object!);
+    method public abstract void setTitle(CharSequence!);
+    method public abstract void setTitle(int);
+    method public void setTitleOptionalHint(boolean);
+  }
+
+  public static interface ActionMode.Callback {
+    method public boolean onActionItemClicked(androidx.appcompat.view.ActionMode!, android.view.MenuItem!);
+    method public boolean onCreateActionMode(androidx.appcompat.view.ActionMode!, android.view.Menu!);
+    method public void onDestroyActionMode(androidx.appcompat.view.ActionMode!);
+    method public boolean onPrepareActionMode(androidx.appcompat.view.ActionMode!, android.view.Menu!);
+  }
+
+  @Deprecated public interface CollapsibleActionView {
+    method @Deprecated public void onActionViewCollapsed();
+    method @Deprecated public void onActionViewExpanded();
+  }
+
+  public class ContextThemeWrapper extends android.content.ContextWrapper {
+    ctor public ContextThemeWrapper();
+    ctor public ContextThemeWrapper(android.content.Context!, @StyleRes int);
+    ctor public ContextThemeWrapper(android.content.Context!, android.content.res.Resources.Theme!);
+    method public void applyOverrideConfiguration(android.content.res.Configuration!);
+    method public int getThemeResId();
+    method protected void onApplyThemeResource(android.content.res.Resources.Theme!, int, boolean);
+  }
+
+}
+
+package androidx.appcompat.widget {
+
+  public class ActionMenuView extends androidx.appcompat.widget.LinearLayoutCompat {
+    ctor public ActionMenuView(android.content.Context);
+    ctor public ActionMenuView(android.content.Context, android.util.AttributeSet?);
+    method public void dismissPopupMenus();
+    method protected androidx.appcompat.widget.ActionMenuView.LayoutParams! generateDefaultLayoutParams();
+    method public androidx.appcompat.widget.ActionMenuView.LayoutParams! generateLayoutParams(android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.ActionMenuView.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+    method public android.view.Menu! getMenu();
+    method public android.graphics.drawable.Drawable? getOverflowIcon();
+    method public int getPopupTheme();
+    method public boolean hideOverflowMenu();
+    method public boolean isOverflowMenuShowing();
+    method public void onConfigurationChanged(android.content.res.Configuration!);
+    method public void onDetachedFromWindow();
+    method public void setOnMenuItemClickListener(androidx.appcompat.widget.ActionMenuView.OnMenuItemClickListener!);
+    method public void setOverflowIcon(android.graphics.drawable.Drawable?);
+    method public void setPopupTheme(@StyleRes int);
+    method public boolean showOverflowMenu();
+  }
+
+  public static class ActionMenuView.LayoutParams extends androidx.appcompat.widget.LinearLayoutCompat.LayoutParams {
+    ctor public ActionMenuView.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public ActionMenuView.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public ActionMenuView.LayoutParams(androidx.appcompat.widget.ActionMenuView.LayoutParams!);
+    ctor public ActionMenuView.LayoutParams(int, int);
+    field public int cellsUsed;
+    field public boolean expandable;
+    field public int extraPixels;
+    field public boolean isOverflowButton;
+    field public boolean preventEdgeOffset;
+  }
+
+  public static interface ActionMenuView.OnMenuItemClickListener {
+    method public boolean onMenuItemClick(android.view.MenuItem!);
+  }
+
+  public class AppCompatAutoCompleteTextView extends android.widget.AutoCompleteTextView implements androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatAutoCompleteTextView(android.content.Context);
+    ctor public AppCompatAutoCompleteTextView(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatAutoCompleteTextView(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTextAppearance(android.content.Context!, int);
+  }
+
+  public class AppCompatButton extends android.widget.Button implements androidx.core.widget.AutoSizeableTextView androidx.core.view.TintableBackgroundView androidx.core.widget.TintableCompoundDrawablesView {
+    ctor public AppCompatButton(android.content.Context);
+    ctor public AppCompatButton(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatButton(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportCompoundDrawablesTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportCompoundDrawablesTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setAutoSizeTextTypeUniformWithConfiguration(int, int, int, int) throws java.lang.IllegalArgumentException;
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setAutoSizeTextTypeUniformWithPresetSizes(int[], int) throws java.lang.IllegalArgumentException;
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method public void setSupportAllCaps(boolean);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportCompoundDrawablesTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportCompoundDrawablesTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTextAppearance(android.content.Context!, int);
+  }
+
+  public class AppCompatCheckBox extends android.widget.CheckBox implements androidx.core.view.TintableBackgroundView androidx.core.widget.TintableCompoundButton {
+    ctor public AppCompatCheckBox(android.content.Context);
+    ctor public AppCompatCheckBox(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatCheckBox(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportButtonTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportButtonTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportButtonTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public class AppCompatCheckedTextView extends android.widget.CheckedTextView {
+    ctor public AppCompatCheckedTextView(android.content.Context);
+    ctor public AppCompatCheckedTextView(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatCheckedTextView(android.content.Context, android.util.AttributeSet?, int);
+    method public void setTextAppearance(android.content.Context!, int);
+  }
+
+  public class AppCompatEditText extends android.widget.EditText implements androidx.core.view.OnReceiveContentViewBehavior androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatEditText(android.content.Context);
+    ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public androidx.core.view.ContentInfoCompat? onReceiveContent(androidx.core.view.ContentInfoCompat);
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTextAppearance(android.content.Context!, int);
+  }
+
+  public class AppCompatImageButton extends android.widget.ImageButton implements androidx.core.view.TintableBackgroundView androidx.core.widget.TintableImageSourceView {
+    ctor public AppCompatImageButton(android.content.Context);
+    ctor public AppCompatImageButton(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatImageButton(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportImageTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportImageTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportImageTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportImageTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public class AppCompatImageView extends android.widget.ImageView implements androidx.core.view.TintableBackgroundView androidx.core.widget.TintableImageSourceView {
+    ctor public AppCompatImageView(android.content.Context);
+    ctor public AppCompatImageView(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatImageView(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportImageTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportImageTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportImageTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportImageTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public class AppCompatMultiAutoCompleteTextView extends android.widget.MultiAutoCompleteTextView implements androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatMultiAutoCompleteTextView(android.content.Context);
+    ctor public AppCompatMultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatMultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTextAppearance(android.content.Context!, int);
+  }
+
+  public class AppCompatRadioButton extends android.widget.RadioButton implements androidx.core.view.TintableBackgroundView androidx.core.widget.TintableCompoundButton {
+    ctor public AppCompatRadioButton(android.content.Context!);
+    ctor public AppCompatRadioButton(android.content.Context!, android.util.AttributeSet?);
+    ctor public AppCompatRadioButton(android.content.Context!, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportButtonTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportButtonTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportButtonTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public class AppCompatRatingBar extends android.widget.RatingBar {
+    ctor public AppCompatRatingBar(android.content.Context);
+    ctor public AppCompatRatingBar(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatRatingBar(android.content.Context, android.util.AttributeSet?, int);
+  }
+
+  public class AppCompatSeekBar extends android.widget.SeekBar {
+    ctor public AppCompatSeekBar(android.content.Context);
+    ctor public AppCompatSeekBar(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatSeekBar(android.content.Context, android.util.AttributeSet?, int);
+  }
+
+  public class AppCompatSpinner extends android.widget.Spinner implements androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatSpinner(android.content.Context);
+    ctor public AppCompatSpinner(android.content.Context, int);
+    ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet?, int);
+    ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet?, int, int);
+    ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet?, int, int, android.content.res.Resources.Theme!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public class AppCompatTextView extends android.widget.TextView implements androidx.core.widget.AutoSizeableTextView androidx.core.view.TintableBackgroundView androidx.core.widget.TintableCompoundDrawablesView {
+    ctor public AppCompatTextView(android.content.Context);
+    ctor public AppCompatTextView(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatTextView(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportCompoundDrawablesTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportCompoundDrawablesTintMode();
+    method public androidx.core.text.PrecomputedTextCompat.Params getTextMetricsParamsCompat();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setAutoSizeTextTypeUniformWithConfiguration(int, int, int, int) throws java.lang.IllegalArgumentException;
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setAutoSizeTextTypeUniformWithPresetSizes(int[], int) throws java.lang.IllegalArgumentException;
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method public void setPrecomputedText(androidx.core.text.PrecomputedTextCompat);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportCompoundDrawablesTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportCompoundDrawablesTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTextAppearance(android.content.Context!, int);
+    method public void setTextFuture(java.util.concurrent.Future<androidx.core.text.PrecomputedTextCompat!>?);
+    method public void setTextMetricsParamsCompat(androidx.core.text.PrecomputedTextCompat.Params);
+  }
+
+  public class AppCompatToggleButton extends android.widget.ToggleButton implements androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatToggleButton(android.content.Context);
+    ctor public AppCompatToggleButton(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatToggleButton(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public class LinearLayoutCompat extends android.view.ViewGroup {
+    ctor public LinearLayoutCompat(android.content.Context);
+    ctor public LinearLayoutCompat(android.content.Context, android.util.AttributeSet?);
+    ctor public LinearLayoutCompat(android.content.Context, android.util.AttributeSet?, int);
+    method protected androidx.appcompat.widget.LinearLayoutCompat.LayoutParams! generateDefaultLayoutParams();
+    method public androidx.appcompat.widget.LinearLayoutCompat.LayoutParams! generateLayoutParams(android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.LinearLayoutCompat.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+    method public int getBaselineAlignedChildIndex();
+    method public android.graphics.drawable.Drawable! getDividerDrawable();
+    method public int getDividerPadding();
+    method public int getGravity();
+    method public int getOrientation();
+    method public int getShowDividers();
+    method public float getWeightSum();
+    method public boolean isBaselineAligned();
+    method public boolean isMeasureWithLargestChildEnabled();
+    method public void setBaselineAligned(boolean);
+    method public void setBaselineAlignedChildIndex(int);
+    method public void setDividerDrawable(android.graphics.drawable.Drawable!);
+    method public void setDividerPadding(int);
+    method public void setGravity(int);
+    method public void setHorizontalGravity(int);
+    method public void setMeasureWithLargestChildEnabled(boolean);
+    method public void setOrientation(int);
+    method public void setShowDividers(int);
+    method public void setVerticalGravity(int);
+    method public void setWeightSum(float);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int SHOW_DIVIDER_BEGINNING = 1; // 0x1
+    field public static final int SHOW_DIVIDER_END = 4; // 0x4
+    field public static final int SHOW_DIVIDER_MIDDLE = 2; // 0x2
+    field public static final int SHOW_DIVIDER_NONE = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public static class LinearLayoutCompat.LayoutParams extends android.widget.LinearLayout.LayoutParams {
+    ctor public LinearLayoutCompat.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public LinearLayoutCompat.LayoutParams(int, int);
+    ctor public LinearLayoutCompat.LayoutParams(int, int, float);
+    ctor public LinearLayoutCompat.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public LinearLayoutCompat.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+  }
+
+  public class ListPopupWindow {
+    ctor public ListPopupWindow(android.content.Context);
+    ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet?);
+    ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet?, @AttrRes int);
+    ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet?, @AttrRes int, @StyleRes int);
+    method public void clearListSelection();
+    method public android.view.View.OnTouchListener! createDragToOpenListener(android.view.View!);
+    method public void dismiss();
+    method public android.view.View? getAnchorView();
+    method @StyleRes public int getAnimationStyle();
+    method public android.graphics.drawable.Drawable? getBackground();
+    method public android.graphics.Rect? getEpicenterBounds();
+    method public int getHeight();
+    method public int getHorizontalOffset();
+    method public int getInputMethodMode();
+    method public android.widget.ListView? getListView();
+    method public int getPromptPosition();
+    method public Object? getSelectedItem();
+    method public long getSelectedItemId();
+    method public int getSelectedItemPosition();
+    method public android.view.View? getSelectedView();
+    method public int getSoftInputMode();
+    method public int getVerticalOffset();
+    method public int getWidth();
+    method public boolean isInputMethodNotNeeded();
+    method public boolean isModal();
+    method public boolean isShowing();
+    method public boolean onKeyDown(int, android.view.KeyEvent);
+    method public boolean onKeyPreIme(int, android.view.KeyEvent);
+    method public boolean onKeyUp(int, android.view.KeyEvent);
+    method public boolean performItemClick(int);
+    method public void postShow();
+    method public void setAdapter(android.widget.ListAdapter?);
+    method public void setAnchorView(android.view.View?);
+    method public void setAnimationStyle(@StyleRes int);
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method public void setContentWidth(int);
+    method public void setDropDownGravity(int);
+    method public void setEpicenterBounds(android.graphics.Rect?);
+    method public void setHeight(int);
+    method public void setHorizontalOffset(int);
+    method public void setInputMethodMode(int);
+    method public void setListSelector(android.graphics.drawable.Drawable!);
+    method public void setModal(boolean);
+    method public void setOnDismissListener(android.widget.PopupWindow.OnDismissListener?);
+    method public void setOnItemClickListener(android.widget.AdapterView.OnItemClickListener?);
+    method public void setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener?);
+    method public void setPromptPosition(int);
+    method public void setPromptView(android.view.View?);
+    method public void setSelection(int);
+    method public void setSoftInputMode(int);
+    method public void setVerticalOffset(int);
+    method public void setWidth(int);
+    method public void setWindowLayoutType(int);
+    method public void show();
+    field public static final int INPUT_METHOD_FROM_FOCUSABLE = 0; // 0x0
+    field public static final int INPUT_METHOD_NEEDED = 1; // 0x1
+    field public static final int INPUT_METHOD_NOT_NEEDED = 2; // 0x2
+    field public static final int MATCH_PARENT = -1; // 0xffffffff
+    field public static final int POSITION_PROMPT_ABOVE = 0; // 0x0
+    field public static final int POSITION_PROMPT_BELOW = 1; // 0x1
+    field public static final int WRAP_CONTENT = -2; // 0xfffffffe
+  }
+
+  public class PopupMenu {
+    ctor public PopupMenu(android.content.Context, android.view.View);
+    ctor public PopupMenu(android.content.Context, android.view.View, int);
+    ctor public PopupMenu(android.content.Context, android.view.View, int, @AttrRes int, @StyleRes int);
+    method public void dismiss();
+    method public android.view.View.OnTouchListener getDragToOpenListener();
+    method public int getGravity();
+    method public android.view.Menu getMenu();
+    method public android.view.MenuInflater getMenuInflater();
+    method public void inflate(@MenuRes int);
+    method public void setGravity(int);
+    method public void setOnDismissListener(androidx.appcompat.widget.PopupMenu.OnDismissListener?);
+    method public void setOnMenuItemClickListener(androidx.appcompat.widget.PopupMenu.OnMenuItemClickListener?);
+    method public void show();
+  }
+
+  public static interface PopupMenu.OnDismissListener {
+    method public void onDismiss(androidx.appcompat.widget.PopupMenu!);
+  }
+
+  public static interface PopupMenu.OnMenuItemClickListener {
+    method public boolean onMenuItemClick(android.view.MenuItem!);
+  }
+
+  public class SearchView extends androidx.appcompat.widget.LinearLayoutCompat implements androidx.appcompat.view.CollapsibleActionView {
+    ctor public SearchView(android.content.Context);
+    ctor public SearchView(android.content.Context, android.util.AttributeSet?);
+    ctor public SearchView(android.content.Context, android.util.AttributeSet?, int);
+    method public int getImeOptions();
+    method public int getInputType();
+    method public int getMaxWidth();
+    method public CharSequence! getQuery();
+    method public CharSequence? getQueryHint();
+    method public androidx.cursoradapter.widget.CursorAdapter! getSuggestionsAdapter();
+    method public boolean isIconfiedByDefault();
+    method public boolean isIconified();
+    method public boolean isQueryRefinementEnabled();
+    method public boolean isSubmitButtonEnabled();
+    method public void onActionViewCollapsed();
+    method public void onActionViewExpanded();
+    method public void setIconified(boolean);
+    method public void setIconifiedByDefault(boolean);
+    method public void setImeOptions(int);
+    method public void setInputType(int);
+    method public void setMaxWidth(int);
+    method public void setOnCloseListener(androidx.appcompat.widget.SearchView.OnCloseListener!);
+    method public void setOnQueryTextFocusChangeListener(android.view.View.OnFocusChangeListener!);
+    method public void setOnQueryTextListener(androidx.appcompat.widget.SearchView.OnQueryTextListener!);
+    method public void setOnSearchClickListener(android.view.View.OnClickListener!);
+    method public void setOnSuggestionListener(androidx.appcompat.widget.SearchView.OnSuggestionListener!);
+    method public void setQuery(CharSequence!, boolean);
+    method public void setQueryHint(CharSequence?);
+    method public void setQueryRefinementEnabled(boolean);
+    method public void setSearchableInfo(android.app.SearchableInfo!);
+    method public void setSubmitButtonEnabled(boolean);
+    method public void setSuggestionsAdapter(androidx.cursoradapter.widget.CursorAdapter!);
+  }
+
+  public static interface SearchView.OnCloseListener {
+    method public boolean onClose();
+  }
+
+  public static interface SearchView.OnQueryTextListener {
+    method public boolean onQueryTextChange(String!);
+    method public boolean onQueryTextSubmit(String!);
+  }
+
+  public static interface SearchView.OnSuggestionListener {
+    method public boolean onSuggestionClick(int);
+    method public boolean onSuggestionSelect(int);
+  }
+
+  public class ShareActionProvider extends androidx.core.view.ActionProvider {
+    ctor public ShareActionProvider(android.content.Context!);
+    method public android.view.View! onCreateActionView();
+    method public void setOnShareTargetSelectedListener(androidx.appcompat.widget.ShareActionProvider.OnShareTargetSelectedListener!);
+    method public void setShareHistoryFileName(String!);
+    method public void setShareIntent(android.content.Intent!);
+    field public static final String DEFAULT_SHARE_HISTORY_FILE_NAME = "share_history.xml";
+  }
+
+  public static interface ShareActionProvider.OnShareTargetSelectedListener {
+    method public boolean onShareTargetSelected(androidx.appcompat.widget.ShareActionProvider!, android.content.Intent!);
+  }
+
+  public class SwitchCompat extends android.widget.CompoundButton {
+    ctor public SwitchCompat(android.content.Context);
+    ctor public SwitchCompat(android.content.Context, android.util.AttributeSet?);
+    ctor public SwitchCompat(android.content.Context, android.util.AttributeSet?, int);
+    method public boolean getShowText();
+    method public boolean getSplitTrack();
+    method public int getSwitchMinWidth();
+    method public int getSwitchPadding();
+    method public CharSequence! getTextOff();
+    method public CharSequence! getTextOn();
+    method public android.graphics.drawable.Drawable! getThumbDrawable();
+    method public int getThumbTextPadding();
+    method public android.content.res.ColorStateList? getThumbTintList();
+    method public android.graphics.PorterDuff.Mode? getThumbTintMode();
+    method public android.graphics.drawable.Drawable! getTrackDrawable();
+    method public android.content.res.ColorStateList? getTrackTintList();
+    method public android.graphics.PorterDuff.Mode? getTrackTintMode();
+    method public void onMeasure(int, int);
+    method public void setShowText(boolean);
+    method public void setSplitTrack(boolean);
+    method public void setSwitchMinWidth(int);
+    method public void setSwitchPadding(int);
+    method public void setSwitchTextAppearance(android.content.Context!, int);
+    method public void setSwitchTypeface(android.graphics.Typeface!, int);
+    method public void setSwitchTypeface(android.graphics.Typeface!);
+    method public void setTextOff(CharSequence!);
+    method public void setTextOn(CharSequence!);
+    method public void setThumbDrawable(android.graphics.drawable.Drawable!);
+    method public void setThumbResource(int);
+    method public void setThumbTextPadding(int);
+    method public void setThumbTintList(android.content.res.ColorStateList?);
+    method public void setThumbTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTrackDrawable(android.graphics.drawable.Drawable!);
+    method public void setTrackResource(int);
+    method public void setTrackTintList(android.content.res.ColorStateList?);
+    method public void setTrackTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public interface ThemedSpinnerAdapter extends android.widget.SpinnerAdapter {
+    method public android.content.res.Resources.Theme? getDropDownViewTheme();
+    method public void setDropDownViewTheme(android.content.res.Resources.Theme?);
+  }
+
+  public static final class ThemedSpinnerAdapter.Helper {
+    ctor public ThemedSpinnerAdapter.Helper(android.content.Context);
+    method public android.view.LayoutInflater getDropDownViewInflater();
+    method public android.content.res.Resources.Theme? getDropDownViewTheme();
+    method public void setDropDownViewTheme(android.content.res.Resources.Theme?);
+  }
+
+  public class Toolbar extends android.view.ViewGroup {
+    ctor public Toolbar(android.content.Context);
+    ctor public Toolbar(android.content.Context, android.util.AttributeSet?);
+    ctor public Toolbar(android.content.Context, android.util.AttributeSet?, int);
+    method public void collapseActionView();
+    method public void dismissPopupMenus();
+    method protected androidx.appcompat.widget.Toolbar.LayoutParams! generateDefaultLayoutParams();
+    method public androidx.appcompat.widget.Toolbar.LayoutParams! generateLayoutParams(android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.Toolbar.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+    method public CharSequence? getCollapseContentDescription();
+    method public android.graphics.drawable.Drawable? getCollapseIcon();
+    method public int getContentInsetEnd();
+    method public int getContentInsetEndWithActions();
+    method public int getContentInsetLeft();
+    method public int getContentInsetRight();
+    method public int getContentInsetStart();
+    method public int getContentInsetStartWithNavigation();
+    method public int getCurrentContentInsetEnd();
+    method public int getCurrentContentInsetLeft();
+    method public int getCurrentContentInsetRight();
+    method public int getCurrentContentInsetStart();
+    method public android.graphics.drawable.Drawable! getLogo();
+    method public CharSequence! getLogoDescription();
+    method public android.view.Menu! getMenu();
+    method public CharSequence? getNavigationContentDescription();
+    method public android.graphics.drawable.Drawable? getNavigationIcon();
+    method public android.graphics.drawable.Drawable? getOverflowIcon();
+    method public int getPopupTheme();
+    method public CharSequence! getSubtitle();
+    method public CharSequence! getTitle();
+    method public int getTitleMarginBottom();
+    method public int getTitleMarginEnd();
+    method public int getTitleMarginStart();
+    method public int getTitleMarginTop();
+    method public boolean hasExpandedActionView();
+    method public boolean hideOverflowMenu();
+    method public void inflateMenu(@MenuRes int);
+    method public boolean isOverflowMenuShowing();
+    method public void setCollapseContentDescription(@StringRes int);
+    method public void setCollapseContentDescription(CharSequence?);
+    method public void setCollapseIcon(@DrawableRes int);
+    method public void setCollapseIcon(android.graphics.drawable.Drawable?);
+    method public void setContentInsetEndWithActions(int);
+    method public void setContentInsetStartWithNavigation(int);
+    method public void setContentInsetsAbsolute(int, int);
+    method public void setContentInsetsRelative(int, int);
+    method public void setLogo(@DrawableRes int);
+    method public void setLogo(android.graphics.drawable.Drawable!);
+    method public void setLogoDescription(@StringRes int);
+    method public void setLogoDescription(CharSequence!);
+    method public void setNavigationContentDescription(@StringRes int);
+    method public void setNavigationContentDescription(CharSequence?);
+    method public void setNavigationIcon(@DrawableRes int);
+    method public void setNavigationIcon(android.graphics.drawable.Drawable?);
+    method public void setNavigationOnClickListener(android.view.View.OnClickListener!);
+    method public void setOnMenuItemClickListener(androidx.appcompat.widget.Toolbar.OnMenuItemClickListener!);
+    method public void setOverflowIcon(android.graphics.drawable.Drawable?);
+    method public void setPopupTheme(@StyleRes int);
+    method public void setSubtitle(@StringRes int);
+    method public void setSubtitle(CharSequence!);
+    method public void setSubtitleTextAppearance(android.content.Context!, @StyleRes int);
+    method public void setSubtitleTextColor(@ColorInt int);
+    method public void setSubtitleTextColor(android.content.res.ColorStateList);
+    method public void setTitle(@StringRes int);
+    method public void setTitle(CharSequence!);
+    method public void setTitleMargin(int, int, int, int);
+    method public void setTitleMarginBottom(int);
+    method public void setTitleMarginEnd(int);
+    method public void setTitleMarginStart(int);
+    method public void setTitleMarginTop(int);
+    method public void setTitleTextAppearance(android.content.Context!, @StyleRes int);
+    method public void setTitleTextColor(@ColorInt int);
+    method public void setTitleTextColor(android.content.res.ColorStateList);
+    method public boolean showOverflowMenu();
+  }
+
+  public static class Toolbar.LayoutParams extends androidx.appcompat.app.ActionBar.LayoutParams {
+    ctor public Toolbar.LayoutParams(android.content.Context, android.util.AttributeSet!);
+    ctor public Toolbar.LayoutParams(int, int);
+    ctor public Toolbar.LayoutParams(int, int, int);
+    ctor public Toolbar.LayoutParams(int);
+    ctor public Toolbar.LayoutParams(androidx.appcompat.widget.Toolbar.LayoutParams!);
+    ctor public Toolbar.LayoutParams(androidx.appcompat.app.ActionBar.LayoutParams!);
+    ctor public Toolbar.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public Toolbar.LayoutParams(android.view.ViewGroup.LayoutParams!);
+  }
+
+  public static interface Toolbar.OnMenuItemClickListener {
+    method public boolean onMenuItemClick(android.view.MenuItem!);
+  }
+
+  public static class Toolbar.SavedState extends androidx.customview.view.AbsSavedState {
+    ctor public Toolbar.SavedState(android.os.Parcel!);
+    ctor public Toolbar.SavedState(android.os.Parcel!, ClassLoader!);
+    ctor public Toolbar.SavedState(android.os.Parcelable!);
+    field public static final android.os.Parcelable.Creator<androidx.appcompat.widget.Toolbar.SavedState!>! CREATOR;
+  }
+
+  public class TooltipCompat {
+    method public static void setTooltipText(android.view.View, CharSequence?);
+  }
+
+}
+
diff --git a/appcompat/appcompat/api/res-1.3.0-beta02.txt b/appcompat/appcompat/api/res-1.3.0-beta02.txt
new file mode 100644
index 0000000..78975ff
--- /dev/null
+++ b/appcompat/appcompat/api/res-1.3.0-beta02.txt
@@ -0,0 +1,368 @@
+attr actionBarDivider
+attr actionBarItemBackground
+attr actionBarPopupTheme
+attr actionBarSize
+attr actionBarSplitStyle
+attr actionBarStyle
+attr actionBarTabBarStyle
+attr actionBarTabStyle
+attr actionBarTabTextStyle
+attr actionBarTheme
+attr actionBarWidgetTheme
+attr actionButtonStyle
+attr actionDropDownStyle
+attr actionLayout
+attr actionMenuTextAppearance
+attr actionMenuTextColor
+attr actionModeBackground
+attr actionModeCloseButtonStyle
+attr actionModeCloseContentDescription
+attr actionModeCloseDrawable
+attr actionModeCopyDrawable
+attr actionModeCutDrawable
+attr actionModeFindDrawable
+attr actionModePasteDrawable
+attr actionModeSelectAllDrawable
+attr actionModeShareDrawable
+attr actionModeSplitBackground
+attr actionModeStyle
+attr actionModeTheme
+attr actionModeWebSearchDrawable
+attr actionOverflowButtonStyle
+attr actionOverflowMenuStyle
+attr actionProviderClass
+attr actionViewClass
+attr alertDialogStyle
+attr alertDialogTheme
+attr arrowHeadLength
+attr arrowShaftLength
+attr autoCompleteTextViewStyle
+attr autoSizeMaxTextSize
+attr autoSizeMinTextSize
+attr autoSizePresetSizes
+attr autoSizeStepGranularity
+attr autoSizeTextType
+attr background
+attr backgroundSplit
+attr backgroundStacked
+attr backgroundTint
+attr backgroundTintMode
+attr barLength
+attr borderlessButtonStyle
+attr buttonBarButtonStyle
+attr buttonBarNegativeButtonStyle
+attr buttonBarNeutralButtonStyle
+attr buttonBarPositiveButtonStyle
+attr buttonBarStyle
+attr buttonGravity
+attr buttonStyle
+attr buttonStyleSmall
+attr buttonTint
+attr buttonTintMode
+attr checkboxStyle
+attr checkedTextViewStyle
+attr closeIcon
+attr closeItemLayout
+attr collapseContentDescription
+attr collapseIcon
+attr color
+attr colorAccent
+attr colorBackgroundFloating
+attr colorButtonNormal
+attr colorControlActivated
+attr colorControlHighlight
+attr colorControlNormal
+attr colorError
+attr colorPrimary
+attr colorPrimaryDark
+attr commitIcon
+attr contentInsetEnd
+attr contentInsetEndWithActions
+attr contentInsetLeft
+attr contentInsetRight
+attr contentInsetStart
+attr contentInsetStartWithNavigation
+attr customNavigationLayout
+attr dialogCornerRadius
+attr dialogPreferredPadding
+attr dialogTheme
+attr displayOptions
+attr divider
+attr dividerHorizontal
+attr dividerPadding
+attr dividerVertical
+attr drawableSize
+attr drawerArrowStyle
+attr dropDownListViewStyle
+attr editTextBackground
+attr editTextColor
+attr editTextStyle
+attr elevation
+attr firstBaselineToTopHeight
+attr fontFamily
+attr fontVariationSettings
+attr gapBetweenBars
+attr goIcon
+attr height
+attr hideOnContentScroll
+attr homeAsUpIndicator
+attr homeLayout
+attr icon
+attr iconTint
+attr iconTintMode
+attr iconifiedByDefault
+attr imageButtonStyle
+attr indeterminateProgressStyle
+attr isLightTheme
+attr itemPadding
+attr lastBaselineToBottomHeight
+attr layout
+attr lineHeight
+attr listChoiceBackgroundIndicator
+attr listChoiceIndicatorMultipleAnimated
+attr listChoiceIndicatorSingleAnimated
+attr listDividerAlertDialog
+attr listPopupWindowStyle
+attr listPreferredItemHeight
+attr listPreferredItemHeightLarge
+attr listPreferredItemHeightSmall
+attr listPreferredItemPaddingEnd
+attr listPreferredItemPaddingLeft
+attr listPreferredItemPaddingRight
+attr listPreferredItemPaddingStart
+attr logo
+attr logoDescription
+attr maxButtonHeight
+attr measureWithLargestChild
+attr navigationContentDescription
+attr navigationIcon
+attr navigationMode
+attr overlapAnchor
+attr paddingEnd
+attr paddingStart
+attr panelBackground
+attr popupMenuStyle
+attr popupTheme
+attr popupWindowStyle
+attr preserveIconSpacing
+attr progressBarPadding
+attr progressBarStyle
+attr queryBackground
+attr queryHint
+attr radioButtonStyle
+attr ratingBarStyle
+attr ratingBarStyleIndicator
+attr ratingBarStyleSmall
+attr searchHintIcon
+attr searchIcon
+attr searchViewStyle
+attr seekBarStyle
+attr selectableItemBackground
+attr selectableItemBackgroundBorderless
+attr showAsAction
+attr showDividers
+attr showText
+attr spinBars
+attr spinnerDropDownItemStyle
+attr spinnerStyle
+attr splitTrack
+attr srcCompat
+attr state_above_anchor
+attr submitBackground
+attr subtitle
+attr subtitleTextAppearance
+attr subtitleTextColor
+attr subtitleTextStyle
+attr suggestionRowLayout
+attr switchMinWidth
+attr switchPadding
+attr switchStyle
+attr switchTextAppearance
+attr textAllCaps
+attr textAppearanceLargePopupMenu
+attr textAppearanceListItem
+attr textAppearanceListItemSecondary
+attr textAppearanceListItemSmall
+attr textAppearancePopupMenuHeader
+attr textAppearanceSearchResultSubtitle
+attr textAppearanceSearchResultTitle
+attr textAppearanceSmallPopupMenu
+attr textColorAlertDialogListItem
+attr textLocale
+attr theme
+attr thickness
+attr thumbTextPadding
+attr thumbTint
+attr thumbTintMode
+attr tickMark
+attr tickMarkTint
+attr tickMarkTintMode
+attr tint
+attr tintMode
+attr title
+attr titleMargin
+attr titleMarginBottom
+attr titleMarginEnd
+attr titleMarginStart
+attr titleMarginTop
+attr titleMargins
+attr titleTextAppearance
+attr titleTextColor
+attr titleTextStyle
+attr toolbarNavigationButtonStyle
+attr toolbarStyle
+attr track
+attr trackTint
+attr trackTintMode
+attr voiceIcon
+attr windowActionBar
+attr windowActionBarOverlay
+attr windowActionModeOverlay
+attr windowNoTitle
+layout support_simple_spinner_dropdown_item
+style TextAppearance_AppCompat
+style TextAppearance_AppCompat_Body1
+style TextAppearance_AppCompat_Body2
+style TextAppearance_AppCompat_Button
+style TextAppearance_AppCompat_Caption
+style TextAppearance_AppCompat_Display1
+style TextAppearance_AppCompat_Display2
+style TextAppearance_AppCompat_Display3
+style TextAppearance_AppCompat_Display4
+style TextAppearance_AppCompat_Headline
+style TextAppearance_AppCompat_Inverse
+style TextAppearance_AppCompat_Large
+style TextAppearance_AppCompat_Large_Inverse
+style TextAppearance_AppCompat_Light_SearchResult_Subtitle
+style TextAppearance_AppCompat_Light_SearchResult_Title
+style TextAppearance_AppCompat_Light_Widget_PopupMenu_Large
+style TextAppearance_AppCompat_Light_Widget_PopupMenu_Small
+style TextAppearance_AppCompat_Medium
+style TextAppearance_AppCompat_Medium_Inverse
+style TextAppearance_AppCompat_Menu
+style TextAppearance_AppCompat_SearchResult_Subtitle
+style TextAppearance_AppCompat_SearchResult_Title
+style TextAppearance_AppCompat_Small
+style TextAppearance_AppCompat_Small_Inverse
+style TextAppearance_AppCompat_Subhead
+style TextAppearance_AppCompat_Subhead_Inverse
+style TextAppearance_AppCompat_Title
+style TextAppearance_AppCompat_Title_Inverse
+style TextAppearance_AppCompat_Widget_ActionBar_Menu
+style TextAppearance_AppCompat_Widget_ActionBar_Subtitle
+style TextAppearance_AppCompat_Widget_ActionBar_Subtitle_Inverse
+style TextAppearance_AppCompat_Widget_ActionBar_Title
+style TextAppearance_AppCompat_Widget_ActionBar_Title_Inverse
+style TextAppearance_AppCompat_Widget_ActionMode_Subtitle
+style TextAppearance_AppCompat_Widget_ActionMode_Subtitle_Inverse
+style TextAppearance_AppCompat_Widget_ActionMode_Title
+style TextAppearance_AppCompat_Widget_ActionMode_Title_Inverse
+style TextAppearance_AppCompat_Widget_Button
+style TextAppearance_AppCompat_Widget_Button_Borderless_Colored
+style TextAppearance_AppCompat_Widget_Button_Colored
+style TextAppearance_AppCompat_Widget_Button_Inverse
+style TextAppearance_AppCompat_Widget_DropDownItem
+style TextAppearance_AppCompat_Widget_PopupMenu_Header
+style TextAppearance_AppCompat_Widget_PopupMenu_Large
+style TextAppearance_AppCompat_Widget_PopupMenu_Small
+style TextAppearance_AppCompat_Widget_Switch
+style TextAppearance_AppCompat_Widget_TextView_SpinnerItem
+style ThemeOverlay_AppCompat
+style ThemeOverlay_AppCompat_ActionBar
+style ThemeOverlay_AppCompat_Dark
+style ThemeOverlay_AppCompat_Dark_ActionBar
+style ThemeOverlay_AppCompat_DayNight
+style ThemeOverlay_AppCompat_DayNight_ActionBar
+style ThemeOverlay_AppCompat_Dialog
+style ThemeOverlay_AppCompat_Dialog_Alert
+style ThemeOverlay_AppCompat_Light
+style Theme_AppCompat
+style Theme_AppCompat_DayNight
+style Theme_AppCompat_DayNight_DarkActionBar
+style Theme_AppCompat_DayNight_Dialog
+style Theme_AppCompat_DayNight_DialogWhenLarge
+style Theme_AppCompat_DayNight_Dialog_Alert
+style Theme_AppCompat_DayNight_Dialog_MinWidth
+style Theme_AppCompat_DayNight_NoActionBar
+style Theme_AppCompat_Dialog
+style Theme_AppCompat_DialogWhenLarge
+style Theme_AppCompat_Dialog_Alert
+style Theme_AppCompat_Dialog_MinWidth
+style Theme_AppCompat_Light
+style Theme_AppCompat_Light_DarkActionBar
+style Theme_AppCompat_Light_Dialog
+style Theme_AppCompat_Light_DialogWhenLarge
+style Theme_AppCompat_Light_Dialog_Alert
+style Theme_AppCompat_Light_Dialog_MinWidth
+style Theme_AppCompat_Light_NoActionBar
+style Theme_AppCompat_NoActionBar
+style Widget_AppCompat_ActionBar
+style Widget_AppCompat_ActionBar_Solid
+style Widget_AppCompat_ActionBar_TabBar
+style Widget_AppCompat_ActionBar_TabText
+style Widget_AppCompat_ActionBar_TabView
+style Widget_AppCompat_ActionButton
+style Widget_AppCompat_ActionButton_CloseMode
+style Widget_AppCompat_ActionButton_Overflow
+style Widget_AppCompat_ActionMode
+style Widget_AppCompat_AutoCompleteTextView
+style Widget_AppCompat_Button
+style Widget_AppCompat_ButtonBar
+style Widget_AppCompat_ButtonBar_AlertDialog
+style Widget_AppCompat_Button_Borderless
+style Widget_AppCompat_Button_Borderless_Colored
+style Widget_AppCompat_Button_ButtonBar_AlertDialog
+style Widget_AppCompat_Button_Colored
+style Widget_AppCompat_Button_Small
+style Widget_AppCompat_CompoundButton_CheckBox
+style Widget_AppCompat_CompoundButton_RadioButton
+style Widget_AppCompat_CompoundButton_Switch
+style Widget_AppCompat_DrawerArrowToggle
+style Widget_AppCompat_DropDownItem_Spinner
+style Widget_AppCompat_EditText
+style Widget_AppCompat_ImageButton
+style Widget_AppCompat_Light_ActionBar
+style Widget_AppCompat_Light_ActionBar_Solid
+style Widget_AppCompat_Light_ActionBar_Solid_Inverse
+style Widget_AppCompat_Light_ActionBar_TabBar
+style Widget_AppCompat_Light_ActionBar_TabBar_Inverse
+style Widget_AppCompat_Light_ActionBar_TabText
+style Widget_AppCompat_Light_ActionBar_TabText_Inverse
+style Widget_AppCompat_Light_ActionBar_TabView
+style Widget_AppCompat_Light_ActionBar_TabView_Inverse
+style Widget_AppCompat_Light_ActionButton
+style Widget_AppCompat_Light_ActionButton_CloseMode
+style Widget_AppCompat_Light_ActionButton_Overflow
+style Widget_AppCompat_Light_ActionMode_Inverse
+style Widget_AppCompat_Light_AutoCompleteTextView
+style Widget_AppCompat_Light_DropDownItem_Spinner
+style Widget_AppCompat_Light_ListPopupWindow
+style Widget_AppCompat_Light_ListView_DropDown
+style Widget_AppCompat_Light_PopupMenu
+style Widget_AppCompat_Light_PopupMenu_Overflow
+style Widget_AppCompat_Light_SearchView
+style Widget_AppCompat_Light_Spinner_DropDown_ActionBar
+style Widget_AppCompat_ListPopupWindow
+style Widget_AppCompat_ListView
+style Widget_AppCompat_ListView_DropDown
+style Widget_AppCompat_ListView_Menu
+style Widget_AppCompat_PopupMenu
+style Widget_AppCompat_PopupMenu_Overflow
+style Widget_AppCompat_PopupWindow
+style Widget_AppCompat_ProgressBar
+style Widget_AppCompat_ProgressBar_Horizontal
+style Widget_AppCompat_RatingBar
+style Widget_AppCompat_RatingBar_Indicator
+style Widget_AppCompat_RatingBar_Small
+style Widget_AppCompat_SearchView
+style Widget_AppCompat_SearchView_ActionBar
+style Widget_AppCompat_SeekBar
+style Widget_AppCompat_SeekBar_Discrete
+style Widget_AppCompat_Spinner
+style Widget_AppCompat_Spinner_DropDown
+style Widget_AppCompat_Spinner_DropDown_ActionBar
+style Widget_AppCompat_Spinner_Underlined
+style Widget_AppCompat_TextView
+style Widget_AppCompat_TextView_SpinnerItem
+style Widget_AppCompat_Toolbar
+style Widget_AppCompat_Toolbar_Button_Navigation
diff --git a/appcompat/appcompat/api/restricted_1.3.0-beta02.txt b/appcompat/appcompat/api/restricted_1.3.0-beta02.txt
new file mode 100644
index 0000000..d86ea87
--- /dev/null
+++ b/appcompat/appcompat/api/restricted_1.3.0-beta02.txt
@@ -0,0 +1,2201 @@
+// Signature format: 4.0
+package androidx.appcompat.app {
+
+  public abstract class ActionBar {
+    ctor public ActionBar();
+    method public abstract void addOnMenuVisibilityListener(androidx.appcompat.app.ActionBar.OnMenuVisibilityListener!);
+    method @Deprecated public abstract void addTab(androidx.appcompat.app.ActionBar.Tab!);
+    method @Deprecated public abstract void addTab(androidx.appcompat.app.ActionBar.Tab!, boolean);
+    method @Deprecated public abstract void addTab(androidx.appcompat.app.ActionBar.Tab!, int);
+    method @Deprecated public abstract void addTab(androidx.appcompat.app.ActionBar.Tab!, int, boolean);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean closeOptionsMenu();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean collapseActionView();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void dispatchMenuVisibilityChanged(boolean);
+    method public abstract android.view.View! getCustomView();
+    method @androidx.appcompat.app.ActionBar.DisplayOptions public abstract int getDisplayOptions();
+    method public float getElevation();
+    method public abstract int getHeight();
+    method public int getHideOffset();
+    method @Deprecated public abstract int getNavigationItemCount();
+    method @Deprecated @androidx.appcompat.app.ActionBar.NavigationMode public abstract int getNavigationMode();
+    method @Deprecated public abstract int getSelectedNavigationIndex();
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab? getSelectedTab();
+    method public abstract CharSequence? getSubtitle();
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! getTabAt(int);
+    method @Deprecated public abstract int getTabCount();
+    method public android.content.Context! getThemedContext();
+    method public abstract CharSequence? getTitle();
+    method public abstract void hide();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean invalidateOptionsMenu();
+    method public boolean isHideOnContentScrollEnabled();
+    method public abstract boolean isShowing();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean isTitleTruncated();
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! newTab();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void onConfigurationChanged(android.content.res.Configuration!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean onKeyShortcut(int, android.view.KeyEvent!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean onMenuKeyEvent(android.view.KeyEvent!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean openOptionsMenu();
+    method @Deprecated public abstract void removeAllTabs();
+    method public abstract void removeOnMenuVisibilityListener(androidx.appcompat.app.ActionBar.OnMenuVisibilityListener!);
+    method @Deprecated public abstract void removeTab(androidx.appcompat.app.ActionBar.Tab!);
+    method @Deprecated public abstract void removeTabAt(int);
+    method @Deprecated public abstract void selectTab(androidx.appcompat.app.ActionBar.Tab!);
+    method public abstract void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method public abstract void setCustomView(android.view.View!);
+    method public abstract void setCustomView(android.view.View!, androidx.appcompat.app.ActionBar.LayoutParams!);
+    method public abstract void setCustomView(int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setDefaultDisplayHomeAsUpEnabled(boolean);
+    method public abstract void setDisplayHomeAsUpEnabled(boolean);
+    method public abstract void setDisplayOptions(@androidx.appcompat.app.ActionBar.DisplayOptions int);
+    method public abstract void setDisplayOptions(@androidx.appcompat.app.ActionBar.DisplayOptions int, @androidx.appcompat.app.ActionBar.DisplayOptions int);
+    method public abstract void setDisplayShowCustomEnabled(boolean);
+    method public abstract void setDisplayShowHomeEnabled(boolean);
+    method public abstract void setDisplayShowTitleEnabled(boolean);
+    method public abstract void setDisplayUseLogoEnabled(boolean);
+    method public void setElevation(float);
+    method public void setHideOffset(int);
+    method public void setHideOnContentScrollEnabled(boolean);
+    method public void setHomeActionContentDescription(CharSequence?);
+    method public void setHomeActionContentDescription(@StringRes int);
+    method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable?);
+    method public void setHomeAsUpIndicator(@DrawableRes int);
+    method public void setHomeButtonEnabled(boolean);
+    method public abstract void setIcon(@DrawableRes int);
+    method public abstract void setIcon(android.graphics.drawable.Drawable!);
+    method @Deprecated public abstract void setListNavigationCallbacks(android.widget.SpinnerAdapter!, androidx.appcompat.app.ActionBar.OnNavigationListener!);
+    method public abstract void setLogo(@DrawableRes int);
+    method public abstract void setLogo(android.graphics.drawable.Drawable!);
+    method @Deprecated public abstract void setNavigationMode(@androidx.appcompat.app.ActionBar.NavigationMode int);
+    method @Deprecated public abstract void setSelectedNavigationItem(int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setShowHideAnimationEnabled(boolean);
+    method public void setSplitBackgroundDrawable(android.graphics.drawable.Drawable!);
+    method public void setStackedBackgroundDrawable(android.graphics.drawable.Drawable!);
+    method public abstract void setSubtitle(CharSequence!);
+    method public abstract void setSubtitle(int);
+    method public abstract void setTitle(CharSequence!);
+    method public abstract void setTitle(@StringRes int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setWindowTitle(CharSequence!);
+    method public abstract void show();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.appcompat.view.ActionMode! startActionMode(androidx.appcompat.view.ActionMode.Callback!);
+    field public static final int DISPLAY_HOME_AS_UP = 4; // 0x4
+    field public static final int DISPLAY_SHOW_CUSTOM = 16; // 0x10
+    field public static final int DISPLAY_SHOW_HOME = 2; // 0x2
+    field public static final int DISPLAY_SHOW_TITLE = 8; // 0x8
+    field public static final int DISPLAY_USE_LOGO = 1; // 0x1
+    field @Deprecated public static final int NAVIGATION_MODE_LIST = 1; // 0x1
+    field @Deprecated public static final int NAVIGATION_MODE_STANDARD = 0; // 0x0
+    field @Deprecated public static final int NAVIGATION_MODE_TABS = 2; // 0x2
+  }
+
+  @IntDef(flag=true, value={androidx.appcompat.app.ActionBar.DISPLAY_USE_LOGO, androidx.appcompat.app.ActionBar.DISPLAY_SHOW_HOME, androidx.appcompat.app.ActionBar.DISPLAY_HOME_AS_UP, androidx.appcompat.app.ActionBar.DISPLAY_SHOW_TITLE, androidx.appcompat.app.ActionBar.DISPLAY_SHOW_CUSTOM}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ActionBar.DisplayOptions {
+  }
+
+  public static class ActionBar.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+    ctor public ActionBar.LayoutParams(android.content.Context, android.util.AttributeSet!);
+    ctor public ActionBar.LayoutParams(int, int);
+    ctor public ActionBar.LayoutParams(int, int, int);
+    ctor public ActionBar.LayoutParams(int);
+    ctor public ActionBar.LayoutParams(androidx.appcompat.app.ActionBar.LayoutParams!);
+    ctor public ActionBar.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    field public int gravity;
+  }
+
+  @IntDef({androidx.appcompat.app.ActionBar.NAVIGATION_MODE_STANDARD, androidx.appcompat.app.ActionBar.NAVIGATION_MODE_LIST, androidx.appcompat.app.ActionBar.NAVIGATION_MODE_TABS}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ActionBar.NavigationMode {
+  }
+
+  public static interface ActionBar.OnMenuVisibilityListener {
+    method public void onMenuVisibilityChanged(boolean);
+  }
+
+  @Deprecated public static interface ActionBar.OnNavigationListener {
+    method @Deprecated public boolean onNavigationItemSelected(int, long);
+  }
+
+  @Deprecated public abstract static class ActionBar.Tab {
+    ctor @Deprecated public ActionBar.Tab();
+    method @Deprecated public abstract CharSequence! getContentDescription();
+    method @Deprecated public abstract android.view.View! getCustomView();
+    method @Deprecated public abstract android.graphics.drawable.Drawable! getIcon();
+    method @Deprecated public abstract int getPosition();
+    method @Deprecated public abstract Object! getTag();
+    method @Deprecated public abstract CharSequence! getText();
+    method @Deprecated public abstract void select();
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setContentDescription(@StringRes int);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setContentDescription(CharSequence!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setCustomView(android.view.View!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setCustomView(int);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setIcon(android.graphics.drawable.Drawable!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setIcon(@DrawableRes int);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setTabListener(androidx.appcompat.app.ActionBar.TabListener!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setTag(Object!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setText(CharSequence!);
+    method @Deprecated public abstract androidx.appcompat.app.ActionBar.Tab! setText(int);
+    field @Deprecated public static final int INVALID_POSITION = -1; // 0xffffffff
+  }
+
+  @Deprecated public static interface ActionBar.TabListener {
+    method @Deprecated public void onTabReselected(androidx.appcompat.app.ActionBar.Tab!, androidx.fragment.app.FragmentTransaction!);
+    method @Deprecated public void onTabSelected(androidx.appcompat.app.ActionBar.Tab!, androidx.fragment.app.FragmentTransaction!);
+    method @Deprecated public void onTabUnselected(androidx.appcompat.app.ActionBar.Tab!, androidx.fragment.app.FragmentTransaction!);
+  }
+
+  public class ActionBarDrawerToggle implements androidx.drawerlayout.widget.DrawerLayout.DrawerListener {
+    ctor public ActionBarDrawerToggle(android.app.Activity!, androidx.drawerlayout.widget.DrawerLayout!, @StringRes int, @StringRes int);
+    ctor public ActionBarDrawerToggle(android.app.Activity!, androidx.drawerlayout.widget.DrawerLayout!, androidx.appcompat.widget.Toolbar!, @StringRes int, @StringRes int);
+    method public androidx.appcompat.graphics.drawable.DrawerArrowDrawable getDrawerArrowDrawable();
+    method public android.view.View.OnClickListener! getToolbarNavigationClickListener();
+    method public boolean isDrawerIndicatorEnabled();
+    method public boolean isDrawerSlideAnimationEnabled();
+    method public void onConfigurationChanged(android.content.res.Configuration!);
+    method public void onDrawerClosed(android.view.View!);
+    method public void onDrawerOpened(android.view.View!);
+    method public void onDrawerSlide(android.view.View!, float);
+    method public void onDrawerStateChanged(int);
+    method public boolean onOptionsItemSelected(android.view.MenuItem!);
+    method public void setDrawerArrowDrawable(androidx.appcompat.graphics.drawable.DrawerArrowDrawable);
+    method public void setDrawerIndicatorEnabled(boolean);
+    method public void setDrawerSlideAnimationEnabled(boolean);
+    method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable!);
+    method public void setHomeAsUpIndicator(int);
+    method public void setToolbarNavigationClickListener(android.view.View.OnClickListener!);
+    method public void syncState();
+  }
+
+  public static interface ActionBarDrawerToggle.Delegate {
+    method public android.content.Context! getActionBarThemedContext();
+    method public android.graphics.drawable.Drawable! getThemeUpIndicator();
+    method public boolean isNavigationVisible();
+    method public void setActionBarDescription(@StringRes int);
+    method public void setActionBarUpIndicator(android.graphics.drawable.Drawable!, @StringRes int);
+  }
+
+  public static interface ActionBarDrawerToggle.DelegateProvider {
+    method public androidx.appcompat.app.ActionBarDrawerToggle.Delegate? getDrawerToggleDelegate();
+  }
+
+  public class AlertDialog extends androidx.appcompat.app.AppCompatDialog implements android.content.DialogInterface {
+    ctor protected AlertDialog(android.content.Context);
+    ctor protected AlertDialog(android.content.Context, @StyleRes int);
+    ctor protected AlertDialog(android.content.Context, boolean, android.content.DialogInterface.OnCancelListener?);
+    method public android.widget.Button! getButton(int);
+    method public android.widget.ListView! getListView();
+    method public void setButton(int, CharSequence!, android.os.Message!);
+    method public void setButton(int, CharSequence!, android.content.DialogInterface.OnClickListener!);
+    method public void setButton(int, CharSequence!, android.graphics.drawable.Drawable!, android.content.DialogInterface.OnClickListener!);
+    method public void setCustomTitle(android.view.View!);
+    method public void setIcon(int);
+    method public void setIcon(android.graphics.drawable.Drawable!);
+    method public void setIconAttribute(int);
+    method public void setMessage(CharSequence!);
+    method public void setView(android.view.View!);
+    method public void setView(android.view.View!, int, int, int, int);
+  }
+
+  public static class AlertDialog.Builder {
+    ctor public AlertDialog.Builder(android.content.Context);
+    ctor public AlertDialog.Builder(android.content.Context, @StyleRes int);
+    method public androidx.appcompat.app.AlertDialog create();
+    method public android.content.Context getContext();
+    method public androidx.appcompat.app.AlertDialog.Builder! setAdapter(android.widget.ListAdapter!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setCancelable(boolean);
+    method public androidx.appcompat.app.AlertDialog.Builder! setCursor(android.database.Cursor!, android.content.DialogInterface.OnClickListener!, String!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setCustomTitle(android.view.View?);
+    method public androidx.appcompat.app.AlertDialog.Builder! setIcon(@DrawableRes int);
+    method public androidx.appcompat.app.AlertDialog.Builder! setIcon(android.graphics.drawable.Drawable?);
+    method public androidx.appcompat.app.AlertDialog.Builder! setIconAttribute(@AttrRes int);
+    method @Deprecated public androidx.appcompat.app.AlertDialog.Builder! setInverseBackgroundForced(boolean);
+    method public androidx.appcompat.app.AlertDialog.Builder! setItems(@ArrayRes int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setItems(CharSequence![]!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setMessage(@StringRes int);
+    method public androidx.appcompat.app.AlertDialog.Builder! setMessage(CharSequence?);
+    method public androidx.appcompat.app.AlertDialog.Builder! setMultiChoiceItems(@ArrayRes int, boolean[]!, android.content.DialogInterface.OnMultiChoiceClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setMultiChoiceItems(CharSequence![]!, boolean[]!, android.content.DialogInterface.OnMultiChoiceClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setMultiChoiceItems(android.database.Cursor!, String!, String!, android.content.DialogInterface.OnMultiChoiceClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNegativeButton(@StringRes int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNegativeButton(CharSequence!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNegativeButtonIcon(android.graphics.drawable.Drawable!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNeutralButton(@StringRes int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNeutralButton(CharSequence!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setNeutralButtonIcon(android.graphics.drawable.Drawable!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setOnCancelListener(android.content.DialogInterface.OnCancelListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setOnDismissListener(android.content.DialogInterface.OnDismissListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setOnKeyListener(android.content.DialogInterface.OnKeyListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setPositiveButton(@StringRes int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setPositiveButton(CharSequence!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setPositiveButtonIcon(android.graphics.drawable.Drawable!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.appcompat.app.AlertDialog.Builder! setRecycleOnMeasureEnabled(boolean);
+    method public androidx.appcompat.app.AlertDialog.Builder! setSingleChoiceItems(@ArrayRes int, int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setSingleChoiceItems(android.database.Cursor!, int, String!, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setSingleChoiceItems(CharSequence![]!, int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setSingleChoiceItems(android.widget.ListAdapter!, int, android.content.DialogInterface.OnClickListener!);
+    method public androidx.appcompat.app.AlertDialog.Builder! setTitle(@StringRes int);
+    method public androidx.appcompat.app.AlertDialog.Builder! setTitle(CharSequence?);
+    method public androidx.appcompat.app.AlertDialog.Builder! setView(int);
+    method public androidx.appcompat.app.AlertDialog.Builder! setView(android.view.View!);
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.appcompat.app.AlertDialog.Builder! setView(android.view.View!, int, int, int, int);
+    method public androidx.appcompat.app.AlertDialog! show();
+  }
+
+  public class AppCompatActivity extends androidx.fragment.app.FragmentActivity implements androidx.appcompat.app.ActionBarDrawerToggle.DelegateProvider androidx.appcompat.app.AppCompatCallback androidx.core.app.TaskStackBuilder.SupportParentable {
+    ctor public AppCompatActivity();
+    ctor @ContentView public AppCompatActivity(@LayoutRes int);
+    method public androidx.appcompat.app.AppCompatDelegate getDelegate();
+    method public androidx.appcompat.app.ActionBarDrawerToggle.Delegate? getDrawerToggleDelegate();
+    method public androidx.appcompat.app.ActionBar? getSupportActionBar();
+    method public android.content.Intent? getSupportParentActivityIntent();
+    method public void onCreateSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder);
+    method public final boolean onMenuItemSelected(int, android.view.MenuItem);
+    method protected void onNightModeChanged(@androidx.appcompat.app.AppCompatDelegate.NightMode int);
+    method public void onPrepareSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder);
+    method @CallSuper public void onSupportActionModeFinished(androidx.appcompat.view.ActionMode);
+    method @CallSuper public void onSupportActionModeStarted(androidx.appcompat.view.ActionMode);
+    method @Deprecated public void onSupportContentChanged();
+    method public boolean onSupportNavigateUp();
+    method public androidx.appcompat.view.ActionMode? onWindowStartingSupportActionMode(androidx.appcompat.view.ActionMode.Callback);
+    method public void setSupportActionBar(androidx.appcompat.widget.Toolbar?);
+    method @Deprecated public void setSupportProgress(int);
+    method @Deprecated public void setSupportProgressBarIndeterminate(boolean);
+    method @Deprecated public void setSupportProgressBarIndeterminateVisibility(boolean);
+    method @Deprecated public void setSupportProgressBarVisibility(boolean);
+    method public androidx.appcompat.view.ActionMode? startSupportActionMode(androidx.appcompat.view.ActionMode.Callback);
+    method public void supportInvalidateOptionsMenu();
+    method public void supportNavigateUpTo(android.content.Intent);
+    method public boolean supportRequestWindowFeature(int);
+    method public boolean supportShouldUpRecreateTask(android.content.Intent);
+  }
+
+  public interface AppCompatCallback {
+    method public void onSupportActionModeFinished(androidx.appcompat.view.ActionMode!);
+    method public void onSupportActionModeStarted(androidx.appcompat.view.ActionMode!);
+    method public androidx.appcompat.view.ActionMode? onWindowStartingSupportActionMode(androidx.appcompat.view.ActionMode.Callback!);
+  }
+
+  public abstract class AppCompatDelegate {
+    method public abstract void addContentView(android.view.View!, android.view.ViewGroup.LayoutParams!);
+    method public abstract boolean applyDayNight();
+    method @Deprecated public void attachBaseContext(android.content.Context!);
+    method @CallSuper public android.content.Context attachBaseContext2(android.content.Context);
+    method public static androidx.appcompat.app.AppCompatDelegate create(android.app.Activity, androidx.appcompat.app.AppCompatCallback?);
+    method public static androidx.appcompat.app.AppCompatDelegate create(android.app.Dialog, androidx.appcompat.app.AppCompatCallback?);
+    method public static androidx.appcompat.app.AppCompatDelegate create(android.content.Context, android.view.Window, androidx.appcompat.app.AppCompatCallback?);
+    method public static androidx.appcompat.app.AppCompatDelegate create(android.content.Context, android.app.Activity, androidx.appcompat.app.AppCompatCallback?);
+    method public abstract android.view.View! createView(android.view.View?, String!, android.content.Context, android.util.AttributeSet);
+    method public abstract <T extends android.view.View> T! findViewById(@IdRes int);
+    method @androidx.appcompat.app.AppCompatDelegate.NightMode public static int getDefaultNightMode();
+    method public abstract androidx.appcompat.app.ActionBarDrawerToggle.Delegate? getDrawerToggleDelegate();
+    method @androidx.appcompat.app.AppCompatDelegate.NightMode public int getLocalNightMode();
+    method public abstract android.view.MenuInflater! getMenuInflater();
+    method public abstract androidx.appcompat.app.ActionBar? getSupportActionBar();
+    method public abstract boolean hasWindowFeature(int);
+    method public abstract void installViewFactory();
+    method public abstract void invalidateOptionsMenu();
+    method public static boolean isCompatVectorFromResourcesEnabled();
+    method public abstract boolean isHandleNativeActionModesEnabled();
+    method public abstract void onConfigurationChanged(android.content.res.Configuration!);
+    method public abstract void onCreate(android.os.Bundle!);
+    method public abstract void onDestroy();
+    method public abstract void onPostCreate(android.os.Bundle!);
+    method public abstract void onPostResume();
+    method public abstract void onSaveInstanceState(android.os.Bundle!);
+    method public abstract void onStart();
+    method public abstract void onStop();
+    method public abstract boolean requestWindowFeature(int);
+    method public static void setCompatVectorFromResourcesEnabled(boolean);
+    method public abstract void setContentView(android.view.View!);
+    method public abstract void setContentView(@LayoutRes int);
+    method public abstract void setContentView(android.view.View!, android.view.ViewGroup.LayoutParams!);
+    method public static void setDefaultNightMode(@androidx.appcompat.app.AppCompatDelegate.NightMode int);
+    method public abstract void setHandleNativeActionModesEnabled(boolean);
+    method @RequiresApi(17) public abstract void setLocalNightMode(@androidx.appcompat.app.AppCompatDelegate.NightMode int);
+    method public abstract void setSupportActionBar(androidx.appcompat.widget.Toolbar?);
+    method public void setTheme(@StyleRes int);
+    method public abstract void setTitle(CharSequence?);
+    method public abstract androidx.appcompat.view.ActionMode? startSupportActionMode(androidx.appcompat.view.ActionMode.Callback);
+    field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+    field public static final int FEATURE_SUPPORT_ACTION_BAR = 108; // 0x6c
+    field public static final int FEATURE_SUPPORT_ACTION_BAR_OVERLAY = 109; // 0x6d
+    field @Deprecated public static final int MODE_NIGHT_AUTO = 0; // 0x0
+    field public static final int MODE_NIGHT_AUTO_BATTERY = 3; // 0x3
+    field @Deprecated public static final int MODE_NIGHT_AUTO_TIME = 0; // 0x0
+    field public static final int MODE_NIGHT_FOLLOW_SYSTEM = -1; // 0xffffffff
+    field public static final int MODE_NIGHT_NO = 1; // 0x1
+    field public static final int MODE_NIGHT_UNSPECIFIED = -100; // 0xffffff9c
+    field public static final int MODE_NIGHT_YES = 2; // 0x2
+  }
+
+  @IntDef({androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO, androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES, androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_TIME, androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM, androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_UNSPECIFIED, androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface AppCompatDelegate.NightMode {
+  }
+
+  public class AppCompatDialog extends android.app.Dialog implements androidx.appcompat.app.AppCompatCallback {
+    ctor public AppCompatDialog(android.content.Context!);
+    ctor public AppCompatDialog(android.content.Context!, int);
+    ctor protected AppCompatDialog(android.content.Context!, boolean, android.content.DialogInterface.OnCancelListener!);
+    method public androidx.appcompat.app.AppCompatDelegate! getDelegate();
+    method public androidx.appcompat.app.ActionBar! getSupportActionBar();
+    method public void onSupportActionModeFinished(androidx.appcompat.view.ActionMode!);
+    method public void onSupportActionModeStarted(androidx.appcompat.view.ActionMode!);
+    method public androidx.appcompat.view.ActionMode? onWindowStartingSupportActionMode(androidx.appcompat.view.ActionMode.Callback!);
+    method public boolean supportRequestWindowFeature(int);
+  }
+
+  public class AppCompatDialogFragment extends androidx.fragment.app.DialogFragment {
+    ctor public AppCompatDialogFragment();
+  }
+
+  public class AppCompatViewInflater {
+    ctor public AppCompatViewInflater();
+    method protected androidx.appcompat.widget.AppCompatAutoCompleteTextView createAutoCompleteTextView(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatButton createButton(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatCheckBox createCheckBox(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatCheckedTextView createCheckedTextView(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatEditText createEditText(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatImageButton createImageButton(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatImageView createImageView(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatMultiAutoCompleteTextView createMultiAutoCompleteTextView(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatRadioButton createRadioButton(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatRatingBar createRatingBar(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatSeekBar createSeekBar(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatSpinner createSpinner(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatTextView createTextView(android.content.Context!, android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.AppCompatToggleButton createToggleButton(android.content.Context!, android.util.AttributeSet!);
+    method protected android.view.View? createView(android.content.Context!, String!, android.util.AttributeSet!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class WindowDecorActionBar extends androidx.appcompat.app.ActionBar implements androidx.appcompat.widget.ActionBarOverlayLayout.ActionBarVisibilityCallback {
+    ctor public WindowDecorActionBar(android.app.Activity!, boolean);
+    ctor public WindowDecorActionBar(android.app.Dialog!);
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public WindowDecorActionBar(android.view.View!);
+    method public void addOnMenuVisibilityListener(androidx.appcompat.app.ActionBar.OnMenuVisibilityListener!);
+    method public void addTab(androidx.appcompat.app.ActionBar.Tab!);
+    method public void addTab(androidx.appcompat.app.ActionBar.Tab!, int);
+    method public void addTab(androidx.appcompat.app.ActionBar.Tab!, boolean);
+    method public void addTab(androidx.appcompat.app.ActionBar.Tab!, int, boolean);
+    method public void animateToMode(boolean);
+    method public void doHide(boolean);
+    method public void doShow(boolean);
+    method public void enableContentAnimations(boolean);
+    method public android.view.View! getCustomView();
+    method public int getDisplayOptions();
+    method public int getHeight();
+    method public int getNavigationItemCount();
+    method public int getNavigationMode();
+    method public int getSelectedNavigationIndex();
+    method public androidx.appcompat.app.ActionBar.Tab! getSelectedTab();
+    method public CharSequence! getSubtitle();
+    method public androidx.appcompat.app.ActionBar.Tab! getTabAt(int);
+    method public int getTabCount();
+    method public CharSequence! getTitle();
+    method public boolean hasIcon();
+    method public boolean hasLogo();
+    method public void hide();
+    method public void hideForSystem();
+    method public boolean isShowing();
+    method public androidx.appcompat.app.ActionBar.Tab! newTab();
+    method public void onContentScrollStarted();
+    method public void onContentScrollStopped();
+    method public void onWindowVisibilityChanged(int);
+    method public void removeAllTabs();
+    method public void removeOnMenuVisibilityListener(androidx.appcompat.app.ActionBar.OnMenuVisibilityListener!);
+    method public void removeTab(androidx.appcompat.app.ActionBar.Tab!);
+    method public void removeTabAt(int);
+    method public boolean requestFocus();
+    method public void selectTab(androidx.appcompat.app.ActionBar.Tab!);
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable!);
+    method public void setCustomView(int);
+    method public void setCustomView(android.view.View!);
+    method public void setCustomView(android.view.View!, androidx.appcompat.app.ActionBar.LayoutParams!);
+    method public void setDisplayHomeAsUpEnabled(boolean);
+    method public void setDisplayOptions(int);
+    method public void setDisplayOptions(int, int);
+    method public void setDisplayShowCustomEnabled(boolean);
+    method public void setDisplayShowHomeEnabled(boolean);
+    method public void setDisplayShowTitleEnabled(boolean);
+    method public void setDisplayUseLogoEnabled(boolean);
+    method public void setIcon(int);
+    method public void setIcon(android.graphics.drawable.Drawable!);
+    method public void setListNavigationCallbacks(android.widget.SpinnerAdapter!, androidx.appcompat.app.ActionBar.OnNavigationListener!);
+    method public void setLogo(int);
+    method public void setLogo(android.graphics.drawable.Drawable!);
+    method public void setNavigationMode(int);
+    method public void setSelectedNavigationItem(int);
+    method public void setSubtitle(int);
+    method public void setSubtitle(CharSequence!);
+    method public void setTitle(int);
+    method public void setTitle(CharSequence!);
+    method public void show();
+    method public void showForSystem();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class WindowDecorActionBar.ActionModeImpl extends androidx.appcompat.view.ActionMode implements androidx.appcompat.view.menu.MenuBuilder.Callback {
+    ctor public WindowDecorActionBar.ActionModeImpl(android.content.Context!, androidx.appcompat.view.ActionMode.Callback!);
+    method public boolean dispatchOnCreate();
+    method public void finish();
+    method public android.view.View! getCustomView();
+    method public android.view.Menu! getMenu();
+    method public android.view.MenuInflater! getMenuInflater();
+    method public CharSequence! getSubtitle();
+    method public CharSequence! getTitle();
+    method public void invalidate();
+    method public void onCloseMenu(androidx.appcompat.view.menu.MenuBuilder!, boolean);
+    method public void onCloseSubMenu(androidx.appcompat.view.menu.SubMenuBuilder!);
+    method public boolean onMenuItemSelected(androidx.appcompat.view.menu.MenuBuilder, android.view.MenuItem);
+    method public void onMenuModeChange(androidx.appcompat.view.menu.MenuBuilder);
+    method public boolean onSubMenuSelected(androidx.appcompat.view.menu.SubMenuBuilder!);
+    method public void setCustomView(android.view.View!);
+    method public void setSubtitle(CharSequence!);
+    method public void setSubtitle(int);
+    method public void setTitle(CharSequence!);
+    method public void setTitle(int);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class WindowDecorActionBar.TabImpl extends androidx.appcompat.app.ActionBar.Tab {
+    ctor public WindowDecorActionBar.TabImpl();
+    method public androidx.appcompat.app.ActionBar.TabListener! getCallback();
+    method public CharSequence! getContentDescription();
+    method public android.view.View! getCustomView();
+    method public android.graphics.drawable.Drawable! getIcon();
+    method public int getPosition();
+    method public Object! getTag();
+    method public CharSequence! getText();
+    method public void select();
+    method public androidx.appcompat.app.ActionBar.Tab! setContentDescription(int);
+    method public androidx.appcompat.app.ActionBar.Tab! setContentDescription(CharSequence!);
+    method public androidx.appcompat.app.ActionBar.Tab! setCustomView(android.view.View!);
+    method public androidx.appcompat.app.ActionBar.Tab! setCustomView(int);
+    method public androidx.appcompat.app.ActionBar.Tab! setIcon(android.graphics.drawable.Drawable!);
+    method public androidx.appcompat.app.ActionBar.Tab! setIcon(int);
+    method public void setPosition(int);
+    method public androidx.appcompat.app.ActionBar.Tab! setTabListener(androidx.appcompat.app.ActionBar.TabListener!);
+    method public androidx.appcompat.app.ActionBar.Tab! setTag(Object!);
+    method public androidx.appcompat.app.ActionBar.Tab! setText(CharSequence!);
+    method public androidx.appcompat.app.ActionBar.Tab! setText(int);
+  }
+
+}
+
+package androidx.appcompat.graphics.drawable {
+
+  public class DrawerArrowDrawable extends android.graphics.drawable.Drawable {
+    ctor public DrawerArrowDrawable(android.content.Context!);
+    method public void draw(android.graphics.Canvas!);
+    method public float getArrowHeadLength();
+    method public float getArrowShaftLength();
+    method public float getBarLength();
+    method public float getBarThickness();
+    method @ColorInt public int getColor();
+    method @androidx.appcompat.graphics.drawable.DrawerArrowDrawable.ArrowDirection public int getDirection();
+    method public float getGapSize();
+    method public int getOpacity();
+    method public final android.graphics.Paint! getPaint();
+    method @FloatRange(from=0.0, to=1.0) public float getProgress();
+    method public boolean isSpinEnabled();
+    method public void setAlpha(int);
+    method public void setArrowHeadLength(float);
+    method public void setArrowShaftLength(float);
+    method public void setBarLength(float);
+    method public void setBarThickness(float);
+    method public void setColor(@ColorInt int);
+    method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setDirection(@androidx.appcompat.graphics.drawable.DrawerArrowDrawable.ArrowDirection int);
+    method public void setGapSize(float);
+    method public void setProgress(@FloatRange(from=0.0, to=1.0) float);
+    method public void setSpinEnabled(boolean);
+    method public void setVerticalMirror(boolean);
+    field public static final int ARROW_DIRECTION_END = 3; // 0x3
+    field public static final int ARROW_DIRECTION_LEFT = 0; // 0x0
+    field public static final int ARROW_DIRECTION_RIGHT = 1; // 0x1
+    field public static final int ARROW_DIRECTION_START = 2; // 0x2
+  }
+
+  @IntDef({androidx.appcompat.graphics.drawable.DrawerArrowDrawable.ARROW_DIRECTION_LEFT, androidx.appcompat.graphics.drawable.DrawerArrowDrawable.ARROW_DIRECTION_RIGHT, androidx.appcompat.graphics.drawable.DrawerArrowDrawable.ARROW_DIRECTION_START, androidx.appcompat.graphics.drawable.DrawerArrowDrawable.ARROW_DIRECTION_END}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface DrawerArrowDrawable.ArrowDirection {
+  }
+
+}
+
+package androidx.appcompat.text {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class AllCapsTransformationMethod implements android.text.method.TransformationMethod {
+    ctor public AllCapsTransformationMethod(android.content.Context!);
+    method public CharSequence! getTransformation(CharSequence!, android.view.View!);
+    method public void onFocusChanged(android.view.View!, CharSequence!, boolean, int, android.graphics.Rect!);
+  }
+
+}
+
+package androidx.appcompat.view {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ActionBarPolicy {
+    method public boolean enableHomeButtonByDefault();
+    method public static androidx.appcompat.view.ActionBarPolicy! get(android.content.Context!);
+    method public int getEmbeddedMenuWidthLimit();
+    method public int getMaxActionButtons();
+    method public int getStackedTabMaxWidth();
+    method public int getTabContainerHeight();
+    method public boolean hasEmbeddedTabs();
+    method public boolean showsOverflowMenuButton();
+  }
+
+  public abstract class ActionMode {
+    ctor public ActionMode();
+    method public abstract void finish();
+    method public abstract android.view.View! getCustomView();
+    method public abstract android.view.Menu! getMenu();
+    method public abstract android.view.MenuInflater! getMenuInflater();
+    method public abstract CharSequence! getSubtitle();
+    method public Object! getTag();
+    method public abstract CharSequence! getTitle();
+    method public boolean getTitleOptionalHint();
+    method public abstract void invalidate();
+    method public boolean isTitleOptional();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean isUiFocusable();
+    method public abstract void setCustomView(android.view.View!);
+    method public abstract void setSubtitle(CharSequence!);
+    method public abstract void setSubtitle(int);
+    method public void setTag(Object!);
+    method public abstract void setTitle(CharSequence!);
+    method public abstract void setTitle(int);
+    method public void setTitleOptionalHint(boolean);
+  }
+
+  public static interface ActionMode.Callback {
+    method public boolean onActionItemClicked(androidx.appcompat.view.ActionMode!, android.view.MenuItem!);
+    method public boolean onCreateActionMode(androidx.appcompat.view.ActionMode!, android.view.Menu!);
+    method public void onDestroyActionMode(androidx.appcompat.view.ActionMode!);
+    method public boolean onPrepareActionMode(androidx.appcompat.view.ActionMode!, android.view.Menu!);
+  }
+
+  @Deprecated public interface CollapsibleActionView {
+    method @Deprecated public void onActionViewCollapsed();
+    method @Deprecated public void onActionViewExpanded();
+  }
+
+  public class ContextThemeWrapper extends android.content.ContextWrapper {
+    ctor public ContextThemeWrapper();
+    ctor public ContextThemeWrapper(android.content.Context!, @StyleRes int);
+    ctor public ContextThemeWrapper(android.content.Context!, android.content.res.Resources.Theme!);
+    method public void applyOverrideConfiguration(android.content.res.Configuration!);
+    method public int getThemeResId();
+    method protected void onApplyThemeResource(android.content.res.Resources.Theme!, int, boolean);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class StandaloneActionMode extends androidx.appcompat.view.ActionMode implements androidx.appcompat.view.menu.MenuBuilder.Callback {
+    ctor public StandaloneActionMode(android.content.Context!, androidx.appcompat.widget.ActionBarContextView!, androidx.appcompat.view.ActionMode.Callback!, boolean);
+    method public void finish();
+    method public android.view.View! getCustomView();
+    method public android.view.Menu! getMenu();
+    method public android.view.MenuInflater! getMenuInflater();
+    method public CharSequence! getSubtitle();
+    method public CharSequence! getTitle();
+    method public void invalidate();
+    method public void onCloseMenu(androidx.appcompat.view.menu.MenuBuilder!, boolean);
+    method public void onCloseSubMenu(androidx.appcompat.view.menu.SubMenuBuilder!);
+    method public boolean onMenuItemSelected(androidx.appcompat.view.menu.MenuBuilder, android.view.MenuItem);
+    method public void onMenuModeChange(androidx.appcompat.view.menu.MenuBuilder);
+    method public boolean onSubMenuSelected(androidx.appcompat.view.menu.SubMenuBuilder!);
+    method public void setCustomView(android.view.View!);
+    method public void setSubtitle(CharSequence!);
+    method public void setSubtitle(int);
+    method public void setTitle(CharSequence!);
+    method public void setTitle(int);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class SupportActionModeWrapper extends android.view.ActionMode {
+    ctor public SupportActionModeWrapper(android.content.Context!, androidx.appcompat.view.ActionMode!);
+    method public void finish();
+    method public android.view.View! getCustomView();
+    method public android.view.Menu! getMenu();
+    method public android.view.MenuInflater! getMenuInflater();
+    method public CharSequence! getSubtitle();
+    method public CharSequence! getTitle();
+    method public void invalidate();
+    method public void setCustomView(android.view.View!);
+    method public void setSubtitle(CharSequence!);
+    method public void setSubtitle(int);
+    method public void setTitle(CharSequence!);
+    method public void setTitle(int);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static class SupportActionModeWrapper.CallbackWrapper implements androidx.appcompat.view.ActionMode.Callback {
+    ctor public SupportActionModeWrapper.CallbackWrapper(android.content.Context!, android.view.ActionMode.Callback!);
+    method public android.view.ActionMode! getActionModeWrapper(androidx.appcompat.view.ActionMode!);
+    method public boolean onActionItemClicked(androidx.appcompat.view.ActionMode!, android.view.MenuItem!);
+    method public boolean onCreateActionMode(androidx.appcompat.view.ActionMode!, android.view.Menu!);
+    method public void onDestroyActionMode(androidx.appcompat.view.ActionMode!);
+    method public boolean onPrepareActionMode(androidx.appcompat.view.ActionMode!, android.view.Menu!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class SupportMenuInflater extends android.view.MenuInflater {
+    ctor public SupportMenuInflater(android.content.Context!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ViewPropertyAnimatorCompatSet {
+    ctor public ViewPropertyAnimatorCompatSet();
+    method public void cancel();
+    method public androidx.appcompat.view.ViewPropertyAnimatorCompatSet! play(androidx.core.view.ViewPropertyAnimatorCompat!);
+    method public androidx.appcompat.view.ViewPropertyAnimatorCompatSet! playSequentially(androidx.core.view.ViewPropertyAnimatorCompat!, androidx.core.view.ViewPropertyAnimatorCompat!);
+    method public androidx.appcompat.view.ViewPropertyAnimatorCompatSet! setDuration(long);
+    method public androidx.appcompat.view.ViewPropertyAnimatorCompatSet! setInterpolator(android.view.animation.Interpolator!);
+    method public androidx.appcompat.view.ViewPropertyAnimatorCompatSet! setListener(androidx.core.view.ViewPropertyAnimatorListener!);
+    method public void start();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class WindowCallbackWrapper implements android.view.Window.Callback {
+    ctor public WindowCallbackWrapper(android.view.Window.Callback!);
+    method public boolean dispatchGenericMotionEvent(android.view.MotionEvent!);
+    method public boolean dispatchKeyEvent(android.view.KeyEvent!);
+    method public boolean dispatchKeyShortcutEvent(android.view.KeyEvent!);
+    method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent!);
+    method public boolean dispatchTouchEvent(android.view.MotionEvent!);
+    method public boolean dispatchTrackballEvent(android.view.MotionEvent!);
+    method public final android.view.Window.Callback! getWrapped();
+    method public void onActionModeFinished(android.view.ActionMode!);
+    method public void onActionModeStarted(android.view.ActionMode!);
+    method public void onAttachedToWindow();
+    method public void onContentChanged();
+    method public boolean onCreatePanelMenu(int, android.view.Menu!);
+    method public android.view.View! onCreatePanelView(int);
+    method public void onDetachedFromWindow();
+    method public boolean onMenuItemSelected(int, android.view.MenuItem!);
+    method public boolean onMenuOpened(int, android.view.Menu!);
+    method public void onPanelClosed(int, android.view.Menu!);
+    method public boolean onPreparePanel(int, android.view.View!, android.view.Menu!);
+    method @RequiresApi(23) public boolean onSearchRequested(android.view.SearchEvent!);
+    method public boolean onSearchRequested();
+    method public void onWindowAttributesChanged(android.view.WindowManager.LayoutParams!);
+    method public void onWindowFocusChanged(boolean);
+    method public android.view.ActionMode! onWindowStartingActionMode(android.view.ActionMode.Callback!);
+    method @RequiresApi(23) public android.view.ActionMode! onWindowStartingActionMode(android.view.ActionMode.Callback!, int);
+  }
+
+}
+
+package androidx.appcompat.view.menu {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ActionMenuItem implements androidx.core.internal.view.SupportMenuItem {
+    ctor public ActionMenuItem(android.content.Context!, int, int, int, int, CharSequence!);
+    method public boolean collapseActionView();
+    method public boolean expandActionView();
+    method public android.view.ActionProvider! getActionProvider();
+    method public android.view.View! getActionView();
+    method public char getAlphabeticShortcut();
+    method public int getGroupId();
+    method public android.graphics.drawable.Drawable! getIcon();
+    method public android.content.Intent! getIntent();
+    method public int getItemId();
+    method public android.view.ContextMenu.ContextMenuInfo! getMenuInfo();
+    method public char getNumericShortcut();
+    method public int getOrder();
+    method public android.view.SubMenu! getSubMenu();
+    method public androidx.core.view.ActionProvider! getSupportActionProvider();
+    method public CharSequence! getTitle();
+    method public CharSequence! getTitleCondensed();
+    method public boolean hasSubMenu();
+    method public boolean invoke();
+    method public boolean isActionViewExpanded();
+    method public boolean isCheckable();
+    method public boolean isChecked();
+    method public boolean isEnabled();
+    method public boolean isVisible();
+    method public boolean requiresActionButton();
+    method public boolean requiresOverflow();
+    method public android.view.MenuItem! setActionProvider(android.view.ActionProvider!);
+    method public androidx.core.internal.view.SupportMenuItem! setActionView(android.view.View!);
+    method public androidx.core.internal.view.SupportMenuItem! setActionView(int);
+    method public android.view.MenuItem! setAlphabeticShortcut(char);
+    method public android.view.MenuItem! setCheckable(boolean);
+    method public android.view.MenuItem! setChecked(boolean);
+    method public androidx.core.internal.view.SupportMenuItem! setContentDescription(CharSequence!);
+    method public android.view.MenuItem! setEnabled(boolean);
+    method public androidx.appcompat.view.menu.ActionMenuItem! setExclusiveCheckable(boolean);
+    method public android.view.MenuItem! setIcon(android.graphics.drawable.Drawable!);
+    method public android.view.MenuItem! setIcon(int);
+    method public android.view.MenuItem! setIntent(android.content.Intent!);
+    method public android.view.MenuItem! setNumericShortcut(char);
+    method public android.view.MenuItem! setOnActionExpandListener(android.view.MenuItem.OnActionExpandListener!);
+    method public android.view.MenuItem! setOnMenuItemClickListener(android.view.MenuItem.OnMenuItemClickListener!);
+    method public android.view.MenuItem! setShortcut(char, char);
+    method public void setShowAsAction(int);
+    method public androidx.core.internal.view.SupportMenuItem! setShowAsActionFlags(int);
+    method public androidx.core.internal.view.SupportMenuItem! setSupportActionProvider(androidx.core.view.ActionProvider!);
+    method public android.view.MenuItem! setTitle(CharSequence!);
+    method public android.view.MenuItem! setTitle(int);
+    method public android.view.MenuItem! setTitleCondensed(CharSequence!);
+    method public androidx.core.internal.view.SupportMenuItem! setTooltipText(CharSequence!);
+    method public android.view.MenuItem! setVisible(boolean);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ActionMenuItemView extends androidx.appcompat.widget.AppCompatTextView implements androidx.appcompat.widget.ActionMenuView.ActionMenuChildView androidx.appcompat.view.menu.MenuView.ItemView android.view.View.OnClickListener {
+    ctor public ActionMenuItemView(android.content.Context!);
+    ctor public ActionMenuItemView(android.content.Context!, android.util.AttributeSet!);
+    ctor public ActionMenuItemView(android.content.Context!, android.util.AttributeSet!, int);
+    method public androidx.appcompat.view.menu.MenuItemImpl! getItemData();
+    method public boolean hasText();
+    method public void initialize(androidx.appcompat.view.menu.MenuItemImpl!, int);
+    method public boolean needsDividerAfter();
+    method public boolean needsDividerBefore();
+    method public void onClick(android.view.View!);
+    method public void onConfigurationChanged(android.content.res.Configuration!);
+    method public boolean prefersCondensedTitle();
+    method public void setCheckable(boolean);
+    method public void setChecked(boolean);
+    method public void setExpandedFormat(boolean);
+    method public void setIcon(android.graphics.drawable.Drawable!);
+    method public void setItemInvoker(androidx.appcompat.view.menu.MenuBuilder.ItemInvoker!);
+    method public void setPopupCallback(androidx.appcompat.view.menu.ActionMenuItemView.PopupCallback!);
+    method public void setShortcut(boolean, char);
+    method public void setTitle(CharSequence!);
+    method public boolean showsIcon();
+  }
+
+  public abstract static class ActionMenuItemView.PopupCallback {
+    ctor public ActionMenuItemView.PopupCallback();
+    method public abstract androidx.appcompat.view.menu.ShowableListMenu! getPopup();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class BaseMenuPresenter implements androidx.appcompat.view.menu.MenuPresenter {
+    ctor public BaseMenuPresenter(android.content.Context!, int, int);
+    method protected void addItemView(android.view.View!, int);
+    method public abstract void bindItemView(androidx.appcompat.view.menu.MenuItemImpl!, androidx.appcompat.view.menu.MenuView.ItemView!);
+    method public boolean collapseItemActionView(androidx.appcompat.view.menu.MenuBuilder!, androidx.appcompat.view.menu.MenuItemImpl!);
+    method public androidx.appcompat.view.menu.MenuView.ItemView! createItemView(android.view.ViewGroup!);
+    method public boolean expandItemActionView(androidx.appcompat.view.menu.MenuBuilder!, androidx.appcompat.view.menu.MenuItemImpl!);
+    method protected boolean filterLeftoverView(android.view.ViewGroup!, int);
+    method public boolean flagActionItems();
+    method public androidx.appcompat.view.menu.MenuPresenter.Callback! getCallback();
+    method public int getId();
+    method public android.view.View! getItemView(androidx.appcompat.view.menu.MenuItemImpl!, android.view.View!, android.view.ViewGroup!);
+    method public androidx.appcompat.view.menu.MenuView! getMenuView(android.view.ViewGroup!);
+    method public void initForMenu(android.content.Context!, androidx.appcompat.view.menu.MenuBuilder!);
+    method public void onCloseMenu(androidx.appcompat.view.menu.MenuBuilder!, boolean);
+    method public boolean onSubMenuSelected(androidx.appcompat.view.menu.SubMenuBuilder!);
+    method public void setCallback(androidx.appcompat.view.menu.MenuPresenter.Callback!);
+    method public void setId(int);
+    method public boolean shouldIncludeItem(int, androidx.appcompat.view.menu.MenuItemImpl!);
+    method public void updateMenuView(boolean);
+    field protected android.content.Context! mContext;
+    field protected android.view.LayoutInflater! mInflater;
+    field protected androidx.appcompat.view.menu.MenuBuilder! mMenu;
+    field protected androidx.appcompat.view.menu.MenuView! mMenuView;
+    field protected android.content.Context! mSystemContext;
+    field protected android.view.LayoutInflater! mSystemInflater;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class ExpandedMenuView extends android.widget.ListView implements android.widget.AdapterView.OnItemClickListener androidx.appcompat.view.menu.MenuBuilder.ItemInvoker androidx.appcompat.view.menu.MenuView {
+    ctor public ExpandedMenuView(android.content.Context!, android.util.AttributeSet!);
+    ctor public ExpandedMenuView(android.content.Context!, android.util.AttributeSet!, int);
+    method public int getWindowAnimations();
+    method public void initialize(androidx.appcompat.view.menu.MenuBuilder!);
+    method public boolean invokeItem(androidx.appcompat.view.menu.MenuItemImpl!);
+    method public void onItemClick(android.widget.AdapterView!, android.view.View!, int, long);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ListMenuItemView extends android.widget.LinearLayout implements android.widget.AbsListView.SelectionBoundsAdjuster androidx.appcompat.view.menu.MenuView.ItemView {
+    ctor public ListMenuItemView(android.content.Context!, android.util.AttributeSet!);
+    ctor public ListMenuItemView(android.content.Context!, android.util.AttributeSet!, int);
+    method public void adjustListItemSelectionBounds(android.graphics.Rect!);
+    method public androidx.appcompat.view.menu.MenuItemImpl! getItemData();
+    method public void initialize(androidx.appcompat.view.menu.MenuItemImpl!, int);
+    method public boolean prefersCondensedTitle();
+    method public void setCheckable(boolean);
+    method public void setChecked(boolean);
+    method public void setForceShowIcon(boolean);
+    method public void setGroupDividerEnabled(boolean);
+    method public void setIcon(android.graphics.drawable.Drawable!);
+    method public void setShortcut(boolean, char);
+    method public void setTitle(CharSequence!);
+    method public boolean showsIcon();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ListMenuPresenter implements android.widget.AdapterView.OnItemClickListener androidx.appcompat.view.menu.MenuPresenter {
+    ctor public ListMenuPresenter(android.content.Context!, int);
+    ctor public ListMenuPresenter(int, int);
+    method public boolean collapseItemActionView(androidx.appcompat.view.menu.MenuBuilder!, androidx.appcompat.view.menu.MenuItemImpl!);
+    method public boolean expandItemActionView(androidx.appcompat.view.menu.MenuBuilder!, androidx.appcompat.view.menu.MenuItemImpl!);
+    method public boolean flagActionItems();
+    method public android.widget.ListAdapter! getAdapter();
+    method public int getId();
+    method public androidx.appcompat.view.menu.MenuView! getMenuView(android.view.ViewGroup!);
+    method public void initForMenu(android.content.Context!, androidx.appcompat.view.menu.MenuBuilder!);
+    method public void onCloseMenu(androidx.appcompat.view.menu.MenuBuilder!, boolean);
+    method public void onItemClick(android.widget.AdapterView<?>!, android.view.View!, int, long);
+    method public void onRestoreInstanceState(android.os.Parcelable!);
+    method public android.os.Parcelable! onSaveInstanceState();
+    method public boolean onSubMenuSelected(androidx.appcompat.view.menu.SubMenuBuilder!);
+    method public void restoreHierarchyState(android.os.Bundle!);
+    method public void saveHierarchyState(android.os.Bundle!);
+    method public void setCallback(androidx.appcompat.view.menu.MenuPresenter.Callback!);
+    method public void setId(int);
+    method public void setItemIndexOffset(int);
+    method public void updateMenuView(boolean);
+    field public static final String VIEWS_TAG = "android:menu:list";
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class MenuAdapter extends android.widget.BaseAdapter {
+    ctor public MenuAdapter(androidx.appcompat.view.menu.MenuBuilder!, android.view.LayoutInflater!, boolean, int);
+    method public androidx.appcompat.view.menu.MenuBuilder! getAdapterMenu();
+    method public int getCount();
+    method public boolean getForceShowIcon();
+    method public androidx.appcompat.view.menu.MenuItemImpl! getItem(int);
+    method public long getItemId(int);
+    method public android.view.View! getView(int, android.view.View!, android.view.ViewGroup!);
+    method public void setForceShowIcon(boolean);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class MenuBuilder implements androidx.core.internal.view.SupportMenu {
+    ctor public MenuBuilder(android.content.Context!);
+    method public android.view.MenuItem! add(CharSequence!);
+    method public android.view.MenuItem! add(int);
+    method public android.view.MenuItem! add(int, int, int, CharSequence!);
+    method public android.view.MenuItem! add(int, int, int, int);
+    method public int addIntentOptions(int, int, int, android.content.ComponentName!, android.content.Intent![]!, android.content.Intent!, int, android.view.MenuItem![]!);
+    method protected android.view.MenuItem! addInternal(int, int, int, CharSequence!);
+    method public void addMenuPresenter(androidx.appcompat.view.menu.MenuPresenter!);
+    method public void addMenuPresenter(androidx.appcompat.view.menu.MenuPresenter!, android.content.Context!);
+    method public android.view.SubMenu! addSubMenu(CharSequence!);
+    method public android.view.SubMenu! addSubMenu(int);
+    method public android.view.SubMenu! addSubMenu(int, int, int, CharSequence!);
+    method public android.view.SubMenu! addSubMenu(int, int, int, int);
+    method public void changeMenuMode();
+    method public void clear();
+    method public void clearAll();
+    method public void clearHeader();
+    method public final void close(boolean);
+    method public void close();
+    method public boolean collapseItemActionView(androidx.appcompat.view.menu.MenuItemImpl!);
+    method public boolean expandItemActionView(androidx.appcompat.view.menu.MenuItemImpl!);
+    method public int findGroupIndex(int);
+    method public int findGroupIndex(int, int);
+    method public android.view.MenuItem! findItem(int);
+    method public int findItemIndex(int);
+    method public void flagActionItems();
+    method public java.util.ArrayList<androidx.appcompat.view.menu.MenuItemImpl!>! getActionItems();
+    method protected String! getActionViewStatesKey();
+    method public android.content.Context! getContext();
+    method public androidx.appcompat.view.menu.MenuItemImpl! getExpandedItem();
+    method public android.graphics.drawable.Drawable! getHeaderIcon();
+    method public CharSequence! getHeaderTitle();
+    method public android.view.View! getHeaderView();
+    method public android.view.MenuItem! getItem(int);
+    method public java.util.ArrayList<androidx.appcompat.view.menu.MenuItemImpl!>! getNonActionItems();
+    method public androidx.appcompat.view.menu.MenuBuilder! getRootMenu();
+    method public java.util.ArrayList<androidx.appcompat.view.menu.MenuItemImpl!> getVisibleItems();
+    method public boolean hasVisibleItems();
+    method public boolean isGroupDividerEnabled();
+    method public boolean isShortcutKey(int, android.view.KeyEvent!);
+    method public boolean isShortcutsVisible();
+    method public void onItemsChanged(boolean);
+    method public boolean performIdentifierAction(int, int);
+    method public boolean performItemAction(android.view.MenuItem!, int);
+    method public boolean performItemAction(android.view.MenuItem!, androidx.appcompat.view.menu.MenuPresenter!, int);
+    method public boolean performShortcut(int, android.view.KeyEvent!, int);
+    method public void removeGroup(int);
+    method public void removeItem(int);
+    method public void removeItemAt(int);
+    method public void removeMenuPresenter(androidx.appcompat.view.menu.MenuPresenter!);
+    method public void restoreActionViewStates(android.os.Bundle!);
+    method public void restorePresenterStates(android.os.Bundle!);
+    method public void saveActionViewStates(android.os.Bundle!);
+    method public void savePresenterStates(android.os.Bundle!);
+    method public void setCallback(androidx.appcompat.view.menu.MenuBuilder.Callback!);
+    method public void setCurrentMenuInfo(android.view.ContextMenu.ContextMenuInfo!);
+    method public androidx.appcompat.view.menu.MenuBuilder! setDefaultShowAsAction(int);
+    method public void setGroupCheckable(int, boolean, boolean);
+    method public void setGroupEnabled(int, boolean);
+    method public void setGroupVisible(int, boolean);
+    method protected androidx.appcompat.view.menu.MenuBuilder! setHeaderIconInt(android.graphics.drawable.Drawable!);
+    method protected androidx.appcompat.view.menu.MenuBuilder! setHeaderIconInt(int);
+    method protected androidx.appcompat.view.menu.MenuBuilder! setHeaderTitleInt(CharSequence!);
+    method protected androidx.appcompat.view.menu.MenuBuilder! setHeaderTitleInt(int);
+    method protected androidx.appcompat.view.menu.MenuBuilder! setHeaderViewInt(android.view.View!);
+    method public void setOptionalIconsVisible(boolean);
+    method public void setOverrideVisibleItems(boolean);
+    method public void setQwertyMode(boolean);
+    method public void setShortcutsVisible(boolean);
+    method public int size();
+    method public void startDispatchingItemsChanged();
+    method public void stopDispatchingItemsChanged();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static interface MenuBuilder.Callback {
+    method public boolean onMenuItemSelected(androidx.appcompat.view.menu.MenuBuilder, android.view.MenuItem);
+    method public void onMenuModeChange(androidx.appcompat.view.menu.MenuBuilder);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static interface MenuBuilder.ItemInvoker {
+    method public boolean invokeItem(androidx.appcompat.view.menu.MenuItemImpl!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class MenuItemImpl implements androidx.core.internal.view.SupportMenuItem {
+    method public void actionFormatChanged();
+    method public boolean collapseActionView();
+    method public boolean expandActionView();
+    method public android.view.ActionProvider! getActionProvider();
+    method public android.view.View! getActionView();
+    method public char getAlphabeticShortcut();
+    method public int getGroupId();
+    method public android.graphics.drawable.Drawable! getIcon();
+    method public android.content.Intent! getIntent();
+    method public int getItemId();
+    method public android.view.ContextMenu.ContextMenuInfo! getMenuInfo();
+    method public char getNumericShortcut();
+    method public int getOrder();
+    method public int getOrdering();
+    method public android.view.SubMenu! getSubMenu();
+    method public androidx.core.view.ActionProvider! getSupportActionProvider();
+    method public CharSequence! getTitle();
+    method public CharSequence! getTitleCondensed();
+    method public boolean hasCollapsibleActionView();
+    method public boolean hasSubMenu();
+    method public boolean invoke();
+    method public boolean isActionButton();
+    method public boolean isActionViewExpanded();
+    method public boolean isCheckable();
+    method public boolean isChecked();
+    method public boolean isEnabled();
+    method public boolean isExclusiveCheckable();
+    method public boolean isVisible();
+    method public boolean requestsActionButton();
+    method public boolean requiresActionButton();
+    method public boolean requiresOverflow();
+    method public android.view.MenuItem! setActionProvider(android.view.ActionProvider!);
+    method public androidx.core.internal.view.SupportMenuItem! setActionView(android.view.View!);
+    method public androidx.core.internal.view.SupportMenuItem! setActionView(int);
+    method public void setActionViewExpanded(boolean);
+    method public android.view.MenuItem! setAlphabeticShortcut(char);
+    method public android.view.MenuItem! setCallback(Runnable!);
+    method public android.view.MenuItem! setCheckable(boolean);
+    method public android.view.MenuItem! setChecked(boolean);
+    method public androidx.core.internal.view.SupportMenuItem! setContentDescription(CharSequence!);
+    method public android.view.MenuItem! setEnabled(boolean);
+    method public void setExclusiveCheckable(boolean);
+    method public android.view.MenuItem! setIcon(android.graphics.drawable.Drawable!);
+    method public android.view.MenuItem! setIcon(int);
+    method public android.view.MenuItem! setIntent(android.content.Intent!);
+    method public void setIsActionButton(boolean);
+    method public android.view.MenuItem! setNumericShortcut(char);
+    method public android.view.MenuItem! setOnActionExpandListener(android.view.MenuItem.OnActionExpandListener!);
+    method public android.view.MenuItem! setOnMenuItemClickListener(android.view.MenuItem.OnMenuItemClickListener!);
+    method public android.view.MenuItem! setShortcut(char, char);
+    method public void setShowAsAction(int);
+    method public androidx.core.internal.view.SupportMenuItem! setShowAsActionFlags(int);
+    method public void setSubMenu(androidx.appcompat.view.menu.SubMenuBuilder!);
+    method public androidx.core.internal.view.SupportMenuItem! setSupportActionProvider(androidx.core.view.ActionProvider!);
+    method public android.view.MenuItem! setTitle(CharSequence!);
+    method public android.view.MenuItem! setTitle(int);
+    method public android.view.MenuItem! setTitleCondensed(CharSequence!);
+    method public androidx.core.internal.view.SupportMenuItem! setTooltipText(CharSequence!);
+    method public android.view.MenuItem! setVisible(boolean);
+    method public boolean shouldShowIcon();
+    method public boolean showsTextAsAction();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class MenuItemWrapperICS implements android.view.MenuItem {
+    ctor public MenuItemWrapperICS(android.content.Context!, androidx.core.internal.view.SupportMenuItem!);
+    method public boolean collapseActionView();
+    method public boolean expandActionView();
+    method public android.view.ActionProvider! getActionProvider();
+    method public android.view.View! getActionView();
+    method public char getAlphabeticShortcut();
+    method public int getGroupId();
+    method public android.graphics.drawable.Drawable! getIcon();
+    method public android.content.Intent! getIntent();
+    method public int getItemId();
+    method public android.view.ContextMenu.ContextMenuInfo! getMenuInfo();
+    method public char getNumericShortcut();
+    method public int getOrder();
+    method public android.view.SubMenu! getSubMenu();
+    method public CharSequence! getTitle();
+    method public CharSequence! getTitleCondensed();
+    method public boolean hasSubMenu();
+    method public boolean isActionViewExpanded();
+    method public boolean isCheckable();
+    method public boolean isChecked();
+    method public boolean isEnabled();
+    method public boolean isVisible();
+    method public android.view.MenuItem! setActionProvider(android.view.ActionProvider!);
+    method public android.view.MenuItem! setActionView(android.view.View!);
+    method public android.view.MenuItem! setActionView(int);
+    method public android.view.MenuItem! setAlphabeticShortcut(char);
+    method public android.view.MenuItem! setCheckable(boolean);
+    method public android.view.MenuItem! setChecked(boolean);
+    method public android.view.MenuItem! setEnabled(boolean);
+    method public void setExclusiveCheckable(boolean);
+    method public android.view.MenuItem! setIcon(android.graphics.drawable.Drawable!);
+    method public android.view.MenuItem! setIcon(int);
+    method public android.view.MenuItem! setIntent(android.content.Intent!);
+    method public android.view.MenuItem! setNumericShortcut(char);
+    method public android.view.MenuItem! setOnActionExpandListener(android.view.MenuItem.OnActionExpandListener!);
+    method public android.view.MenuItem! setOnMenuItemClickListener(android.view.MenuItem.OnMenuItemClickListener!);
+    method public android.view.MenuItem! setShortcut(char, char);
+    method public void setShowAsAction(int);
+    method public android.view.MenuItem! setShowAsActionFlags(int);
+    method public android.view.MenuItem! setTitle(CharSequence!);
+    method public android.view.MenuItem! setTitle(int);
+    method public android.view.MenuItem! setTitleCondensed(CharSequence!);
+    method public android.view.MenuItem! setVisible(boolean);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class MenuPopupHelper {
+    ctor public MenuPopupHelper(android.content.Context, androidx.appcompat.view.menu.MenuBuilder);
+    ctor public MenuPopupHelper(android.content.Context, androidx.appcompat.view.menu.MenuBuilder, android.view.View);
+    ctor public MenuPopupHelper(android.content.Context, androidx.appcompat.view.menu.MenuBuilder, android.view.View, boolean, @AttrRes int);
+    ctor public MenuPopupHelper(android.content.Context, androidx.appcompat.view.menu.MenuBuilder, android.view.View, boolean, @AttrRes int, @StyleRes int);
+    method public void dismiss();
+    method public int getGravity();
+    method public android.widget.ListView! getListView();
+    method public boolean isShowing();
+    method protected void onDismiss();
+    method public void setAnchorView(android.view.View);
+    method public void setForceShowIcon(boolean);
+    method public void setGravity(int);
+    method public void setOnDismissListener(android.widget.PopupWindow.OnDismissListener?);
+    method public void setPresenterCallback(androidx.appcompat.view.menu.MenuPresenter.Callback?);
+    method public void show();
+    method public void show(int, int);
+    method public boolean tryShow();
+    method public boolean tryShow(int, int);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface MenuPresenter {
+    method public boolean collapseItemActionView(androidx.appcompat.view.menu.MenuBuilder!, androidx.appcompat.view.menu.MenuItemImpl!);
+    method public boolean expandItemActionView(androidx.appcompat.view.menu.MenuBuilder!, androidx.appcompat.view.menu.MenuItemImpl!);
+    method public boolean flagActionItems();
+    method public int getId();
+    method public androidx.appcompat.view.menu.MenuView! getMenuView(android.view.ViewGroup!);
+    method public void initForMenu(android.content.Context!, androidx.appcompat.view.menu.MenuBuilder!);
+    method public void onCloseMenu(androidx.appcompat.view.menu.MenuBuilder!, boolean);
+    method public void onRestoreInstanceState(android.os.Parcelable!);
+    method public android.os.Parcelable! onSaveInstanceState();
+    method public boolean onSubMenuSelected(androidx.appcompat.view.menu.SubMenuBuilder!);
+    method public void setCallback(androidx.appcompat.view.menu.MenuPresenter.Callback!);
+    method public void updateMenuView(boolean);
+  }
+
+  public static interface MenuPresenter.Callback {
+    method public void onCloseMenu(androidx.appcompat.view.menu.MenuBuilder, boolean);
+    method public boolean onOpenSubMenu(androidx.appcompat.view.menu.MenuBuilder);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface MenuView {
+    method public int getWindowAnimations();
+    method public void initialize(androidx.appcompat.view.menu.MenuBuilder!);
+  }
+
+  public static interface MenuView.ItemView {
+    method public androidx.appcompat.view.menu.MenuItemImpl! getItemData();
+    method public void initialize(androidx.appcompat.view.menu.MenuItemImpl!, int);
+    method public boolean prefersCondensedTitle();
+    method public void setCheckable(boolean);
+    method public void setChecked(boolean);
+    method public void setEnabled(boolean);
+    method public void setIcon(android.graphics.drawable.Drawable!);
+    method public void setShortcut(boolean, char);
+    method public void setTitle(CharSequence!);
+    method public boolean showsIcon();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class MenuWrapperICS implements android.view.Menu {
+    ctor public MenuWrapperICS(android.content.Context!, androidx.core.internal.view.SupportMenu!);
+    method public android.view.MenuItem! add(CharSequence!);
+    method public android.view.MenuItem! add(int);
+    method public android.view.MenuItem! add(int, int, int, CharSequence!);
+    method public android.view.MenuItem! add(int, int, int, int);
+    method public int addIntentOptions(int, int, int, android.content.ComponentName!, android.content.Intent![]!, android.content.Intent!, int, android.view.MenuItem![]!);
+    method public android.view.SubMenu! addSubMenu(CharSequence!);
+    method public android.view.SubMenu! addSubMenu(int);
+    method public android.view.SubMenu! addSubMenu(int, int, int, CharSequence!);
+    method public android.view.SubMenu! addSubMenu(int, int, int, int);
+    method public void clear();
+    method public void close();
+    method public android.view.MenuItem! findItem(int);
+    method public android.view.MenuItem! getItem(int);
+    method public boolean hasVisibleItems();
+    method public boolean isShortcutKey(int, android.view.KeyEvent!);
+    method public boolean performIdentifierAction(int, int);
+    method public boolean performShortcut(int, android.view.KeyEvent!, int);
+    method public void removeGroup(int);
+    method public void removeItem(int);
+    method public void setGroupCheckable(int, boolean, boolean);
+    method public void setGroupEnabled(int, boolean);
+    method public void setGroupVisible(int, boolean);
+    method public void setQwertyMode(boolean);
+    method public int size();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface ShowableListMenu {
+    method public void dismiss();
+    method public android.widget.ListView! getListView();
+    method public boolean isShowing();
+    method public void show();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class SubMenuBuilder extends androidx.appcompat.view.menu.MenuBuilder implements android.view.SubMenu {
+    ctor public SubMenuBuilder(android.content.Context!, androidx.appcompat.view.menu.MenuBuilder!, androidx.appcompat.view.menu.MenuItemImpl!);
+    method public String! getActionViewStatesKey();
+    method public android.view.MenuItem! getItem();
+    method public android.view.Menu! getParentMenu();
+    method public boolean isQwertyMode();
+    method public android.view.SubMenu! setHeaderIcon(android.graphics.drawable.Drawable!);
+    method public android.view.SubMenu! setHeaderIcon(int);
+    method public android.view.SubMenu! setHeaderTitle(CharSequence!);
+    method public android.view.SubMenu! setHeaderTitle(int);
+    method public android.view.SubMenu! setHeaderView(android.view.View!);
+    method public android.view.SubMenu! setIcon(android.graphics.drawable.Drawable!);
+    method public android.view.SubMenu! setIcon(int);
+  }
+
+}
+
+package androidx.appcompat.widget {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ActionBarContainer extends android.widget.FrameLayout {
+    ctor public ActionBarContainer(android.content.Context!);
+    ctor public ActionBarContainer(android.content.Context!, android.util.AttributeSet!);
+    method public android.view.View! getTabContainer();
+    method public void onFinishInflate();
+    method public void onLayout(boolean, int, int, int, int);
+    method public void onMeasure(int, int);
+    method public void setPrimaryBackground(android.graphics.drawable.Drawable!);
+    method public void setSplitBackground(android.graphics.drawable.Drawable!);
+    method public void setStackedBackground(android.graphics.drawable.Drawable!);
+    method public void setTabContainer(androidx.appcompat.widget.ScrollingTabContainerView!);
+    method public void setTransitioning(boolean);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ActionBarContextView extends android.view.ViewGroup {
+    ctor public ActionBarContextView(android.content.Context);
+    ctor public ActionBarContextView(android.content.Context, android.util.AttributeSet?);
+    ctor public ActionBarContextView(android.content.Context, android.util.AttributeSet?, int);
+    method public void animateToVisibility(int);
+    method public boolean canShowOverflowMenu();
+    method public void closeMode();
+    method public void dismissPopupMenus();
+    method public int getAnimatedVisibility();
+    method public int getContentHeight();
+    method public CharSequence! getSubtitle();
+    method public CharSequence! getTitle();
+    method public boolean hideOverflowMenu();
+    method public void initForMode(androidx.appcompat.view.ActionMode!);
+    method public boolean isOverflowMenuShowPending();
+    method public boolean isOverflowMenuShowing();
+    method public boolean isOverflowReserved();
+    method public boolean isTitleOptional();
+    method public void killMode();
+    method public void onDetachedFromWindow();
+    method public void postShowOverflowMenu();
+    method public void setContentHeight(int);
+    method public void setCustomView(android.view.View!);
+    method public void setSubtitle(CharSequence!);
+    method public void setTitle(CharSequence!);
+    method public void setTitleOptional(boolean);
+    method public androidx.core.view.ViewPropertyAnimatorCompat! setupAnimatorToVisibility(int, long);
+    method public boolean showOverflowMenu();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ActionBarOverlayLayout extends android.view.ViewGroup implements androidx.appcompat.widget.DecorContentParent androidx.core.view.NestedScrollingParent androidx.core.view.NestedScrollingParent2 androidx.core.view.NestedScrollingParent3 {
+    ctor public ActionBarOverlayLayout(android.content.Context);
+    ctor public ActionBarOverlayLayout(android.content.Context, android.util.AttributeSet?);
+    method public boolean canShowOverflowMenu();
+    method public void dismissPopups();
+    method protected boolean fitSystemWindows(android.graphics.Rect!);
+    method protected androidx.appcompat.widget.ActionBarOverlayLayout.LayoutParams! generateDefaultLayoutParams();
+    method public androidx.appcompat.widget.ActionBarOverlayLayout.LayoutParams! generateLayoutParams(android.util.AttributeSet!);
+    method public int getActionBarHideOffset();
+    method public CharSequence! getTitle();
+    method public boolean hasIcon();
+    method public boolean hasLogo();
+    method public boolean hideOverflowMenu();
+    method public void initFeature(int);
+    method public boolean isHideOnContentScrollEnabled();
+    method public boolean isInOverlayMode();
+    method public boolean isOverflowMenuShowPending();
+    method public boolean isOverflowMenuShowing();
+    method public void onNestedPreScroll(android.view.View!, int, int, int[]!, int);
+    method public void onNestedScroll(android.view.View!, int, int, int, int, int, int[]!);
+    method public void onNestedScroll(android.view.View!, int, int, int, int, int);
+    method public void onNestedScrollAccepted(android.view.View!, android.view.View!, int, int);
+    method public boolean onStartNestedScroll(android.view.View!, android.view.View!, int, int);
+    method public void onStopNestedScroll(android.view.View!, int);
+    method public void restoreToolbarHierarchyState(android.util.SparseArray<android.os.Parcelable!>!);
+    method public void saveToolbarHierarchyState(android.util.SparseArray<android.os.Parcelable!>!);
+    method public void setActionBarHideOffset(int);
+    method public void setActionBarVisibilityCallback(androidx.appcompat.widget.ActionBarOverlayLayout.ActionBarVisibilityCallback!);
+    method public void setHasNonEmbeddedTabs(boolean);
+    method public void setHideOnContentScrollEnabled(boolean);
+    method public void setIcon(int);
+    method public void setIcon(android.graphics.drawable.Drawable!);
+    method public void setLogo(int);
+    method public void setMenu(android.view.Menu!, androidx.appcompat.view.menu.MenuPresenter.Callback!);
+    method public void setMenuPrepared();
+    method public void setOverlayMode(boolean);
+    method public void setShowingForActionMode(boolean);
+    method public void setUiOptions(int);
+    method public void setWindowCallback(android.view.Window.Callback!);
+    method public void setWindowTitle(CharSequence!);
+    method public boolean showOverflowMenu();
+  }
+
+  public static interface ActionBarOverlayLayout.ActionBarVisibilityCallback {
+    method public void enableContentAnimations(boolean);
+    method public void hideForSystem();
+    method public void onContentScrollStarted();
+    method public void onContentScrollStopped();
+    method public void onWindowVisibilityChanged(int);
+    method public void showForSystem();
+  }
+
+  public static class ActionBarOverlayLayout.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+    ctor public ActionBarOverlayLayout.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public ActionBarOverlayLayout.LayoutParams(int, int);
+    ctor public ActionBarOverlayLayout.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public ActionBarOverlayLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+  }
+
+  public class ActionMenuView extends androidx.appcompat.widget.LinearLayoutCompat implements androidx.appcompat.view.menu.MenuBuilder.ItemInvoker androidx.appcompat.view.menu.MenuView {
+    ctor public ActionMenuView(android.content.Context);
+    ctor public ActionMenuView(android.content.Context, android.util.AttributeSet?);
+    method public void dismissPopupMenus();
+    method protected androidx.appcompat.widget.ActionMenuView.LayoutParams! generateDefaultLayoutParams();
+    method public androidx.appcompat.widget.ActionMenuView.LayoutParams! generateLayoutParams(android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.ActionMenuView.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.appcompat.widget.ActionMenuView.LayoutParams! generateOverflowButtonLayoutParams();
+    method public android.view.Menu! getMenu();
+    method public android.graphics.drawable.Drawable? getOverflowIcon();
+    method public int getPopupTheme();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int getWindowAnimations();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) protected boolean hasSupportDividerBeforeChildAt(int);
+    method public boolean hideOverflowMenu();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void initialize(androidx.appcompat.view.menu.MenuBuilder!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean invokeItem(androidx.appcompat.view.menu.MenuItemImpl!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean isOverflowMenuShowPending();
+    method public boolean isOverflowMenuShowing();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean isOverflowReserved();
+    method public void onConfigurationChanged(android.content.res.Configuration!);
+    method public void onDetachedFromWindow();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.appcompat.view.menu.MenuBuilder! peekMenu();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setExpandedActionViewsExclusive(boolean);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setMenuCallbacks(androidx.appcompat.view.menu.MenuPresenter.Callback!, androidx.appcompat.view.menu.MenuBuilder.Callback!);
+    method public void setOnMenuItemClickListener(androidx.appcompat.widget.ActionMenuView.OnMenuItemClickListener!);
+    method public void setOverflowIcon(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setOverflowReserved(boolean);
+    method public void setPopupTheme(@StyleRes int);
+    method public boolean showOverflowMenu();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static interface ActionMenuView.ActionMenuChildView {
+    method public boolean needsDividerAfter();
+    method public boolean needsDividerBefore();
+  }
+
+  public static class ActionMenuView.LayoutParams extends androidx.appcompat.widget.LinearLayoutCompat.LayoutParams {
+    ctor public ActionMenuView.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public ActionMenuView.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public ActionMenuView.LayoutParams(androidx.appcompat.widget.ActionMenuView.LayoutParams!);
+    ctor public ActionMenuView.LayoutParams(int, int);
+    field public int cellsUsed;
+    field public boolean expandable;
+    field public int extraPixels;
+    field public boolean isOverflowButton;
+    field public boolean preventEdgeOffset;
+  }
+
+  public static interface ActionMenuView.OnMenuItemClickListener {
+    method public boolean onMenuItemClick(android.view.MenuItem!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ActivityChooserView extends android.view.ViewGroup {
+    ctor public ActivityChooserView(android.content.Context);
+    ctor public ActivityChooserView(android.content.Context, android.util.AttributeSet?);
+    ctor public ActivityChooserView(android.content.Context, android.util.AttributeSet?, int);
+    method public boolean dismissPopup();
+    method public boolean isShowingPopup();
+    method public void setDefaultActionButtonContentDescription(int);
+    method public void setExpandActivityOverflowButtonContentDescription(int);
+    method public void setExpandActivityOverflowButtonDrawable(android.graphics.drawable.Drawable!);
+    method public void setInitialActivityCount(int);
+    method public void setOnDismissListener(android.widget.PopupWindow.OnDismissListener!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setProvider(androidx.core.view.ActionProvider!);
+    method public boolean showPopup();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static class ActivityChooserView.InnerLayout extends android.widget.LinearLayout {
+    ctor public ActivityChooserView.InnerLayout(android.content.Context!, android.util.AttributeSet!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class AlertDialogLayout extends androidx.appcompat.widget.LinearLayoutCompat {
+    ctor public AlertDialogLayout(android.content.Context?);
+    ctor public AlertDialogLayout(android.content.Context?, android.util.AttributeSet?);
+  }
+
+  public class AppCompatAutoCompleteTextView extends android.widget.AutoCompleteTextView implements androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatAutoCompleteTextView(android.content.Context);
+    ctor public AppCompatAutoCompleteTextView(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatAutoCompleteTextView(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTextAppearance(android.content.Context!, int);
+  }
+
+  public class AppCompatButton extends android.widget.Button implements androidx.core.widget.AutoSizeableTextView androidx.core.view.TintableBackgroundView androidx.core.widget.TintableCompoundDrawablesView {
+    ctor public AppCompatButton(android.content.Context);
+    ctor public AppCompatButton(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatButton(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportCompoundDrawablesTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportCompoundDrawablesTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setAutoSizeTextTypeUniformWithConfiguration(int, int, int, int) throws java.lang.IllegalArgumentException;
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setAutoSizeTextTypeUniformWithPresetSizes(int[], int) throws java.lang.IllegalArgumentException;
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method public void setSupportAllCaps(boolean);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportCompoundDrawablesTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportCompoundDrawablesTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTextAppearance(android.content.Context!, int);
+  }
+
+  public class AppCompatCheckBox extends android.widget.CheckBox implements androidx.core.view.TintableBackgroundView androidx.core.widget.TintableCompoundButton {
+    ctor public AppCompatCheckBox(android.content.Context);
+    ctor public AppCompatCheckBox(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatCheckBox(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportButtonTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportButtonTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportButtonTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public class AppCompatCheckedTextView extends android.widget.CheckedTextView {
+    ctor public AppCompatCheckedTextView(android.content.Context);
+    ctor public AppCompatCheckedTextView(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatCheckedTextView(android.content.Context, android.util.AttributeSet?, int);
+    method public void setTextAppearance(android.content.Context!, int);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class AppCompatDrawableManager {
+    ctor public AppCompatDrawableManager();
+    method public static androidx.appcompat.widget.AppCompatDrawableManager! get();
+    method public android.graphics.drawable.Drawable! getDrawable(android.content.Context, @DrawableRes int);
+    method public static android.graphics.PorterDuffColorFilter! getPorterDuffColorFilter(int, android.graphics.PorterDuff.Mode!);
+    method public void onConfigurationChanged(android.content.Context);
+    method public static void preload();
+  }
+
+  public class AppCompatEditText extends android.widget.EditText implements androidx.core.view.OnReceiveContentViewBehavior androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatEditText(android.content.Context);
+    ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public androidx.core.view.ContentInfoCompat? onReceiveContent(androidx.core.view.ContentInfoCompat);
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTextAppearance(android.content.Context!, int);
+  }
+
+  public class AppCompatImageButton extends android.widget.ImageButton implements androidx.core.view.TintableBackgroundView androidx.core.widget.TintableImageSourceView {
+    ctor public AppCompatImageButton(android.content.Context);
+    ctor public AppCompatImageButton(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatImageButton(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportImageTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportImageTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportImageTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportImageTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class AppCompatImageHelper {
+    ctor public AppCompatImageHelper(android.widget.ImageView);
+    method public void loadFromAttributes(android.util.AttributeSet!, int);
+    method public void setImageResource(int);
+  }
+
+  public class AppCompatImageView extends android.widget.ImageView implements androidx.core.view.TintableBackgroundView androidx.core.widget.TintableImageSourceView {
+    ctor public AppCompatImageView(android.content.Context);
+    ctor public AppCompatImageView(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatImageView(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportImageTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportImageTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportImageTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportImageTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public class AppCompatMultiAutoCompleteTextView extends android.widget.MultiAutoCompleteTextView implements androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatMultiAutoCompleteTextView(android.content.Context);
+    ctor public AppCompatMultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatMultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTextAppearance(android.content.Context!, int);
+  }
+
+  public class AppCompatRadioButton extends android.widget.RadioButton implements androidx.core.view.TintableBackgroundView androidx.core.widget.TintableCompoundButton {
+    ctor public AppCompatRadioButton(android.content.Context!);
+    ctor public AppCompatRadioButton(android.content.Context!, android.util.AttributeSet?);
+    ctor public AppCompatRadioButton(android.content.Context!, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportButtonTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportButtonTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportButtonTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public class AppCompatRatingBar extends android.widget.RatingBar {
+    ctor public AppCompatRatingBar(android.content.Context);
+    ctor public AppCompatRatingBar(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatRatingBar(android.content.Context, android.util.AttributeSet?, int);
+  }
+
+  public class AppCompatSeekBar extends android.widget.SeekBar {
+    ctor public AppCompatSeekBar(android.content.Context);
+    ctor public AppCompatSeekBar(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatSeekBar(android.content.Context, android.util.AttributeSet?, int);
+  }
+
+  public class AppCompatSpinner extends android.widget.Spinner implements androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatSpinner(android.content.Context);
+    ctor public AppCompatSpinner(android.content.Context, int);
+    ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet?, int);
+    ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet?, int, int);
+    ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet?, int, int, android.content.res.Resources.Theme!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public class AppCompatTextView extends android.widget.TextView implements androidx.core.widget.AutoSizeableTextView androidx.core.view.TintableBackgroundView androidx.core.widget.TintableCompoundDrawablesView {
+    ctor public AppCompatTextView(android.content.Context);
+    ctor public AppCompatTextView(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatTextView(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportCompoundDrawablesTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportCompoundDrawablesTintMode();
+    method public androidx.core.text.PrecomputedTextCompat.Params getTextMetricsParamsCompat();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setAutoSizeTextTypeUniformWithConfiguration(int, int, int, int) throws java.lang.IllegalArgumentException;
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setAutoSizeTextTypeUniformWithPresetSizes(int[], int) throws java.lang.IllegalArgumentException;
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method public void setPrecomputedText(androidx.core.text.PrecomputedTextCompat);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportCompoundDrawablesTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportCompoundDrawablesTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTextAppearance(android.content.Context!, int);
+    method public void setTextFuture(java.util.concurrent.Future<androidx.core.text.PrecomputedTextCompat!>?);
+    method public void setTextMetricsParamsCompat(androidx.core.text.PrecomputedTextCompat.Params);
+  }
+
+  public class AppCompatToggleButton extends android.widget.ToggleButton implements androidx.core.view.TintableBackgroundView {
+    ctor public AppCompatToggleButton(android.content.Context);
+    ctor public AppCompatToggleButton(android.content.Context, android.util.AttributeSet?);
+    ctor public AppCompatToggleButton(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ButtonBarLayout extends android.widget.LinearLayout {
+    ctor public ButtonBarLayout(android.content.Context, android.util.AttributeSet?);
+    method public void setAllowStacking(boolean);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface DecorContentParent {
+    method public boolean canShowOverflowMenu();
+    method public void dismissPopups();
+    method public CharSequence! getTitle();
+    method public boolean hasIcon();
+    method public boolean hasLogo();
+    method public boolean hideOverflowMenu();
+    method public void initFeature(int);
+    method public boolean isOverflowMenuShowPending();
+    method public boolean isOverflowMenuShowing();
+    method public void restoreToolbarHierarchyState(android.util.SparseArray<android.os.Parcelable!>!);
+    method public void saveToolbarHierarchyState(android.util.SparseArray<android.os.Parcelable!>!);
+    method public void setIcon(int);
+    method public void setIcon(android.graphics.drawable.Drawable!);
+    method public void setLogo(int);
+    method public void setMenu(android.view.Menu!, androidx.appcompat.view.menu.MenuPresenter.Callback!);
+    method public void setMenuPrepared();
+    method public void setUiOptions(int);
+    method public void setWindowCallback(android.view.Window.Callback!);
+    method public void setWindowTitle(CharSequence!);
+    method public boolean showOverflowMenu();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface DecorToolbar {
+    method public void animateToVisibility(int);
+    method public boolean canShowOverflowMenu();
+    method public void collapseActionView();
+    method public void dismissPopupMenus();
+    method public android.content.Context! getContext();
+    method public android.view.View! getCustomView();
+    method public int getDisplayOptions();
+    method public int getDropdownItemCount();
+    method public int getDropdownSelectedPosition();
+    method public int getHeight();
+    method public android.view.Menu! getMenu();
+    method public int getNavigationMode();
+    method public CharSequence! getSubtitle();
+    method public CharSequence! getTitle();
+    method public android.view.ViewGroup! getViewGroup();
+    method public int getVisibility();
+    method public boolean hasEmbeddedTabs();
+    method public boolean hasExpandedActionView();
+    method public boolean hasIcon();
+    method public boolean hasLogo();
+    method public boolean hideOverflowMenu();
+    method public void initIndeterminateProgress();
+    method public void initProgress();
+    method public boolean isOverflowMenuShowPending();
+    method public boolean isOverflowMenuShowing();
+    method public boolean isTitleTruncated();
+    method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable!>!);
+    method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable!>!);
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable!);
+    method public void setCollapsible(boolean);
+    method public void setCustomView(android.view.View!);
+    method public void setDefaultNavigationContentDescription(int);
+    method public void setDefaultNavigationIcon(android.graphics.drawable.Drawable!);
+    method public void setDisplayOptions(int);
+    method public void setDropdownParams(android.widget.SpinnerAdapter!, android.widget.AdapterView.OnItemSelectedListener!);
+    method public void setDropdownSelectedPosition(int);
+    method public void setEmbeddedTabView(androidx.appcompat.widget.ScrollingTabContainerView!);
+    method public void setHomeButtonEnabled(boolean);
+    method public void setIcon(int);
+    method public void setIcon(android.graphics.drawable.Drawable!);
+    method public void setLogo(int);
+    method public void setLogo(android.graphics.drawable.Drawable!);
+    method public void setMenu(android.view.Menu!, androidx.appcompat.view.menu.MenuPresenter.Callback!);
+    method public void setMenuCallbacks(androidx.appcompat.view.menu.MenuPresenter.Callback!, androidx.appcompat.view.menu.MenuBuilder.Callback!);
+    method public void setMenuPrepared();
+    method public void setNavigationContentDescription(CharSequence!);
+    method public void setNavigationContentDescription(int);
+    method public void setNavigationIcon(android.graphics.drawable.Drawable!);
+    method public void setNavigationIcon(int);
+    method public void setNavigationMode(int);
+    method public void setSubtitle(CharSequence!);
+    method public void setTitle(CharSequence!);
+    method public void setVisibility(int);
+    method public void setWindowCallback(android.view.Window.Callback!);
+    method public void setWindowTitle(CharSequence!);
+    method public androidx.core.view.ViewPropertyAnimatorCompat! setupAnimatorToVisibility(int, long);
+    method public boolean showOverflowMenu();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class DialogTitle extends androidx.appcompat.widget.AppCompatTextView {
+    ctor public DialogTitle(android.content.Context, android.util.AttributeSet?, int);
+    ctor public DialogTitle(android.content.Context, android.util.AttributeSet?);
+    ctor public DialogTitle(android.content.Context);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class FitWindowsFrameLayout extends android.widget.FrameLayout implements androidx.appcompat.widget.FitWindowsViewGroup {
+    ctor public FitWindowsFrameLayout(android.content.Context);
+    ctor public FitWindowsFrameLayout(android.content.Context, android.util.AttributeSet?);
+    method protected boolean fitSystemWindows(android.graphics.Rect!);
+    method public void setOnFitSystemWindowsListener(androidx.appcompat.widget.FitWindowsViewGroup.OnFitSystemWindowsListener!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class FitWindowsLinearLayout extends android.widget.LinearLayout implements androidx.appcompat.widget.FitWindowsViewGroup {
+    ctor public FitWindowsLinearLayout(android.content.Context);
+    ctor public FitWindowsLinearLayout(android.content.Context, android.util.AttributeSet?);
+    method protected boolean fitSystemWindows(android.graphics.Rect!);
+    method public void setOnFitSystemWindowsListener(androidx.appcompat.widget.FitWindowsViewGroup.OnFitSystemWindowsListener!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface FitWindowsViewGroup {
+    method public void setOnFitSystemWindowsListener(androidx.appcompat.widget.FitWindowsViewGroup.OnFitSystemWindowsListener!);
+  }
+
+  public static interface FitWindowsViewGroup.OnFitSystemWindowsListener {
+    method public void onFitSystemWindows(android.graphics.Rect!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class ForwardingListener implements android.view.View.OnAttachStateChangeListener android.view.View.OnTouchListener {
+    ctor public ForwardingListener(android.view.View!);
+    method public abstract androidx.appcompat.view.menu.ShowableListMenu! getPopup();
+    method protected boolean onForwardingStarted();
+    method protected boolean onForwardingStopped();
+    method public boolean onTouch(android.view.View!, android.view.MotionEvent!);
+    method public void onViewAttachedToWindow(android.view.View!);
+    method public void onViewDetachedFromWindow(android.view.View!);
+  }
+
+  public class LinearLayoutCompat extends android.view.ViewGroup {
+    ctor public LinearLayoutCompat(android.content.Context);
+    ctor public LinearLayoutCompat(android.content.Context, android.util.AttributeSet?);
+    ctor public LinearLayoutCompat(android.content.Context, android.util.AttributeSet?, int);
+    method protected androidx.appcompat.widget.LinearLayoutCompat.LayoutParams! generateDefaultLayoutParams();
+    method public androidx.appcompat.widget.LinearLayoutCompat.LayoutParams! generateLayoutParams(android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.LinearLayoutCompat.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+    method public int getBaselineAlignedChildIndex();
+    method public android.graphics.drawable.Drawable! getDividerDrawable();
+    method public int getDividerPadding();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int getDividerWidth();
+    method public int getGravity();
+    method @androidx.appcompat.widget.LinearLayoutCompat.OrientationMode public int getOrientation();
+    method @androidx.appcompat.widget.LinearLayoutCompat.DividerMode public int getShowDividers();
+    method public float getWeightSum();
+    method public boolean isBaselineAligned();
+    method public boolean isMeasureWithLargestChildEnabled();
+    method public void setBaselineAligned(boolean);
+    method public void setBaselineAlignedChildIndex(int);
+    method public void setDividerDrawable(android.graphics.drawable.Drawable!);
+    method public void setDividerPadding(int);
+    method public void setGravity(int);
+    method public void setHorizontalGravity(int);
+    method public void setMeasureWithLargestChildEnabled(boolean);
+    method public void setOrientation(@androidx.appcompat.widget.LinearLayoutCompat.OrientationMode int);
+    method public void setShowDividers(@androidx.appcompat.widget.LinearLayoutCompat.DividerMode int);
+    method public void setVerticalGravity(int);
+    method public void setWeightSum(float);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int SHOW_DIVIDER_BEGINNING = 1; // 0x1
+    field public static final int SHOW_DIVIDER_END = 4; // 0x4
+    field public static final int SHOW_DIVIDER_MIDDLE = 2; // 0x2
+    field public static final int SHOW_DIVIDER_NONE = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  @IntDef(flag=true, value={androidx.appcompat.widget.LinearLayoutCompat.SHOW_DIVIDER_NONE, androidx.appcompat.widget.LinearLayoutCompat.SHOW_DIVIDER_BEGINNING, androidx.appcompat.widget.LinearLayoutCompat.SHOW_DIVIDER_MIDDLE, androidx.appcompat.widget.LinearLayoutCompat.SHOW_DIVIDER_END}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface LinearLayoutCompat.DividerMode {
+  }
+
+  public static class LinearLayoutCompat.LayoutParams extends android.widget.LinearLayout.LayoutParams {
+    ctor public LinearLayoutCompat.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public LinearLayoutCompat.LayoutParams(int, int);
+    ctor public LinearLayoutCompat.LayoutParams(int, int, float);
+    ctor public LinearLayoutCompat.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public LinearLayoutCompat.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+  }
+
+  @IntDef({androidx.appcompat.widget.LinearLayoutCompat.HORIZONTAL, androidx.appcompat.widget.LinearLayoutCompat.VERTICAL}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface LinearLayoutCompat.OrientationMode {
+  }
+
+  public class ListPopupWindow implements androidx.appcompat.view.menu.ShowableListMenu {
+    ctor public ListPopupWindow(android.content.Context);
+    ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet?);
+    ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet?, @AttrRes int);
+    ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet?, @AttrRes int, @StyleRes int);
+    method public void clearListSelection();
+    method public android.view.View.OnTouchListener! createDragToOpenListener(android.view.View!);
+    method public void dismiss();
+    method public android.view.View? getAnchorView();
+    method @StyleRes public int getAnimationStyle();
+    method public android.graphics.drawable.Drawable? getBackground();
+    method public android.graphics.Rect? getEpicenterBounds();
+    method public int getHeight();
+    method public int getHorizontalOffset();
+    method public int getInputMethodMode();
+    method public android.widget.ListView? getListView();
+    method public int getPromptPosition();
+    method public Object? getSelectedItem();
+    method public long getSelectedItemId();
+    method public int getSelectedItemPosition();
+    method public android.view.View? getSelectedView();
+    method public int getSoftInputMode();
+    method public int getVerticalOffset();
+    method public int getWidth();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean isDropDownAlwaysVisible();
+    method public boolean isInputMethodNotNeeded();
+    method public boolean isModal();
+    method public boolean isShowing();
+    method public boolean onKeyDown(int, android.view.KeyEvent);
+    method public boolean onKeyPreIme(int, android.view.KeyEvent);
+    method public boolean onKeyUp(int, android.view.KeyEvent);
+    method public boolean performItemClick(int);
+    method public void postShow();
+    method public void setAdapter(android.widget.ListAdapter?);
+    method public void setAnchorView(android.view.View?);
+    method public void setAnimationStyle(@StyleRes int);
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable?);
+    method public void setContentWidth(int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setDropDownAlwaysVisible(boolean);
+    method public void setDropDownGravity(int);
+    method public void setEpicenterBounds(android.graphics.Rect?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setForceIgnoreOutsideTouch(boolean);
+    method public void setHeight(int);
+    method public void setHorizontalOffset(int);
+    method public void setInputMethodMode(int);
+    method public void setListSelector(android.graphics.drawable.Drawable!);
+    method public void setModal(boolean);
+    method public void setOnDismissListener(android.widget.PopupWindow.OnDismissListener?);
+    method public void setOnItemClickListener(android.widget.AdapterView.OnItemClickListener?);
+    method public void setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setOverlapAnchor(boolean);
+    method public void setPromptPosition(int);
+    method public void setPromptView(android.view.View?);
+    method public void setSelection(int);
+    method public void setSoftInputMode(int);
+    method public void setVerticalOffset(int);
+    method public void setWidth(int);
+    method public void setWindowLayoutType(int);
+    method public void show();
+    field public static final int INPUT_METHOD_FROM_FOCUSABLE = 0; // 0x0
+    field public static final int INPUT_METHOD_NEEDED = 1; // 0x1
+    field public static final int INPUT_METHOD_NOT_NEEDED = 2; // 0x2
+    field public static final int MATCH_PARENT = -1; // 0xffffffff
+    field public static final int POSITION_PROMPT_ABOVE = 0; // 0x0
+    field public static final int POSITION_PROMPT_BELOW = 1; // 0x1
+    field public static final int WRAP_CONTENT = -2; // 0xfffffffe
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface MenuItemHoverListener {
+    method public void onItemHoverEnter(androidx.appcompat.view.menu.MenuBuilder, android.view.MenuItem);
+    method public void onItemHoverExit(androidx.appcompat.view.menu.MenuBuilder, android.view.MenuItem);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class MenuPopupWindow extends androidx.appcompat.widget.ListPopupWindow implements androidx.appcompat.widget.MenuItemHoverListener {
+    ctor public MenuPopupWindow(android.content.Context, android.util.AttributeSet?, int, int);
+    method public void onItemHoverEnter(androidx.appcompat.view.menu.MenuBuilder, android.view.MenuItem);
+    method public void onItemHoverExit(androidx.appcompat.view.menu.MenuBuilder, android.view.MenuItem);
+    method public void setEnterTransition(Object!);
+    method public void setExitTransition(Object!);
+    method public void setHoverListener(androidx.appcompat.widget.MenuItemHoverListener!);
+    method public void setTouchModal(boolean);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static class MenuPopupWindow.MenuDropDownListView extends android.widget.ListView {
+    ctor public MenuPopupWindow.MenuDropDownListView(android.content.Context!, boolean);
+    method public void clearSelection();
+    method public int lookForSelectablePosition(int, boolean);
+    method public int measureHeightOfChildrenCompat(int, int, int, int, int);
+    method public boolean onForwardedEvent(android.view.MotionEvent!, int);
+    method public void setHoverListener(androidx.appcompat.widget.MenuItemHoverListener!);
+    field public static final int INVALID_POSITION = -1; // 0xffffffff
+    field public static final int NO_POSITION = -1; // 0xffffffff
+  }
+
+  public class PopupMenu {
+    ctor public PopupMenu(android.content.Context, android.view.View);
+    ctor public PopupMenu(android.content.Context, android.view.View, int);
+    ctor public PopupMenu(android.content.Context, android.view.View, int, @AttrRes int, @StyleRes int);
+    method public void dismiss();
+    method public android.view.View.OnTouchListener getDragToOpenListener();
+    method public int getGravity();
+    method public android.view.Menu getMenu();
+    method public android.view.MenuInflater getMenuInflater();
+    method public void inflate(@MenuRes int);
+    method public void setGravity(int);
+    method public void setOnDismissListener(androidx.appcompat.widget.PopupMenu.OnDismissListener?);
+    method public void setOnMenuItemClickListener(androidx.appcompat.widget.PopupMenu.OnMenuItemClickListener?);
+    method public void show();
+  }
+
+  public static interface PopupMenu.OnDismissListener {
+    method public void onDismiss(androidx.appcompat.widget.PopupMenu!);
+  }
+
+  public static interface PopupMenu.OnMenuItemClickListener {
+    method public boolean onMenuItemClick(android.view.MenuItem!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ScrollingTabContainerView extends android.widget.HorizontalScrollView implements android.widget.AdapterView.OnItemSelectedListener {
+    ctor public ScrollingTabContainerView(android.content.Context);
+    method public void addTab(androidx.appcompat.app.ActionBar.Tab!, boolean);
+    method public void addTab(androidx.appcompat.app.ActionBar.Tab!, int, boolean);
+    method public void animateToTab(int);
+    method public void animateToVisibility(int);
+    method public void onAttachedToWindow();
+    method public void onDetachedFromWindow();
+    method public void onItemSelected(android.widget.AdapterView<?>!, android.view.View!, int, long);
+    method public void onMeasure(int, int);
+    method public void onNothingSelected(android.widget.AdapterView<?>!);
+    method public void removeAllTabs();
+    method public void removeTabAt(int);
+    method public void setAllowCollapse(boolean);
+    method public void setContentHeight(int);
+    method public void setTabSelected(int);
+    method public void updateTab(int);
+    field protected final androidx.appcompat.widget.ScrollingTabContainerView.VisibilityAnimListener! mVisAnimListener;
+    field protected android.view.ViewPropertyAnimator! mVisibilityAnim;
+  }
+
+  protected class ScrollingTabContainerView.VisibilityAnimListener extends android.animation.AnimatorListenerAdapter {
+    ctor protected ScrollingTabContainerView.VisibilityAnimListener();
+    method public androidx.appcompat.widget.ScrollingTabContainerView.VisibilityAnimListener! withFinalVisibility(android.view.ViewPropertyAnimator!, int);
+  }
+
+  public class SearchView extends androidx.appcompat.widget.LinearLayoutCompat implements androidx.appcompat.view.CollapsibleActionView {
+    ctor public SearchView(android.content.Context);
+    ctor public SearchView(android.content.Context, android.util.AttributeSet?);
+    ctor public SearchView(android.content.Context, android.util.AttributeSet?, int);
+    method public int getImeOptions();
+    method public int getInputType();
+    method public int getMaxWidth();
+    method public CharSequence! getQuery();
+    method public CharSequence? getQueryHint();
+    method public androidx.cursoradapter.widget.CursorAdapter! getSuggestionsAdapter();
+    method public boolean isIconfiedByDefault();
+    method public boolean isIconified();
+    method public boolean isQueryRefinementEnabled();
+    method public boolean isSubmitButtonEnabled();
+    method public void onActionViewCollapsed();
+    method public void onActionViewExpanded();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setAppSearchData(android.os.Bundle!);
+    method public void setIconified(boolean);
+    method public void setIconifiedByDefault(boolean);
+    method public void setImeOptions(int);
+    method public void setInputType(int);
+    method public void setMaxWidth(int);
+    method public void setOnCloseListener(androidx.appcompat.widget.SearchView.OnCloseListener!);
+    method public void setOnQueryTextFocusChangeListener(android.view.View.OnFocusChangeListener!);
+    method public void setOnQueryTextListener(androidx.appcompat.widget.SearchView.OnQueryTextListener!);
+    method public void setOnSearchClickListener(android.view.View.OnClickListener!);
+    method public void setOnSuggestionListener(androidx.appcompat.widget.SearchView.OnSuggestionListener!);
+    method public void setQuery(CharSequence!, boolean);
+    method public void setQueryHint(CharSequence?);
+    method public void setQueryRefinementEnabled(boolean);
+    method public void setSearchableInfo(android.app.SearchableInfo!);
+    method public void setSubmitButtonEnabled(boolean);
+    method public void setSuggestionsAdapter(androidx.cursoradapter.widget.CursorAdapter!);
+  }
+
+  public static interface SearchView.OnCloseListener {
+    method public boolean onClose();
+  }
+
+  public static interface SearchView.OnQueryTextListener {
+    method public boolean onQueryTextChange(String!);
+    method public boolean onQueryTextSubmit(String!);
+  }
+
+  public static interface SearchView.OnSuggestionListener {
+    method public boolean onSuggestionClick(int);
+    method public boolean onSuggestionSelect(int);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static class SearchView.SearchAutoComplete extends androidx.appcompat.widget.AppCompatAutoCompleteTextView {
+    ctor public SearchView.SearchAutoComplete(android.content.Context!);
+    ctor public SearchView.SearchAutoComplete(android.content.Context!, android.util.AttributeSet!);
+    ctor public SearchView.SearchAutoComplete(android.content.Context!, android.util.AttributeSet!, int);
+  }
+
+  public class ShareActionProvider extends androidx.core.view.ActionProvider {
+    ctor public ShareActionProvider(android.content.Context!);
+    method public android.view.View! onCreateActionView();
+    method public void setOnShareTargetSelectedListener(androidx.appcompat.widget.ShareActionProvider.OnShareTargetSelectedListener!);
+    method public void setShareHistoryFileName(String!);
+    method public void setShareIntent(android.content.Intent!);
+    field public static final String DEFAULT_SHARE_HISTORY_FILE_NAME = "share_history.xml";
+  }
+
+  public static interface ShareActionProvider.OnShareTargetSelectedListener {
+    method public boolean onShareTargetSelected(androidx.appcompat.widget.ShareActionProvider!, android.content.Intent!);
+  }
+
+  public class SwitchCompat extends android.widget.CompoundButton {
+    ctor public SwitchCompat(android.content.Context);
+    ctor public SwitchCompat(android.content.Context, android.util.AttributeSet?);
+    ctor public SwitchCompat(android.content.Context, android.util.AttributeSet?, int);
+    method public boolean getShowText();
+    method public boolean getSplitTrack();
+    method public int getSwitchMinWidth();
+    method public int getSwitchPadding();
+    method public CharSequence! getTextOff();
+    method public CharSequence! getTextOn();
+    method public android.graphics.drawable.Drawable! getThumbDrawable();
+    method public int getThumbTextPadding();
+    method public android.content.res.ColorStateList? getThumbTintList();
+    method public android.graphics.PorterDuff.Mode? getThumbTintMode();
+    method public android.graphics.drawable.Drawable! getTrackDrawable();
+    method public android.content.res.ColorStateList? getTrackTintList();
+    method public android.graphics.PorterDuff.Mode? getTrackTintMode();
+    method public void onMeasure(int, int);
+    method public void setShowText(boolean);
+    method public void setSplitTrack(boolean);
+    method public void setSwitchMinWidth(int);
+    method public void setSwitchPadding(int);
+    method public void setSwitchTextAppearance(android.content.Context!, int);
+    method public void setSwitchTypeface(android.graphics.Typeface!, int);
+    method public void setSwitchTypeface(android.graphics.Typeface!);
+    method public void setTextOff(CharSequence!);
+    method public void setTextOn(CharSequence!);
+    method public void setThumbDrawable(android.graphics.drawable.Drawable!);
+    method public void setThumbResource(int);
+    method public void setThumbTextPadding(int);
+    method public void setThumbTintList(android.content.res.ColorStateList?);
+    method public void setThumbTintMode(android.graphics.PorterDuff.Mode?);
+    method public void setTrackDrawable(android.graphics.drawable.Drawable!);
+    method public void setTrackResource(int);
+    method public void setTrackTintList(android.content.res.ColorStateList?);
+    method public void setTrackTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public interface ThemedSpinnerAdapter extends android.widget.SpinnerAdapter {
+    method public android.content.res.Resources.Theme? getDropDownViewTheme();
+    method public void setDropDownViewTheme(android.content.res.Resources.Theme?);
+  }
+
+  public static final class ThemedSpinnerAdapter.Helper {
+    ctor public ThemedSpinnerAdapter.Helper(android.content.Context);
+    method public android.view.LayoutInflater getDropDownViewInflater();
+    method public android.content.res.Resources.Theme? getDropDownViewTheme();
+    method public void setDropDownViewTheme(android.content.res.Resources.Theme?);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class TintTypedArray {
+    method public boolean getBoolean(int, boolean);
+    method @RequiresApi(21) public int getChangingConfigurations();
+    method public int getColor(int, int);
+    method public android.content.res.ColorStateList! getColorStateList(int);
+    method public float getDimension(int, float);
+    method public int getDimensionPixelOffset(int, int);
+    method public int getDimensionPixelSize(int, int);
+    method public android.graphics.drawable.Drawable! getDrawable(int);
+    method public android.graphics.drawable.Drawable! getDrawableIfKnown(int);
+    method public float getFloat(int, float);
+    method public android.graphics.Typeface? getFont(@StyleableRes int, int, androidx.core.content.res.ResourcesCompat.FontCallback?);
+    method public float getFraction(int, int, int, float);
+    method public int getIndex(int);
+    method public int getIndexCount();
+    method public int getInt(int, int);
+    method public int getInteger(int, int);
+    method public int getLayoutDimension(int, String!);
+    method public int getLayoutDimension(int, int);
+    method public String! getNonResourceString(int);
+    method public String! getPositionDescription();
+    method public int getResourceId(int, int);
+    method public android.content.res.Resources! getResources();
+    method public String! getString(int);
+    method public CharSequence! getText(int);
+    method public CharSequence![]! getTextArray(int);
+    method public int getType(int);
+    method public boolean getValue(int, android.util.TypedValue!);
+    method public android.content.res.TypedArray! getWrappedTypeArray();
+    method public boolean hasValue(int);
+    method public int length();
+    method public static androidx.appcompat.widget.TintTypedArray! obtainStyledAttributes(android.content.Context!, android.util.AttributeSet!, int[]!);
+    method public static androidx.appcompat.widget.TintTypedArray! obtainStyledAttributes(android.content.Context!, android.util.AttributeSet!, int[]!, int, int);
+    method public static androidx.appcompat.widget.TintTypedArray! obtainStyledAttributes(android.content.Context!, int, int[]!);
+    method public android.util.TypedValue! peekValue(int);
+    method public void recycle();
+  }
+
+  public class Toolbar extends android.view.ViewGroup {
+    ctor public Toolbar(android.content.Context);
+    ctor public Toolbar(android.content.Context, android.util.AttributeSet?);
+    ctor public Toolbar(android.content.Context, android.util.AttributeSet?, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean canShowOverflowMenu();
+    method public void collapseActionView();
+    method public void dismissPopupMenus();
+    method protected androidx.appcompat.widget.Toolbar.LayoutParams! generateDefaultLayoutParams();
+    method public androidx.appcompat.widget.Toolbar.LayoutParams! generateLayoutParams(android.util.AttributeSet!);
+    method protected androidx.appcompat.widget.Toolbar.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+    method public CharSequence? getCollapseContentDescription();
+    method public android.graphics.drawable.Drawable? getCollapseIcon();
+    method public int getContentInsetEnd();
+    method public int getContentInsetEndWithActions();
+    method public int getContentInsetLeft();
+    method public int getContentInsetRight();
+    method public int getContentInsetStart();
+    method public int getContentInsetStartWithNavigation();
+    method public int getCurrentContentInsetEnd();
+    method public int getCurrentContentInsetLeft();
+    method public int getCurrentContentInsetRight();
+    method public int getCurrentContentInsetStart();
+    method public android.graphics.drawable.Drawable! getLogo();
+    method public CharSequence! getLogoDescription();
+    method public android.view.Menu! getMenu();
+    method public CharSequence? getNavigationContentDescription();
+    method public android.graphics.drawable.Drawable? getNavigationIcon();
+    method public android.graphics.drawable.Drawable? getOverflowIcon();
+    method public int getPopupTheme();
+    method public CharSequence! getSubtitle();
+    method public CharSequence! getTitle();
+    method public int getTitleMarginBottom();
+    method public int getTitleMarginEnd();
+    method public int getTitleMarginStart();
+    method public int getTitleMarginTop();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.appcompat.widget.DecorToolbar! getWrapper();
+    method public boolean hasExpandedActionView();
+    method public boolean hideOverflowMenu();
+    method public void inflateMenu(@MenuRes int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean isOverflowMenuShowPending();
+    method public boolean isOverflowMenuShowing();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean isTitleTruncated();
+    method public void setCollapseContentDescription(@StringRes int);
+    method public void setCollapseContentDescription(CharSequence?);
+    method public void setCollapseIcon(@DrawableRes int);
+    method public void setCollapseIcon(android.graphics.drawable.Drawable?);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setCollapsible(boolean);
+    method public void setContentInsetEndWithActions(int);
+    method public void setContentInsetStartWithNavigation(int);
+    method public void setContentInsetsAbsolute(int, int);
+    method public void setContentInsetsRelative(int, int);
+    method public void setLogo(@DrawableRes int);
+    method public void setLogo(android.graphics.drawable.Drawable!);
+    method public void setLogoDescription(@StringRes int);
+    method public void setLogoDescription(CharSequence!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setMenuCallbacks(androidx.appcompat.view.menu.MenuPresenter.Callback!, androidx.appcompat.view.menu.MenuBuilder.Callback!);
+    method public void setNavigationContentDescription(@StringRes int);
+    method public void setNavigationContentDescription(CharSequence?);
+    method public void setNavigationIcon(@DrawableRes int);
+    method public void setNavigationIcon(android.graphics.drawable.Drawable?);
+    method public void setNavigationOnClickListener(android.view.View.OnClickListener!);
+    method public void setOnMenuItemClickListener(androidx.appcompat.widget.Toolbar.OnMenuItemClickListener!);
+    method public void setOverflowIcon(android.graphics.drawable.Drawable?);
+    method public void setPopupTheme(@StyleRes int);
+    method public void setSubtitle(@StringRes int);
+    method public void setSubtitle(CharSequence!);
+    method public void setSubtitleTextAppearance(android.content.Context!, @StyleRes int);
+    method public void setSubtitleTextColor(@ColorInt int);
+    method public void setSubtitleTextColor(android.content.res.ColorStateList);
+    method public void setTitle(@StringRes int);
+    method public void setTitle(CharSequence!);
+    method public void setTitleMargin(int, int, int, int);
+    method public void setTitleMarginBottom(int);
+    method public void setTitleMarginEnd(int);
+    method public void setTitleMarginStart(int);
+    method public void setTitleMarginTop(int);
+    method public void setTitleTextAppearance(android.content.Context!, @StyleRes int);
+    method public void setTitleTextColor(@ColorInt int);
+    method public void setTitleTextColor(android.content.res.ColorStateList);
+    method public boolean showOverflowMenu();
+  }
+
+  public static class Toolbar.LayoutParams extends androidx.appcompat.app.ActionBar.LayoutParams {
+    ctor public Toolbar.LayoutParams(android.content.Context, android.util.AttributeSet!);
+    ctor public Toolbar.LayoutParams(int, int);
+    ctor public Toolbar.LayoutParams(int, int, int);
+    ctor public Toolbar.LayoutParams(int);
+    ctor public Toolbar.LayoutParams(androidx.appcompat.widget.Toolbar.LayoutParams!);
+    ctor public Toolbar.LayoutParams(androidx.appcompat.app.ActionBar.LayoutParams!);
+    ctor public Toolbar.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public Toolbar.LayoutParams(android.view.ViewGroup.LayoutParams!);
+  }
+
+  public static interface Toolbar.OnMenuItemClickListener {
+    method public boolean onMenuItemClick(android.view.MenuItem!);
+  }
+
+  public static class Toolbar.SavedState extends androidx.customview.view.AbsSavedState {
+    ctor public Toolbar.SavedState(android.os.Parcel!);
+    ctor public Toolbar.SavedState(android.os.Parcel!, ClassLoader!);
+    ctor public Toolbar.SavedState(android.os.Parcelable!);
+    field public static final android.os.Parcelable.Creator<androidx.appcompat.widget.Toolbar.SavedState!>! CREATOR;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ToolbarWidgetWrapper implements androidx.appcompat.widget.DecorToolbar {
+    ctor public ToolbarWidgetWrapper(androidx.appcompat.widget.Toolbar!, boolean);
+    ctor public ToolbarWidgetWrapper(androidx.appcompat.widget.Toolbar!, boolean, int, int);
+    method public void animateToVisibility(int);
+    method public boolean canShowOverflowMenu();
+    method public void collapseActionView();
+    method public void dismissPopupMenus();
+    method public android.content.Context! getContext();
+    method public android.view.View! getCustomView();
+    method public int getDisplayOptions();
+    method public int getDropdownItemCount();
+    method public int getDropdownSelectedPosition();
+    method public int getHeight();
+    method public android.view.Menu! getMenu();
+    method public int getNavigationMode();
+    method public CharSequence! getSubtitle();
+    method public CharSequence! getTitle();
+    method public android.view.ViewGroup! getViewGroup();
+    method public int getVisibility();
+    method public boolean hasEmbeddedTabs();
+    method public boolean hasExpandedActionView();
+    method public boolean hasIcon();
+    method public boolean hasLogo();
+    method public boolean hideOverflowMenu();
+    method public void initIndeterminateProgress();
+    method public void initProgress();
+    method public boolean isOverflowMenuShowPending();
+    method public boolean isOverflowMenuShowing();
+    method public boolean isTitleTruncated();
+    method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable!>!);
+    method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable!>!);
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable!);
+    method public void setCollapsible(boolean);
+    method public void setCustomView(android.view.View!);
+    method public void setDefaultNavigationContentDescription(int);
+    method public void setDefaultNavigationIcon(android.graphics.drawable.Drawable!);
+    method public void setDisplayOptions(int);
+    method public void setDropdownParams(android.widget.SpinnerAdapter!, android.widget.AdapterView.OnItemSelectedListener!);
+    method public void setDropdownSelectedPosition(int);
+    method public void setEmbeddedTabView(androidx.appcompat.widget.ScrollingTabContainerView!);
+    method public void setHomeButtonEnabled(boolean);
+    method public void setIcon(int);
+    method public void setIcon(android.graphics.drawable.Drawable!);
+    method public void setLogo(int);
+    method public void setLogo(android.graphics.drawable.Drawable!);
+    method public void setMenu(android.view.Menu!, androidx.appcompat.view.menu.MenuPresenter.Callback!);
+    method public void setMenuCallbacks(androidx.appcompat.view.menu.MenuPresenter.Callback!, androidx.appcompat.view.menu.MenuBuilder.Callback!);
+    method public void setMenuPrepared();
+    method public void setNavigationContentDescription(CharSequence!);
+    method public void setNavigationContentDescription(int);
+    method public void setNavigationIcon(android.graphics.drawable.Drawable!);
+    method public void setNavigationIcon(int);
+    method public void setNavigationMode(int);
+    method public void setSubtitle(CharSequence!);
+    method public void setTitle(CharSequence!);
+    method public void setVisibility(int);
+    method public void setWindowCallback(android.view.Window.Callback!);
+    method public void setWindowTitle(CharSequence!);
+    method public androidx.core.view.ViewPropertyAnimatorCompat! setupAnimatorToVisibility(int, long);
+    method public boolean showOverflowMenu();
+  }
+
+  public class TooltipCompat {
+    method public static void setTooltipText(android.view.View, CharSequence?);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class ViewStubCompat extends android.view.View {
+    ctor public ViewStubCompat(android.content.Context, android.util.AttributeSet?);
+    ctor public ViewStubCompat(android.content.Context, android.util.AttributeSet?, int);
+    method public int getInflatedId();
+    method public android.view.LayoutInflater! getLayoutInflater();
+    method public int getLayoutResource();
+    method public android.view.View! inflate();
+    method public void setInflatedId(int);
+    method public void setLayoutInflater(android.view.LayoutInflater!);
+    method public void setLayoutResource(int);
+    method public void setOnInflateListener(androidx.appcompat.widget.ViewStubCompat.OnInflateListener!);
+  }
+
+  public static interface ViewStubCompat.OnInflateListener {
+    method public void onInflate(androidx.appcompat.widget.ViewStubCompat!, android.view.View!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ViewUtils {
+    method public static void computeFitSystemWindows(android.view.View!, android.graphics.Rect!, android.graphics.Rect!);
+    method public static boolean isLayoutRtl(android.view.View!);
+    method public static void makeOptionalFitsSystemWindows(android.view.View!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface WithHint {
+    method public CharSequence? getHint();
+  }
+
+}
+
diff --git a/appcompat/appcompat/build.gradle b/appcompat/appcompat/build.gradle
index 05e1d78..833d12e 100644
--- a/appcompat/appcompat/build.gradle
+++ b/appcompat/appcompat/build.gradle
@@ -15,8 +15,8 @@
     api(project(":core:core"))
     implementation("androidx.collection:collection:1.0.0")
     api("androidx.cursoradapter:cursoradapter:1.0.0")
-    api("androidx.activity:activity:1.2.0-rc01")
-    api("androidx.fragment:fragment:1.3.0-rc01")
+    api("androidx.activity:activity:1.2.0")
+    api("androidx.fragment:fragment:1.3.0")
     api(project(":appcompat:appcompat-resources"))
     api("androidx.drawerlayout:drawerlayout:1.0.0")
     implementation("androidx.lifecycle:lifecycle-runtime:2.3.0")
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/DropDownListView.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/DropDownListView.java
index ade4ed8..b06ba21 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/DropDownListView.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/DropDownListView.java
@@ -114,6 +114,7 @@
      *
      * @param context this view's context
      */
+    @SuppressWarnings("CatchAndPrintStackTrace")
     DropDownListView(@NonNull Context context, boolean hijackFocus) {
         super(context, null, R.attr.dropDownListViewStyle);
         mHijackFocus = hijackFocus;
@@ -598,6 +599,7 @@
         }
     }
 
+    @SuppressWarnings("CatchAndPrintStackTrace")
     private void positionSelectorCompat(int position, View sel) {
         final Rect selectorRect = mSelectorRect;
         selectorRect.set(sel.getLeft(), sel.getTop(), sel.getRight(), sel.getBottom());
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSchema.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSchema.java
index 11b587b..aad7c19 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSchema.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSchema.java
@@ -85,6 +85,7 @@
      * <p>This method creates a new list when called.
      */
     @NonNull
+    @SuppressWarnings("MixedMutabilityReturnType")
     public List<PropertyConfig> getProperties() {
         ArrayList<Bundle> propertyBundles =
                 mBundle.getParcelableArrayList(AppSearchSchema.PROPERTIES_FIELD);
diff --git a/benchmark/macro-junit4/src/androidTest/java/androidx/benchmark/macro/test/PerfettoRuleTest.kt b/benchmark/macro-junit4/src/androidTest/java/androidx/benchmark/macro/test/PerfettoRuleTest.kt
index 9ea9dd6..cb58a02 100644
--- a/benchmark/macro-junit4/src/androidTest/java/androidx/benchmark/macro/test/PerfettoRuleTest.kt
+++ b/benchmark/macro-junit4/src/androidTest/java/androidx/benchmark/macro/test/PerfettoRuleTest.kt
@@ -61,7 +61,7 @@
     verifyWithPolling(
         "Timeout waiting for Trace.isEnabled == $enabled",
         periodMs = 50,
-        timeoutMs = 500
+        timeoutMs = 5000
     ) {
         Trace.isEnabled() == enabled
     }
diff --git a/benchmark/macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureTest.kt b/benchmark/macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureTest.kt
index 1f24a66..8e6513c 100644
--- a/benchmark/macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureTest.kt
+++ b/benchmark/macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureTest.kt
@@ -72,7 +72,7 @@
     verifyWithPolling(
         "Timeout waiting for Trace.isEnabled == $enabled",
         periodMs = 50,
-        timeoutMs = 500
+        timeoutMs = 5000
     ) {
         Trace.isEnabled() == enabled
     }
diff --git a/benchmark/macro/src/main/java/androidx/benchmark/macro/perfetto/PerfettoTraceProcessor.kt b/benchmark/macro/src/main/java/androidx/benchmark/macro/perfetto/PerfettoTraceProcessor.kt
index 4b6c09e..0edf790 100644
--- a/benchmark/macro/src/main/java/androidx/benchmark/macro/perfetto/PerfettoTraceProcessor.kt
+++ b/benchmark/macro/src/main/java/androidx/benchmark/macro/perfetto/PerfettoTraceProcessor.kt
@@ -36,7 +36,8 @@
     @TestOnly
     fun isAbiSupported(): Boolean {
         Log.d(TAG, "Supported ABIs: ${Build.SUPPORTED_ABIS.joinToString()}")
-        return Build.SUPPORTED_64_BIT_ABIS.any { it == "arm64-v8a" }
+        return !Build.MODEL.contains("Cuttlefish") && // b/180022458
+            Build.SUPPORTED_64_BIT_ABIS.any { it == "arm64-v8a" }
     }
 
     /**
diff --git a/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt b/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
index 0fd843a..b123344 100644
--- a/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
@@ -267,6 +267,7 @@
         }
 
         project.extensions.getByType<LibraryAndroidComponentsExtension>().apply {
+            @Suppress("deprecation")
             beforeUnitTests(selector().withBuildType("release")) { unitTest ->
                 unitTest.enabled = false
             }
@@ -385,6 +386,7 @@
         }
 
         // Force AGP to use our version of JaCoCo
+        @Suppress("deprecation")
         jacoco.version = Jacoco.VERSION
         compileSdkVersion(COMPILE_SDK_VERSION)
         buildToolsVersion = BUILD_TOOLS_VERSION
diff --git a/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt b/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt
index 2d28169..afb2421 100644
--- a/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt
@@ -92,8 +92,6 @@
             "-Xep:RestrictTo:OFF",
 
             // Disable the following checks.
-            "-Xep:CatchAndPrintStackTrace:OFF",
-            "-Xep:MixedMutabilityReturnType:OFF",
             "-Xep:UnescapedEntity:OFF",
             "-Xep:MissingSummary:OFF",
             "-Xep:StaticAssignmentInConstructor:OFF",
@@ -162,6 +160,8 @@
             "-Xep:BadImport:ERROR",
             "-Xep:MissingCasesInEnumSwitch:ERROR",
             "-Xep:ObjectToString:ERROR",
+            "-Xep:CatchAndPrintStackTrace:ERROR",
+            "-Xep:MixedMutabilityReturnType:ERROR",
 
             // Nullaway
             "-XepIgnoreUnknownCheckNames", // https://github.com/uber/NullAway/issues/25
diff --git a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
index daa930d..1fa3da7 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
@@ -20,11 +20,11 @@
  * The list of versions codes of all the libraries in this project.
  */
 object LibraryVersions {
-    val ACTIVITY = Version("1.3.0-alpha02")
+    val ACTIVITY = Version("1.3.0-alpha03")
     val ADS_IDENTIFIER = Version("1.0.0-alpha04")
-    val ANNOTATION = Version("1.2.0-beta01")
-    val ANNOTATION_EXPERIMENTAL = Version("1.1.0-beta01")
-    val APPCOMPAT = Version("1.3.0-beta01")
+    val ANNOTATION = Version("1.2.0-rc01")
+    val ANNOTATION_EXPERIMENTAL = Version("1.1.0-rc01")
+    val APPCOMPAT = Version("1.3.0-beta02")
     val APPSEARCH = Version("1.0.0-alpha01")
     val ARCH_CORE = Version("2.2.0-alpha01")
     val ARCH_CORE_TESTING = ARCH_CORE
@@ -94,7 +94,7 @@
     val PERCENTLAYOUT = Version("1.1.0-alpha01")
     val PREFERENCE = Version("1.2.0-alpha01")
     val RECOMMENDATION = Version("1.1.0-alpha01")
-    val RECYCLERVIEW = Version("1.2.0-beta01")
+    val RECYCLERVIEW = Version("1.2.0-beta02")
     val RECYCLERVIEW_SELECTION = Version("2.0.0-alpha01")
     val REMOTECALLBACK = Version("1.0.0-alpha02")
     val RESOURCEINSPECTION = Version("1.0.0-alpha01")
diff --git a/buildSrc/src/main/kotlin/androidx/build/LintConfiguration.kt b/buildSrc/src/main/kotlin/androidx/build/LintConfiguration.kt
index 158065e..4ce1461 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LintConfiguration.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LintConfiguration.kt
@@ -74,17 +74,20 @@
         project.rootProject.project(":lint-checks")
     )
 
+    // The purpose of this specific project is to test that lint is running, so
+    // it contains expected violations that we do not want to trigger a build failure
+    val isTestingLintItself = (project.path == ":lint-checks:integration-tests")
+
     // If -PupdateLintBaseline was set we should update the baseline if it exists
-    val updateLintBaseline = hasProperty(UPDATE_LINT_BASELINE)
+    val updateLintBaseline = hasProperty(UPDATE_LINT_BASELINE) && !isTestingLintItself
 
     // Lint is configured entirely in afterEvaluate so that individual projects cannot easily
-    // disable individual checks in the DSL for any reason. That being said, when rolling out a new
-    // check as fatal, it can be beneficial to set it to fatal above this comment. This allows you
-    // to override it in a build script rather than messing with the baseline files. This is
-    // especially relevant for checks which cause hundreds or more failures.
+    // disable individual checks in the DSL for any reason.
     afterEvaluate {
         lintOptions.apply {
-            isAbortOnError = true
+            if (!isTestingLintItself) {
+                isAbortOnError = true
+            }
             isIgnoreWarnings = true
 
             // Workaround for b/177359055 where 27.2.0-beta04 incorrectly computes severity.
diff --git a/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt b/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
index 5420ab4..4f01dc7 100644
--- a/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
@@ -102,7 +102,7 @@
 const val MOCKITO_KOTLIN = "com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0"
 const val MULTIDEX = "androidx.multidex:multidex:2.0.1"
 const val NULLAWAY = "com.uber.nullaway:nullaway:0.3.7"
-const val PLAY_CORE = "com.google.android.play:core:1.8.0"
+const val PLAY_CORE = "com.google.android.play:core:1.9.1"
 const val REACTIVE_STREAMS = "org.reactivestreams:reactive-streams:1.0.0"
 const val RX_JAVA = "io.reactivex.rxjava2:rxjava:2.2.9"
 const val RX_JAVA3 = "io.reactivex.rxjava3:rxjava:3.0.0"
diff --git a/buildSrc/src/main/kotlin/androidx/build/testConfiguration/TestSuiteConfiguration.kt b/buildSrc/src/main/kotlin/androidx/build/testConfiguration/TestSuiteConfiguration.kt
index 37d0efc..9312d82 100644
--- a/buildSrc/src/main/kotlin/androidx/build/testConfiguration/TestSuiteConfiguration.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/testConfiguration/TestSuiteConfiguration.kt
@@ -266,6 +266,7 @@
 
 fun Project.configureTestConfigGeneration(testedExtension: TestedExtension) {
     extensions.getByType<AndroidComponentsExtension<*, *>>().apply {
+        @Suppress("deprecation")
         androidTests(selector().all()) { androidTest ->
             when {
                 path.contains("media2:media2-session:version-compat-tests:") -> {
diff --git a/busytown/androidx.sh b/busytown/androidx.sh
index 08af1347..c8e3ed2c 100755
--- a/busytown/androidx.sh
+++ b/busytown/androidx.sh
@@ -8,7 +8,7 @@
 # Run Gradle
 impl/build.sh listTaskOutputs "$@"
 impl/build.sh allProperties -Pandroidx.validateNoUnrecognizedMessages=false "$@" >/dev/null
-subsets="MAIN COMPOSE FLAN MEDIA"
+subsets="MAIN COMPOSE FLAN MEDIA WEAR"
 for subset in $subsets; do
   ANDROIDX_PROJECTS=$subset impl/build.sh tasks -Pandroidx.validateNoUnrecognizedMessages=false >/dev/null
 done
diff --git a/camera/camera-camera2-pipe-testing/src/test/java/androidx/camera/camera2/pipe/testing/CameraGraphSimulatorTest.kt b/camera/camera-camera2-pipe-testing/src/test/java/androidx/camera/camera2/pipe/testing/CameraGraphSimulatorTest.kt
index affeb12..4bb4026 100644
--- a/camera/camera-camera2-pipe-testing/src/test/java/androidx/camera/camera2/pipe/testing/CameraGraphSimulatorTest.kt
+++ b/camera/camera-camera2-pipe-testing/src/test/java/androidx/camera/camera2/pipe/testing/CameraGraphSimulatorTest.kt
@@ -195,6 +195,7 @@
         assertThat(lossEvent.streamId).isEqualTo(stream.id)
     }
 
+    @Ignore // TODO(b/179825103): Ensure test does not flake
     @Test
     fun simulatorCanIssueMultipleFrames() = runBlocking {
         val listener = FakeRequestListener()
diff --git a/camera/camera-lifecycle/src/main/java/androidx/camera/lifecycle/ProcessCameraProvider.java b/camera/camera-lifecycle/src/main/java/androidx/camera/lifecycle/ProcessCameraProvider.java
index 5c4a17d8..475172b 100644
--- a/camera/camera-lifecycle/src/main/java/androidx/camera/lifecycle/ProcessCameraProvider.java
+++ b/camera/camera-lifecycle/src/main/java/androidx/camera/lifecycle/ProcessCameraProvider.java
@@ -482,6 +482,7 @@
         mLifecycleCameraRepository.unbindAll();
     }
 
+    /** {@inheritDoc} */
     @Override
     public boolean hasCamera(@NonNull CameraSelector cameraSelector)
             throws CameraInfoUnavailableException {
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/activity/Camera2TestActivity.java b/camera/camera-testing/src/main/java/androidx/camera/testing/activity/Camera2TestActivity.java
index 9d40e6f..6377d1cb 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/activity/Camera2TestActivity.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/activity/Camera2TestActivity.java
@@ -189,6 +189,7 @@
     }
 
     @RequiresPermission(Manifest.permission.CAMERA)
+    @SuppressWarnings("CatchAndPrintStackTrace")
     void openCamera() {
         if (TextUtils.isEmpty(mCameraId)) {
             Logger.d(TAG, "Cannot open the camera");
@@ -233,7 +234,8 @@
     /**
      * Creates a new {@link CameraCaptureSession} for camera preview.
      */
-    @SuppressWarnings("deprecation") /* createCaptureSession */
+    /* createCaptureSession */
+    @SuppressWarnings({"deprecation", "CatchAndPrintStackTrace"})
     void createCameraPreviewSession() {
         Preconditions.checkNotNull(mCameraDevice);
         try {
@@ -257,6 +259,7 @@
                     new CameraCaptureSession.StateCallback() {
 
                         @Override
+                        @SuppressWarnings("CatchAndPrintStackTrace")
                         public void onConfigured(
                                 @NonNull CameraCaptureSession cameraCaptureSession) {
                             // The camera is already closed
@@ -305,6 +308,7 @@
     /**
      * Stops the background thread and its {@link Handler}.
      */
+    @SuppressWarnings("CatchAndPrintStackTrace")
     private void stopBackgroundThread() {
         if (mBackgroundThread != null) {
             mBackgroundThread.quitSafely();
diff --git a/camera/camera-view/src/androidTest/java/androidx/camera/view/PreviewTransformationDeviceTest.kt b/camera/camera-view/src/androidTest/java/androidx/camera/view/PreviewTransformationDeviceTest.kt
index f2e0369..43554b2 100644
--- a/camera/camera-view/src/androidTest/java/androidx/camera/view/PreviewTransformationDeviceTest.kt
+++ b/camera/camera-view/src/androidTest/java/androidx/camera/view/PreviewTransformationDeviceTest.kt
@@ -23,6 +23,7 @@
 import android.view.View
 import androidx.camera.core.SurfaceRequest
 import androidx.camera.core.impl.ImageOutputConfig.RotationValue
+import androidx.camera.view.TransformUtils.sizeToVertices
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -191,7 +192,7 @@
         )
 
         // Act.
-        val surfaceVertexes = PreviewTransformation.sizeToVertices(SURFACE_SIZE)
+        val surfaceVertexes = sizeToVertices(SURFACE_SIZE)
         mPreviewTransform.textureViewCorrectionMatrix.mapPoints(surfaceVertexes)
         return convertToIntArray(surfaceVertexes)
     }
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/PreviewTransformation.java b/camera/camera-view/src/main/java/androidx/camera/view/PreviewTransformation.java
index c464fbe..1260701 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/PreviewTransformation.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/PreviewTransformation.java
@@ -24,6 +24,12 @@
 import static androidx.camera.view.PreviewView.ScaleType.FIT_CENTER;
 import static androidx.camera.view.PreviewView.ScaleType.FIT_END;
 import static androidx.camera.view.PreviewView.ScaleType.FIT_START;
+import static androidx.camera.view.TransformUtils.createRotatedVertices;
+import static androidx.camera.view.TransformUtils.is90or270;
+import static androidx.camera.view.TransformUtils.rectToVertices;
+import static androidx.camera.view.TransformUtils.sizeToVertices;
+import static androidx.camera.view.TransformUtils.surfaceRotationToRotationDegrees;
+import static androidx.camera.view.TransformUtils.verticesToRect;
 
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -87,10 +93,6 @@
  *
  * <p> The transformed Surface is how the PreviewView's inner view should behave, to make the
  * crop rect matches the PreviewView.
- *
- * <p> The class uses the vertices to represent a rectangle with arbitrary rotation and chirality.
- * It could be otherwise represented by a triple of a {@link RectF}, a rotation degrees and a
- * flag for the orientation of rotation (clockwise v.s. counter-clockwise).
  */
 final class PreviewTransformation {
 
@@ -98,8 +100,6 @@
 
     private static final PreviewView.ScaleType DEFAULT_SCALE_TYPE = FILL_CENTER;
 
-    // Each vertex is represented by a pair of (x, y) which is 2 slots in a float array.
-    private static final int FLOAT_NUMBER_PER_VERTEX = 2;
     // SurfaceRequest.getResolution().
     private Size mResolution;
     // TransformationInfo.getCropRect().
@@ -150,7 +150,7 @@
         Matrix matrix = new Matrix();
         float[] surfaceVertices = sizeToVertices(mResolution);
         float[] rotatedSurfaceVertices = createRotatedVertices(surfaceVertices,
-                -rotationValueToRotationDegrees(mTargetRotation));
+                -surfaceRotationToRotationDegrees(mTargetRotation));
         matrix.setPolyToPoly(surfaceVertices, 0, rotatedSurfaceVertices, 0, 4);
         return matrix;
     }
@@ -439,95 +439,7 @@
         return matrix;
     }
 
-    static int rotationValueToRotationDegrees(int rotationValue) {
-        switch (rotationValue) {
-            case Surface.ROTATION_0:
-                return 0;
-            case Surface.ROTATION_90:
-                return 90;
-            case Surface.ROTATION_180:
-                return 180;
-            case Surface.ROTATION_270:
-                return 270;
-            default:
-                throw new IllegalStateException("Unexpected rotation value " + rotationValue);
-        }
-    }
-
-    private static boolean is90or270(int rotationDegrees) {
-        if (rotationDegrees == 90 || rotationDegrees == 270) {
-            return true;
-        }
-        if (rotationDegrees == 0 || rotationDegrees == 180) {
-            return false;
-        }
-        throw new IllegalArgumentException("Invalid rotation degrees: " + rotationDegrees);
-    }
-
-    /**
-     * Converts a {@link Size} to an float array of vertices.
-     */
-    @VisibleForTesting
-    static float[] sizeToVertices(Size size) {
-        return new float[]{0, 0, size.getWidth(), 0, size.getWidth(), size.getHeight(), 0,
-                size.getHeight()};
-    }
-
-    /**
-     * Converts a {@link Rect} defined by left, top right and bottom to an array of vertices.
-     */
-    private static float[] rectToVertices(RectF rectF) {
-        return new float[]{rectF.left, rectF.top, rectF.right, rectF.top, rectF.right, rectF.bottom,
-                rectF.left, rectF.bottom};
-    }
-
-    /**
-     * Converts an array of vertices to a {@link Rect}.
-     */
-    private static RectF verticesToRect(float[] vertices) {
-        return new RectF(
-                min(vertices[0], vertices[2], vertices[4], vertices[6]),
-                min(vertices[1], vertices[3], vertices[5], vertices[7]),
-                max(vertices[0], vertices[2], vertices[4], vertices[6]),
-                max(vertices[1], vertices[3], vertices[5], vertices[7])
-        );
-    }
-
-    private static float max(float value1, float value2, float value3, float value4) {
-        return Math.max(Math.max(value1, value2), Math.max(value3, value4));
-    }
-
-    private static float min(float value1, float value2, float value3, float value4) {
-        return Math.min(Math.min(value1, value2), Math.min(value3, value4));
-    }
-
     private boolean isTransformationInfoReady() {
         return mSurfaceCropRect != null && mResolution != null;
     }
-
-    /**
-     * Creates a new quad that the vertices are rotated clockwise with the given degrees.
-     *
-     * <pre>
-     *  a----b
-     *  |    |
-     *  d----c  vertices = {a.x, a.y, b.x, b.y, c.x, c.y, d.x, d.y}
-     *
-     * After 90° rotation:
-     *
-     *  d----a
-     *  |    |
-     *  c----b  vertices = {d.x, d.y, a.x, a.y, b.x, b.y, c.x, c.y}
-     * </pre>
-     */
-    private static float[] createRotatedVertices(float[] original, int rotationDegrees) {
-        float[] rotated = new float[original.length];
-        int offset = -rotationDegrees / 90 * FLOAT_NUMBER_PER_VERTEX;
-        for (int originalIndex = 0; originalIndex < original.length; originalIndex++) {
-            int rotatedIndex = (originalIndex + offset) % original.length;
-            rotatedIndex = rotatedIndex < 0 ? rotatedIndex + original.length : rotatedIndex;
-            rotated[rotatedIndex] = original[originalIndex];
-        }
-        return rotated;
-    }
 }
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/TransformUtils.java b/camera/camera-view/src/main/java/androidx/camera/view/TransformUtils.java
new file mode 100644
index 0000000..0e6b15d
--- /dev/null
+++ b/camera/camera-view/src/main/java/androidx/camera/view/TransformUtils.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.view;
+
+import android.graphics.RectF;
+import android.util.Size;
+import android.view.Surface;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+
+/**
+ * Utility class for transform.
+ *
+ * <p> The vertices representation uses a float array to represent a rectangle with arbitrary
+ * rotation and rotation-direction. It could be otherwise represented by a triple of a
+ * {@link RectF}, a rotation degrees integer and a boolean flag for the rotation-direction
+ * (clockwise v.s. counter-clockwise).
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public class TransformUtils {
+
+    // Each vertex is represented by a pair of (x, y) which is 2 slots in a float array.
+    private static final int FLOAT_NUMBER_PER_VERTEX = 2;
+
+    private TransformUtils() {
+    }
+
+    /**
+     * Creates a new quad by rotating {@code original}'s vertices {@code rotationDegrees} clockwise.
+     *
+     * <pre>
+     *  a----b
+     *  |    |
+     *  d----c  vertices = {a.x, a.y, b.x, b.y, c.x, c.y, d.x, d.y}
+     *
+     * After 90° rotation:
+     *
+     *  d----a
+     *  |    |
+     *  c----b  vertices = {d.x, d.y, a.x, a.y, b.x, b.y, c.x, c.y}
+     * </pre>
+     *
+     * @param rotationDegrees multiple of 90.
+     */
+    @NonNull
+    public static float[] createRotatedVertices(@NonNull float[] original, int rotationDegrees) {
+        float[] rotated = new float[original.length];
+        int offset = -rotationDegrees / 90 * FLOAT_NUMBER_PER_VERTEX;
+        for (int originalIndex = 0; originalIndex < original.length; originalIndex++) {
+            int rotatedIndex = (originalIndex + offset) % original.length;
+            rotatedIndex = rotatedIndex < 0 ? rotatedIndex + original.length : rotatedIndex;
+            rotated[rotatedIndex] = original[originalIndex];
+        }
+        return rotated;
+    }
+
+    /**
+     * Converts an array of vertices to a {@link RectF}.
+     */
+    @NonNull
+    public static RectF verticesToRect(@NonNull float[] vertices) {
+        return new RectF(
+                min(vertices[0], vertices[2], vertices[4], vertices[6]),
+                min(vertices[1], vertices[3], vertices[5], vertices[7]),
+                max(vertices[0], vertices[2], vertices[4], vertices[6]),
+                max(vertices[1], vertices[3], vertices[5], vertices[7])
+        );
+    }
+
+    /**
+     * Returns the max value.
+     */
+    public static float max(float value1, float value2, float value3, float value4) {
+        return Math.max(Math.max(value1, value2), Math.max(value3, value4));
+    }
+
+    /**
+     * Returns the min value.
+     */
+    public static float min(float value1, float value2, float value3, float value4) {
+        return Math.min(Math.min(value1, value2), Math.min(value3, value4));
+    }
+
+    /**
+     * Converts {@link Surface} rotation to rotation degrees: 90, 180, 270 or 0.
+     */
+    public static int surfaceRotationToRotationDegrees(int rotationValue) {
+        switch (rotationValue) {
+            case Surface.ROTATION_0:
+                return 0;
+            case Surface.ROTATION_90:
+                return 90;
+            case Surface.ROTATION_180:
+                return 180;
+            case Surface.ROTATION_270:
+                return 270;
+            default:
+                throw new IllegalStateException("Unexpected rotation value " + rotationValue);
+        }
+    }
+
+
+    /**
+     * Returns true if the rotation degrees is 90 or 270.
+     */
+    public static boolean is90or270(int rotationDegrees) {
+        if (rotationDegrees == 90 || rotationDegrees == 270) {
+            return true;
+        }
+        if (rotationDegrees == 0 || rotationDegrees == 180) {
+            return false;
+        }
+        throw new IllegalArgumentException("Invalid rotation degrees: " + rotationDegrees);
+    }
+
+    /**
+     * Converts a {@link Size} to a float array of vertices.
+     */
+    @NonNull
+    public static float[] sizeToVertices(@NonNull Size size) {
+        return new float[]{0, 0, size.getWidth(), 0, size.getWidth(), size.getHeight(), 0,
+                size.getHeight()};
+    }
+
+    /**
+     * Converts a {@link RectF} defined by top, left, right and bottom to an array of vertices.
+     */
+    @NonNull
+    public static float[] rectToVertices(@NonNull RectF rectF) {
+        return new float[]{rectF.left, rectF.top, rectF.right, rectF.top, rectF.right, rectF.bottom,
+                rectF.left, rectF.bottom};
+    }
+}
diff --git a/camera/integration-tests/timingtestapp/build.gradle b/camera/integration-tests/timingtestapp/build.gradle
index 6237f3d..8590b2b 100644
--- a/camera/integration-tests/timingtestapp/build.gradle
+++ b/camera/integration-tests/timingtestapp/build.gradle
@@ -62,7 +62,7 @@
     implementation("androidx.collection:collection:1.0.0")
     implementation("androidx.preference:preference:1.1.0")
     implementation("androidx.exifinterface:exifinterface:1.0.0")
-    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.2.0-rc02")
+    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.2.0")
     implementation(CONSTRAINT_LAYOUT, { transitive = true })
     implementation(KOTLIN_STDLIB)
     implementation(KOTLIN_COROUTINES_ANDROID)
diff --git a/car/app/app-aaos/api/current.txt b/car/app/app-aaos/api/current.txt
index e6f50d0..015dfc5 100644
--- a/car/app/app-aaos/api/current.txt
+++ b/car/app/app-aaos/api/current.txt
@@ -1 +1,43 @@
 // Signature format: 4.0
+package androidx.car.app.aaos {
+
+  public final class CarAppActivity extends android.app.Activity {
+    ctor public CarAppActivity();
+  }
+
+}
+
+package androidx.car.app.aaos.renderer.surface {
+
+  public final class LegacySurfacePackage implements android.os.Parcelable {
+    ctor public LegacySurfacePackage(androidx.car.app.aaos.renderer.surface.SurfaceControlCallback);
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.car.app.aaos.renderer.surface.LegacySurfacePackage!> CREATOR;
+  }
+
+  public interface SurfaceControlCallback {
+    method public void onTouchEvent(android.view.MotionEvent);
+    method public void onWindowFocusChanged(boolean, boolean);
+    method public void setSurfaceWrapper(androidx.car.app.aaos.renderer.surface.SurfaceWrapper);
+  }
+
+  public final class SurfacePackageCompat implements android.os.Parcelable {
+    ctor public SurfacePackageCompat(androidx.car.app.aaos.renderer.surface.LegacySurfacePackage);
+    ctor @RequiresApi(android.os.Build.VERSION_CODES.R) public SurfacePackageCompat(android.view.SurfaceControlViewHost.SurfacePackage);
+    method public int describeContents();
+    method public android.os.Parcelable? getSurfacePackage();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.car.app.aaos.renderer.surface.SurfacePackageCompat!> CREATOR;
+  }
+
+  public final class SurfaceWrapper implements android.os.Parcelable {
+    ctor public SurfaceWrapper(android.os.IBinder?, int, int, int, int, android.view.Surface);
+    method public int describeContents();
+    method public android.os.IBinder? getHostToken();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.car.app.aaos.renderer.surface.SurfaceWrapper!> CREATOR;
+  }
+
+}
+
diff --git a/car/app/app-aaos/api/public_plus_experimental_current.txt b/car/app/app-aaos/api/public_plus_experimental_current.txt
index e6f50d0..015dfc5 100644
--- a/car/app/app-aaos/api/public_plus_experimental_current.txt
+++ b/car/app/app-aaos/api/public_plus_experimental_current.txt
@@ -1 +1,43 @@
 // Signature format: 4.0
+package androidx.car.app.aaos {
+
+  public final class CarAppActivity extends android.app.Activity {
+    ctor public CarAppActivity();
+  }
+
+}
+
+package androidx.car.app.aaos.renderer.surface {
+
+  public final class LegacySurfacePackage implements android.os.Parcelable {
+    ctor public LegacySurfacePackage(androidx.car.app.aaos.renderer.surface.SurfaceControlCallback);
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.car.app.aaos.renderer.surface.LegacySurfacePackage!> CREATOR;
+  }
+
+  public interface SurfaceControlCallback {
+    method public void onTouchEvent(android.view.MotionEvent);
+    method public void onWindowFocusChanged(boolean, boolean);
+    method public void setSurfaceWrapper(androidx.car.app.aaos.renderer.surface.SurfaceWrapper);
+  }
+
+  public final class SurfacePackageCompat implements android.os.Parcelable {
+    ctor public SurfacePackageCompat(androidx.car.app.aaos.renderer.surface.LegacySurfacePackage);
+    ctor @RequiresApi(android.os.Build.VERSION_CODES.R) public SurfacePackageCompat(android.view.SurfaceControlViewHost.SurfacePackage);
+    method public int describeContents();
+    method public android.os.Parcelable? getSurfacePackage();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.car.app.aaos.renderer.surface.SurfacePackageCompat!> CREATOR;
+  }
+
+  public final class SurfaceWrapper implements android.os.Parcelable {
+    ctor public SurfaceWrapper(android.os.IBinder?, int, int, int, int, android.view.Surface);
+    method public int describeContents();
+    method public android.os.IBinder? getHostToken();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.car.app.aaos.renderer.surface.SurfaceWrapper!> CREATOR;
+  }
+
+}
+
diff --git a/car/app/app-aaos/api/restricted_current.txt b/car/app/app-aaos/api/restricted_current.txt
index e6f50d0..015dfc5 100644
--- a/car/app/app-aaos/api/restricted_current.txt
+++ b/car/app/app-aaos/api/restricted_current.txt
@@ -1 +1,43 @@
 // Signature format: 4.0
+package androidx.car.app.aaos {
+
+  public final class CarAppActivity extends android.app.Activity {
+    ctor public CarAppActivity();
+  }
+
+}
+
+package androidx.car.app.aaos.renderer.surface {
+
+  public final class LegacySurfacePackage implements android.os.Parcelable {
+    ctor public LegacySurfacePackage(androidx.car.app.aaos.renderer.surface.SurfaceControlCallback);
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.car.app.aaos.renderer.surface.LegacySurfacePackage!> CREATOR;
+  }
+
+  public interface SurfaceControlCallback {
+    method public void onTouchEvent(android.view.MotionEvent);
+    method public void onWindowFocusChanged(boolean, boolean);
+    method public void setSurfaceWrapper(androidx.car.app.aaos.renderer.surface.SurfaceWrapper);
+  }
+
+  public final class SurfacePackageCompat implements android.os.Parcelable {
+    ctor public SurfacePackageCompat(androidx.car.app.aaos.renderer.surface.LegacySurfacePackage);
+    ctor @RequiresApi(android.os.Build.VERSION_CODES.R) public SurfacePackageCompat(android.view.SurfaceControlViewHost.SurfacePackage);
+    method public int describeContents();
+    method public android.os.Parcelable? getSurfacePackage();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.car.app.aaos.renderer.surface.SurfacePackageCompat!> CREATOR;
+  }
+
+  public final class SurfaceWrapper implements android.os.Parcelable {
+    ctor public SurfaceWrapper(android.os.IBinder?, int, int, int, int, android.view.Surface);
+    method public int describeContents();
+    method public android.os.IBinder? getHostToken();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.car.app.aaos.renderer.surface.SurfaceWrapper!> CREATOR;
+  }
+
+}
+
diff --git a/car/app/app-aaos/build.gradle b/car/app/app-aaos/build.gradle
index 95c8ee8..57aca64 100644
--- a/car/app/app-aaos/build.gradle
+++ b/car/app/app-aaos/build.gradle
@@ -17,13 +17,33 @@
 import androidx.build.LibraryType
 import androidx.build.LibraryVersions
 
+import static androidx.build.dependencies.DependenciesKt.*
+
 plugins {
     id("AndroidXPlugin")
     id("com.android.library")
 }
-
 dependencies {
-    // Add dependencies here
+    api(project(":car:app:app"))
+    implementation "androidx.lifecycle:lifecycle-common-java8:2.2.0"
+    implementation 'androidx.annotation:annotation:1.1.0'
+
+    testImplementation(ANDROIDX_TEST_CORE)
+    testImplementation(ANDROIDX_TEST_RUNNER)
+    testImplementation(JUNIT)
+    testImplementation(MOCKITO_CORE)
+    testImplementation(ROBOLECTRIC)
+    testImplementation(TRUTH)
+}
+
+android {
+    defaultConfig {
+        minSdkVersion 29
+    }
+    buildFeatures {
+        aidl = true
+    }
+    testOptions.unitTests.includeAndroidResources = true
 }
 
 androidx {
diff --git a/car/app/app-aaos/src/main/AndroidManifest.xml b/car/app/app-aaos/src/main/AndroidManifest.xml
index c562b9f..31bce5b 100644
--- a/car/app/app-aaos/src/main/AndroidManifest.xml
+++ b/car/app/app-aaos/src/main/AndroidManifest.xml
@@ -15,6 +15,20 @@
   limitations under the License.
   -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="androidx.car.app.aaos">
-
+    package="androidx.car.app.aaos"
+    android:versionCode="1"
+    android:versionName="0.1">
+    <queries>
+        <intent>
+            <action android:name="android.car.template.host.action.RENDER" />
+        </intent>
+    </queries>
+    <application>
+        <activity
+            android:name=".CarAppActivity"
+            android:theme="@android:style/Theme.NoTitleBar"
+            android:exported="false"
+            android:windowSoftInputMode="adjustResize">
+        </activity>
+    </application>
 </manifest>
\ No newline at end of file
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/IBackButtonListener.aidl
similarity index 65%
copy from compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt
copy to car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/IBackButtonListener.aidl
index 63fdeeb..d48ca1b 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt
+++ b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/IBackButtonListener.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,14 @@
  * limitations under the License.
  */
 
-package androidx.compose.foundation.layout
+package androidx.car.app.aaos.renderer;
 
-@RequiresOptIn("The API of this layout is experimental and is likely to change in the future.")
-annotation class ExperimentalLayout
+/**
+ * Classes that wish to listen for back button events should implement this.
+ *
+ * @hide
+ */
+interface IBackButtonListener {
+  /** Notifies that the button was pressed. */
+  void onBackPressed() = 1;
+}
diff --git a/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/ICarAppActivity.aidl b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/ICarAppActivity.aidl
new file mode 100644
index 0000000..d06bdf2
--- /dev/null
+++ b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/ICarAppActivity.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos.renderer;
+
+import androidx.car.app.aaos.renderer.IBackButtonListener;
+import androidx.car.app.aaos.renderer.IInputConnectionListener;
+import androidx.car.app.aaos.renderer.ILifecycleListener;
+import androidx.car.app.aaos.renderer.IRotaryEventListener;
+import androidx.car.app.aaos.renderer.surface.ISurfaceListener;
+import androidx.car.app.aaos.renderer.surface.SurfacePackageCompat;
+
+/**
+ * An interface to let renderer service communicate with the car activity.
+ *
+ * @hide
+ */
+oneway interface ICarAppActivity {
+    /** Sets the surface package. */
+    void setSurfacePackage(in SurfacePackageCompat surfacePackageCompat) = 1;
+
+    /** Registers the listener to get callbacks for surface events. */
+    void setSurfaceListener(ISurfaceListener listener) = 2;
+
+    /** Registers the listener to get callbacks for lifecyle events. */
+    void setLifecycleListener(ILifecycleListener listener) = 3;
+
+    /** Registers the listener to get callbacks for back button events. */
+    void setBackButtonListener(IBackButtonListener listener) = 4;
+
+    /** Notifies to start the input, i.e. to show the keyboard. */
+    void onStartInput() = 5;
+
+    /** Notifies to stop the input, i.e. to hide the keyboard. */
+    void onStopInput() = 6;
+
+    /**
+     * Registers the listener for input connection.
+     *
+     * This listener can be used to establish an input connection with the host.
+     */
+    void setInputConnectionListener(IInputConnectionListener listener) = 7;
+
+    /** Registers the listener to get rotary events. */
+    void setRotaryEventListener(IRotaryEventListener listener) = 8;
+
+    /** Sends the Intent to be used to start a car app. */
+    void startCarApp(in Intent intent) = 9;
+
+    /** Requests the activity to finish itself. */
+    void finishCarApp() = 10;
+}
diff --git a/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/IInputConnectionListener.aidl b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/IInputConnectionListener.aidl
new file mode 100644
index 0000000..2fe9f33e
--- /dev/null
+++ b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/IInputConnectionListener.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos.renderer;
+
+import  androidx.car.app.aaos.renderer.IProxyInputConnection;
+
+/**
+ * Proxies input connection events from {@link CarAppActivity} to the host renderer.
+ *
+ * @hide
+ */
+interface IInputConnectionListener {
+
+  /**
+   * Creates a proxy to a remote {@link InputConnection}.
+   *
+   * @params editorInfo the {@link EditorInfo} for which the input connection should be created
+   *
+   * @return an {@link IProxyInputConnection} through which communication to the
+   *   remote {@code InputConnection} should occur
+   */
+  IProxyInputConnection onCreateInputConnection(in EditorInfo editorInfo) = 1;
+}
diff --git a/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/ILifecycleListener.aidl b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/ILifecycleListener.aidl
new file mode 100644
index 0000000..5c5d85fd
--- /dev/null
+++ b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/ILifecycleListener.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos.renderer;
+
+/**
+ * A lifecycle event listener interface.
+ *
+ * @hide
+ */
+interface ILifecycleListener {
+
+  /**
+   * Notifies that {@link CarAppActivity} called {Activity#onCreate()}.
+   */
+  void onCreate() = 1;
+
+  /**
+   * Notifies that {@link CarAppActivity} called {Activity#onStart()}.
+   */
+  void onStart() = 2;
+
+  /**
+   * Notifies that {@link CarAppActivity} called {Activity#onResume()}.
+   */
+  void onResume() = 3;
+
+  /**
+   * Notifies that {@link CarAppActivity} called {Activity#onPause()}.
+   */
+  void onPause() = 4;
+
+  /**
+   * Notifies that {@link CarAppActivity} called {Activity#onStop()}.
+   */
+  void onStop() = 5;
+
+  /**
+   * Notifies that {@link CarAppActivity} called {Activity#onDestroyed()}.
+   */
+  void onDestroyed() = 6;
+}
diff --git a/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/IProxyInputConnection.aidl b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/IProxyInputConnection.aidl
new file mode 100644
index 0000000..e760f10
--- /dev/null
+++ b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/IProxyInputConnection.aidl
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos.renderer;
+
+/**
+ * Proxies the {@link InputConnection} method invocations from {@link CarAppActivity} across a
+ * binder interface to the host renderer.
+ *
+ * @hide
+ */
+interface IProxyInputConnection {
+    /** Proxies a call to {@link InputConnection#getTextBeforeCursor}. */
+    CharSequence getTextBeforeCursor(int length, int flags) = 1;
+
+    /** Proxies a call to {@link InputConnection#getTextAfterCursor}. */
+    CharSequence getTextAfterCursor(int length, int flags) = 2;
+
+    /** Proxies a call to {@link InputConnection#getSelectedText}. */
+    CharSequence getSelectedText(int flags) = 3;
+
+    /** Proxies a call to {@link InputConnection#getCursorCapsMode}. */
+    int getCursorCapsMode(int reqModes) = 4;
+
+    /** Proxies a call to {@link InputConnection#deleteSurroundingText}. */
+    boolean deleteSurroundingText(int beforeLength, int afterLength) = 5;
+
+    /** Proxies a call to {@link InputConnection#setComposingText}. */
+    boolean setComposingText(CharSequence text, int newCursorPosition) = 6;
+
+    /** Proxies a call to {@link InputConnection#setComposingRegion}. */
+    boolean setComposingRegion(int start, int end) = 7;
+
+    /** Proxies a call to {@link InputConnection#finishComposingText}. */
+    boolean finishComposingText() = 8;
+
+    /** Proxies a call to {@link InputConnection#commitText}. */
+    boolean commitText(CharSequence text, int newCursorPosition) = 9;
+
+    /** Proxies a call to {@link InputConnection#setSelection}. */
+    boolean setSelection(int start, int end) = 10;
+
+    /** Proxies a call to {@link InputConnection#performEditorAction}. */
+    boolean performEditorAction(int editorAction) = 11;
+
+    /** Proxies a call to {@link InputConnection#performContextMenuAction}. */
+    boolean performContextMenuAction(int id) = 12;
+
+    /** Proxies a call to {@link InputConnection#beginBatchEdit}. */
+    boolean beginBatchEdit() = 13;
+
+    /** Proxies a call to {@link InputConnection#endBatchEdit}. */
+    boolean endBatchEdit() = 14;
+
+    /** Proxies a call to {@link InputConnection#sendKeyEvent}. */
+    boolean sendKeyEvent(in KeyEvent event) = 15;
+
+    /** Proxies a call to {@link InputConnection#clearMetaKeyStates}. */
+    boolean clearMetaKeyStates(int states) = 16;
+
+    /** Proxies a call to {@link InputConnection#reportFullscreenMode}. */
+    boolean reportFullscreenMode(boolean enabled) = 17;
+
+    /** Proxies a call to {@link InputConnection#performPrivateCommand}. */
+    boolean performPrivateCommand(String action, in Bundle data) = 18;
+
+    /** Proxies a call to {@link InputConnection#requestCursorUpdates}. */
+    boolean requestCursorUpdates(int cursorUpdateMode) = 19;
+
+    /** Proxies a call to {@link InputConnection#commitCorrection}. */
+    boolean commitCorrection(in CorrectionInfo correctionInfo) = 20;
+
+    /** Proxies a call to {@link InputConnection#commitCompletion}. */
+    boolean commitCompletion(in CompletionInfo text) = 21;
+
+    /** Proxies a call to {@link InputConnection#getExtractedText}. */
+    ExtractedText getExtractedText(in ExtractedTextRequest request, int flags) = 22;
+
+    /** Proxies a call to {@link InputConnection#closeConnection}. */
+    void closeConnection() = 23;
+
+    /** Returns the {@link EditorInfo} associated with the input connection. */
+    EditorInfo getEditorInfo() = 24;
+}
\ No newline at end of file
diff --git a/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/IRendererService.aidl b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/IRendererService.aidl
new file mode 100644
index 0000000..012d483
--- /dev/null
+++ b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/IRendererService.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos.renderer;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import androidx.car.app.aaos.renderer.ICarAppActivity;
+
+/**
+ * An interface to be used for communicating with the renderer.
+ *
+ * @hide
+ */
+interface IRendererService {
+
+  /**
+   * Initializes rendering.
+   *
+   * @param carActivity the binder for performing two-way communication
+   * @param serviceName the service that is associated with the activity
+   * @param displayId the display ID on which the content should be rendered
+   *
+   * @return true if successful
+   */
+  boolean initialize(ICarAppActivity carActivity, in ComponentName serviceName, int
+  displayId) = 1;
+
+  /**
+   * Notifies of a new intent that requires processing.
+   *
+   * @param intent The intent that needs to be processed
+   * @param serviceName the service that is associated with the activity
+   * @param displayId the display ID on which the content should be rendererd
+   *
+   * @return true if successful
+   */
+  boolean onNewIntent(in Intent intent, in ComponentName serviceName, int displayId) = 2;
+
+  /**
+   * Notifies that {@link CarAppActivity} no longer needs the renderer.
+   *
+   * @param serviceName the service that is associated with the activity
+   */
+  void terminate(in ComponentName serviceName) = 3;
+
+  /**
+   * Returns whether the given version is supported.
+   *
+   * @return true if the version is supported
+   */
+  boolean isVersionSupported(String version) = 4;
+}
diff --git a/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/IRotaryEventListener.aidl b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/IRotaryEventListener.aidl
new file mode 100644
index 0000000..755c641
--- /dev/null
+++ b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/IRotaryEventListener.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos.renderer;
+
+/**
+ * Interface to receive rotary events.
+ *
+ * @hide
+ */
+interface IRotaryEventListener {
+
+  /**
+   * Notifies of a rotary rotation.
+   *
+   * @param steps the number of rotation steps detected. Should be a positive number
+   * @param isClockwise true if the rotation direction is clockwise
+   */
+  void onRotate(int steps, boolean isClockwise) = 1;
+
+  /**
+   * Notifies of a nudge event.
+   *
+   * @param key the nudge key code. It can be {@code KEYCODE_DPAD_RIGHT}, {@code KEYCODE_DPAD_LEFT},
+   * {@code KEYCODE_DPAD_UP}, {@code KEYCODE_DPAD_DOWN}.
+   *
+   * @return true if handled successfully
+   */
+  boolean onNudge(int keyCode) = 2;
+
+  /** Will be called when rotary select is triggered. */
+  void onSelect() = 3;
+}
diff --git a/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/surface/ISurfaceControl.aidl b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/surface/ISurfaceControl.aidl
new file mode 100644
index 0000000..b865b16
--- /dev/null
+++ b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/surface/ISurfaceControl.aidl
@@ -0,0 +1,20 @@
+package androidx.car.app.aaos.renderer.surface;
+
+import androidx.car.app.aaos.renderer.surface.SurfaceWrapper;
+
+/**
+ * Interface implemented by an off-process renderer to receive events affecting the
+ * {@link SurfaceView} it renders content on.
+ *
+ * @hide
+ */
+interface ISurfaceControl {
+  /** Notifies that the underlying surface changed. */
+  void setSurfaceWrapper(in SurfaceWrapper surfaceWrapper) = 1;
+
+  /** Notifies that the surface received a new touch event. */
+  void onTouchEvent(in MotionEvent event) = 2;
+
+  /** Notifies that the window focus changed. */
+  void onWindowFocusChanged(boolean hasFocus, boolean isInTouchMode) = 3;
+}
diff --git a/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/surface/ISurfaceListener.aidl b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/surface/ISurfaceListener.aidl
new file mode 100644
index 0000000..700276b
--- /dev/null
+++ b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/surface/ISurfaceListener.aidl
@@ -0,0 +1,26 @@
+package androidx.car.app.aaos.renderer.surface;
+
+import androidx.car.app.aaos.renderer.surface.SurfaceWrapper;
+
+/**
+ * A surface event listener interface.
+ *
+ * @hide
+ */
+interface ISurfaceListener {
+  /**
+   * Notifies that the surface has become available.
+   *
+   * @param surfaceWrapper a {@link SurfaceWrapper} that contains information on the surface that
+   * has become available.
+   */
+  void onSurfaceAvailable(in SurfaceWrapper surfaceWrapper) = 1;
+
+  /**
+   * Notifies that the surface size has changed.
+   *
+   * @param surfaceWrapper a {@link SurfaceWrapper} that contains the updated information on the
+   * surface.
+   */
+  void onSurfaceChanged(in SurfaceWrapper surfaceWrapper) = 2;
+}
diff --git a/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/surface/LegacySurfacePackage.aidl b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/surface/LegacySurfacePackage.aidl
new file mode 100644
index 0000000..89e0862
--- /dev/null
+++ b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/surface/LegacySurfacePackage.aidl
@@ -0,0 +1,3 @@
+package androidx.car.app.aaos.renderer.surface;
+
+parcelable LegacySurfacePackage;
\ No newline at end of file
diff --git a/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/surface/SurfacePackageCompat.aidl b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/surface/SurfacePackageCompat.aidl
new file mode 100644
index 0000000..41def00
--- /dev/null
+++ b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/surface/SurfacePackageCompat.aidl
@@ -0,0 +1,3 @@
+package androidx.car.app.aaos.renderer.surface;
+
+parcelable SurfacePackageCompat;
\ No newline at end of file
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/surface/SurfaceWrapper.aidl
similarity index 79%
copy from compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt
copy to car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/surface/SurfaceWrapper.aidl
index bae8c9a..4558bb7 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt
+++ b/car/app/app-aaos/src/main/aidl/androidx/car/app/aaos/renderer/surface/SurfaceWrapper.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-package androidx.compose.ui.input.pointer
+package androidx.car.app.aaos.renderer.surface;
 
-@MouseTemporaryApi
-expect val isMouseInput: Boolean
\ No newline at end of file
+parcelable SurfaceWrapper;
diff --git a/car/app/app-aaos/src/main/java/androidx/car/app/aaos/ActivityLifecycleDelegate.java b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/ActivityLifecycleDelegate.java
new file mode 100644
index 0000000..0153bfa
--- /dev/null
+++ b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/ActivityLifecycleDelegate.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos;
+
+import static java.util.Objects.requireNonNull;
+
+import android.app.Activity;
+import android.app.Application.ActivityLifecycleCallbacks;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.car.app.aaos.renderer.ILifecycleListener;
+import androidx.lifecycle.Lifecycle.Event;
+
+/**
+ * An activity lifecycle listener which dispatches the lifecycle events to the {@link
+ * ILifecycleListener}.
+ */
+final class ActivityLifecycleDelegate implements ActivityLifecycleCallbacks {
+    public static final String TAG = "ActivityLifecycleListener";
+    @Nullable
+    private ILifecycleListener mLifecycleListener;
+    @NonNull
+    private Event mLastObservedEvent = Event.ON_ANY;
+
+    /**
+     * Registers the lifecycle listener. This listener gets notified of lifecycle method
+     * invocations.
+     */
+    void setLifecycleListener(@Nullable ILifecycleListener lifecycleListener) {
+        mLifecycleListener = lifecycleListener;
+        onActive();
+    }
+
+    private void onActive() {
+        notifyEvent(mLastObservedEvent);
+    }
+
+    @Override
+    public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
+        requireNonNull(activity);
+        notifyEvent(Event.ON_CREATE);
+    }
+
+    @Override
+    public void onActivityStarted(@NonNull Activity activity) {
+        requireNonNull(activity);
+        notifyEvent(Event.ON_START);
+    }
+
+    @Override
+    public void onActivityResumed(@NonNull Activity activity) {
+        requireNonNull(activity);
+        notifyEvent(Event.ON_RESUME);
+    }
+
+    @Override
+    public void onActivityPaused(@NonNull Activity activity) {
+        requireNonNull(activity);
+        notifyEvent(Event.ON_PAUSE);
+    }
+
+    @Override
+    public void onActivityStopped(@NonNull Activity activity) {
+        requireNonNull(activity);
+        notifyEvent(Event.ON_STOP);
+    }
+
+    @Override
+    public void onActivityDestroyed(@NonNull Activity activity) {
+        requireNonNull(activity);
+        notifyEvent(Event.ON_DESTROY);
+    }
+
+    @Override
+    public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
+        // No-op
+    }
+
+    private void notifyEvent(Event event) {
+        mLastObservedEvent = event;
+
+        if (mLifecycleListener == null) {
+            return;
+        }
+
+        try {
+            switch (event) {
+                case ON_CREATE:
+                    mLifecycleListener.onCreate();
+                    break;
+                case ON_START:
+                    mLifecycleListener.onStart();
+                    break;
+                case ON_RESUME:
+                    mLifecycleListener.onResume();
+                    break;
+                case ON_PAUSE:
+                    mLifecycleListener.onPause();
+                    break;
+                case ON_STOP:
+                    mLifecycleListener.onStop();
+                    break;
+                case ON_DESTROY:
+                    mLifecycleListener.onDestroyed();
+                    break;
+                case ON_ANY:
+                    break;
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Remote connection lost", e);
+        }
+    }
+}
+
diff --git a/car/app/app-aaos/src/main/java/androidx/car/app/aaos/CarAppActivity.java b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/CarAppActivity.java
new file mode 100644
index 0000000..1d47918
--- /dev/null
+++ b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/CarAppActivity.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos;
+
+import static android.content.pm.PackageManager.NameNotFoundException;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.car.app.aaos.renderer.IBackButtonListener;
+import androidx.car.app.aaos.renderer.ICarAppActivity;
+import androidx.car.app.aaos.renderer.IInputConnectionListener;
+import androidx.car.app.aaos.renderer.ILifecycleListener;
+import androidx.car.app.aaos.renderer.IRendererService;
+import androidx.car.app.aaos.renderer.IRotaryEventListener;
+import androidx.car.app.aaos.renderer.surface.ISurfaceListener;
+import androidx.car.app.aaos.renderer.surface.SurfaceHolderListener;
+import androidx.car.app.aaos.renderer.surface.SurfacePackageCompat;
+import androidx.car.app.aaos.renderer.surface.SurfaceWrapperProvider;
+import androidx.car.app.aaos.renderer.surface.TemplateSurfaceView;
+import androidx.car.app.utils.ThreadUtils;
+
+import java.util.List;
+
+/**
+ * The class representing all the car app activities. This class is responsible for binding to the
+ * host and rendering the content given by the car app service.
+ *
+ * <p> The apps that wish to show their content in AAOS, should define an activity-alias for the
+ * {@link  CarAppActivity} and provide the car app service associated with the activity using a
+ * metadata tag.
+ */
+//TODO(b/179146927) update javadoc
+@SuppressLint({"ForbiddenSuperClass"})
+public final class CarAppActivity extends Activity {
+    @VisibleForTesting
+    static final String SERVICE_METADATA_KEY = "car-app-service";
+    private static final String TAG = "TemplateActivity";
+
+    // TODO(b/177448399): Update after service intent action is added to car-lib.
+    @SuppressLint({"ActionValue"})
+    @VisibleForTesting
+    static final String ACTION_RENDER = "android.car.template.host.action.RENDER";
+
+    private ComponentName mServiceComponentName;
+    TemplateSurfaceView mSurfaceView;
+    SurfaceHolderListener mSurfaceHolderListener;
+    ActivityLifecycleDelegate mActivityLifecycleDelegate;
+    @Nullable
+    IBackButtonListener mBackButtonListener;
+    @Nullable
+    IRendererService mRendererService;
+    private int mDisplayId;
+
+    /**
+     * {@link ICarAppActivity} implementation that allows the {@link IRendererService} to
+     * communicate with this {@link CarAppActivity}.
+     */
+    private final ICarAppActivity.Stub mCarActivity = new ICarAppActivity.Stub() {
+        @Override
+        public void setSurfacePackage(@NonNull SurfacePackageCompat surfacePackage) {
+            requireNonNull(surfacePackage);
+            ThreadUtils.runOnMain(() -> mSurfaceView.setSurfacePackage(surfacePackage));
+        }
+
+        @Override
+        public void setSurfaceListener(@NonNull ISurfaceListener listener) {
+            requireNonNull(listener);
+            ThreadUtils.runOnMain(() -> mSurfaceHolderListener.setSurfaceListener(listener));
+        }
+
+        @Override
+        public void setLifecycleListener(@NonNull ILifecycleListener listener) {
+            requireNonNull(listener);
+            ThreadUtils.runOnMain(() -> mActivityLifecycleDelegate.setLifecycleListener(listener));
+        }
+
+        @Override
+        public void setBackButtonListener(@NonNull IBackButtonListener listener) {
+            mBackButtonListener = requireNonNull(listener);
+            mSurfaceView.setBackButtonListener(listener);
+        }
+
+        @Override
+        public void onStartInput() {
+            ThreadUtils.runOnMain(() -> mSurfaceView.onStartInput());
+        }
+
+        @Override
+        public void onStopInput() {
+            ThreadUtils.runOnMain(() -> mSurfaceView.onStopInput());
+        }
+
+        @Override
+        public void setInputConnectionListener(@NonNull IInputConnectionListener listener) {
+            mSurfaceView.setInputConnectionListener(requireNonNull(listener));
+        }
+
+        @Override
+        public void setRotaryEventListener(@NonNull IRotaryEventListener listener) {
+            mSurfaceView.setRotaryEventListener(requireNonNull(listener));
+        }
+
+        @Override
+        public void startCarApp(@NonNull Intent intent) {
+            startActivity(intent);
+        }
+
+        @Override
+        public void finishCarApp() {
+            finish();
+        }
+    };
+
+    /** The service connection for the renderer service. */
+    private ServiceConnection mServiceConnectionImpl = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(@NonNull ComponentName name,
+                @NonNull IBinder service) {
+            requireNonNull(name);
+            requireNonNull(service);
+            IRendererService rendererService = IRendererService.Stub.asInterface(service);
+            if (rendererService == null) {
+                onServiceConnectionError(String.format("Failed to get IRenderService binder from "
+                        + "host: %s", name.flattenToShortString()));
+                return;
+            }
+
+            verifyServiceVersion(rendererService);
+            initializeService(rendererService);
+            updateIntent(rendererService);
+            CarAppActivity.this.mRendererService = rendererService;
+        }
+
+        @Override
+        public void onServiceDisconnected(@NonNull ComponentName name) {
+            onServiceConnectionError(
+                    String.format("Host service %s is disconnected", requireNonNull(name)));
+        }
+    };
+
+    @SuppressWarnings("deprecation")
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_template);
+
+        mServiceComponentName = serviceComponentName();
+        if (mServiceComponentName == null) {
+            Log.e(TAG, "Unspecified service class name");
+            finish();
+            return;
+        }
+
+        mActivityLifecycleDelegate = new ActivityLifecycleDelegate();
+        registerActivityLifecycleCallbacks(mActivityLifecycleDelegate);
+
+        mSurfaceView = requireViewById(R.id.template_view_surface);
+
+        // Set the z-order to receive the UI events on the surface.
+        mSurfaceView.setZOrderOnTop(true);
+
+        mSurfaceHolderListener = new SurfaceHolderListener(
+                new SurfaceWrapperProvider(mSurfaceView));
+        mSurfaceView.getHolder().addCallback(mSurfaceHolderListener);
+        mDisplayId = getWindowManager().getDefaultDisplay().getDisplayId();
+        bindService();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        if (mSurfaceView != null) {
+            mSurfaceView.setVisibility(View.GONE);
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        if (mSurfaceView != null) {
+            mSurfaceView.setVisibility(View.VISIBLE);
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        if (isFinishing()) {
+            unbindService();
+        }
+        super.onDestroy();
+    }
+
+    @Override
+    public void onBackPressed() {
+        if (mBackButtonListener != null) {
+            try {
+                mBackButtonListener.onBackPressed();
+            } catch (RemoteException e) {
+                onServiceConnectionError(
+                        "Failed to send onBackPressed event to renderer: " + e.getMessage());
+            }
+        }
+    }
+
+    @Override
+    protected void onNewIntent(@Nullable Intent intent) {
+        super.onNewIntent(intent);
+        if (mRendererService == null) {
+            bindService();
+        } else {
+            updateIntent(mRendererService);
+        }
+    }
+
+    @VisibleForTesting
+    ServiceConnection getServiceConnection() {
+        return mServiceConnectionImpl;
+    }
+
+    @VisibleForTesting
+    void setServiceConnection(ServiceConnection serviceConnection) {
+        mServiceConnectionImpl = serviceConnection;
+    }
+
+    @VisibleForTesting
+    int getDisplayId() {
+        return mDisplayId;
+    }
+
+    @Nullable
+    private ComponentName serviceComponentName() {
+        ActivityInfo activityInfo = null;
+        try {
+            activityInfo = getPackageManager().getActivityInfo(getComponentName(),
+                    PackageManager.GET_META_DATA);
+        } catch (NameNotFoundException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Unable to find component: " + getComponentName(), e);
+        }
+
+        if (activityInfo == null) {
+            return null;
+        }
+
+        String serviceName = activityInfo.metaData.getString(SERVICE_METADATA_KEY);
+        if (serviceName == null) {
+            Log.e(LogTags.TAG_AAOS_HOST, String.format("Unable to find required metadata tag with "
+                            + "name %s. App manifest must include metadata tag with name %s and "
+                            + "the name of the car app service as the value",
+                    SERVICE_METADATA_KEY,
+                    SERVICE_METADATA_KEY));
+            return null;
+        }
+
+        return new ComponentName(this, serviceName);
+    }
+
+    /** Binds to the renderer service. */
+    private void bindService() {
+        Intent rendererIntent = new Intent(ACTION_RENDER);
+        List<ResolveInfo> resolveInfoList = getPackageManager().queryIntentServices(rendererIntent,
+                PackageManager.GET_META_DATA);
+        if (resolveInfoList.size() == 1) {
+            rendererIntent.setPackage(resolveInfoList.get(0).serviceInfo.packageName);
+        } else if (resolveInfoList.isEmpty()) {
+            onServiceConnectionError("Host was not found");
+            //TODO("b/161744611: Unavailable host fallback is not implemented")
+        } else {
+
+            StringBuilder logMessage = new StringBuilder("Multiple hosts found, only one is "
+                    + "allowed");
+            for (ResolveInfo resolveInfo : resolveInfoList) {
+                logMessage.append(String.format("\nFound host %s",
+                        resolveInfo.serviceInfo.packageName));
+            }
+            onServiceConnectionError(logMessage.toString());
+            //TODO("b/177083268: Multiple hosts support is not implemented")
+        }
+
+        if (!bindService(rendererIntent, mServiceConnectionImpl, Context.BIND_AUTO_CREATE)) {
+            onServiceConnectionError(
+                    "Cannot bind to the renderer host with intent: " + rendererIntent);
+        }
+    }
+
+    /**
+     * Handles the service connection errors by unbinding from the service and finishing the
+     * activity.
+     *
+     * @param errorMessage the error message to be shown in the logs
+     */
+    void onServiceConnectionError(@Nullable String errorMessage) {
+        // TODO(b/171085325): Add Rendering error handling
+        if (errorMessage != null) {
+            Log.e(TAG, errorMessage);
+        }
+        // Remove the lifecycle listener since there is no need to communicate the state with
+        // the host.
+        mActivityLifecycleDelegate.setLifecycleListener(null);
+        finish();
+    }
+
+    /**
+     * Verifies that the renderer service supports the current version.
+     *
+     * @param rendererService the renderer service which should verify the version
+     */
+    void verifyServiceVersion(IRendererService rendererService) {
+        // TODO(169604451) Add version support logic
+    }
+
+    /**
+     * Initializes the {@code rendererService} for the current activity with {@code carActivity},
+     * {@code serviceComponentName} and {@code displayId}.
+     *
+     * @param rendererService the renderer service that needs to be initialized
+     */
+    void initializeService(@NonNull IRendererService rendererService) {
+        requireNonNull(rendererService);
+        try {
+            if (!rendererService.initialize(mCarActivity, mServiceComponentName,
+                    mDisplayId)) {
+                throw new IllegalArgumentException(
+                        "Cannot create renderer for" + mServiceComponentName);
+            }
+        } catch (RemoteException e) {
+            onServiceConnectionError(
+                    "Failed to call onCreateActivity on renderer: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Closes the connection to the connected {@code rendererService} if any.
+     */
+    private void unbindService() {
+        mSurfaceView.getHolder().removeCallback(mSurfaceHolderListener);
+        // If host has already disconnected, there is no need for an unbind.
+        if (mRendererService == null) {
+            return;
+        }
+        try {
+            mRendererService.terminate(mServiceComponentName);
+        } catch (RemoteException e) {
+            // We are already unbinding (maybe because the host has already cut the connection)
+            // Let's not log more errors unnecessarily.
+            //TODO(179506019): Revisit calls to unbindService()
+        }
+
+        unbindService(mServiceConnectionImpl);
+        mRendererService = null;
+    }
+
+    /**
+     * Updates the activity intent for the {@code rendererService}.
+     *
+     * @param rendererService the renderer service that needs to handle the new intent
+     */
+    void updateIntent(@NonNull IRendererService rendererService) {
+        requireNonNull(rendererService);
+        Intent intent = getIntent();
+        try {
+            if (!rendererService.onNewIntent(intent, mServiceComponentName, mDisplayId)) {
+                throw new IllegalArgumentException("Renderer cannot handle the intent: " + intent);
+            }
+        } catch (RemoteException e) {
+            onServiceConnectionError(
+                    "Failed to send new intent to renderer: " + e.getMessage());
+        }
+    }
+}
diff --git a/car/app/app-aaos/src/main/java/androidx/car/app/aaos/LogTags.java b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/LogTags.java
new file mode 100644
index 0000000..458c702
--- /dev/null
+++ b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/LogTags.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+
+import androidx.annotation.RestrictTo;
+
+/**
+ * Assorted tags for logging.
+ *
+ * @hide
+ */
+@RestrictTo(LIBRARY)
+public final class LogTags {
+    public static final String TAG_AAOS_HOST = "CarApp.H";
+
+    private LogTags() {
+    }
+}
diff --git a/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/rotary/FocusDispatcherView.java b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/rotary/FocusDispatcherView.java
new file mode 100644
index 0000000..5b0de5e
--- /dev/null
+++ b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/rotary/FocusDispatcherView.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos.renderer.rotary;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.car.app.aaos.R;
+
+/**
+ * A view to dispatch the focus to another view.
+ *
+ * Once focused, dispatches the focus to the focus target specified as app:focusTarget.
+ */
+final class FocusDispatcherView extends View {
+    private final int mFocusTargetId;
+
+    FocusDispatcherView(@NonNull Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs, 0);
+        // This view is focusable, visible and enabled so it can take focus.
+        setFocusable(FOCUSABLE);
+        setVisibility(VISIBLE);
+        setEnabled(true);
+
+        // This view is always transparent.
+        setAlpha(0.0F);
+
+        // Prevent Android from drawing the default focus highlight for this view when it's focused.
+        setDefaultFocusHighlightEnabled(false);
+
+        // Get the focus target reference.
+        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.FocusDispatcherView, 0,
+                0);
+        try {
+            mFocusTargetId = ta.getResourceId(R.styleable.FocusDispatcherView_focusTarget, 0);
+        } finally {
+            ta.recycle();
+        }
+    }
+
+    @Override
+    protected void onFocusChanged(boolean gainFocus, int direction,
+            @Nullable Rect previouslyFocusedRect) {
+        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+        if (gainFocus) {
+            // Need to query the focus view every time since it is not a child view and can be
+            // changed without our knowledge.
+            View targetView = getRootView().findViewById(mFocusTargetId);
+            if (targetView != null) {
+                targetView.requestFocus();
+            }
+        }
+    }
+}
diff --git a/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/rotary/FocusParkingView.java b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/rotary/FocusParkingView.java
new file mode 100644
index 0000000..da196e3
--- /dev/null
+++ b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/rotary/FocusParkingView.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos.renderer.rotary;
+
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * A transparent {@link View} that can take focus. It's used by the Rotary service to support rotary
+ * controller navigation. It's also used to initialize the focus when in rotary mode.
+ * <p>
+ * To support the rotary controller, each {@link android.view.Window} must have a FocusParkingView
+ * as the first focusable view in the view tree.
+ * <p>
+ * Android doesn't clear focus automatically when focus is set in another window. If we try to clear
+ * focus in the previous window, Android will re-focus a view in that window, resulting in two
+ * windows being focused simultaneously. Adding this view to each window can fix this issue. This
+ * view is transparent and its default focus highlight is disabled, so it's invisible to the user no
+ * matter whether it's focused or not. It can take focus so that RotaryService can "park" the focus
+ * on it to remove the focus highlight.
+ * <p>
+ * If there is only one focus area in the current window, rotating the controller within the focus
+ * area will cause RotaryService to move the focus around from the view on the right to the view on
+ * the left or vice versa. Adding this view to each window can fix this issue. When RotaryService
+ * finds out the focus target is a FocusParkingView, it will know a wrap-around is going to happen.
+ * Then it will avoid the wrap-around by not moving focus.
+ * <p>
+ * To ensure the focus is initialized properly when there is a window change, the FocusParkingView
+ * will not get focused when the framework wants to focus on it. Instead, it will try to find a
+ * better focus target in the window and focus on the target. That said, the FocusParkingView can
+ * still be focused in order to clear focus highlight in the window, such as when RotaryService
+ * performs {@link android.view.accessibility.AccessibilityNodeInfo#ACTION_FOCUS} on the
+ * FocusParkingView, or the window has lost focus.
+ */
+class FocusParkingView extends View {
+    /**
+     * This value should not change, even if the actual package containing this class is different
+     * as this value must match the value defined at
+     * <a href="https://android.googlesource.com/platform/packages/apps/Car/RotaryController/+/refs/heads/android11-release/src/com/android/car/rotary/Utils.java#46">Utils#FOCUS_PARKING_VIEW_CLASS_NAME</a>
+     */
+    private static final String FOCUS_PARKING_VIEW_LITE_CLASS_NAME =
+            "com.android.car.rotary.FocusParkingView";
+
+    /** Action performed on this view to hide the IME. */
+    private static final int ACTION_HIDE_IME = 0x08000000;
+
+    FocusParkingView(@NonNull Context context) {
+        super(context);
+        init();
+    }
+
+    FocusParkingView(@NonNull Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    FocusParkingView(@NonNull Context context, @Nullable AttributeSet attrs,
+            int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    FocusParkingView(@NonNull Context context, @Nullable AttributeSet attrs,
+            int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init();
+    }
+
+    private void init() {
+        // This view is focusable, visible and enabled so it can take focus.
+        setFocusable(View.FOCUSABLE);
+        setVisibility(VISIBLE);
+        setEnabled(true);
+
+        // This view is not clickable so it won't affect the app's behavior when the user clicks on
+        // it by accident.
+        setClickable(false);
+
+        // This view is always transparent.
+        setAlpha(0f);
+
+        // Prevent Android from drawing the default focus highlight for this view when it's focused.
+        setDefaultFocusHighlightEnabled(false);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        // This size of the view is always 1 x 1 pixel, no matter what value is set in the layout
+        // file (match_parent, wrap_content, 100dp, 0dp, etc). Small size is to ensure it has little
+        // impact on the layout, non-zero size is to ensure it can take focus.
+        setMeasuredDimension(1, 1);
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasWindowFocus) {
+        if (!hasWindowFocus) {
+            // We need to clear the focus highlight(by parking the focus on this view)
+            // once the current window goes to background. This can't be done by RotaryService
+            // because RotaryService sees the window as removed, thus can't perform any action
+            // (such as focus, clear focus) on the nodes in the window. So this view has to
+            // grab the focus proactively.
+            super.requestFocus(FOCUS_DOWN, null);
+        }
+        super.onWindowFocusChanged(hasWindowFocus);
+    }
+
+    @NonNull
+    @Override
+    public CharSequence getAccessibilityClassName() {
+        return FOCUS_PARKING_VIEW_LITE_CLASS_NAME;
+    }
+
+    @Override
+    public boolean performAccessibilityAction(int action, @Nullable Bundle arguments) {
+        switch (action) {
+            case ACTION_HIDE_IME:
+                InputMethodManager inputMethodManager =
+                        getContext().getSystemService(InputMethodManager.class);
+                return inputMethodManager.hideSoftInputFromWindow(getWindowToken(),
+                        /* flags= */ 0);
+            case ACTION_FOCUS:
+                // Don't leave this to View to handle as it will exit touch mode.
+                if (!hasFocus()) {
+                    return super.requestFocus(FOCUS_DOWN, null);
+                }
+                return false;
+        }
+        return super.performAccessibilityAction(action, arguments);
+    }
+}
diff --git a/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/LegacySurfacePackage.java b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/LegacySurfacePackage.java
new file mode 100644
index 0000000..d947f7e
--- /dev/null
+++ b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/LegacySurfacePackage.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos.renderer.surface;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.SuppressLint;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.MotionEvent;
+
+import androidx.annotation.NonNull;
+
+/**
+ * A serializable class containing all the data required to render and interact with a surface from
+ * an off-process renderer.
+ *
+ * This class exists for compatibility with Q devices. In Android R and later,
+ * {@link android.view.SurfaceControlViewHost.SurfacePackage} will be used instead.
+ */
+//TODO(179714355): Investigate using Bundleable instead of Parcelable
+@SuppressLint({"BanParcelableUsage"})
+public final class LegacySurfacePackage implements Parcelable {
+    private final ISurfaceControl mSurfaceControl;
+
+    /**
+     * Creates a {@link LegacySurfacePackage}.
+     *
+     * @param callback a {@link SurfaceControlCallback} to be registered to receive off-process
+     *                 renderer events affecting the {@link android.view.SurfaceView} that
+     *                 content is rendered on.
+     */
+    @SuppressLint("ExecutorRegistration")
+    public LegacySurfacePackage(@NonNull SurfaceControlCallback callback) {
+        mSurfaceControl = new ISurfaceControl.Stub() {
+            final SurfaceControlCallback mCallback = callback;
+
+            @Override
+            public void setSurfaceWrapper(@NonNull SurfaceWrapper surfaceWrapper) {
+                requireNonNull(surfaceWrapper);
+                if (mCallback != null) {
+                    mCallback.setSurfaceWrapper(surfaceWrapper);
+                }
+            }
+
+            @Override
+            public void onWindowFocusChanged(boolean hasFocus, boolean isInTouchMode) {
+                if (mCallback != null) {
+                    mCallback.onWindowFocusChanged(hasFocus, isInTouchMode);
+                }
+            }
+
+            @Override
+            public void onTouchEvent(@NonNull MotionEvent event) {
+                requireNonNull(event);
+                if (mCallback != null) {
+                    mCallback.onTouchEvent(event);
+                }
+            }
+        };
+    }
+
+    LegacySurfacePackage(@NonNull Parcel parcel) {
+        mSurfaceControl = ISurfaceControl.Stub.asInterface(parcel.readStrongBinder());
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeStrongInterface(mSurfaceControl);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @NonNull
+    ISurfaceControl getSurfaceControl() {
+        return mSurfaceControl;
+    }
+
+    @NonNull
+    public static final Creator<LegacySurfacePackage> CREATOR =
+            new Creator<LegacySurfacePackage>() {
+                @NonNull
+                @Override
+                public LegacySurfacePackage createFromParcel(@NonNull Parcel parcel) {
+                    return new LegacySurfacePackage(parcel);
+                }
+
+                @NonNull
+                @Override
+                public LegacySurfacePackage[] newArray(int size) {
+                    return new LegacySurfacePackage[size];
+                }
+            };
+}
+
diff --git a/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/RemoteProxyInputConnection.java b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/RemoteProxyInputConnection.java
new file mode 100644
index 0000000..209a054
--- /dev/null
+++ b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/RemoteProxyInputConnection.java
@@ -0,0 +1,357 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos.renderer.surface;
+
+import static java.util.Objects.requireNonNull;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.inputmethod.CompletionInfo;
+import android.view.inputmethod.CorrectionInfo;
+import android.view.inputmethod.ExtractedText;
+import android.view.inputmethod.ExtractedTextRequest;
+import android.view.inputmethod.InputConnectionWrapper;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.car.app.aaos.LogTags;
+import androidx.car.app.aaos.renderer.IProxyInputConnection;
+
+/** Proxies input connection calls to the provided {@link IProxyInputConnection}. */
+final class RemoteProxyInputConnection extends InputConnectionWrapper {
+    private final IProxyInputConnection mProxyInputConnection;
+
+    RemoteProxyInputConnection(@NonNull IProxyInputConnection proxyInputConnection) {
+        super(null, true);
+        mProxyInputConnection = proxyInputConnection;
+    }
+
+    @Nullable
+    @Override
+    public CharSequence getTextBeforeCursor(int n, int flags) {
+        CharSequence text;
+        try {
+            text = mProxyInputConnection.getTextBeforeCursor(n, flags);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            text = null;
+        }
+        return text;
+    }
+
+    @Nullable
+    @Override
+    public CharSequence getTextAfterCursor(int n, int flags) {
+        CharSequence text;
+        try {
+            text = mProxyInputConnection.getTextAfterCursor(n, flags);
+        } catch (RemoteException e) {
+            Log.w(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            text = null;
+        }
+
+        return text;
+    }
+
+    @Nullable
+    @Override
+    public CharSequence getSelectedText(int flags) {
+        CharSequence text;
+        try {
+            text = mProxyInputConnection.getSelectedText(flags);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            text = null;
+        }
+
+        return text;
+    }
+
+    @Override
+    public int getCursorCapsMode(int reqModes) {
+        int text;
+        try {
+            text = mProxyInputConnection.getCursorCapsMode(reqModes);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            text = 0;
+        }
+
+        return text;
+    }
+
+    @Nullable
+    @Override
+    public ExtractedText getExtractedText(@NonNull ExtractedTextRequest request, int flags) {
+        requireNonNull(request);
+        ExtractedText text;
+        try {
+            text = mProxyInputConnection.getExtractedText(request, flags);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            text = null;
+        }
+
+        return text;
+    }
+
+    @Override
+    public boolean deleteSurroundingText(int beforeLength, int afterLength) {
+        boolean success;
+        try {
+            success = mProxyInputConnection.deleteSurroundingText(beforeLength, afterLength);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean setComposingText(@NonNull CharSequence text, int newCursorPosition) {
+        requireNonNull(text);
+        boolean success;
+        try {
+            success = mProxyInputConnection.setComposingText(text, newCursorPosition);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean setComposingRegion(int start, int end) {
+        boolean success;
+        try {
+            success = mProxyInputConnection.setComposingRegion(start, end);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean finishComposingText() {
+        boolean success;
+        try {
+            success = mProxyInputConnection.finishComposingText();
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean commitText(@NonNull CharSequence text, int newCursorPosition) {
+        requireNonNull(text);
+        boolean success;
+        try {
+            success = mProxyInputConnection.commitText(text, newCursorPosition);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean commitCompletion(@NonNull CompletionInfo text) {
+        requireNonNull(text);
+        boolean success;
+        try {
+            success = mProxyInputConnection.commitCompletion(text);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean commitCorrection(@NonNull CorrectionInfo correctionInfo) {
+        requireNonNull(correctionInfo);
+        boolean success;
+        try {
+            success = mProxyInputConnection.commitCorrection(correctionInfo);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean setSelection(int start, int end) {
+        boolean success;
+        try {
+            success = mProxyInputConnection.setSelection(start, end);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean performEditorAction(int editorAction) {
+        boolean success;
+        try {
+            success = mProxyInputConnection.performEditorAction(editorAction);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean performContextMenuAction(int id) {
+        boolean success;
+        try {
+            success = mProxyInputConnection.performContextMenuAction(id);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean beginBatchEdit() {
+        boolean success;
+        try {
+            success = mProxyInputConnection.beginBatchEdit();
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean endBatchEdit() {
+        boolean success;
+        try {
+            success = mProxyInputConnection.endBatchEdit();
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean sendKeyEvent(@NonNull KeyEvent event) {
+        requireNonNull(event);
+        boolean success;
+        try {
+            success = mProxyInputConnection.sendKeyEvent(event);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean clearMetaKeyStates(int states) {
+        boolean success;
+        try {
+            success = mProxyInputConnection.clearMetaKeyStates(states);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean reportFullscreenMode(boolean enabled) {
+        boolean success;
+        try {
+            success = mProxyInputConnection.reportFullscreenMode(enabled);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean performPrivateCommand(@NonNull String action, @NonNull Bundle data) {
+        requireNonNull(action);
+        requireNonNull(data);
+        boolean success;
+        try {
+            success = mProxyInputConnection.performPrivateCommand(action, data);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean requestCursorUpdates(int cursorUpdateMode) {
+        boolean success;
+        try {
+            success = mProxyInputConnection.requestCursorUpdates(cursorUpdateMode);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    public void closeConnection() {
+        try {
+            mProxyInputConnection.closeConnection();
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+        }
+    }
+
+    @Nullable
+    @Override
+    public Handler getHandler() {
+        return null;
+    }
+}
diff --git a/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/SurfaceControlCallback.java b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/SurfaceControlCallback.java
new file mode 100644
index 0000000..6df9726
--- /dev/null
+++ b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/SurfaceControlCallback.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos.renderer.surface;
+
+import android.annotation.SuppressLint;
+import android.view.MotionEvent;
+
+import androidx.annotation.NonNull;
+
+/**
+ * A host-side interface for reporting to an off-process renderer events affecting the
+ * {@link android.view.SurfaceView} it renders content on.
+ */
+public interface SurfaceControlCallback {
+    /** Notifies when the underlying surface changes. */
+    @SuppressLint({"CallbackMethodName"})
+    void setSurfaceWrapper(@NonNull SurfaceWrapper surfaceWrapper);
+
+    /** Notifies when {@link android.view.SurfaceView} receives a new touch event. */
+    void onTouchEvent(@NonNull MotionEvent event);
+
+    /** Notifies when the window focus changes. */
+    void onWindowFocusChanged(boolean hasFocus, boolean isInTouchMode);
+}
diff --git a/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/SurfaceHolderListener.java b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/SurfaceHolderListener.java
new file mode 100644
index 0000000..67cb801
--- /dev/null
+++ b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/SurfaceHolderListener.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos.renderer.surface;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+
+import static java.util.Objects.requireNonNull;
+
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.car.app.aaos.LogTags;
+
+/**
+ * A listener of {@link SurfaceHolder}.
+ *
+ * @hide
+ */
+@RestrictTo(LIBRARY)
+public class SurfaceHolderListener implements SurfaceHolder.Callback {
+    private ISurfaceListener mSurfaceListener;
+    private boolean mIsSurfaceAvailable;
+    private final SurfaceWrapperProvider mSurfaceWrapperProvider;
+
+    public SurfaceHolderListener(@NonNull SurfaceWrapperProvider surfaceWrapperProvider) {
+        super();
+        mSurfaceWrapperProvider = surfaceWrapperProvider;
+    }
+
+    /**
+     * Registers a listener for surface events.
+     */
+    public final void setSurfaceListener(@Nullable ISurfaceListener surfaceListener) {
+        mSurfaceListener = surfaceListener;
+        onActive();
+    }
+
+    private void onActive() {
+        if (mIsSurfaceAvailable) {
+            notifySurfaceCreated();
+        }
+    }
+
+    @Override
+    public void surfaceCreated(@NonNull SurfaceHolder holder) {
+        requireNonNull(holder);
+        mIsSurfaceAvailable = true;
+        notifySurfaceCreated();
+    }
+
+    @Override
+    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
+        requireNonNull(holder);
+        notifySurfaceChanged();
+    }
+
+    @Override
+    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+        mIsSurfaceAvailable = false;
+    }
+
+    private void notifySurfaceCreated() {
+        try {
+            if (mSurfaceListener != null) {
+                mSurfaceListener.onSurfaceAvailable(mSurfaceWrapperProvider.createSurfaceWrapper());
+            }
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+        }
+
+    }
+
+    private void notifySurfaceChanged() {
+        try {
+            if (mSurfaceListener != null) {
+                mSurfaceListener.onSurfaceChanged(mSurfaceWrapperProvider.createSurfaceWrapper());
+            }
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+        }
+    }
+}
diff --git a/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/SurfacePackageCompat.java b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/SurfacePackageCompat.java
new file mode 100644
index 0000000..25b21d4
--- /dev/null
+++ b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/SurfacePackageCompat.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos.renderer.surface;
+
+import android.annotation.SuppressLint;
+import android.os.Build;
+import android.os.Build.VERSION;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.SurfaceControlViewHost.SurfacePackage;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+
+/**
+ * A parcelable that stores either a {@link LegacySurfacePackage} or a
+ * {@link android.view.SurfaceControlViewHost.SurfacePackage}.
+ *
+ * Please note that {@link android.view.SurfaceControlViewHost.SurfacePackage} requires API level R.
+ */
+//TODO(179714355): Investigate using Bundleable instead of Parcelable
+@SuppressLint({"BanParcelableUsage"})
+public final class SurfacePackageCompat implements Parcelable {
+    enum SurfacePackageType {
+        LEGACY,
+        SURFACE_CONTROL;
+    }
+
+    @Nullable
+    private final Parcelable mSurfacePackage;
+
+    /**
+     * Creates a {@link SurfacePackageCompat} that stores a
+     * {@link android.view.SurfaceControlViewHost.SurfacePackage}.
+     *
+     * @param legacySurfacePackage the {@link android.view.SurfaceControlViewHost.SurfacePackage}
+     *                             to be stored in this wrapper.
+     */
+    public SurfacePackageCompat(@NonNull LegacySurfacePackage legacySurfacePackage) {
+        mSurfacePackage = legacySurfacePackage;
+    }
+
+    /**
+     * Creates a {@link SurfacePackageCompat} that stores a {@link LegacySurfacePackage}.
+     *
+     * @param surfacePackage the {@link LegacySurfacePackage} to be stored in this wrapper.
+     */
+    @RequiresApi(Build.VERSION_CODES.R)
+    public SurfacePackageCompat(@NonNull SurfacePackage surfacePackage) {
+        mSurfacePackage = surfacePackage;
+    }
+
+    SurfacePackageCompat(Parcel parcel) {
+        SurfacePackageType type = SurfacePackageType.values()[parcel.readInt()];
+        if (type == SurfacePackageType.LEGACY) {
+            mSurfacePackage = parcel.readParcelable(LegacySurfacePackage.class.getClassLoader());
+        } else if (type == SurfacePackageCompat.SurfacePackageType.SURFACE_CONTROL
+                && VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+            mSurfacePackage = parcel.readParcelable(SurfacePackage.class.getClassLoader());
+        } else {
+            mSurfacePackage = null;
+        }
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        SurfacePackageCompat.SurfacePackageType type =
+                mSurfacePackage instanceof LegacySurfacePackage
+                        ? SurfacePackageCompat.SurfacePackageType.LEGACY
+                        : SurfacePackageCompat.SurfacePackageType.SURFACE_CONTROL;
+        parcel.writeInt(type.ordinal());
+        parcel.writeParcelable(mSurfacePackage, flags);
+    }
+
+    @Nullable
+    public Parcelable getSurfacePackage() {
+        return mSurfacePackage;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @NonNull
+    public static final Creator<SurfacePackageCompat> CREATOR =
+            new Creator<SurfacePackageCompat>() {
+                @NonNull
+                @Override
+                public SurfacePackageCompat createFromParcel(@NonNull Parcel parcel) {
+                    return new SurfacePackageCompat(parcel);
+                }
+
+                @NonNull
+                @Override
+                public SurfacePackageCompat[] newArray(int size) {
+                    return new SurfacePackageCompat[size];
+                }
+            };
+}
+
diff --git a/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/SurfaceWrapper.java b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/SurfaceWrapper.java
new file mode 100644
index 0000000..474196a
--- /dev/null
+++ b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/SurfaceWrapper.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos.renderer.surface;
+
+import android.annotation.SuppressLint;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.Surface;
+import android.view.SurfaceView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * A class holding the information needed to render the content on a surface.
+ */
+//TODO(179714355): Investigate using Bundleable instead of Parcelable
+@SuppressLint("BanParcelableUsage")
+public final class SurfaceWrapper implements Parcelable {
+    @Nullable
+    private final IBinder mHostToken;
+    private final int mWidth;
+    private final int mHeight;
+    private final int mDisplayId;
+    private final int mDensityDpi;
+    private final Surface mSurface;
+
+    /**
+     * Creates a {@link SurfaceWrapper}.
+     *
+     * @param hostToken  a token used for constructing SurfaceControlViewHost. see
+     *                   {@link SurfaceView} for more details
+     * @param width      the width of the surface view
+     * @param height     the height of the surface view
+     * @param displayId  the ID of the display showing the surface
+     * @param densityDpi the density of the display showing the surface
+     * @param surface    the surface for which the wrapper is created
+     */
+    public SurfaceWrapper(@Nullable IBinder hostToken, int width, int height, int displayId,
+            int densityDpi, @NonNull Surface surface) {
+        mHostToken = hostToken;
+        mWidth = width;
+        mHeight = height;
+        mDisplayId = displayId;
+        mDensityDpi = densityDpi;
+        mSurface = surface;
+    }
+
+    SurfaceWrapper(@NonNull Parcel parcel) {
+        mHostToken = parcel.readStrongBinder();
+        mWidth = parcel.readInt();
+        mHeight = parcel.readInt();
+        mDisplayId = parcel.readInt();
+        mDensityDpi = parcel.readInt();
+        mSurface = parcel.readParcelable(Surface.class.getClassLoader());
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeStrongBinder(mHostToken);
+        parcel.writeInt(mWidth);
+        parcel.writeInt(mHeight);
+        parcel.writeInt(mDisplayId);
+        parcel.writeInt(mDensityDpi);
+        parcel.writeParcelable((Parcelable) mSurface, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Nullable
+    public IBinder getHostToken() {
+        return mHostToken;
+    }
+
+    int getWidth() {
+        return mWidth;
+    }
+
+    int getHeight() {
+        return mHeight;
+    }
+
+    int getDisplayId() {
+        return mDisplayId;
+    }
+
+    int getDensityDpi() {
+        return mDensityDpi;
+    }
+
+    @NonNull
+    Surface getSurface() {
+        return mSurface;
+    }
+
+    @NonNull
+    public static final Creator<SurfaceWrapper> CREATOR = new Creator<SurfaceWrapper>() {
+        @NonNull
+        @Override
+        public SurfaceWrapper createFromParcel(@NonNull Parcel parcel) {
+            return new SurfaceWrapper(parcel);
+        }
+
+        @NonNull
+        @Override
+        public SurfaceWrapper[] newArray(int size) {
+            return new SurfaceWrapper[size];
+        }
+    };
+}
diff --git a/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/SurfaceWrapperProvider.java b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/SurfaceWrapperProvider.java
new file mode 100644
index 0000000..a2a43c0
--- /dev/null
+++ b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/SurfaceWrapperProvider.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos.renderer.surface;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+
+import android.os.IBinder;
+import android.util.DisplayMetrics;
+import android.view.Surface;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+
+/**
+ * Provides the render config for the given {@link TemplateSurfaceView}.
+ *
+ * @hide
+ */
+@RestrictTo(LIBRARY)
+public final class SurfaceWrapperProvider {
+    private final TemplateSurfaceView mSurfaceView;
+
+    public SurfaceWrapperProvider(@NonNull TemplateSurfaceView surfaceView) {
+        super();
+        mSurfaceView = surfaceView;
+    }
+
+    /** Creates a new render config for the current state of the holding surface view. */
+    @NonNull
+    public SurfaceWrapper createSurfaceWrapper() {
+        IBinder hostToken = mSurfaceView.getSurfaceToken();
+        int width = mSurfaceView.getWidth();
+        int height = mSurfaceView.getHeight();
+        int displayId = mSurfaceView.getDisplay().getDisplayId();
+        int densityDpi = densityDpi();
+        Surface surface = mSurfaceView.getHolder().getSurface();
+        return new SurfaceWrapper(hostToken, width, height, displayId, densityDpi, surface);
+    }
+
+    private int densityDpi() {
+        DisplayMetrics displayMetrics = new DisplayMetrics();
+        mSurfaceView.getDisplay().getRealMetrics(displayMetrics);
+        return displayMetrics.densityDpi;
+    }
+}
diff --git a/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/TemplateSurfaceView.java b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/TemplateSurfaceView.java
new file mode 100644
index 0000000..2b11220
--- /dev/null
+++ b/car/app/app-aaos/src/main/java/androidx/car/app/aaos/renderer/surface/TemplateSurfaceView.java
@@ -0,0 +1,415 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos.renderer.surface;
+
+import static android.view.KeyEvent.ACTION_DOWN;
+import static android.view.KeyEvent.KEYCODE_BACK;
+import static android.view.KeyEvent.KEYCODE_DPAD_CENTER;
+import static android.view.KeyEvent.KEYCODE_DPAD_DOWN;
+import static android.view.KeyEvent.KEYCODE_DPAD_LEFT;
+import static android.view.KeyEvent.KEYCODE_DPAD_RIGHT;
+import static android.view.KeyEvent.KEYCODE_DPAD_UP;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.Build;
+import android.os.Build.VERSION;
+import android.os.IBinder;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.SurfaceControlViewHost.SurfacePackage;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnTouchModeChangeListener;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputMethodManager;
+
+import androidx.annotation.DoNotInline;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+import androidx.car.app.aaos.LogTags;
+import androidx.car.app.aaos.renderer.IBackButtonListener;
+import androidx.car.app.aaos.renderer.IInputConnectionListener;
+import androidx.car.app.aaos.renderer.IProxyInputConnection;
+import androidx.car.app.aaos.renderer.IRotaryEventListener;
+
+/**
+ * A surface view suitable for template rendering.
+ *
+ * <p>This view supports surface package even for builds lower than {@link Build.VERSION_CODES.R}.
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+public final class TemplateSurfaceView extends SurfaceView {
+    private static final boolean SUPPORTS_SURFACE_CONTROL =
+            VERSION.SDK_INT >= Build.VERSION_CODES.R;
+
+    /**
+     * StateDescription for a {@link View} to support direct manipulation mode. It's also used as
+     * class name of {@link AccessibilityEvent} to indicate that the {@link AccessibilityEvent}
+     * represents a request to toggle direct manipulation mode.
+     *
+     * This value should not change, even if the actual package containing this class is different
+     * as this value must match the value defined at
+     * <a href="https://android.googlesource.com/platform/packages/apps/Car/libs/+/refs/heads/androi
+     * d11-release/car-ui-lib/src/com/android/car/ui/utils/DirectManipulationHelper.java#38">DIRECT_
+     * MANIPULATION</a>
+     */
+    private static final String DIRECT_MANIPULATION = "com.android.car.ui.utils"
+            + ".DIRECT_MANIPULATION";
+
+    @Nullable
+    private IInputConnectionListener mInputConnectionListener;
+    @Nullable
+    private IRotaryEventListener mRotaryEventListener;
+    @Nullable
+    private IBackButtonListener mBackButtonListener;
+
+    ISurfaceControl mSurfaceControl;
+    private boolean mIsInInputMode;
+
+    private final InputMethodManager mInputMethodManager =
+            (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+    private final SurfaceWrapperProvider mSurfaceWrapperProvider =
+            new SurfaceWrapperProvider(this);
+    private final OnTouchModeChangeListener mOnTouchModeChangeListener =
+            new ViewTreeObserver.OnTouchModeChangeListener() {
+                @Override
+                public void onTouchModeChanged(boolean isInTouchMode) {
+                    try {
+                        if (mSurfaceControl != null) {
+                            mSurfaceControl.onWindowFocusChanged(hasFocus(), isInTouchMode);
+                        }
+                    } catch (RemoteException e) {
+                        Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+                    }
+                }
+            };
+
+    TemplateSurfaceView(@NonNull Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs, 0);
+    }
+
+    public void setInputConnectionListener(
+            @Nullable IInputConnectionListener inputConnectionListener) {
+        mInputConnectionListener = inputConnectionListener;
+    }
+
+    public void setRotaryEventListener(
+            @Nullable IRotaryEventListener rotaryEventListener) {
+        mRotaryEventListener = rotaryEventListener;
+    }
+
+    public void setBackButtonListener(@Nullable IBackButtonListener backButtonListener) {
+        mBackButtonListener = backButtonListener;
+    }
+
+    /**
+     * Returns the surface token used to create a {@link android.view.SurfaceControlViewHost}, or
+     * null if not available.
+     */
+    @SuppressLint({"UnsafeNewApiCall"})
+    @Nullable
+    public IBinder getSurfaceToken() {
+        return SUPPORTS_SURFACE_CONTROL ? getHostToken() : null;
+    }
+
+    @Override
+    @NonNull
+    public AccessibilityNodeInfo createAccessibilityNodeInfo() {
+        AccessibilityNodeInfo accessibilityNodeInfo = super.createAccessibilityNodeInfo();
+        // Indicate this as an editable view so the rotary service does not remove the focus when
+        // IME is presented.
+        accessibilityNodeInfo.setEditable(mIsInInputMode);
+        return accessibilityNodeInfo;
+    }
+
+    @Override
+    protected void onFocusChanged(boolean gainFocus, int direction,
+            @Nullable Rect previouslyFocusedRect) {
+        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+        try {
+            if (mSurfaceControl != null) {
+                mSurfaceControl.onWindowFocusChanged(gainFocus, isInTouchMode());
+            }
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+        }
+        enableDirectManipulationMode(this, gainFocus);
+    }
+
+    @Override
+    @Nullable
+    public InputConnection onCreateInputConnection(@NonNull EditorInfo editorInfo) {
+        requireNonNull(editorInfo);
+
+        if (!mIsInInputMode || mInputConnectionListener == null) {
+            return null;
+        }
+
+        try {
+            IProxyInputConnection proxyInputConnection =
+                    mInputConnectionListener.onCreateInputConnection(editorInfo);
+
+            // Clear the input and return null if inputConnectionListener is null or there is no
+            // open input connection on the host.
+            if (proxyInputConnection == null) {
+                Log.e(LogTags.TAG_AAOS_HOST,
+                        "InputConnectionListener has not been received yet. Canceling the input");
+                onStopInput();
+                return null;
+            }
+            copyEditorInfo(proxyInputConnection.getEditorInfo(), editorInfo);
+            return new RemoteProxyInputConnection(proxyInputConnection);
+
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+        }
+
+        return null;
+    }
+
+    /**
+     * Enables or disables direct manipulation mode. This method sends an {@link AccessibilityEvent}
+     * to tell the Rotary service to enter or exit direct manipulation mode. Typically pressing
+     * the center button of the rotary controller with a direct manipulation view focused will
+     * enter direct manipulation mode, while pressing the Back button will exit direct
+     * manipulation mode.
+     *
+     * @param view   the direct manipulation view
+     * @param enable true to enter direct manipulation mode, false to exit direct manipulation mode
+     * @return whether the AccessibilityEvent was sent
+     */
+    private boolean enableDirectManipulationMode(@NonNull View view, boolean enable) {
+        requireNonNull(view);
+        AccessibilityManager accessibilityManager = (AccessibilityManager)
+                view.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
+        if (accessibilityManager == null || !accessibilityManager.isEnabled()) {
+            return false;
+        }
+        AccessibilityEvent event = AccessibilityEvent.obtain();
+        event.setClassName(DIRECT_MANIPULATION);
+        event.setSource(view);
+        event.setEventType(enable
+                ? AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED
+                : AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
+        accessibilityManager.sendAccessibilityEvent(event);
+        return true;
+    }
+
+    private void copyEditorInfo(@NonNull EditorInfo from, @NonNull EditorInfo to) {
+        requireNonNull(from);
+        requireNonNull(to);
+        to.inputType = from.inputType;
+        to.imeOptions = from.imeOptions;
+        to.privateImeOptions = from.privateImeOptions;
+        to.actionLabel = from.actionLabel;
+        to.actionId = from.actionId;
+        to.initialSelStart = from.initialSelStart;
+        to.initialSelEnd = from.initialSelEnd;
+        to.initialCapsMode = from.initialCapsMode;
+        to.hintText = from.hintText;
+        to.label = from.label;
+        to.packageName = from.packageName;
+        to.fieldId = from.fieldId;
+        to.fieldName = from.fieldName;
+        to.extras = from.extras;
+        to.hintLocales = from.hintLocales;
+        to.contentMimeTypes = from.contentMimeTypes;
+    }
+
+    /** Notifies to start the input, i.e. to show the keyboard. */
+    public void onStartInput() {
+        if (!hasFocus()) {
+            requestFocus();
+        }
+
+        mIsInInputMode = true;
+        mInputMethodManager.restartInput(this);
+        mInputMethodManager.showSoftInput(this, 0);
+    }
+
+    /** Notifies to stop the input, i.e. to hide the keyboard. */
+    public void onStopInput() {
+        if (mIsInInputMode) {
+            mIsInInputMode = false;
+            mInputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
+        }
+    }
+
+    @Override
+    public boolean onCheckIsTextEditor() {
+        return mIsInInputMode;
+    }
+
+    @Override
+    public boolean checkInputConnectionProxy(@Nullable View view) {
+        return mIsInInputMode;
+    }
+
+    /**
+     * Updates the surface package. The surface package can be either a
+     * {@link android.view.SurfaceControlViewHost.SurfacePackage} or a
+     * {@link LegacySurfacePackage} wrapped in a {@link SurfacePackageCompat}.
+     */
+    public void setSurfacePackage(@NonNull SurfacePackageCompat surfacePackageCompat) {
+        Parcelable surfacePackage = surfacePackageCompat.getSurfacePackage();
+        if (SUPPORTS_SURFACE_CONTROL && surfacePackage instanceof SurfacePackage) {
+            Api30Impl.setSurfacePackage(this, (SurfacePackage) surfacePackage);
+        } else if (surfacePackage instanceof LegacySurfacePackage) {
+            setLegacySurfacePackage((LegacySurfacePackage) surfacePackage);
+        } else {
+            Log.e(LogTags.TAG_AAOS_HOST, "Unrecognized surface package");
+        }
+    }
+
+    /**
+     * Updates the surface control with the {@link LegacySurfacePackage}.
+     *
+     * This control is used to communicate the UI events and focus with the host.
+     */
+    @SuppressLint({"ClickableViewAccessibility"})
+    private void setLegacySurfacePackage(LegacySurfacePackage surfacePackage) {
+        ISurfaceControl surfaceControl = surfacePackage.getSurfaceControl();
+        SurfaceWrapper surfaceWrapper = mSurfaceWrapperProvider.createSurfaceWrapper();
+        try {
+            surfaceControl.setSurfaceWrapper(surfaceWrapper);
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+            return;
+        }
+        mSurfaceControl = surfaceControl;
+        setOnTouchListener((view, event) -> handleTouchEvent(event));
+        setOnKeyListener((view, keyCode, event) -> handleKeyEvent(event));
+        setOnGenericMotionListener((view, event) -> handleGenericMotionEvent(event));
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        getViewTreeObserver().addOnTouchModeChangeListener(mOnTouchModeChangeListener);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        getViewTreeObserver().removeOnTouchModeChangeListener(mOnTouchModeChangeListener);
+    }
+
+    /** Passes the touch events to the host. */
+    boolean handleTouchEvent(@NonNull MotionEvent event) {
+        // Make a copy to avoid double recycling of the event.
+        MotionEvent eventCopy = MotionEvent.obtain(requireNonNull(event));
+        try {
+            if (mSurfaceControl != null) {
+                mSurfaceControl.onTouchEvent(eventCopy);
+                return true;
+            }
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+        }
+
+        return false;
+    }
+
+    /** Passes the generic motion events to the host. */
+    boolean handleGenericMotionEvent(@NonNull MotionEvent event) {
+        try {
+            if (requireNonNull(event).getActionMasked() == MotionEvent.ACTION_SCROLL) {
+                int steps = (int) event.getAxisValue(MotionEvent.AXIS_SCROLL);
+                boolean isClockwise = steps > 0;
+                if (mRotaryEventListener != null) {
+                    mRotaryEventListener.onRotate(steps, isClockwise);
+                }
+                return true;
+            }
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+        }
+        return false;
+    }
+
+    /** Passes the appropriate key events to the host for rotary support. */
+    boolean handleKeyEvent(KeyEvent event) {
+        if (event.getAction() == ACTION_DOWN) {
+            return false;
+        }
+
+        try {
+            switch (event.getKeyCode()) {
+                case KEYCODE_BACK:
+                    if (mBackButtonListener != null) {
+                        mBackButtonListener.onBackPressed();
+                        return true;
+                    }
+                    break;
+                case KEYCODE_DPAD_CENTER:
+                    if (mRotaryEventListener != null) {
+                        mRotaryEventListener.onSelect();
+                        return true;
+                    }
+                    break;
+                case KEYCODE_DPAD_RIGHT:
+                case KEYCODE_DPAD_LEFT:
+                case KEYCODE_DPAD_UP:
+                case KEYCODE_DPAD_DOWN:
+                    if (mRotaryEventListener != null) {
+                        boolean success = mRotaryEventListener.onNudge(event.getKeyCode());
+                        if (!success) {
+                            // Quit direct manipulation mode if the nudge event cannot be handled.
+                            enableDirectManipulationMode(this, false);
+                            return false;
+                        }
+                        return true;
+                    }
+                    break;
+                default:
+                    return false;
+            }
+        } catch (RemoteException e) {
+            Log.e(LogTags.TAG_AAOS_HOST, "Remote connection lost", e);
+        }
+
+        return false;
+    }
+
+    @RequiresApi(Build.VERSION_CODES.R)
+    private static class Api30Impl {
+        private Api30Impl() {
+        }
+
+        @DoNotInline
+        static void setSurfacePackage(TemplateSurfaceView view, SurfacePackage surfacePackage) {
+            view.setChildSurfacePackage(surfacePackage);
+        }
+    }
+}
diff --git a/car/app/app-aaos/src/main/res/layout/activity_template.xml b/car/app/app-aaos/src/main/res/layout/activity_template.xml
new file mode 100644
index 0000000..7c7b1af
--- /dev/null
+++ b/car/app/app-aaos/src/main/res/layout/activity_template.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/fragment_container">
+  <androidx.car.app.aaos.renderer.rotary.FocusParkingView
+      android:id="@+id/template_focus_parking"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"/>
+    <!-- Since RotaryService can turn off the direct manipulation mode without
+        notifying the surface view, the focus dispatcher view is added to ensure
+        surface view can clear and regain focus when rotary rotation happens
+        while direct manipulation mode is turned off. This is necessary to
+        ensure SurfaceView does not stuck without having direction
+        manipulation while having focus.
+        Please note that SurfaceView should be surrounded by FocusDispatcherView
+        so the focus goes back to the SurfaceView as soon as it loses the focus.
+        This view must have a non-zero size to gain focus by the rotary
+        service. -->
+    <androidx.car.app.aaos.renderer.rotary.FocusDispatcherView
+        android:layout_width="1dp"
+        android:layout_height="match_parent"
+        app:focusTarget="@id/template_view_surface"/>
+    <androidx.car.app.aaos.renderer.surface.TemplateSurfaceView
+        android:id="@+id/template_view_surface"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:focusable="true"
+        android:focusableInTouchMode="true"/>
+    <androidx.car.app.aaos.renderer.rotary.FocusDispatcherView
+        android:layout_width="1dp"
+        android:layout_height="match_parent"
+        app:focusTarget="@id/template_view_surface"/>
+</merge>
\ No newline at end of file
diff --git a/car/app/app-aaos/src/main/res/values/attrs.xml b/car/app/app-aaos/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..175b076
--- /dev/null
+++ b/car/app/app-aaos/src/main/res/values/attrs.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+  <declare-styleable name="FocusDispatcherView">
+    <!-- Points to the view that should gain the focus when FocusDispatcherView is focused. -->
+    <attr name="focusTarget" format="reference"/>
+  </declare-styleable>
+</resources>
\ No newline at end of file
diff --git a/car/app/app-aaos/src/test/AndroidManifest.xml b/car/app/app-aaos/src/test/AndroidManifest.xml
new file mode 100644
index 0000000..e3943bc
--- /dev/null
+++ b/car/app/app-aaos/src/test/AndroidManifest.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="androidx.car.app.aaos">
+</manifest>
diff --git a/car/app/app-aaos/src/test/java/androidx/car/app/aaos/CarAppActivityTest.java b/car/app/app-aaos/src/test/java/androidx/car/app/aaos/CarAppActivityTest.java
new file mode 100644
index 0000000..77e8f78
--- /dev/null
+++ b/car/app/app-aaos/src/test/java/androidx/car/app/aaos/CarAppActivityTest.java
@@ -0,0 +1,428 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.car.app.aaos;
+
+import static android.view.KeyEvent.ACTION_UP;
+import static android.view.KeyEvent.KEYCODE_BACK;
+import static android.view.KeyEvent.KEYCODE_DPAD_CENTER;
+import static android.view.KeyEvent.KEYCODE_DPAD_DOWN;
+import static android.view.KeyEvent.KEYCODE_DPAD_RIGHT;
+import static android.view.KeyEvent.KEYCODE_R;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.app.Application;
+import android.app.Application.ActivityLifecycleCallbacks;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+
+import androidx.car.app.aaos.renderer.IBackButtonListener;
+import androidx.car.app.aaos.renderer.ICarAppActivity;
+import androidx.car.app.aaos.renderer.IInputConnectionListener;
+import androidx.car.app.aaos.renderer.ILifecycleListener;
+import androidx.car.app.aaos.renderer.IProxyInputConnection;
+import androidx.car.app.aaos.renderer.IRendererService;
+import androidx.car.app.aaos.renderer.IRotaryEventListener;
+import androidx.car.app.aaos.renderer.surface.LegacySurfacePackage;
+import androidx.car.app.aaos.renderer.surface.SurfaceControlCallback;
+import androidx.car.app.aaos.renderer.surface.SurfacePackageCompat;
+import androidx.lifecycle.Lifecycle;
+import androidx.test.core.app.ActivityScenario;
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.internal.DoNotInstrument;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.shadows.ShadowPackageManager;
+
+/** Tests for {@link CarAppActivity}. */
+@RunWith(RobolectricTestRunner.class)
+@DoNotInstrument
+public class CarAppActivityTest {
+    private final ComponentName mRendererComponent = new ComponentName(
+            ApplicationProvider.getApplicationContext(), getClass().getName());
+    private final ComponentName mCarAppActivityComponent = new ComponentName(
+            ApplicationProvider.getApplicationContext(), CarAppActivity.class);
+    private final String mFakeCarAppServiceClass = "com.fake.FakeCarAppService";
+    private final ComponentName mFakeCarAppServiceComponent = new ComponentName(
+            ApplicationProvider.getApplicationContext(), mFakeCarAppServiceClass);
+    private final IRendererService mRenderService = mock(IRendererService.class);
+    private final RenderServiceDelegate mRenderServiceDelegate =
+            new RenderServiceDelegate(mRenderService);
+
+    private void setupCarAppActivityForTesting() {
+        try {
+            Application app = ApplicationProvider.getApplicationContext();
+
+            // Add fake metadata to simulate manifest entry for car app service.
+            Bundle metaData = new Bundle();
+            metaData.putString(CarAppActivity.SERVICE_METADATA_KEY, mFakeCarAppServiceClass);
+            app.getApplicationInfo().metaData = metaData;
+            PackageManager packageManager = app.getPackageManager();
+            ActivityInfo activityInfo;
+            activityInfo = packageManager.getActivityInfo(mCarAppActivityComponent,
+                    PackageManager.GET_META_DATA);
+            activityInfo.metaData = metaData;
+            ShadowPackageManager spm = shadowOf(packageManager);
+            spm.addOrUpdateActivity(activityInfo);
+
+            // Register fake renderer service which will be simulated by {@code mRenderService}.
+            spm.addServiceIfNotPresent(mRendererComponent);
+            spm.addIntentFilterForService(mRendererComponent,
+                    new IntentFilter(CarAppActivity.ACTION_RENDER));
+
+            when(mRenderService.initialize(any(ICarAppActivity.class),
+                    any(ComponentName.class),
+                    anyInt())).thenReturn(true);
+            when(mRenderService.onNewIntent(any(Intent.class), any(ComponentName.class),
+                    anyInt())).thenReturn(true);
+
+            ShadowApplication sa = shadowOf(app);
+            sa.setComponentNameAndServiceForBindService(mRendererComponent, mRenderServiceDelegate);
+
+        } catch (PackageManager.NameNotFoundException | RemoteException e) {
+            fail(Log.getStackTraceString(e));
+        }
+    }
+
+    @Test
+    public void testRendererInitialization() {
+        setupCarAppActivityForTesting();
+        try (ActivityScenario<CarAppActivity> scenario = ActivityScenario.launch(
+                CarAppActivity.class)) {
+            scenario.onActivity(activity -> {
+                try {
+                    verify(mRenderService, times(1)).initialize(
+                            mRenderServiceDelegate.getCarAppActivity(),
+                            mFakeCarAppServiceComponent, activity.getDisplayId());
+                    verify(mRenderService, times(1)).onNewIntent(activity.getIntent(),
+                            mFakeCarAppServiceComponent, activity.getDisplayId());
+                } catch (RemoteException e) {
+                    fail(Log.getStackTraceString(e));
+                }
+            });
+        }
+    }
+
+    @Test
+    public void testSurfaceViewVisibilityOnLifecycleChange() {
+        setupCarAppActivityForTesting();
+        try (ActivityScenario<CarAppActivity> scenario = ActivityScenario.launch(
+                CarAppActivity.class)) {
+            scenario.onActivity(activity -> {
+                assertThat(activity.mSurfaceView.getVisibility()).isEqualTo(View.VISIBLE);
+                scenario.moveToState(Lifecycle.State.CREATED);
+                assertThat(activity.mSurfaceView.getVisibility()).isEqualTo(View.GONE);
+            });
+        }
+    }
+
+    @Test
+    public void testActivityLifecycleCallbacks() {
+        setupCarAppActivityForTesting();
+        try (ActivityScenario<CarAppActivity> scenario = ActivityScenario.launch(
+                CarAppActivity.class)) {
+            scenario.onActivity(activity -> {
+                ILifecycleListener listener = mock(ILifecycleListener.class);
+                try {
+                    mRenderServiceDelegate.getCarAppActivity().setLifecycleListener(listener);
+                    // Last observed event is reported as soon as listener is set.
+                    verify(listener, times(1)).onResume();
+                    // Verify lifecycle events are reported to registered listener.
+                    scenario.moveToState(Lifecycle.State.STARTED);
+                    verify(listener, times(1)).onPause();
+                    scenario.moveToState(Lifecycle.State.RESUMED);
+                    verify(listener, times(2)).onResume();
+                    scenario.moveToState(Lifecycle.State.CREATED);
+                    verify(listener, times(1)).onStop();
+                    scenario.moveToState(Lifecycle.State.CREATED);
+                    verify(listener, times(1)).onStop();
+                    scenario.moveToState(Lifecycle.State.DESTROYED);
+                    verify(listener, times(1)).onDestroyed();
+                } catch (RemoteException e) {
+                    fail(Log.getStackTraceString(e));
+                }
+            });
+        }
+    }
+
+    @Test
+    public void testOnServiceConnectionError() {
+        setupCarAppActivityForTesting();
+        try (ActivityScenario<CarAppActivity> scenario = ActivityScenario.launch(
+                CarAppActivity.class)) {
+            scenario.onActivity(activity -> {
+                try {
+                    ILifecycleListener listener = mock(ILifecycleListener.class);
+                    mRenderServiceDelegate.getCarAppActivity().setLifecycleListener(listener);
+                    // Last observed event is reported as soon as listener is set.
+                    verify(listener, times(1)).onResume();
+
+                    // Add a test-specific lifecycle listener to activity.
+                    ActivityLifecycleCallbacks callback = mock(ActivityLifecycleCallbacks.class);
+                    activity.registerActivityLifecycleCallbacks(callback);
+                    // Report service connection error.
+                    activity.onServiceConnectionError("fake error");
+
+                    assertThat(activity.isFinishing()).isEqualTo(true);
+
+                    // After service connection error has been reported, test that lifecycle
+                    // events are no longer reported to host lifecycle listener.
+                    scenario.moveToState(Lifecycle.State.STARTED);
+                    verify(callback, times(1)).onActivityPaused(activity);
+                    verify(listener, times(0)).onPause();
+                } catch (RemoteException e) {
+                    fail(Log.getStackTraceString(e));
+                }
+            });
+        }
+    }
+
+    @Test
+    public void testBackButtonListener() {
+        setupCarAppActivityForTesting();
+        try (ActivityScenario<CarAppActivity> scenario = ActivityScenario.launch(
+                CarAppActivity.class)) {
+            scenario.onActivity(activity -> {
+                try {
+                    IBackButtonListener listener = mock(IBackButtonListener.class);
+                    mRenderServiceDelegate.getCarAppActivity().setBackButtonListener(listener);
+                    activity.onBackPressed();
+                    verify(listener, times(1)).onBackPressed();
+                } catch (RemoteException e) {
+                    fail(Log.getStackTraceString(e));
+                }
+            });
+        }
+    }
+
+    @Test
+    public void testUnbindOnDestroy() {
+        setupCarAppActivityForTesting();
+        try (ActivityScenario<CarAppActivity> scenario = ActivityScenario.launch(
+                CarAppActivity.class)) {
+            scenario.onActivity(activity -> {
+                try {
+                    ServiceConnection serviceConnection = spy(activity.getServiceConnection());
+                    activity.setServiceConnection(serviceConnection);
+
+                    // Destroy activity to force unbind.
+                    scenario.moveToState(Lifecycle.State.DESTROYED);
+
+                    // Verify Activity onDestroy even is reported to renderer.
+                    verify(mRenderService, times(1)).terminate(
+                            mFakeCarAppServiceComponent);
+                    // Verify service connection is closed.
+                    verify(serviceConnection, times(1)).onServiceDisconnected(
+                            mRendererComponent);
+                    assertThat(activity.mRendererService).isNull();
+                } catch (RemoteException e) {
+                    fail(Log.getStackTraceString(e));
+                }
+            });
+        }
+    }
+
+    @Test
+    public void testLegacySurfacePackageEvents() {
+        setupCarAppActivityForTesting();
+        try (ActivityScenario<CarAppActivity> scenario = ActivityScenario.launch(
+                CarAppActivity.class)) {
+            scenario.onActivity(activity -> {
+                try {
+                    SurfaceControlCallback callback = mock(SurfaceControlCallback.class);
+                    IBackButtonListener backButtonListener = mock(IBackButtonListener.class);
+                    IRotaryEventListener rotaryEventListener = mock(IRotaryEventListener.class);
+
+                    SurfacePackageCompat wrapper =
+                            new SurfacePackageCompat(new LegacySurfacePackage(callback));
+                    ICarAppActivity carAppActivity = mRenderServiceDelegate.getCarAppActivity();
+                    carAppActivity.setSurfacePackage(wrapper);
+                    carAppActivity.setBackButtonListener(backButtonListener);
+                    carAppActivity.setRotaryEventListener(rotaryEventListener);
+
+                    // Verify back events on surfaceView are sent to host.
+                    activity.mSurfaceView.dispatchKeyEvent(new KeyEvent(ACTION_UP, KEYCODE_BACK));
+                    verify(backButtonListener, times(1)).onBackPressed();
+
+                    // Verify focus request sent to host.
+                    activity.mSurfaceView.requestFocus();
+                    verify(callback, times(1)).onWindowFocusChanged(true, false);
+                    activity.mSurfaceView.clearFocus();
+                    verify(callback, times(1)).onWindowFocusChanged(false, false);
+
+                    // Verify rotary events on surfaceView are sent to host.
+                    activity.mSurfaceView.dispatchKeyEvent(
+                            new KeyEvent(ACTION_UP, KEYCODE_DPAD_RIGHT));
+                    verify(rotaryEventListener, times(1)).onNudge(KEYCODE_DPAD_RIGHT);
+                    activity.mSurfaceView.dispatchKeyEvent(
+                            new KeyEvent(ACTION_UP, KEYCODE_DPAD_DOWN));
+                    verify(rotaryEventListener, times(1)).onNudge(KEYCODE_DPAD_DOWN);
+                    activity.mSurfaceView.dispatchKeyEvent(
+                            new KeyEvent(ACTION_UP, KEYCODE_DPAD_CENTER));
+                    verify(rotaryEventListener, times(1)).onSelect();
+
+                    long downTime = SystemClock.uptimeMillis();
+                    long eventTime = SystemClock.uptimeMillis();
+                    int action = MotionEvent.ACTION_UP;
+                    int x = 50;
+                    int y = 50;
+                    int metaState = 0;
+                    MotionEvent event = MotionEvent.obtain(downTime, eventTime, action, x, y,
+                            metaState);
+                    activity.mSurfaceView.dispatchTouchEvent(event);
+                    ArgumentCaptor<MotionEvent> argument = ArgumentCaptor.forClass(
+                            MotionEvent.class);
+                    verify(callback, times(1)).onTouchEvent(argument.capture());
+                    // Compare string representations as equals in MotionEvent checks for same
+                    // object.
+                    assertThat(argument.getValue().toString()).isEqualTo(event.toString());
+
+                    // Test a action scroll event.
+                    event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_SCROLL, x,
+                            y, metaState);
+                    activity.mSurfaceView.dispatchGenericMotionEvent(event);
+                    verify(rotaryEventListener, times(1)).onRotate(anyInt(), eq(false));
+                } catch (RemoteException e) {
+                    fail(Log.getStackTraceString(e));
+                }
+            });
+        }
+    }
+
+    @Test
+    public void testKeyboardInputWithoutStartInput() {
+        setupCarAppActivityForTesting();
+        try (ActivityScenario<CarAppActivity> scenario = ActivityScenario.launch(
+                CarAppActivity.class)) {
+            scenario.onActivity(activity -> {
+                try {
+                    EditorInfo editorInfo = new EditorInfo();
+                    IInputConnectionListener listener = mock(IInputConnectionListener.class);
+                    IProxyInputConnection inputConnection = mock(IProxyInputConnection.class);
+                    when(listener.onCreateInputConnection(any())).thenReturn(inputConnection);
+                    when(inputConnection.getEditorInfo()).thenReturn(editorInfo);
+
+                    mRenderServiceDelegate.getCarAppActivity().setInputConnectionListener(listener);
+                    // Create input connection without first calling ICarAppActivity#startInput().
+                    InputConnection remoteProxyInputConnection =
+                            activity.mSurfaceView.onCreateInputConnection(editorInfo);
+
+                    assertThat(remoteProxyInputConnection).isNull();
+                } catch (RemoteException e) {
+                    fail(Log.getStackTraceString(e));
+                }
+            });
+        }
+    }
+
+    @Test
+    public void testKeyboardInput() {
+        setupCarAppActivityForTesting();
+        try (ActivityScenario<CarAppActivity> scenario = ActivityScenario.launch(
+                CarAppActivity.class)) {
+            scenario.onActivity(activity -> {
+                try {
+                    EditorInfo editorInfo = new EditorInfo();
+                    IInputConnectionListener listener = mock(IInputConnectionListener.class);
+                    IProxyInputConnection inputConnection = mock(IProxyInputConnection.class);
+                    when(listener.onCreateInputConnection(any())).thenReturn(inputConnection);
+                    when(inputConnection.getEditorInfo()).thenReturn(editorInfo);
+
+                    mRenderServiceDelegate.getCarAppActivity().setInputConnectionListener(listener);
+                    mRenderServiceDelegate.getCarAppActivity().onStartInput();
+                    InputConnection remoteProxyInputConnection =
+                            activity.mSurfaceView.onCreateInputConnection(editorInfo);
+
+                    assertThat(remoteProxyInputConnection).isNotNull();
+
+                    // Verify input events re proxied to host.
+                    KeyEvent event = new KeyEvent(ACTION_UP, KEYCODE_R);
+                    remoteProxyInputConnection.sendKeyEvent(event);
+                    verify(inputConnection, times(1)).sendKeyEvent(event);
+                } catch (RemoteException e) {
+                    fail(Log.getStackTraceString(e));
+                }
+            });
+        }
+    }
+
+    // Use delegate to forward events to a mock. Mockito interceptor is not maintained on
+    // top-level IBinder after call to IRenderService.Stub.asInterface() in CarAppActivity.
+    private static class RenderServiceDelegate extends IRendererService.Stub {
+        private final IRendererService mService;
+        private ICarAppActivity mCarAppActivity;
+
+        RenderServiceDelegate(IRendererService service) {
+            mService = service;
+        }
+
+        @Override
+        public boolean initialize(ICarAppActivity carActivity, ComponentName serviceName,
+                int displayId) throws RemoteException {
+            mCarAppActivity = carActivity;
+            return mService.initialize(carActivity, serviceName, displayId);
+        }
+
+        @Override
+        public boolean onNewIntent(Intent intent, ComponentName serviceName, int displayId)
+                throws RemoteException {
+            return mService.onNewIntent(intent, serviceName, displayId);
+        }
+
+        @Override
+        public void terminate(ComponentName serviceName) throws RemoteException {
+            mService.terminate(serviceName);
+        }
+
+        @Override
+        public boolean isVersionSupported(String version) {
+            return true;
+        }
+
+        public ICarAppActivity getCarAppActivity() {
+            return mCarAppActivity;
+        }
+    }
+}
diff --git a/car/app/app-aaos/src/test/resources/robolectric.properties b/car/app/app-aaos/src/test/resources/robolectric.properties
new file mode 100644
index 0000000..ce87047
--- /dev/null
+++ b/car/app/app-aaos/src/test/resources/robolectric.properties
@@ -0,0 +1,3 @@
+# Robolectric currently doesn't support API 30, so we have to explicitly specify 29 as the target
+# sdk for now. Remove when no longer necessary.
+sdk=29
diff --git a/car/app/app-samples/build.gradle b/car/app/app-samples/build.gradle
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/car/app/app-samples/build.gradle
diff --git a/car/app/app-samples/showcase/src/main/java/androidx/car/app/samples/showcase/textandicons/ContentProviderIconsDemoScreen.java b/car/app/app-samples/showcase/src/main/java/androidx/car/app/samples/showcase/textandicons/ContentProviderIconsDemoScreen.java
index c262319..21214d7 100644
--- a/car/app/app-samples/showcase/src/main/java/androidx/car/app/samples/showcase/textandicons/ContentProviderIconsDemoScreen.java
+++ b/car/app/app-samples/showcase/src/main/java/androidx/car/app/samples/showcase/textandicons/ContentProviderIconsDemoScreen.java
@@ -76,6 +76,7 @@
     }
 
     @Nullable
+    @SuppressWarnings("CatchAndPrintStackTrace")
     private Uri customIconUri(int resId) {
         Uri uri = null;
         try {
diff --git a/car/app/app-testing/api/current.txt b/car/app/app-testing/api/current.txt
index e6f50d0..06c1307 100644
--- a/car/app/app-testing/api/current.txt
+++ b/car/app/app-testing/api/current.txt
@@ -1 +1,71 @@
 // Signature format: 4.0
+package androidx.car.app.testing {
+
+  public class CarAppServiceController {
+    method public androidx.car.app.testing.CarAppServiceController create(android.content.Intent?);
+    method public androidx.car.app.testing.CarAppServiceController destroy();
+    method public androidx.car.app.CarAppService get();
+    method public androidx.car.app.testing.CarAppServiceController newIntent(android.content.Intent);
+    method public static androidx.car.app.testing.CarAppServiceController of(androidx.car.app.testing.TestCarContext, androidx.car.app.Session, androidx.car.app.CarAppService);
+    method public androidx.car.app.testing.CarAppServiceController pause();
+    method public androidx.car.app.testing.CarAppServiceController resume();
+    method public void setAppInfo(androidx.car.app.AppInfo);
+    method public void setHostInfo(androidx.car.app.HostInfo);
+    method public androidx.car.app.testing.CarAppServiceController start();
+    method public androidx.car.app.testing.CarAppServiceController stop();
+  }
+
+  public class FakeHost {
+    method public void performNotificationActionClick(android.app.PendingIntent);
+  }
+
+  public class ScreenController {
+    method public androidx.car.app.testing.ScreenController create();
+    method public androidx.car.app.testing.ScreenController destroy();
+    method public androidx.car.app.Screen get();
+    method public java.util.List<androidx.car.app.model.Template!> getTemplatesReturned();
+    method public static androidx.car.app.testing.ScreenController of(androidx.car.app.testing.TestCarContext, androidx.car.app.Screen);
+    method public androidx.car.app.testing.ScreenController pause();
+    method public void reset();
+    method public androidx.car.app.testing.ScreenController resume();
+    method public androidx.car.app.testing.ScreenController start();
+    method public androidx.car.app.testing.ScreenController stop();
+  }
+
+  public class TestAppManager extends androidx.car.app.AppManager {
+    method public androidx.car.app.SurfaceCallback? getSurfaceListener();
+    method public java.util.List<android.util.Pair<androidx.car.app.Screen!,androidx.car.app.model.Template!>!> getTemplatesReturned();
+    method public java.util.List<java.lang.CharSequence!> getToastsShown();
+    method public void reset();
+  }
+
+  public class TestCarContext extends androidx.car.app.CarContext {
+    method public static androidx.car.app.testing.TestCarContext createCarContext(android.content.Context);
+    method public androidx.car.app.testing.FakeHost getFakeHost();
+    method public java.util.List<android.content.Intent!> getStartCarAppIntents();
+    method public boolean hasCalledFinishCarApp();
+    method public void reset();
+  }
+
+  public class TestScreenManager extends androidx.car.app.ScreenManager {
+    method public java.util.List<androidx.car.app.Screen!> getScreensPushed();
+    method public java.util.List<androidx.car.app.Screen!> getScreensRemoved();
+    method public boolean hasScreens();
+    method public void reset();
+  }
+
+}
+
+package androidx.car.app.testing.navigation {
+
+  public class TestNavigationManager extends androidx.car.app.navigation.NavigationManager {
+    ctor public TestNavigationManager(androidx.car.app.testing.TestCarContext, androidx.car.app.HostDispatcher);
+    method public int getNavigationEndedCount();
+    method public androidx.car.app.navigation.NavigationManagerCallback? getNavigationManagerCallback();
+    method public int getNavigationStartedCount();
+    method public java.util.List<androidx.car.app.navigation.model.Trip!> getTripsSent();
+    method public void reset();
+  }
+
+}
+
diff --git a/car/app/app-testing/api/public_plus_experimental_current.txt b/car/app/app-testing/api/public_plus_experimental_current.txt
index e6f50d0..06c1307 100644
--- a/car/app/app-testing/api/public_plus_experimental_current.txt
+++ b/car/app/app-testing/api/public_plus_experimental_current.txt
@@ -1 +1,71 @@
 // Signature format: 4.0
+package androidx.car.app.testing {
+
+  public class CarAppServiceController {
+    method public androidx.car.app.testing.CarAppServiceController create(android.content.Intent?);
+    method public androidx.car.app.testing.CarAppServiceController destroy();
+    method public androidx.car.app.CarAppService get();
+    method public androidx.car.app.testing.CarAppServiceController newIntent(android.content.Intent);
+    method public static androidx.car.app.testing.CarAppServiceController of(androidx.car.app.testing.TestCarContext, androidx.car.app.Session, androidx.car.app.CarAppService);
+    method public androidx.car.app.testing.CarAppServiceController pause();
+    method public androidx.car.app.testing.CarAppServiceController resume();
+    method public void setAppInfo(androidx.car.app.AppInfo);
+    method public void setHostInfo(androidx.car.app.HostInfo);
+    method public androidx.car.app.testing.CarAppServiceController start();
+    method public androidx.car.app.testing.CarAppServiceController stop();
+  }
+
+  public class FakeHost {
+    method public void performNotificationActionClick(android.app.PendingIntent);
+  }
+
+  public class ScreenController {
+    method public androidx.car.app.testing.ScreenController create();
+    method public androidx.car.app.testing.ScreenController destroy();
+    method public androidx.car.app.Screen get();
+    method public java.util.List<androidx.car.app.model.Template!> getTemplatesReturned();
+    method public static androidx.car.app.testing.ScreenController of(androidx.car.app.testing.TestCarContext, androidx.car.app.Screen);
+    method public androidx.car.app.testing.ScreenController pause();
+    method public void reset();
+    method public androidx.car.app.testing.ScreenController resume();
+    method public androidx.car.app.testing.ScreenController start();
+    method public androidx.car.app.testing.ScreenController stop();
+  }
+
+  public class TestAppManager extends androidx.car.app.AppManager {
+    method public androidx.car.app.SurfaceCallback? getSurfaceListener();
+    method public java.util.List<android.util.Pair<androidx.car.app.Screen!,androidx.car.app.model.Template!>!> getTemplatesReturned();
+    method public java.util.List<java.lang.CharSequence!> getToastsShown();
+    method public void reset();
+  }
+
+  public class TestCarContext extends androidx.car.app.CarContext {
+    method public static androidx.car.app.testing.TestCarContext createCarContext(android.content.Context);
+    method public androidx.car.app.testing.FakeHost getFakeHost();
+    method public java.util.List<android.content.Intent!> getStartCarAppIntents();
+    method public boolean hasCalledFinishCarApp();
+    method public void reset();
+  }
+
+  public class TestScreenManager extends androidx.car.app.ScreenManager {
+    method public java.util.List<androidx.car.app.Screen!> getScreensPushed();
+    method public java.util.List<androidx.car.app.Screen!> getScreensRemoved();
+    method public boolean hasScreens();
+    method public void reset();
+  }
+
+}
+
+package androidx.car.app.testing.navigation {
+
+  public class TestNavigationManager extends androidx.car.app.navigation.NavigationManager {
+    ctor public TestNavigationManager(androidx.car.app.testing.TestCarContext, androidx.car.app.HostDispatcher);
+    method public int getNavigationEndedCount();
+    method public androidx.car.app.navigation.NavigationManagerCallback? getNavigationManagerCallback();
+    method public int getNavigationStartedCount();
+    method public java.util.List<androidx.car.app.navigation.model.Trip!> getTripsSent();
+    method public void reset();
+  }
+
+}
+
diff --git a/car/app/app-testing/api/restricted_current.txt b/car/app/app-testing/api/restricted_current.txt
index e6f50d0..06c1307 100644
--- a/car/app/app-testing/api/restricted_current.txt
+++ b/car/app/app-testing/api/restricted_current.txt
@@ -1 +1,71 @@
 // Signature format: 4.0
+package androidx.car.app.testing {
+
+  public class CarAppServiceController {
+    method public androidx.car.app.testing.CarAppServiceController create(android.content.Intent?);
+    method public androidx.car.app.testing.CarAppServiceController destroy();
+    method public androidx.car.app.CarAppService get();
+    method public androidx.car.app.testing.CarAppServiceController newIntent(android.content.Intent);
+    method public static androidx.car.app.testing.CarAppServiceController of(androidx.car.app.testing.TestCarContext, androidx.car.app.Session, androidx.car.app.CarAppService);
+    method public androidx.car.app.testing.CarAppServiceController pause();
+    method public androidx.car.app.testing.CarAppServiceController resume();
+    method public void setAppInfo(androidx.car.app.AppInfo);
+    method public void setHostInfo(androidx.car.app.HostInfo);
+    method public androidx.car.app.testing.CarAppServiceController start();
+    method public androidx.car.app.testing.CarAppServiceController stop();
+  }
+
+  public class FakeHost {
+    method public void performNotificationActionClick(android.app.PendingIntent);
+  }
+
+  public class ScreenController {
+    method public androidx.car.app.testing.ScreenController create();
+    method public androidx.car.app.testing.ScreenController destroy();
+    method public androidx.car.app.Screen get();
+    method public java.util.List<androidx.car.app.model.Template!> getTemplatesReturned();
+    method public static androidx.car.app.testing.ScreenController of(androidx.car.app.testing.TestCarContext, androidx.car.app.Screen);
+    method public androidx.car.app.testing.ScreenController pause();
+    method public void reset();
+    method public androidx.car.app.testing.ScreenController resume();
+    method public androidx.car.app.testing.ScreenController start();
+    method public androidx.car.app.testing.ScreenController stop();
+  }
+
+  public class TestAppManager extends androidx.car.app.AppManager {
+    method public androidx.car.app.SurfaceCallback? getSurfaceListener();
+    method public java.util.List<android.util.Pair<androidx.car.app.Screen!,androidx.car.app.model.Template!>!> getTemplatesReturned();
+    method public java.util.List<java.lang.CharSequence!> getToastsShown();
+    method public void reset();
+  }
+
+  public class TestCarContext extends androidx.car.app.CarContext {
+    method public static androidx.car.app.testing.TestCarContext createCarContext(android.content.Context);
+    method public androidx.car.app.testing.FakeHost getFakeHost();
+    method public java.util.List<android.content.Intent!> getStartCarAppIntents();
+    method public boolean hasCalledFinishCarApp();
+    method public void reset();
+  }
+
+  public class TestScreenManager extends androidx.car.app.ScreenManager {
+    method public java.util.List<androidx.car.app.Screen!> getScreensPushed();
+    method public java.util.List<androidx.car.app.Screen!> getScreensRemoved();
+    method public boolean hasScreens();
+    method public void reset();
+  }
+
+}
+
+package androidx.car.app.testing.navigation {
+
+  public class TestNavigationManager extends androidx.car.app.navigation.NavigationManager {
+    ctor public TestNavigationManager(androidx.car.app.testing.TestCarContext, androidx.car.app.HostDispatcher);
+    method public int getNavigationEndedCount();
+    method public androidx.car.app.navigation.NavigationManagerCallback? getNavigationManagerCallback();
+    method public int getNavigationStartedCount();
+    method public java.util.List<androidx.car.app.navigation.model.Trip!> getTripsSent();
+    method public void reset();
+  }
+
+}
+
diff --git a/car/app/app-testing/build.gradle b/car/app/app-testing/build.gradle
index 9d261e4..bcea8f9 100644
--- a/car/app/app-testing/build.gradle
+++ b/car/app/app-testing/build.gradle
@@ -24,7 +24,17 @@
 }
 
 dependencies {
-    // Add dependencies here
+    api(project(":car:app:app"))
+    implementation "androidx.lifecycle:lifecycle-common-java8:2.2.0"
+    implementation 'androidx.annotation:annotation:1.1.0'
+    implementation project(path: ':lifecycle:lifecycle-runtime')
+}
+
+android {
+    defaultConfig {
+        minSdkVersion 23
+        multiDexEnabled = true
+    }
 }
 
 androidx {
diff --git a/car/app/app-testing/src/androidTest/AndroidManifest.xml b/car/app/app-testing/src/androidTest/AndroidManifest.xml
index ab24596..c409a24 100644
--- a/car/app/app-testing/src/androidTest/AndroidManifest.xml
+++ b/car/app/app-testing/src/androidTest/AndroidManifest.xml
@@ -14,7 +14,6 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="androidx.car.app.testing.test">
+<manifest package="androidx.car.app.testing.test">
 
 </manifest>
diff --git a/car/app/app-testing/src/main/AndroidManifest.xml b/car/app/app-testing/src/main/AndroidManifest.xml
index 16463b7..bb0c15a 100644
--- a/car/app/app-testing/src/main/AndroidManifest.xml
+++ b/car/app/app-testing/src/main/AndroidManifest.xml
@@ -14,7 +14,6 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="androidx.car.app.testing">
+<manifest  package="androidx.car.app.testing">
 
 </manifest>
\ No newline at end of file
diff --git a/car/app/app/src/test/java/androidx/car/app/testing/CarAppServiceController.java b/car/app/app-testing/src/main/java/androidx/car/app/testing/CarAppServiceController.java
similarity index 80%
rename from car/app/app/src/test/java/androidx/car/app/testing/CarAppServiceController.java
rename to car/app/app-testing/src/main/java/androidx/car/app/testing/CarAppServiceController.java
index cce56b9..50c1afe 100644
--- a/car/app/app/src/test/java/androidx/car/app/testing/CarAppServiceController.java
+++ b/car/app/app-testing/src/main/java/androidx/car/app/testing/CarAppServiceController.java
@@ -32,7 +32,6 @@
 import androidx.lifecycle.Lifecycle.State;
 
 import java.lang.reflect.Field;
-import java.util.Objects;
 
 /**
  * A controller that allows testing of a {@link CarAppService}.
@@ -45,12 +44,19 @@
  *   <li>Moving a {@link CarAppService} through its different {@link State}s.
  * </ul>
  */
+@SuppressWarnings("NotCloseable")
 public class CarAppServiceController {
     private final TestCarContext mTestCarContext;
     private final CarAppService mCarAppService;
     private final ICarApp mCarAppStub;
 
-    /** Creates a {@link CarAppServiceController} to control the provided {@link CarAppService}. */
+    /**
+     * Creates a {@link CarAppServiceController} to control the provided {@link CarAppService}.
+     *
+     * @throws NullPointerException if {@code testCarContext}, {@code session} or {@code
+     *                              carAppService} are {@code null}
+     */
+    @NonNull
     public static CarAppServiceController of(
             @NonNull TestCarContext testCarContext,
             @NonNull Session session, @NonNull CarAppService carAppService) {
@@ -62,23 +68,15 @@
     /**
      * Initializes the {@link CarAppService} that is being controlled.
      *
-     * <p>This will send an empty {@link Intent} to the {@link Session} returned from
-     * {@link CarAppService#onCreateSession}.
+     * @param intent the intent that will be sent to {@link Session#onCreateScreen}. If it is
+     *               {@code null}, then an {@link Intent} with only the component set will be sent.
      */
-    public CarAppServiceController create() {
-        return create(
-                new Intent().setComponent(
-                        new ComponentName(mTestCarContext, mCarAppService.getClass())));
-    }
-
-    /**
-     * Initializes the {@link CarAppService} that is being controlled.
-     *
-     * <p>This will send the provided {@link Intent} to {@link Session#onCreateScreen}.
-     */
-    public CarAppServiceController create(@NonNull Intent intent) {
-        Objects.requireNonNull(intent);
-
+    @NonNull
+    public CarAppServiceController create(@Nullable Intent intent) {
+        if (intent == null) {
+            intent = new Intent().setComponent(
+                    new ComponentName(mTestCarContext, mCarAppService.getClass()));
+        }
         try {
             mCarAppStub.onAppCreate(
                     mTestCarContext.getCarHostStub(),
@@ -92,9 +90,14 @@
         return this;
     }
 
-    /** Sends the provided {@link Intent} to the {@link CarAppService} that is being controlled. */
+    /**
+     * Sends the provided {@link Intent} to the {@link CarAppService} that is being controlled.
+     *
+     * @throws NullPointerException if {@code intent} is {@code null}
+     */
+    @NonNull
     public CarAppServiceController newIntent(@NonNull Intent intent) {
-        Objects.requireNonNull(intent);
+        requireNonNull(intent);
 
         try {
             mCarAppStub.onNewIntent(intent, new TestOnDoneCallbackStub());
@@ -110,6 +113,7 @@
      *
      * @see Session#getLifecycle
      */
+    @NonNull
     public CarAppServiceController start() {
         try {
             mCarAppStub.onAppStart(new TestOnDoneCallbackStub());
@@ -125,6 +129,7 @@
      *
      * @see Session#getLifecycle
      */
+    @NonNull
     public CarAppServiceController resume() {
         try {
             mCarAppStub.onAppResume(new TestOnDoneCallbackStub());
@@ -140,6 +145,7 @@
      *
      * @see Session#getLifecycle
      */
+    @NonNull
     public CarAppServiceController pause() {
         try {
             mCarAppStub.onAppPause(new TestOnDoneCallbackStub());
@@ -155,6 +161,7 @@
      *
      * @see Session#getLifecycle
      */
+    @NonNull
     public CarAppServiceController stop() {
         try {
             mCarAppStub.onAppStop(new TestOnDoneCallbackStub());
@@ -169,13 +176,21 @@
      *
      * @see Session#getLifecycle
      */
+    @NonNull
     public CarAppServiceController destroy() {
         mCarAppService.onUnbind(new Intent());
         mCarAppService.onDestroy();
         return this;
     }
 
-    public void setHostInfo(@Nullable HostInfo hostInfo) {
+    /**
+     * Sets the {@link HostInfo} to aid in testing host validation logic.
+     *
+     * @throws NullPointerException if {@code hostInfo} is {@code null}
+     */
+    public void setHostInfo(@NonNull HostInfo hostInfo) {
+        requireNonNull(hostInfo);
+
         try {
             Field hostInfoField = CarAppService.class.getDeclaredField("mHostInfo");
             hostInfoField.setAccessible(true);
@@ -186,7 +201,14 @@
         }
     }
 
-    public void setAppInfo(@Nullable AppInfo appInfo) {
+    /**
+     * Sets the app to be at a specific {@link AppInfo} version to test code at specific versions.
+     *
+     * @throws NullPointerException if {@code appInfo} is {@code null}
+     */
+    public void setAppInfo(@NonNull AppInfo appInfo) {
+        requireNonNull(appInfo);
+
         try {
             Field appInfoField = CarAppService.class.getDeclaredField("mAppInfo");
             appInfoField.setAccessible(true);
@@ -197,7 +219,7 @@
         }
     }
 
-    /** Retrieves the {@link CarAppService} that is being controlled. */
+    /** Returns the {@link CarAppService} that is being controlled. */
     @NonNull
     public CarAppService get() {
         return mCarAppService;
diff --git a/car/app/app/src/test/java/androidx/car/app/testing/FakeHost.java b/car/app/app-testing/src/main/java/androidx/car/app/testing/FakeHost.java
similarity index 87%
rename from car/app/app/src/test/java/androidx/car/app/testing/FakeHost.java
rename to car/app/app-testing/src/main/java/androidx/car/app/testing/FakeHost.java
index 2ceefdb..89bccef 100644
--- a/car/app/app/src/test/java/androidx/car/app/testing/FakeHost.java
+++ b/car/app/app-testing/src/main/java/androidx/car/app/testing/FakeHost.java
@@ -46,15 +46,9 @@
  */
 public class FakeHost {
     private final ICarHost.Stub mCarHost = new TestCarHost();
-    private final IAppHost mAppHost = new TestAppHost();
-    private final INavigationHost mNavigationHost = new TestNavigationHost();
-    private final TestCarContext mTestCarContext;
-
-    /** Returns the {@link FakeHost} that is associated with the provided {@code TestCarContext}. */
-    @NonNull
-    public static FakeHost getFakeHost(@NonNull TestCarContext testCarContext) {
-        return testCarContext.getFakeHost();
-    }
+    final IAppHost mAppHost = new TestAppHost();
+    final INavigationHost mNavigationHost = new TestNavigationHost();
+    final TestCarContext mTestCarContext;
 
     /**
      * Sends the given pending intent as if the user clicked on a notification action.
@@ -67,6 +61,8 @@
      *
      * <p>You can then test your {@link android.content.BroadcastReceiver} by calling {@link
      * android.content.BroadcastReceiver#onReceive} with the {@link Intent} that was fired.
+     *
+     * @throws NullPointerException if {@code pendingIntent} is {@code null}
      */
     public void performNotificationActionClick(@NonNull PendingIntent pendingIntent) {
         requireNonNull(pendingIntent);
@@ -92,10 +88,16 @@
         return mCarHost;
     }
 
-    private class TestCarHost extends ICarHost.Stub {
-
+    /**
+     * A fake implementation of the host binder.
+     *
+     * <p>Mainly it provides the fake host services {@link TestAppHost} and
+     * {@link TestNavigationHost}.
+     */
+    class TestCarHost extends ICarHost.Stub {
         @Override
         public void startCarApp(Intent intent) {
+            // No-op.
         }
 
         @Override
@@ -112,11 +114,12 @@
 
         @Override
         public void finish() {
+            // No-op.
         }
     }
 
     /** Testing version of the app host. */
-    private class TestAppHost extends IAppHost.Stub {
+    class TestAppHost extends IAppHost.Stub {
         @Override
         public void invalidate() {
             Screen top = mTestCarContext.getCarService(TestScreenManager.class).getTop();
@@ -137,7 +140,7 @@
     }
 
     /** Testing version of the navigation host. */
-    private static class TestNavigationHost extends INavigationHost.Stub {
+    static class TestNavigationHost extends INavigationHost.Stub {
         @Override
         public void navigationStarted() {
             // No-op.
diff --git a/car/app/app/src/test/java/androidx/car/app/testing/ScreenController.java b/car/app/app-testing/src/main/java/androidx/car/app/testing/ScreenController.java
similarity index 89%
rename from car/app/app/src/test/java/androidx/car/app/testing/ScreenController.java
rename to car/app/app-testing/src/main/java/androidx/car/app/testing/ScreenController.java
index 8565154..60d9140 100644
--- a/car/app/app/src/test/java/androidx/car/app/testing/ScreenController.java
+++ b/car/app/app-testing/src/main/java/androidx/car/app/testing/ScreenController.java
@@ -18,6 +18,7 @@
 
 import static java.util.Objects.requireNonNull;
 
+import android.annotation.SuppressLint;
 import android.util.Pair;
 
 import androidx.annotation.NonNull;
@@ -42,11 +43,17 @@
  *       be reset with {@link #reset}.
  * </ul>
  */
+@SuppressWarnings("NotCloseable")
 public class ScreenController {
     private final TestCarContext mTestCarContext;
     private final Screen mScreen;
 
-    /** Creates a ScreenController to control a {@link Screen} for testing. */
+    /**
+     * Creates a ScreenController to control a {@link Screen} for testing.
+     *
+     * @throws NullPointerException if either {@code testCarContext} or {@code screen} are null
+     */
+    @NonNull
     public static ScreenController of(
             @NonNull TestCarContext testCarContext, @NonNull Screen screen) {
         return new ScreenController(requireNonNull(screen), requireNonNull(testCarContext));
@@ -58,10 +65,12 @@
     }
 
     /**
-     * Retrieves all the {@link Template}s returned from {@link Screen#onGetTemplate} for the {@link
+     * Returns all the {@link Template}s returned from {@link Screen#onGetTemplate} for the {@link
      * Screen} being controlled.
      *
-     * <p>The templates are stored in order of calls.
+     * <p>The templates are stored in the order in which they were returned from
+     * {@link Screen#onGetTemplate}, where the first template in the list, is the first template
+     * returned.
      *
      * <p>The templates will be stored until {@link #reset} is called.
      */
@@ -156,7 +165,7 @@
         return this;
     }
 
-    /** Retrieves the {@link Screen} being controlled. */
+    /** Returns the {@link Screen} being controlled. */
     @NonNull
     public Screen get() {
         return mScreen;
@@ -184,6 +193,7 @@
         }
     }
 
+    @SuppressLint("BanUncheckedReflection")
     private void dispatchLifecycleEvent(Event event) {
         // Use reflection to call internal APIs for testing purposes.
         try {
diff --git a/car/app/app/src/test/java/androidx/car/app/testing/TestAppManager.java b/car/app/app-testing/src/main/java/androidx/car/app/testing/TestAppManager.java
similarity index 68%
rename from car/app/app/src/test/java/androidx/car/app/testing/TestAppManager.java
rename to car/app/app-testing/src/main/java/androidx/car/app/testing/TestAppManager.java
index 35cce02..e51888a 100644
--- a/car/app/app/src/test/java/androidx/car/app/testing/TestAppManager.java
+++ b/car/app/app-testing/src/main/java/androidx/car/app/testing/TestAppManager.java
@@ -16,15 +16,20 @@
 
 package androidx.car.app.testing;
 
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.SuppressLint;
 import android.util.Pair;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.car.app.AppManager;
+import androidx.car.app.CarToast;
 import androidx.car.app.HostDispatcher;
 import androidx.car.app.Screen;
 import androidx.car.app.SurfaceCallback;
 import androidx.car.app.model.Template;
+import androidx.car.app.utils.CollectionUtils;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -42,69 +47,70 @@
  * </ul>
  */
 public class TestAppManager extends AppManager {
-    private final List<SurfaceCallback> mSurfaceCallbacks = new ArrayList<>();
     private final List<CharSequence> mToastsShown = new ArrayList<>();
     private final List<Pair<Screen, Template>> mTemplatesReturned = new ArrayList<>();
+    private SurfaceCallback mSurfaceCallback;
 
     /**
-     * Resets the values tracked by this {@link TestAppManager} and all {@link ScreenController}
-     * s.
+     * Resets the values tracked by this {@link TestAppManager} and all {@link ScreenController}s.
      */
     public void reset() {
-        mSurfaceCallbacks.clear();
+        mSurfaceCallback = null;
         mToastsShown.clear();
         mTemplatesReturned.clear();
     }
 
     /**
-     * Retrieves all the {@link SurfaceCallback}s set via {@link AppManager#setSurfaceCallback}.
-     *
-     * <p>The listeners are stored in order of calls.
-     *
-     * <p>The listeners will be stored until {@link #reset} is called.
+     * Returns the callback set via {@link AppManager#setSurfaceCallback}, or {@code null} if not
+     * set.
      */
-    @NonNull
-    public List<SurfaceCallback> getSurfaceListeners() {
-        return mSurfaceCallbacks;
+    @Nullable
+    public SurfaceCallback getSurfaceListener() {
+        return mSurfaceCallback;
     }
 
     /**
-     * Retrieves all the toasts shown via {@link AppManager#showToast}.
+     * Returns all the toasts shown via {@link AppManager#showToast}.
      *
-     * <p>The toasts are stored in order of calls.
+     * <p>The toasts are stored in the order in which they are sent via
+     * {@link AppManager#showToast}, where the first toast in the list is the first toast that
+     * was sent.
      *
      * <p>The toasts will be stored until {@link #reset} is called.
      */
     @NonNull
     public List<CharSequence> getToastsShown() {
-        return mToastsShown;
+        return CollectionUtils.unmodifiableCopy(mToastsShown);
     }
 
     /**
-     * Retrieves all the {@link Template}s returned from {@link Screen#onGetTemplate} due to a call
+     * Returns all the {@link Template}s returned from {@link Screen#onGetTemplate} due to a call
      * to {@link AppManager#invalidate}, and the respective {@link Screen} instance that returned
      * it.
      *
-     * <p>The results are stored in order of calls.
+     * The results are stored in the order in which they were returned from
+     * {@link Screen#onGetTemplate}, where the first template in the list, is the first template
+     * returned.
      *
      * <p>The results will be stored until {@link #reset} is called.
      */
     @NonNull
     public List<Pair<Screen, Template>> getTemplatesReturned() {
-        return mTemplatesReturned;
+        return CollectionUtils.unmodifiableCopy(mTemplatesReturned);
     }
 
+    @SuppressLint("ExecutorRegistration")
     @Override
     public void setSurfaceCallback(@Nullable SurfaceCallback surfaceCallback) {
-        mSurfaceCallbacks.add(surfaceCallback);
+        mSurfaceCallback = surfaceCallback;
     }
 
     @Override
-    public void showToast(@NonNull CharSequence text, int duration) {
-        mToastsShown.add(text);
+    public void showToast(@NonNull CharSequence text, @CarToast.Duration int duration) {
+        mToastsShown.add(requireNonNull(text));
     }
 
-    void resetTemplatesStoredForScreen(@NonNull Screen screen) {
+    void resetTemplatesStoredForScreen(Screen screen) {
         List<Pair<Screen, Template>> templatesForOtherScreens = new ArrayList<>();
 
         for (Pair<Screen, Template> pair : mTemplatesReturned) {
diff --git a/car/app/app/src/test/java/androidx/car/app/testing/TestCarContext.java b/car/app/app-testing/src/main/java/androidx/car/app/testing/TestCarContext.java
similarity index 81%
rename from car/app/app/src/test/java/androidx/car/app/testing/TestCarContext.java
rename to car/app/app-testing/src/main/java/androidx/car/app/testing/TestCarContext.java
index 19e5091..30051d1 100644
--- a/car/app/app/src/test/java/androidx/car/app/testing/TestCarContext.java
+++ b/car/app/app-testing/src/main/java/androidx/car/app/testing/TestCarContext.java
@@ -16,21 +16,22 @@
 
 package androidx.car.app.testing;
 
-import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
 import static java.util.Objects.requireNonNull;
 
+import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.Intent;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.car.app.CarContext;
 import androidx.car.app.HostDispatcher;
 import androidx.car.app.ICarHost;
 import androidx.car.app.IStartCarApp;
 import androidx.car.app.testing.navigation.TestNavigationManager;
+import androidx.car.app.utils.CollectionUtils;
 
 import java.lang.reflect.Method;
 import java.util.ArrayList;
@@ -56,8 +57,6 @@
  * {@link CarContext#startCarApp(Intent, Intent)}.
  */
 public class TestCarContext extends CarContext {
-    private static TestCarContext sLatestInstance;
-
     private final Map<String, Object> mOverriddenService = new HashMap<>();
     private final IStartCarApp mStartCarApp = new StartCarAppStub();
 
@@ -67,7 +66,7 @@
     private final TestNavigationManager mTestNavigationManager;
     private final TestScreenManager mTestScreenManager;
 
-    private final List<Intent> mStartCarAppIntents = new ArrayList<>();
+    final List<Intent> mStartCarAppIntents = new ArrayList<>();
     private boolean mHasCalledFinishCarApp;
 
     /** Resets the values tracked by this {@link TestCarContext}. */
@@ -78,7 +77,6 @@
     @NonNull
     @Override
     public <T> T getCarService(@NonNull Class<T> serviceClass) {
-        requireNonNull(serviceClass);
         String serviceName;
 
         if (serviceClass.isInstance(mTestAppManager)) {
@@ -91,7 +89,7 @@
             serviceName = getCarServiceName(serviceClass);
         }
 
-        return requireNonNull(requireNonNull(serviceClass).cast(getCarService(serviceName)));
+        return requireNonNull(serviceClass.cast(getCarService(serviceName)));
     }
 
     @Override
@@ -125,35 +123,42 @@
         mHasCalledFinishCarApp = true;
     }
 
-    /** Creates a {@link TestCarContext} to use for testing. */
+    /**
+     * Creates a {@link TestCarContext} to use for testing.
+     *
+     * @throws NullPointerException if {@code testContext} is null
+     */
+    @SuppressLint("BanUncheckedReflection")
     @NonNull
     public static TestCarContext createCarContext(@NonNull Context testContext) {
         requireNonNull(testContext);
 
-        sLatestInstance = new TestCarContext(new TestLifecycleOwner(), new HostDispatcher());
-        sLatestInstance.attachBaseContext(testContext);
+        TestCarContext carContext = new TestCarContext(new TestLifecycleOwner(),
+                new HostDispatcher());
+        carContext.attachBaseContext(testContext);
 
         try {
             Method method = CarContext.class.getDeclaredMethod("setCarHost", ICarHost.class);
             method.setAccessible(true);
-            method.invoke(sLatestInstance, sLatestInstance.mFakeHost.getCarHost());
+            method.invoke(carContext, carContext.mFakeHost.getCarHost());
         } catch (ReflectiveOperationException e) {
             throw new IllegalStateException("Failed to attach the base context", e);
         }
 
-        return sLatestInstance;
+        return carContext;
     }
 
     /**
-     * Retrieves all {@link Intent}s sent via {@link CarContext#startCarApp}.
+     * Returns all {@link Intent}s sent via {@link CarContext#startCarApp}.
      *
-     * <p>The {@link Intent}s are stored in order of calls.
+     * <p>The {@link Intent}s are stored in the order of when they were sent, where the first
+     * intent in the list, is the first intent sent.
      *
      * <p>The results will be stored until {@link #reset} is called.
      */
     @NonNull
     public List<Intent> getStartCarAppIntents() {
-        return mStartCarAppIntents;
+        return CollectionUtils.unmodifiableCopy(mStartCarAppIntents);
     }
 
     /** Verifies if {@link CarContext#finishCarApp} has been called. */
@@ -162,48 +167,38 @@
     }
 
     /**
+     * Retrieve the {@link FakeHost} being used.
+     */
+    @NonNull
+    public FakeHost getFakeHost() {
+        return mFakeHost;
+    }
+
+    /**
      * Sets the {@code service} as the service instance for the given {@code serviceClass}.
      *
      * <p>This can be used to mock a car service.
      *
      * <p>Internal use only.
      *
+     * @throws NullPointerException if either {@code serviceClass} or {@code service} are {@code
+     *                              null}
+     *
      * @hide
      */
-    @RestrictTo(LIBRARY)
+    @RestrictTo(LIBRARY_GROUP)
     public void overrideCarService(@NonNull Class<?> serviceClass, @NonNull Object service) {
         requireNonNull(service);
         requireNonNull(serviceClass);
 
         String serviceName = getCarServiceName(serviceClass);
-        if (serviceName == null) {
-            throw new IllegalArgumentException(
-                    "Not an expected car service class: " + serviceClass.getName());
-        }
         mOverriddenService.put(serviceName, service);
     }
 
-    /**
-     * Retrieve the last instance of TestCarContext created for internal testing purposes.
-     *
-     * <p>Internal use only.
-     *
-     * @hide
-     */
-    @RestrictTo(LIBRARY)
-    @Nullable
-    public static TestCarContext getLatestInstance() {
-        return sLatestInstance;
-    }
-
     TestLifecycleOwner getLifecycleOwner() {
         return mTestLifecycleOwner;
     }
 
-    FakeHost getFakeHost() {
-        return mFakeHost;
-    }
-
     IStartCarApp getStartCarAppStub() {
         return mStartCarApp;
     }
@@ -213,7 +208,7 @@
     }
 
     /** Testing version of the start car app binder for notifications. */
-    private class StartCarAppStub extends IStartCarApp.Stub {
+    class StartCarAppStub extends IStartCarApp.Stub {
         @Override
         public void startCarApp(Intent intent) {
             mStartCarAppIntents.add(intent);
diff --git a/car/app/app/src/test/java/androidx/car/app/testing/TestLifecycleOwner.java b/car/app/app-testing/src/main/java/androidx/car/app/testing/TestLifecycleOwner.java
similarity index 98%
rename from car/app/app/src/test/java/androidx/car/app/testing/TestLifecycleOwner.java
rename to car/app/app-testing/src/main/java/androidx/car/app/testing/TestLifecycleOwner.java
index d955743..8274929 100644
--- a/car/app/app/src/test/java/androidx/car/app/testing/TestLifecycleOwner.java
+++ b/car/app/app-testing/src/main/java/androidx/car/app/testing/TestLifecycleOwner.java
@@ -47,6 +47,7 @@
      * androidx.car.app.ScreenManager} APIs, but don't want to setup the {@link
      * androidx.car.app.CarAppService} for testing.
      */
+    @NonNull
     public LifecycleRegistry getRegistry() {
         return mRegistry;
     }
diff --git a/car/app/app/src/test/java/androidx/car/app/testing/TestOnDoneCallbackStub.java b/car/app/app-testing/src/main/java/androidx/car/app/testing/TestOnDoneCallbackStub.java
similarity index 84%
rename from car/app/app/src/test/java/androidx/car/app/testing/TestOnDoneCallbackStub.java
rename to car/app/app-testing/src/main/java/androidx/car/app/testing/TestOnDoneCallbackStub.java
index e78ab3d..82c4b9d 100644
--- a/car/app/app/src/test/java/androidx/car/app/testing/TestOnDoneCallbackStub.java
+++ b/car/app/app-testing/src/main/java/androidx/car/app/testing/TestOnDoneCallbackStub.java
@@ -16,6 +16,8 @@
 
 package androidx.car.app.testing;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
 import androidx.car.app.IOnDoneCallback;
@@ -28,12 +30,11 @@
  */
 @RestrictTo(Scope.LIBRARY)
 public class TestOnDoneCallbackStub extends IOnDoneCallback.Stub {
-
     @Override
-    public void onSuccess(Bundleable response) {
+    public void onSuccess(@Nullable Bundleable response) {
     }
 
     @Override
-    public void onFailure(Bundleable failureResponse) {
+    public void onFailure(@NonNull Bundleable failureResponse) {
     }
 }
diff --git a/car/app/app/src/test/java/androidx/car/app/testing/TestScreenManager.java b/car/app/app-testing/src/main/java/androidx/car/app/testing/TestScreenManager.java
similarity index 80%
rename from car/app/app/src/test/java/androidx/car/app/testing/TestScreenManager.java
rename to car/app/app-testing/src/main/java/androidx/car/app/testing/TestScreenManager.java
index 85f375e..e563063 100644
--- a/car/app/app/src/test/java/androidx/car/app/testing/TestScreenManager.java
+++ b/car/app/app-testing/src/main/java/androidx/car/app/testing/TestScreenManager.java
@@ -16,10 +16,15 @@
 
 package androidx.car.app.testing;
 
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.SuppressLint;
+
 import androidx.annotation.NonNull;
 import androidx.car.app.OnScreenResultListener;
 import androidx.car.app.Screen;
 import androidx.car.app.ScreenManager;
+import androidx.car.app.utils.CollectionUtils;
 import androidx.lifecycle.Lifecycle.State;
 
 import java.util.ArrayList;
@@ -44,8 +49,7 @@
     private final List<Screen> mScreensRemoved = new ArrayList<>();
 
     /**
-     * Resets the values tracked by this {@link TestScreenManager}, and the {@link Screen} stack
-     * .
+     * Resets the values tracked by this {@link TestScreenManager} and the {@link Screen} stack.
      */
     public void reset() {
         getScreenStack().clear();
@@ -54,29 +58,31 @@
     }
 
     /**
-     * Retrieves all the {@link Screen}s pushed via {@link ScreenManager#push}, and {@link
+     * Returns all the {@link Screen}s pushed via {@link ScreenManager#push}, and {@link
      * ScreenManager#pushForResult}.
      *
-     * <p>The screens are stored in order of calls.
+     * <p>The screens are stored in the order in which they were pushed, where the first screen
+     * in the list is the first screen that was pushed.
      *
      * <p>The screens will be stored until {@link #reset} is called.
      */
     @NonNull
     public List<Screen> getScreensPushed() {
-        return mScreensPushed;
+        return CollectionUtils.unmodifiableCopy(mScreensPushed);
     }
 
     /**
-     * Retrieves all the {@link Screen}s removed via {@link ScreenManager#pop}, {@link
+     * Returns all the {@link Screen}s removed via {@link ScreenManager#pop}, {@link
      * ScreenManager#popTo}, and {@link ScreenManager#remove}.
      *
-     * <p>The screens are stored in order of calls.
+     * <p>The screens are stored in the order in which they were removed, where the first screen
+     * in the list, is the first screen that was removed.
      *
      * <p>The screens will be stored until {@link #reset} is called.
      */
     @NonNull
     public List<Screen> getScreensRemoved() {
-        return mScreensRemoved;
+        return CollectionUtils.unmodifiableCopy(mScreensRemoved);
     }
 
     /** Returns {@code true} if the {@link Screen} stack has any screens in it. */
@@ -86,10 +92,11 @@
 
     @Override
     public void push(@NonNull Screen screen) {
-        mScreensPushed.add(screen);
+        mScreensPushed.add(requireNonNull(screen));
         super.push(screen);
     }
 
+    @SuppressLint("ExecutorRegistration")
     @Override
     public void pushForResult(
             @NonNull Screen screen, @NonNull OnScreenResultListener onScreenResultListener) {
diff --git a/car/app/app/src/test/java/androidx/car/app/testing/navigation/TestNavigationManager.java b/car/app/app-testing/src/main/java/androidx/car/app/testing/navigation/TestNavigationManager.java
similarity index 62%
rename from car/app/app/src/test/java/androidx/car/app/testing/navigation/TestNavigationManager.java
rename to car/app/app-testing/src/main/java/androidx/car/app/testing/navigation/TestNavigationManager.java
index b8fbbd5..a942932 100644
--- a/car/app/app/src/test/java/androidx/car/app/testing/navigation/TestNavigationManager.java
+++ b/car/app/app-testing/src/main/java/androidx/car/app/testing/navigation/TestNavigationManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,8 +16,6 @@
 
 package androidx.car.app.testing.navigation;
 
-import static java.util.Objects.requireNonNull;
-
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.car.app.HostDispatcher;
@@ -25,9 +23,11 @@
 import androidx.car.app.navigation.NavigationManagerCallback;
 import androidx.car.app.navigation.model.Trip;
 import androidx.car.app.testing.TestCarContext;
+import androidx.car.app.utils.CollectionUtils;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.Executor;
 
 /**
  * The {@link NavigationManager} that is used for testing.
@@ -46,54 +46,53 @@
  */
 public class TestNavigationManager extends NavigationManager {
     private final List<Trip> mTripsSent = new ArrayList<>();
-    private final List<NavigationManagerCallback> mListenersSet = new ArrayList<>();
+    private NavigationManagerCallback mCallback;
     private int mNavigationStartedCount;
     private int mNavigationEndedCount;
 
     /** Resets the values tracked by this {@link TestNavigationManager}. */
     public void reset() {
         mTripsSent.clear();
-        mListenersSet.clear();
+        mCallback = null;
         mNavigationStartedCount = 0;
         mNavigationEndedCount = 0;
     }
 
     /**
-     * Retrieves all the {@link Trip}s sent via {@link NavigationManager#updateTrip}.
+     * Returns all the {@link Trip}s sent via {@link NavigationManager#updateTrip}.
      *
-     * <p>The trips are stored in order of calls.
+     * <p>The trips are stored in the order in which they were sent, where the first trip in the
+     * list, is the first trip sent.
      *
      * <p>The trips will be stored until {@link #reset} is called.
      */
     @NonNull
     public List<Trip> getTripsSent() {
-        return mTripsSent;
+        return CollectionUtils.unmodifiableCopy(mTripsSent);
     }
 
     /**
-     * Retrieves all the {@link NavigationManagerCallback}s added via {@link
-     * NavigationManager#setNavigationManagerCallback(NavigationManagerCallback)}.
+     * Returns the callback set via {@link NavigationManager#setNavigationManagerCallback}.
      *
-     * <p>The listeners are stored in order of calls.
-     *
-     * <p>The listeners will be stored until {@link #reset} is called.
+     * <p>The listener will be {@code null} if one was never set, or if
+     * {@link NavigationManager#clearNavigationManagerCallback()}  or {@link #reset} was called.
      */
-    @NonNull
-    public List<NavigationManagerCallback> getNavigationManagerCallbacksSet() {
-        return mListenersSet;
+    @Nullable
+    public NavigationManagerCallback getNavigationManagerCallback() {
+        return mCallback;
     }
 
     /**
-     * Retrieves the number of times that navigation was started via {@link
-     * NavigationManager#navigationStarted()} since the creation or the last call to {@link #reset}.
+     * Returns the number of times that navigation was started via {@link
+     * NavigationManager#navigationStarted()} since creation or the last call to {@link #reset}.
      */
     public int getNavigationStartedCount() {
         return mNavigationStartedCount;
     }
 
     /**
-     * Retrieves the number of times that navigation was ended via {@link
-     * NavigationManager#navigationEnded()} since the creation or the last call to {@link #reset}.
+     * Returns the number of times that navigation was ended via {@link
+     * NavigationManager#navigationEnded()} since creation or the last call to {@link #reset}.
      */
     public int getNavigationEndedCount() {
         return mNavigationEndedCount;
@@ -101,14 +100,21 @@
 
     @Override
     public void updateTrip(@NonNull Trip trip) {
-        mTripsSent.add(requireNonNull(trip));
+        mTripsSent.add(trip);
         super.updateTrip(trip);
     }
 
     @Override
-    public void setNavigationManagerCallback(@Nullable NavigationManagerCallback listener) {
-        mListenersSet.add(listener);
-        super.setNavigationManagerCallback(listener);
+    public void setNavigationManagerCallback(@NonNull /* @CallbackExecutor */ Executor executor,
+            @NonNull NavigationManagerCallback callback) {
+        mCallback = callback;
+        super.setNavigationManagerCallback(executor, callback);
+    }
+
+    @Override
+    public void clearNavigationManagerCallback() {
+        mCallback = null;
+        super.clearNavigationManagerCallback();
     }
 
     @Override
@@ -123,7 +129,8 @@
         super.navigationEnded();
     }
 
-    public TestNavigationManager(TestCarContext testCarContext, HostDispatcher hostDispatcher) {
+    public TestNavigationManager(@NonNull TestCarContext testCarContext,
+            @NonNull HostDispatcher hostDispatcher) {
         super(testCarContext, hostDispatcher);
     }
 }
diff --git a/car/app/app/build.gradle b/car/app/app/build.gradle
index 5b9a4ce..1faab1a 100644
--- a/car/app/app/build.gradle
+++ b/car/app/app/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.LibraryGroups
 import androidx.build.LibraryType
+import androidx.build.LibraryVersions
 
 import static androidx.build.dependencies.DependenciesKt.*
 
@@ -40,6 +41,7 @@
     testImplementation(MOCKITO_CORE)
     testImplementation(ROBOLECTRIC)
     testImplementation(TRUTH)
+    testImplementation project(path: ':car:app:app-testing')
 }
 
 android {
diff --git a/car/app/app/src/main/java/androidx/car/app/AppManager.java b/car/app/app/src/main/java/androidx/car/app/AppManager.java
index eeda0a1..0da4b12 100644
--- a/car/app/app/src/main/java/androidx/car/app/AppManager.java
+++ b/car/app/app/src/main/java/androidx/car/app/AppManager.java
@@ -18,6 +18,8 @@
 
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
+import static java.util.Objects.requireNonNull;
+
 import android.annotation.SuppressLint;
 import android.os.Looper;
 import android.view.Surface;
@@ -29,8 +31,6 @@
 import androidx.car.app.utils.RemoteUtils;
 import androidx.car.app.utils.ThreadUtils;
 
-import java.util.Objects;
-
 /** Manages the communication between the app and the host. */
 public class AppManager {
     @NonNull
@@ -89,8 +89,10 @@
      * @param text     the text to show
      * @param duration how long to display the message
      * @throws HostException if the remote call fails
+     * @throws NullPointerException if {@code text} is {@code null}
      */
-    public void showToast(@NonNull CharSequence text, int duration) {
+    public void showToast(@NonNull CharSequence text, @CarToast.Duration int duration) {
+        requireNonNull(text);
         mHostDispatcher.dispatch(
                 CarContext.APP_SERVICE,
                 (IAppHost host) -> {
@@ -108,8 +110,8 @@
     /** Creates an instance of {@link AppManager}. */
     static AppManager create(@NonNull CarContext carContext,
             @NonNull HostDispatcher hostDispatcher) {
-        Objects.requireNonNull(carContext);
-        Objects.requireNonNull(hostDispatcher);
+        requireNonNull(carContext);
+        requireNonNull(hostDispatcher);
 
         return new AppManager(carContext, hostDispatcher);
     }
diff --git a/car/app/app/src/main/java/androidx/car/app/utils/CollectionUtils.java b/car/app/app/src/main/java/androidx/car/app/utils/CollectionUtils.java
index 7da8461..7e5ba1c 100644
--- a/car/app/app/src/main/java/androidx/car/app/utils/CollectionUtils.java
+++ b/car/app/app/src/main/java/androidx/car/app/utils/CollectionUtils.java
@@ -16,7 +16,7 @@
 
 package androidx.car.app.utils;
 
-import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -33,7 +33,7 @@
  *
  * @hide
  */
-@RestrictTo(LIBRARY)
+@RestrictTo(LIBRARY_GROUP)
 public final class CollectionUtils {
     /** Returns the input {@code list} if not {@code null}, or an empty list otherwise. */
     @NonNull
diff --git a/car/app/app/src/main/java/androidx/car/app/utils/ThreadUtils.java b/car/app/app/src/main/java/androidx/car/app/utils/ThreadUtils.java
index 01d85cc..b5df988 100644
--- a/car/app/app/src/main/java/androidx/car/app/utils/ThreadUtils.java
+++ b/car/app/app/src/main/java/androidx/car/app/utils/ThreadUtils.java
@@ -16,7 +16,7 @@
 
 package androidx.car.app.utils;
 
-import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
 import android.os.Handler;
 import android.os.Looper;
@@ -29,7 +29,7 @@
  *
  * @hide
  */
-@RestrictTo(LIBRARY)
+@RestrictTo(LIBRARY_GROUP)
 public final class ThreadUtils {
     private static final Handler HANDLER = new Handler(Looper.getMainLooper());
 
diff --git a/compose/androidview/androidview/integration-tests/androidview-demos/src/main/java/androidx/compose/androidview/demos/ComplexInteractions.kt b/compose/androidview/androidview/integration-tests/androidview-demos/src/main/java/androidx/compose/androidview/demos/ComplexInteractions.kt
index e596cbe44..f7c8578 100644
--- a/compose/androidview/androidview/integration-tests/androidview-demos/src/main/java/androidx/compose/androidview/demos/ComplexInteractions.kt
+++ b/compose/androidview/androidview/integration-tests/androidview-demos/src/main/java/androidx/compose/androidview/demos/ComplexInteractions.kt
@@ -77,7 +77,7 @@
 
             AndroidView(
                 modifier = Modifier.fillMaxHeight(),
-                viewBlock = {
+                factory = {
                     FrameLayout(context).apply {
                         setPadding(100, 100, 100, 100)
                         setBackgroundColor(0xFF888888.toInt())
diff --git a/compose/androidview/androidview/integration-tests/androidview-demos/src/main/java/androidx/compose/androidview/demos/FocusTransferDemo.kt b/compose/androidview/androidview/integration-tests/androidview-demos/src/main/java/androidx/compose/androidview/demos/FocusTransferDemo.kt
index 3019104..f789ba7 100644
--- a/compose/androidview/androidview/integration-tests/androidview-demos/src/main/java/androidx/compose/androidview/demos/FocusTransferDemo.kt
+++ b/compose/androidview/androidview/integration-tests/androidview-demos/src/main/java/androidx/compose/androidview/demos/FocusTransferDemo.kt
@@ -47,7 +47,7 @@
 @Composable
 fun FocusTransferDemo() {
     AndroidView(
-        viewBlock = {
+        factory = {
             RecyclerView(it).apply {
                 setHasFixedSize(true)
                 layoutManager = LinearLayoutManager(it, VERTICAL, false)
diff --git a/compose/animation/animation-core/api/current.txt b/compose/animation/animation-core/api/current.txt
index 13d1c54..cc3acca 100644
--- a/compose/animation/animation-core/api/current.txt
+++ b/compose/animation/animation-core/api/current.txt
@@ -1,6 +1,9 @@
 // Signature format: 4.0
 package androidx.compose.animation.core {
 
+  public final class ActualJvmKt {
+  }
+
   public final class Animatable<T, V extends androidx.compose.animation.core.AnimationVector> {
     ctor public Animatable(T? initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? visibilityThreshold);
     method public suspend Object? animateDecay(T? initialVelocity, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>> p);
@@ -66,7 +69,6 @@
   public enum AnimationEndReason {
     enum_constant public static final androidx.compose.animation.core.AnimationEndReason BoundReached;
     enum_constant public static final androidx.compose.animation.core.AnimationEndReason Finished;
-    enum_constant public static final androidx.compose.animation.core.AnimationEndReason Interrupted;
   }
 
   public final class AnimationKt {
@@ -512,15 +514,6 @@
     property public final S! targetState;
   }
 
-  @androidx.compose.animation.core.InternalAnimationApi public final class Transition.TransitionAnimationState<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.runtime.State<T> {
-    method public String getLabel();
-    method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
-    method public T! getValue();
-    property public final String label;
-    property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
-    property public T! value;
-  }
-
   public final class TransitionKt {
     method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> animateDp(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.Dp>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.unit.Dp> targetValueByState);
     method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<java.lang.Float> animateFloat(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,java.lang.Float> targetValueByState);
diff --git a/compose/animation/animation-core/api/public_plus_experimental_current.txt b/compose/animation/animation-core/api/public_plus_experimental_current.txt
index 13d1c54..cc3acca 100644
--- a/compose/animation/animation-core/api/public_plus_experimental_current.txt
+++ b/compose/animation/animation-core/api/public_plus_experimental_current.txt
@@ -1,6 +1,9 @@
 // Signature format: 4.0
 package androidx.compose.animation.core {
 
+  public final class ActualJvmKt {
+  }
+
   public final class Animatable<T, V extends androidx.compose.animation.core.AnimationVector> {
     ctor public Animatable(T? initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? visibilityThreshold);
     method public suspend Object? animateDecay(T? initialVelocity, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>> p);
@@ -66,7 +69,6 @@
   public enum AnimationEndReason {
     enum_constant public static final androidx.compose.animation.core.AnimationEndReason BoundReached;
     enum_constant public static final androidx.compose.animation.core.AnimationEndReason Finished;
-    enum_constant public static final androidx.compose.animation.core.AnimationEndReason Interrupted;
   }
 
   public final class AnimationKt {
@@ -512,15 +514,6 @@
     property public final S! targetState;
   }
 
-  @androidx.compose.animation.core.InternalAnimationApi public final class Transition.TransitionAnimationState<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.runtime.State<T> {
-    method public String getLabel();
-    method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
-    method public T! getValue();
-    property public final String label;
-    property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
-    property public T! value;
-  }
-
   public final class TransitionKt {
     method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> animateDp(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.Dp>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.unit.Dp> targetValueByState);
     method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<java.lang.Float> animateFloat(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,java.lang.Float> targetValueByState);
diff --git a/compose/animation/animation-core/api/restricted_current.txt b/compose/animation/animation-core/api/restricted_current.txt
index ec1377c..a4a2771 100644
--- a/compose/animation/animation-core/api/restricted_current.txt
+++ b/compose/animation/animation-core/api/restricted_current.txt
@@ -1,6 +1,9 @@
 // Signature format: 4.0
 package androidx.compose.animation.core {
 
+  public final class ActualJvmKt {
+  }
+
   public final class Animatable<T, V extends androidx.compose.animation.core.AnimationVector> {
     ctor public Animatable(T? initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? visibilityThreshold);
     method public suspend Object? animateDecay(T? initialVelocity, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>> p);
@@ -66,7 +69,6 @@
   public enum AnimationEndReason {
     enum_constant public static final androidx.compose.animation.core.AnimationEndReason BoundReached;
     enum_constant public static final androidx.compose.animation.core.AnimationEndReason Finished;
-    enum_constant public static final androidx.compose.animation.core.AnimationEndReason Interrupted;
   }
 
   public final class AnimationKt {
@@ -515,20 +517,6 @@
     property public final S! targetState;
   }
 
-  @androidx.compose.animation.core.InternalAnimationApi public final class Transition.TransitionAnimationState<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.runtime.State<T> {
-    ctor @kotlin.PublishedApi internal Transition.TransitionAnimationState(T? initialValue, V initialVelocityVector, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, String label);
-    method public String getLabel();
-    method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
-    method public T! getValue();
-    method @kotlin.PublishedApi internal void updateInitialAndTargetValue(T? initialValue, T? targetValue);
-    method @kotlin.PublishedApi internal void updateTargetValue(T? targetValue);
-    property public final String label;
-    property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
-    property public T! value;
-    field @kotlin.PublishedApi internal final androidx.compose.runtime.MutableState animationSpec$delegate;
-    field @kotlin.PublishedApi internal final androidx.compose.runtime.MutableState? targetValue$delegate;
-  }
-
   public final class TransitionKt {
     method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> animateDp(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.Dp>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.unit.Dp> targetValueByState);
     method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<java.lang.Float> animateFloat(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,java.lang.Float> targetValueByState);
diff --git a/compose/animation/animation-core/samples/src/main/java/androidx/compose/animation/core/samples/AnimatableSamples.kt b/compose/animation/animation-core/samples/src/main/java/androidx/compose/animation/core/samples/AnimatableSamples.kt
index 8138f41..0ca9c61 100644
--- a/compose/animation/animation-core/samples/src/main/java/androidx/compose/animation/core/samples/AnimatableSamples.kt
+++ b/compose/animation/animation-core/samples/src/main/java/androidx/compose/animation/core/samples/AnimatableSamples.kt
@@ -85,6 +85,7 @@
         Box(
             Modifier
                 .offset {
+                    // Use the animated offset as the offset of the Box.
                     IntOffset(
                         animatedOffset.value.x.roundToInt(),
                         animatedOffset.value.y.roundToInt()
@@ -98,9 +99,13 @@
 
 @Sampled
 fun AnimatableDecayAndAnimateToSample() {
+    /**
+     * In this example, we create a swipe-to-dismiss modifier that dismisses the child via a
+     * vertical swipe-up.
+     */
     fun Modifier.swipeToDismiss(): Modifier = composed {
         // Creates a Float type `Animatable` and `remember`s it
-        val animatedOffset = remember { Animatable(0f) }
+        val animatedOffsetY = remember { Animatable(0f) }
         this.pointerInput(Unit) {
             coroutineScope {
                 while (true) {
@@ -112,7 +117,9 @@
                         verticalDrag(pointerId) {
                             // Snaps the value by the amount of finger movement
                             launch {
-                                animatedOffset.snapTo(animatedOffset.value + it.positionChange().y)
+                                animatedOffsetY.snapTo(
+                                    animatedOffsetY.value + it.positionChange().y
+                                )
                             }
                             velocityTracker.addPosition(
                                 it.uptimeMillis,
@@ -120,33 +127,38 @@
                             )
                         }
                     }
+                    // At this point, drag has finished. Now we obtain the velocity at the end of
+                    // the drag, and animate the offset with it as the starting velocity.
                     val velocity = velocityTracker.calculateVelocity().y
+
+                    // The goal for the animation below is to animate the dismissal if the fling
+                    // velocity is high enough. Otherwise, spring back.
                     launch {
-                        // Either fling vertically up, or spring back
-                        val decay = splineBasedDecay<Float>(this@pointerInput)
                         // Checks where the animation will end using decay
+                        val decay = splineBasedDecay<Float>(this@pointerInput)
+
+                        // If the animation can naturally end outside of visual bounds, we will
+                        // animate with decay.
                         if (decay.calculateTargetValue(
-                                animatedOffset.value,
+                                animatedOffsetY.value,
                                 velocity
                             ) < -size.height
-                        ) { // If the animation can naturally end outside of visual bounds, we will
-                            // animate with decay.
-
+                        ) {
                             // (Optionally) updates lower bounds. This stops the animation as soon
                             // as bounds are reached.
-                            animatedOffset.updateBounds(
+                            animatedOffsetY.updateBounds(
                                 lowerBound = -size.height.toFloat()
                             )
                             // Animate with the decay animation spec using the fling velocity
-                            animatedOffset.animateDecay(velocity, decay)
+                            animatedOffsetY.animateDecay(velocity, decay)
                         } else {
                             // Not enough velocity to be dismissed, spring back to 0f
-                            animatedOffset.animateTo(0f, initialVelocity = velocity)
+                            animatedOffsetY.animateTo(0f, initialVelocity = velocity)
                         }
                     }
                 }
             }
-        }.offset { IntOffset(0, animatedOffset.value.roundToInt()) }
+        }.offset { IntOffset(0, animatedOffsetY.value.roundToInt()) }
     }
 }
 
@@ -191,18 +203,19 @@
 fun AnimatableFadeIn() {
     fun Modifier.fadeIn(): Modifier = composed {
         // Creates an `Animatable` and remembers it.
-        val alpha = remember { Animatable(0f) }
+        val alphaAnimation = remember { Animatable(0f) }
         // Launches a coroutine for the animation when entering the composition.
-        // Uses `Unit` as the subject so the job in `LaunchedEffect` will run once, until it
-        // leaves composition.
-        LaunchedEffect(Unit) {
+        // Uses `alphaAnimation` as the subject so the job in `LaunchedEffect` will run only when
+        // `alphaAnimation` is created, which happens one time when the modifier enters
+        // composition.
+        LaunchedEffect(alphaAnimation) {
             // Animates to 1f from 0f for the fade-in, and uses a 500ms tween animation.
-            alpha.animateTo(
+            alphaAnimation.animateTo(
                 targetValue = 1f,
                 // Default animationSpec uses [spring] animation, here we overwrite the default.
                 animationSpec = tween(500)
             )
         }
-        this.graphicsLayer(alpha = alpha.value)
+        this.graphicsLayer(alpha = alphaAnimation.value)
     }
 }
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Animatable.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Animatable.kt
index 9dd909f..6f69027 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Animatable.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Animatable.kt
@@ -34,7 +34,7 @@
  *
  * Unlike [AnimationState], [Animatable] ensures *mutual exclusiveness* on its animations. To
  * achieve this, when a new animation is started via [animateTo] (or [animateDecay]), any ongoing
- * animation will be canceled.
+ * animation will be canceled via a [CancellationException].
  *
  * @sample androidx.compose.animation.core.samples.AnimatableAnimateToGenericsType
  *
@@ -42,6 +42,9 @@
  * @param typeConverter A two-way converter that converts the given type [T] from and to
  *                      [AnimationVector]
  * @param visibilityThreshold Threshold at which the animation may round off to its target value.
+ *
+ * @see animateTo
+ * @see animateDecay
  */
 @Suppress("NotCloseable")
 class Animatable<T, V : AnimationVector>(
@@ -87,7 +90,7 @@
         private set
 
     /**
-     * Lower bound of the animation. Defaults to null, which means no lower bound. Bounds can be
+     * Lower bound of the animation, null by default (meaning no lower bound). Bounds can be
      * changed using [updateBounds].
      *
      * Animation will stop as soon as *any* dimension specified in [lowerBound] is reached. For
@@ -98,7 +101,7 @@
         private set
 
     /**
-     * Upper bound of the animation. Defaults to null, which means no upper bound. Bounds can be
+     * Upper bound of the animation, null by default (meaning no upper bound). Bounds can be
      * changed using [updateBounds].
      *
      * Animation will stop as soon as *any* dimension specified in [upperBound] is reached. For
@@ -173,12 +176,11 @@
     }
 
     /**
-     * Sets the target value, which effectively starts an animation to change the value from [value]
-     * to the [targetValue]. If there is already an animation in-flight, this method will cancel
-     * the ongoing animation and start a new animation continuing the current [value] and
-     * [velocity]. It's recommended to set the optional [initialVelocity] only when [animateTo] is
-     * used immediately after a fling. In most of the other cases, altering velocity would result
-     * in visual discontinuity.
+     * Starts an animation to animate from [value] to the provided [targetValue]. If there is
+     * already an animation in-flight, this method will cancel the ongoing animation before
+     * starting a new animation continuing the current [value] and [velocity]. It's recommended to
+     * set the optional [initialVelocity] only when [animateTo] is used immediately after a fling.
+     * In most of the other cases, altering velocity would result in visual discontinuity.
      *
      * The animation will use the provided [animationSpec] to animate the value towards the
      * [targetValue]. When no [animationSpec] is specified, a [spring] will be used.  [block] will
@@ -192,8 +194,11 @@
      *    dimension, the animation will end with [BoundReached] being the end reason.
      *
      * If the animation gets interrupted by 1) another call to start an animation
-     * (i.e. [animateTo]/[animateDecay]), 2) [Animatable.stop], or 3)[Animatable.snapTo], it will
-     * throw a [CancellationException] as the job gets canceled.
+     * (i.e. [animateTo]/[animateDecay]), 2) [Animatable.stop], or 3)[Animatable.snapTo], the
+     * canceled animation will throw a [CancellationException] as the job gets canceled. As a
+     * result, all the subsequent work in the caller's coroutine will be canceled. This is often
+     * the desired behavior. If there's any cleanup that needs to be done when an animation gets
+     * canceled, consider starting the animation in a `try-catch` block.
      *
      * __Note__: once the animation ends, its velocity will be reset to 0. The animation state at
      * the point of interruption/reaching bound is captured in the returned [AnimationResult].
@@ -201,7 +206,6 @@
      * or reached the bound, it's recommended to use the velocity in the returned
      * [AnimationResult.endState] to start another animation.
      *
-     * @sample androidx.compose.animation.core.samples.AnimatableAnimateToGenericsType
      * @sample androidx.compose.animation.core.samples.AnimatableFadeIn
      */
     suspend fun animateTo(
@@ -221,10 +225,10 @@
     }
 
     /**
-     * Starts an animation that slows down from the given [initialVelocity] starting at
-     * current [Animatable.value] until the velocity reaches 0. If there's already an ongoing
-     * animation, the animation in-flight will be immediately cancelled. Decay animation is often
-     * used after a fling gesture.
+     * Start a decay animation (i.e. an animation that *slows down* from the given
+     * [initialVelocity] starting at current [Animatable.value] until the velocity reaches 0.
+     * If there's already an ongoing animation, the animation in-flight will be immediately
+     * cancelled. Decay animation is often used after a fling gesture.
      *
      * [animationSpec] defines the decay animation that will be used for this animation. Some
      * options for this [animationSpec] include: [splineBasedDecay][androidx.compose
@@ -233,13 +237,16 @@
      *
      * Returns an [AnimationResult] object, that contains the [reason][AnimationEndReason] for
      * ending the animation, and an end state of the animation. The reason for ending the animation
-     * will be [Finished], when the animation finishes successfully without any interruption.
+     * will be [Finished] if the animation finishes successfully without any interruption.
      * If the animation reaches the either [lowerBound] or [upperBound] in any dimension, the
      * animation will end with [BoundReached] being the end reason.
      *
      * If the animation gets interrupted by 1) another call to start an animation
-     * (i.e. [animateTo]/[animateDecay]), 2) [Animatable.stop], or 3)[Animatable.snapTo], it will
-     * throw a [CancellationException] as the job gets canceled.
+     * (i.e. [animateTo]/[animateDecay]), 2) [Animatable.stop], or 3)[Animatable.snapTo], the
+     * canceled animation will throw a [CancellationException] as the job gets canceled. As a
+     * result, all the subsequent work in the caller's coroutine will be canceled. This is often
+     * the desired behavior. If there's any cleanup that needs to be done when an animation gets
+     * canceled, consider starting the animation in a `try-catch` block.
      *
      * __Note__, once the animation ends, its velocity will be reset to 0. If there's a need to
      * continue the momentum before the animation gets interrupted or reaches the bound, it's
@@ -342,10 +349,17 @@
     }
 
     /**
-     * Sets the current value to the target value immediately, without any animation. This will
-     * also cancel any on-going animation
+     * Sets the current value to the target value, without any animation. This will also cancel any
+     * on-going animation with a [CancellationException]. This function will return *after*
+     * canceling any on-going animation and updating the [value] to the provided [targetValue].
+     *
+     * See [animateTo] and [animateDecay] for more details about animation being canceled.
      *
      * @param targetValue The new target value to set [value] to.
+     *
+     * @see animateTo
+     * @see animateDecay
+     * @see stop
      */
     suspend fun snapTo(targetValue: T) {
         mutatorMutex.mutate {
@@ -356,9 +370,18 @@
     }
 
     /**
-     * Stops any on-going animation. No op if no animation is running. Note that this method does
-     * not skip the animation value to its target value. Rather the animation will be stopped in its
-     * track.
+     * Stops any on-going animation with a [CancellationException].
+     *
+     * This function will not return until the ongoing animation has been canceled (if any).
+     * Note, [stop] function does **not** skip the animation value to its target value. Rather the
+     * animation will be stopped in its track. Consider [snapTo] if it's desired to not only stop
+     * the animation but also snap the [value] to a given value.
+     *
+     * See [animateTo] and [animateDecay] for more details about animation being canceled.
+     *
+     * @see animateTo
+     * @see animateDecay
+     * @see snapTo
      */
     suspend fun stop() {
         mutatorMutex.mutate {
@@ -387,7 +410,7 @@
  * do so, when a new animation is started via [animateTo] (or [animateDecay]), any ongoing
  * animation job will be cancelled.
  *
- * @sample androidx.compose.animation.core.samples.AnimatableDecayAndAnimateToSample
+ * @sample androidx.compose.animation.core.samples.AnimatableFadeIn
  *
  * @param initialValue initial value of the animatable value holder
  * @param visibilityThreshold Threshold at which the animation may round off to its target value.
@@ -416,6 +439,18 @@
  * @sample androidx.compose.animation.core.samples.AnimatableAnimationResultSample
  */
 class AnimationResult<T, V : AnimationVector>(
+    /**
+     * The state of the animation in its last frame before it's canceled or reset. This captures
+     * the animation value/velocity/frame time, etc at the point of interruption, or before the
+     * velocity is reset when the animation finishes successfully.
+     */
     val endState: AnimationState<T, V>,
+    /**
+     * The reason why the animation has ended. Could be either of the following:
+     * -  [Finished], when the animation finishes successfully without any interruption
+     * -  [BoundReached] If the animation reaches the either [lowerBound][Animatable.lowerBound] or
+     *    [upperBound][Animatable.upperBound] in any dimension, the animation will end with
+     *    [BoundReached] being the end reason.
+     */
     val endReason: AnimationEndReason
 )
\ No newline at end of file
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/AnimateAsState.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/AnimateAsState.kt
index ce28089..854be30 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/AnimateAsState.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/AnimateAsState.kt
@@ -35,7 +35,7 @@
  * Fire-and-forget animation function for [Float]. This Composable function is overloaded for
  * different parameter types such as [Dp], [Color][androidx.compose.ui.graphics.Color], [Offset],
  * etc. When the provided [targetValue] is changed, the animation will run automatically. If there
- * is already an animation in-flight whe [targetValue] changes, the on-going animation will adjust
+ * is already an animation in-flight when [targetValue] changes, the on-going animation will adjust
  * course to animate towards the new target value.
  *
  * [animateFloatAsState] returns a [State] object. The value of the state object will continuously
@@ -88,7 +88,7 @@
  * Fire-and-forget animation function for [Dp]. This Composable function is overloaded for
  * different parameter types such as [Float], [Color][androidx.compose.ui.graphics.Color], [Offset],
  * etc. When the provided [targetValue] is changed, the animation will run automatically. If there
- * is already an animation in-flight whe [targetValue] changes, the on-going animation will adjust
+ * is already an animation in-flight when [targetValue] changes, the on-going animation will adjust
  * course to animate towards the new target value.
  *
  * [animateDpAsState] returns a [State] object. The value of the state object will continuously be
@@ -125,7 +125,7 @@
  * Fire-and-forget animation function for [Size]. This Composable function is overloaded for
  * different parameter types such as [Dp], [Color][androidx.compose.ui.graphics.Color], [Offset],
  * etc. When the provided [targetValue] is changed, the animation will run automatically. If there
- * is already an animation in-flight whe [targetValue] changes, the on-going animation will adjust
+ * is already an animation in-flight when [targetValue] changes, the on-going animation will adjust
  * course to animate towards the new target value.
  *
  * [animateSizeAsState] returns a [State] object. The value of the state object will continuously be
@@ -163,7 +163,7 @@
  * Fire-and-forget animation function for [Offset]. This Composable function is overloaded for
  * different parameter types such as [Dp], [Color][androidx.compose.ui.graphics.Color], [Float],
  * etc. When the provided [targetValue] is changed, the animation will run automatically. If there
- * is already an animation in-flight whe [targetValue] changes, the on-going animation will adjust
+ * is already an animation in-flight when [targetValue] changes, the on-going animation will adjust
  * course to animate towards the new target value.
  *
  * [animateOffsetAsState] returns a [State] object. The value of the state object will
@@ -197,7 +197,7 @@
  * Fire-and-forget animation function for [Rect]. This Composable function is overloaded for
  * different parameter types such as [Dp], [Color][androidx.compose.ui.graphics.Color], [Offset],
  * etc. When the provided [targetValue] is changed, the animation will run automatically. If there
- * is already an animation in-flight whe [targetValue] changes, the on-going animation will adjust
+ * is already an animation in-flight when [targetValue] changes, the on-going animation will adjust
  * course to animate towards the new target value.
  *
  * [animateRectAsState] returns a [State] object. The value of the state object will continuously be
@@ -232,7 +232,7 @@
  * Fire-and-forget animation function for [Int]. This Composable function is overloaded for
  * different parameter types such as [Dp], [Color][androidx.compose.ui.graphics.Color], [Offset],
  * etc. When the provided [targetValue] is changed, the animation will run automatically. If there
- * is already an animation in-flight whe [targetValue] changes, the on-going animation will adjust
+ * is already an animation in-flight when [targetValue] changes, the on-going animation will adjust
  * course to animate towards the new target value.
  *
  * [animateIntAsState] returns a [State] object. The value of the state object will continuously be
@@ -264,7 +264,7 @@
  * Fire-and-forget animation function for [IntOffset]. This Composable function is overloaded for
  * different parameter types such as [Dp], [Color][androidx.compose.ui.graphics.Color], [Offset],
  * etc. When the provided [targetValue] is changed, the animation will run automatically. If there
- * is already an animation in-flight whe [targetValue] changes, the on-going animation will adjust
+ * is already an animation in-flight when [targetValue] changes, the on-going animation will adjust
  * course to animate towards the new target value.
  *
  * [animateIntOffsetAsState] returns a [State] object. The value of the state object will
@@ -298,7 +298,7 @@
  * Fire-and-forget animation function for [IntSize]. This Composable function is overloaded for
  * different parameter types such as [Dp], [Color][androidx.compose.ui.graphics.Color], [Offset],
  * etc. When the provided [targetValue] is changed, the animation will run automatically. If there
- * is already an animation in-flight whe [targetValue] changes, the on-going animation will adjust
+ * is already an animation in-flight when [targetValue] changes, the on-going animation will adjust
  * course to animate towards the new target value.
  *
  * [animateIntSizeAsState] returns a [State] object. The value of the state object will continuously
@@ -330,7 +330,7 @@
  * Fire-and-forget animation function for any value. This Composable function is overloaded for
  * different parameter types such as [Dp], [Color][androidx.compose.ui.graphics.Color], [Offset],
  * etc. When the provided [targetValue] is changed, the animation will run automatically. If there
- * is already an animation in-flight whe [targetValue] changes, the on-going animation will adjust
+ * is already an animation in-flight when [targetValue] changes, the on-going animation will adjust
  * course to animate towards the new target value.
  *
  * [animateValueAsState] returns a [State] object. The value of the state object will continuously be
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/AnimationEndReason.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/AnimationEndReason.kt
index d050f2b..91b6a8b 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/AnimationEndReason.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/AnimationEndReason.kt
@@ -21,10 +21,6 @@
  */
 enum class AnimationEndReason {
     /**
-     * Animation was interrupted, e.g by another animation
-     */
-    Interrupted,
-    /**
      * Animation will be forced to end when its value reaches upper/lower bound (if they have
      * been defined, e.g via [Animatable.updateBounds])
      *
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Expect.kt
similarity index 65%
copy from compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt
copy to compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Expect.kt
index 63fdeeb..e0b26ae 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Expect.kt
@@ -1,5 +1,7 @@
+// ktlint-disable filename
+
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +16,11 @@
  * limitations under the License.
  */
 
-package androidx.compose.foundation.layout
+package androidx.compose.animation.core
 
-@RequiresOptIn("The API of this layout is experimental and is likely to change in the future.")
-annotation class ExperimentalLayout
+expect class AtomicReference<V>(value: V) {
+    fun get(): V
+    fun set(value: V)
+    fun getAndSet(value: V): V
+    fun compareAndSet(expect: V, newValue: V): Boolean
+}
\ No newline at end of file
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/InternalMutatorMutex.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/InternalMutatorMutex.kt
index f3c3ae3..0ba64b0 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/InternalMutatorMutex.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/InternalMutatorMutex.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.animation.core
 
-import androidx.compose.runtime.AtomicReference
 import androidx.compose.runtime.Stable
 import kotlinx.coroutines.CancellationException
 import kotlinx.coroutines.Job
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Transition.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Transition.kt
index c1e7a15..467e6d8 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Transition.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Transition.kt
@@ -25,11 +25,11 @@
 import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.State
 import androidx.compose.runtime.collection.mutableVectorOf
-import androidx.compose.runtime.withFrameNanos
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
+import androidx.compose.runtime.withFrameNanos
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.geometry.Size
@@ -47,13 +47,18 @@
  *
  * [label] is used to differentiate different transitions in Android Studio.
  *
+ * __Note__: There is another [updateTransition] overload that accepts a [MutableTransitionState].
+ * The difference between the two is that the [MutableTransitionState] variant: 1) supports a
+ * different initial state than target state (This would allow a transition to start as soon as
+ * it enters composition.) 2) can be recreated to intentionally trigger a re-start of the
+ * transition.
+ *
  * @sample androidx.compose.animation.core.samples.GestureAnimationSample
  *
  * @return a [Transition] object, to which animations can be added.
  * @see Transition
- * @see animateFloat
- * @see animateValue
- * @see androidx.compose.animation.animateColor
+ * @see Transition.animateFloat
+ * @see Transition.animateValue
  */
 @Composable
 fun <T> updateTransition(
@@ -103,13 +108,13 @@
  * the provided [transitionState]. Whenever the [targetState][MutableTransitionState.targetState] of
  * the [transitionState] changes, the [Transition] will animate to the new target state.
  *
+ * __Remember__: The provided [transitionState] needs to be [remember]ed.
+ *
  * Compared to the [updateTransition] variant that takes a targetState, this function supports a
  * different initial state than the first targetState. Here is an example:
  *
  * @sample androidx.compose.animation.core.samples.InitialStateSample
  *
- * __Note__: The provided [transitionState] needs to be [remember]ed.
- *
  * In most cases, it is recommended to reuse the same [transitionState] that is [remember]ed, such
  * that [Transition] preserves continuity when [targetState][MutableTransitionState.targetState] is
  * changed. However, in some rare cases it is more critical to immediately *snap* to a state
@@ -131,7 +136,7 @@
 
 /**
  * [Transition] manages all the child animations on a state level. Child animations
- * can be created in a declarative way using [animateFloat], [animateValue],
+ * can be created in a declarative way using [Transition.animateFloat], [Transition.animateValue],
  * [animateColor][androidx.compose.animation.animateColor] etc. When the [targetState] changes,
  * [Transition] will automatically start or adjust course for all its child animations to animate
  * to the new target values defined for each animation.
@@ -144,8 +149,8 @@
  *
  * @return a [Transition] object, to which animations can be added.
  * @see updateTransition
- * @see animateFloat
- * @see animateValue
+ * @see Transition.animateFloat
+ * @see Transition.animateValue
  * @see androidx.compose.animation.animateColor
  */
 // TODO: Support creating Transition outside of composition and support imperative use of Transition
@@ -270,11 +275,16 @@
     }
 
     @PublishedApi
-    internal fun addAnimation(animation: TransitionAnimationState<*, *>) =
-        _animations.add(animation)
+    internal fun addAnimation(
+        @Suppress("HiddenTypeParameter")
+        animation: TransitionAnimationState<*, *>
+    ) = _animations.add(animation)
 
     @PublishedApi
-    internal fun removeAnimation(animation: TransitionAnimationState<*, *>) {
+    internal fun removeAnimation(
+        @Suppress("HiddenTypeParameter")
+        animation: TransitionAnimationState<*, *>
+    ) {
         _animations.remove(animation)
     }
 
@@ -343,10 +353,10 @@
     }
 
     // TODO: Consider making this public
-    /** Suppress **/
+    /** @suppress **/
     @InternalAnimationApi
-    inner class TransitionAnimationState<T, V : AnimationVector> @PublishedApi internal
-    constructor(
+    inner class TransitionAnimationState<T, V : AnimationVector>
+    @PublishedApi @Suppress("ShowingMemberInHiddenClass") internal constructor(
         initialValue: T,
         initialVelocityVector: V,
         val typeConverter: TwoWayConverter<T, V>,
@@ -354,10 +364,12 @@
     ) : State<T> {
 
         // Changed during composition, may rollback
+        @Suppress("ShowingMemberInHiddenClass")
         @PublishedApi
         internal var targetValue: T by mutableStateOf(initialValue)
             internal set
 
+        @Suppress("ShowingMemberInHiddenClass")
         @PublishedApi
         internal var animationSpec: FiniteAnimationSpec<T> by mutableStateOf(spring())
         private var animation: TargetBasedAnimation<T, V> by mutableStateOf(
@@ -411,6 +423,7 @@
         }
 
         @PublishedApi
+        @Suppress("ShowingMemberInHiddenClass")
         // This gets called *during* composition
         internal fun updateTargetValue(targetValue: T) {
             if (this.targetValue != targetValue) {
@@ -423,7 +436,7 @@
         }
 
         @PublishedApi
-        @Suppress("ControlFlowWithEmptyBody")
+        @Suppress("ControlFlowWithEmptyBody", "ShowingMemberInHiddenClass")
         // This gets called *during* composition
         internal fun updateInitialAndTargetValue(initialValue: T, targetValue: T) {
             this.targetValue = targetValue
@@ -472,7 +485,7 @@
  *
  * @return A [State] object, the value of which is updated by animation
  * @see updateTransition
- * @see animateFloat
+ * @see Transition.animateFloat
  * @see androidx.compose.animation.animateColor
  */
 @Composable
@@ -549,7 +562,7 @@
  *
  * @return A [State] object, the value of which is updated by animation
  * @see updateTransition
- * @see animateValue
+ * @see Transition.animateValue
  * @see androidx.compose.animation.animateColor
  */
 @Composable
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt b/compose/animation/animation-core/src/desktopMain/kotlin/androidx/compose/animation/core/ActualDesktop.kt
similarity index 72%
copy from compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt
copy to compose/animation/animation-core/src/desktopMain/kotlin/androidx/compose/animation/core/ActualDesktop.kt
index bae8c9a..537e0ce 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt
+++ b/compose/animation/animation-core/src/desktopMain/kotlin/androidx/compose/animation/core/ActualDesktop.kt
@@ -1,5 +1,7 @@
+// ktlint-disable filename
+
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +16,6 @@
  * limitations under the License.
  */
 
-package androidx.compose.ui.input.pointer
+package androidx.compose.animation.core
 
-@MouseTemporaryApi
-expect val isMouseInput: Boolean
\ No newline at end of file
+internal actual typealias AtomicReference<V> = java.util.concurrent.atomic.AtomicReference<V>
\ No newline at end of file
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt b/compose/animation/animation-core/src/jvmMain/kotlin/androidx/compose/animation/core/ActualJvm.kt
similarity index 72%
copy from compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt
copy to compose/animation/animation-core/src/jvmMain/kotlin/androidx/compose/animation/core/ActualJvm.kt
index bae8c9a..537e0ce 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt
+++ b/compose/animation/animation-core/src/jvmMain/kotlin/androidx/compose/animation/core/ActualJvm.kt
@@ -1,5 +1,7 @@
+// ktlint-disable filename
+
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +16,6 @@
  * limitations under the License.
  */
 
-package androidx.compose.ui.input.pointer
+package androidx.compose.animation.core
 
-@MouseTemporaryApi
-expect val isMouseInput: Boolean
\ No newline at end of file
+internal actual typealias AtomicReference<V> = java.util.concurrent.atomic.AtomicReference<V>
\ No newline at end of file
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/MultiDimensionalAnimationDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/MultiDimensionalAnimationDemo.kt
index b1cd642..2eb8910 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/MultiDimensionalAnimationDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/MultiDimensionalAnimationDemo.kt
@@ -22,7 +22,7 @@
 import androidx.compose.animation.core.tween
 import androidx.compose.animation.core.updateTransition
 import androidx.compose.foundation.Canvas
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
@@ -70,7 +70,7 @@
         modifier = Modifier.fillMaxSize().clickable(
             onClick = onClick,
             indication = null,
-            interactionState = remember { InteractionState() }
+            interactionSource = remember { MutableInteractionSource() }
         )
     ) {
         width = size.width
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/SingleValueAnimationDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/SingleValueAnimationDemo.kt
index bbcd355..9202ca8 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/SingleValueAnimationDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/SingleValueAnimationDemo.kt
@@ -20,7 +20,7 @@
 import androidx.compose.animation.core.AnimationSpec
 import androidx.compose.animation.core.animateFloatAsState
 import androidx.compose.animation.core.spring
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.background
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Box
@@ -48,7 +48,7 @@
     Box(
         Modifier.fillMaxSize().clickable(
             indication = null,
-            interactionState = remember { InteractionState() }
+            interactionSource = remember { MutableInteractionSource() }
         ) {
             enabled
                 .value = !enabled
diff --git a/compose/animation/animation/samples/src/main/java/androidx/compose/animation/samples/TransitionSamples.kt b/compose/animation/animation/samples/src/main/java/androidx/compose/animation/samples/TransitionSamples.kt
new file mode 100644
index 0000000..7f71599
--- /dev/null
+++ b/compose/animation/animation/samples/src/main/java/androidx/compose/animation/samples/TransitionSamples.kt
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.animation.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.animation.animateColor
+import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.RepeatMode
+import androidx.compose.animation.core.Transition
+import androidx.compose.animation.core.animateFloat
+import androidx.compose.animation.core.infiniteRepeatable
+import androidx.compose.animation.core.rememberInfiniteTransition
+import androidx.compose.animation.core.spring
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.core.updateTransition
+import androidx.compose.foundation.background
+import androidx.compose.foundation.gestures.detectTapGestures
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.material.Button
+import androidx.compose.material.Icon
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Text
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Favorite
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.unit.dp
+
+private enum class ComponentState { Pressed, Released }
+
+@Sampled
+@Composable
+fun GestureAnimationSample() {
+    // enum class ComponentState { Pressed, Released }
+    var useRed by remember { mutableStateOf(false) }
+    var toState by remember { mutableStateOf(ComponentState.Released) }
+    val modifier = Modifier.pointerInput(Unit) {
+        detectTapGestures(
+            onPress = {
+                toState = ComponentState.Pressed
+                tryAwaitRelease()
+                toState = ComponentState.Released
+            }
+        )
+    }
+
+    // Defines a transition of `ComponentState`, and updates the transition when the provided
+    // [targetState] changes. The tran
+    // sition will run all of the child animations towards the new
+    // [targetState] in response to the [targetState] change.
+    val transition: Transition<ComponentState> = updateTransition(targetState = toState)
+    // Defines a float animation as a child animation the transition. The current animation value
+    // can be read from the returned State<Float>.
+    val scale: Float by transition.animateFloat(
+        // Defines a transition spec that uses the same low-stiffness spring for *all*
+        // transitions of this float, no matter what the target is.
+        transitionSpec = { spring(stiffness = 50f) }
+    ) { state ->
+        // This code block declares a mapping from state to value.
+        if (state == ComponentState.Pressed) 3f else 1f
+    }
+
+    // Defines a color animation as a child animation of the transition.
+    val color: Color by transition.animateColor(
+        transitionSpec = {
+            when {
+                ComponentState.Pressed isTransitioningTo ComponentState.Released ->
+                    // Uses spring for the transition going from pressed to released
+                    spring(stiffness = 50f)
+                else ->
+                    // Uses tween for all the other transitions. (In this case there is
+                    // only one other transition. i.e. released -> pressed.)
+                    tween(durationMillis = 500)
+            }
+        }
+    ) { state ->
+        when (state) {
+            // Similar to the float animation, we need to declare the target values
+            // for each state. In this code block we can access theme colors.
+            ComponentState.Pressed -> MaterialTheme.colors.primary
+            // We can also have the target value depend on other mutableStates,
+            // such as `useRed` here. Whenever the target value changes, transition
+            // will automatically animate to the new value even if it has already
+            // arrived at its target state.
+            ComponentState.Released -> if (useRed) Color.Red else MaterialTheme.colors.secondary
+        }
+    }
+    Column {
+        Button(
+            modifier = Modifier.padding(10.dp).align(Alignment.CenterHorizontally),
+            onClick = { useRed = !useRed }
+        ) {
+            Text("Change Color")
+        }
+        Box(
+            modifier.fillMaxSize().wrapContentSize(Alignment.Center)
+                .size((100 * scale).dp).background(color)
+        )
+    }
+}
+
+@Sampled
+@Composable
+fun InfiniteTransitionSample() {
+    @Composable
+    fun InfinitelyPulsingHeart() {
+        // Creates an [InfiniteTransition] instance for managing child animations.
+        val infiniteTransition = rememberInfiniteTransition()
+
+        // Creates a child animation of float type as a part of the [InfiniteTransition].
+        val scale by infiniteTransition.animateFloat(
+            initialValue = 3f,
+            targetValue = 6f,
+            animationSpec = infiniteRepeatable(
+                // Infinitely repeating a 1000ms tween animation using default easing curve.
+                animation = tween(1000),
+                // After each iteration of the animation (i.e. every 1000ms), the animation will
+                // start again from the [initialValue] defined above.
+                // This is the default [RepeatMode]. See [RepeatMode.Reverse] below for an
+                // alternative.
+                repeatMode = RepeatMode.Restart
+            )
+        )
+
+        // Creates a Color animation as a part of the [InfiniteTransition].
+        val color by infiniteTransition.animateColor(
+            initialValue = Color.Red,
+            targetValue = Color(0xff800000), // Dark Red
+            animationSpec = infiniteRepeatable(
+                // Linearly interpolate between initialValue and targetValue every 1000ms.
+                animation = tween(1000, easing = LinearEasing),
+                // Once [TargetValue] is reached, starts the next iteration in reverse (i.e. from
+                // TargetValue to InitialValue). Then again from InitialValue to TargetValue. This
+                // [RepeatMode] ensures that the animation value is *always continuous*.
+                repeatMode = RepeatMode.Reverse
+            )
+        )
+
+        Box(Modifier.fillMaxSize()) {
+            Icon(
+                Icons.Filled.Favorite,
+                contentDescription = null,
+                modifier = Modifier.align(Alignment.Center)
+                    .graphicsLayer(
+                        scaleX = scale,
+                        scaleY = scale
+                    ),
+                tint = color
+            )
+        }
+    }
+}
diff --git a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimationModifier.kt b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimationModifier.kt
index 0db809e..3087a0c 100644
--- a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimationModifier.kt
+++ b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimationModifier.kt
@@ -21,7 +21,6 @@
 import androidx.compose.animation.core.AnimationSpec
 import androidx.compose.animation.core.AnimationVector2D
 import androidx.compose.animation.core.FiniteAnimationSpec
-import androidx.compose.animation.core.SpringSpec
 import androidx.compose.animation.core.VectorConverter
 import androidx.compose.animation.core.spring
 import androidx.compose.runtime.remember
@@ -44,9 +43,8 @@
  * is already at the tail of the chain) changes size. This allows the parent modifier to observe
  * a smooth size change, resulting in an overall continuous visual change.
  *
- * An [AnimationSpec] can be optionally specified for the size change animation. By default,
- * [SpringSpec] will be used. Clipping defaults to true, such that the content outside of animated
- * size will not be shown.
+ * A [FiniteAnimationSpec] can be optionally specified for the size change animation. By default,
+ * [spring] will be used.
  *
  * An optional [finishedListener] can be supplied to get notified when the size change animation is
  * finished. Since the content size change can be dynamic in many cases, both initial value and
@@ -57,8 +55,9 @@
  *
  * @sample androidx.compose.animation.samples.AnimateContent
  *
- * @param animationSpec the animation that will be used to animate size change
- * @param finishedListener optional listener to be called when the content change animation is
+ * @param animationSpec a finite animation that will be used to animate size change, [spring] by
+ *                      default
+ * @param finishedListener an optional listener to be called when the content change animation is
  *                         completed.
  */
 fun Modifier.animateContentSize(
diff --git a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt
index ae2b9d5..0224332 100644
--- a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt
+++ b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt
@@ -481,8 +481,8 @@
 }
 
 /**
- * This slides in the content horizontally, from a starting offset defined in
- * [initialOffsetX] to `0`. The direction of the slide can be controlled by configuring the
+ * This slides in the content horizontally, from a starting offset defined in [initialOffsetX] to
+ * `0` **pixels**. The direction of the slide can be controlled by configuring the
  * [initialOffsetX]. A positive value means sliding from right to left, whereas a negative
  * value would slide the content from left to right.
  *
@@ -493,7 +493,7 @@
  *
  * @sample androidx.compose.animation.samples.SlideTransition
  *
- * @param initialOffsetX a lambda that takes the full width of the content and returns the
+ * @param initialOffsetX a lambda that takes the full width of the content in pixels and returns the
  *                             initial offset for the slide-in, by default it returns `-fullWidth/2`
  * @param animationSpec the animation used for the slide-in, [spring] by default.
  */
@@ -509,8 +509,8 @@
     )
 
 /**
- * This slides in the content vertically, from a starting offset defined in
- * [initialOffsetY] to `0`. The direction of the slide can be controlled by configuring the
+ * This slides in the content vertically, from a starting offset defined in [initialOffsetY] to `0`
+ * in **pixels**. The direction of the slide can be controlled by configuring the
  * [initialOffsetY]. A positive initial offset means sliding up, whereas a negative value would
  * slide the content down.
  *
@@ -537,8 +537,8 @@
     )
 
 /**
- * This slides out the content horizontally, from 0 to a target offset defined in
- * [targetOffsetX]. The direction of the slide can be controlled by configuring the
+ * This slides out the content horizontally, from 0 to a target offset defined in [targetOffsetX]
+ * in **pixels**. The direction of the slide can be controlled by configuring the
  * [targetOffsetX]. A positive value means sliding to the right, whereas a negative
  * value would slide the content towards the left.
  *
@@ -565,8 +565,8 @@
     )
 
 /**
- * This slides out the content vertically, from 0 to a target offset defined in
- * [targetOffsetY]. The direction of the slide-out can be controlled by configuring the
+ * This slides out the content vertically, from 0 to a target offset defined in [targetOffsetY]
+ * in **pixels**. The direction of the slide-out can be controlled by configuring the
  * [targetOffsetY]. A positive target offset means sliding down, whereas a negative value would
  * slide the content up.
  *
diff --git a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/SingleValueAnimation.kt b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/SingleValueAnimation.kt
index c71dab8..9730f0f 100644
--- a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/SingleValueAnimation.kt
+++ b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/SingleValueAnimation.kt
@@ -36,21 +36,21 @@
  * Fire-and-forget animation function for [Color]. This Composable function is overloaded for
  * different parameter types such as [Dp], [Float], [Int], [Size], [Offset],
  * etc. When the provided [targetValue] is changed, the animation will run automatically. If there
- * is already an animation in-flight whe [targetValue] changes, the on-going animation will adjust
+ * is already an animation in-flight when [targetValue] changes, the on-going animation will adjust
  * course to animate towards the new target value.
  *
  * [animateColorAsState] returns a [State] object. The value of the state object will
  * continuously be updated by the animation until the animation finishes.
  *
  * Note, [animateColorAsState] cannot be canceled/stopped without removing this composable function
- * from the tree. See [Animatable] for cancelable animations.
+ * from the tree. See [Animatable][androidx.compose.animation.Animatable] for cancelable animations.
  *
  * @sample androidx.compose.animation.samples.ColorAnimationSample
  *
  * @param targetValue Target value of the animation
- * @param animationSpec The animation that will be used to change the value through time. Physics
- *                    animation will be used by default.
- * @param finishedListener An optional end listener to get notified when the animation is finished.
+ * @param animationSpec The animation that will be used to change the value through time,
+ *                      [spring] by default
+ * @param finishedListener An optional listener to get notified when the animation is finished.
  */
 @Composable
 fun animateColorAsState(
@@ -79,11 +79,15 @@
  *
  * Unlike [AnimationState], [Animatable] ensures mutual exclusiveness on its animation. To
  * do so, when a new animation is started via [animateTo] (or [animateDecay]), any ongoing
- * animation job will be cancelled.
+ * animation job will be cancelled via a
+ * [CancellationException][kotlinx.coroutines.CancellationException].
+ *
+ * [Animatable] also supports animating data types other than [Color], such as Floats and generic
+ * types. See [androidx.compose.animation.core.Animatable] for other variants.
  *
  * @sample androidx.compose.animation.samples.AnimatableColor
  *
- * @param initialValue initial value of the animatable value holder
+ * @param initialValue initial value of the [Animatable]
  */
 fun Animatable(initialValue: Color): Animatable<Color, AnimationVector4D> =
     Animatable(initialValue, (Color.VectorConverter)(initialValue.colorSpace))
\ No newline at end of file
diff --git a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/Transition.kt b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/Transition.kt
index c58614d..990334a 100644
--- a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/Transition.kt
+++ b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/Transition.kt
@@ -39,14 +39,13 @@
  * [targetValueByState] is used as a mapping from a target state to the target value of this
  * animation. [Transition] will be using this mapping to determine what value to target this
  * animation towards. __Note__ that [targetValueByState] is a composable function. This means the
- * mapping function could access states, CompositionLocals, themes, etc. If the targetValue changes
- * outside of a [Transition] run (i.e. when the [Transition] already reached its targetState),
- * the [Transition] will start running again to ensure this animation reaches its new target
- * smoothly.
+ * mapping function could access states, CompositionLocals, themes, etc. If the target value changes
+ * when the [Transition] already reached its [targetState][Transition.targetState],
+ * the [Transition] will run an animation to ensure the new target value is reached smoothly.
  *
- * An optional [transitionSpec] can be provided to specify (potentially different) animation for
- * each pair of initialState and targetState. [FiniteAnimationSpec] includes any non-infinite
- * animation, such as [tween], [spring], [keyframes] and even [repeatable], but not
+ * An optional [transitionSpec] can be provided to specify (potentially different) animations for
+ * each pair of initialState and targetState. [FiniteAnimationSpec] can be used to describe such
+ * animations, such as [tween], [spring], [keyframes] and even [repeatable], but not
  * [infiniteRepeatable]. By default, [transitionSpec] uses a [spring] animation for all transition
  * destinations.
  *
@@ -54,8 +53,9 @@
  *
  * @return A [State] object, the value of which is updated by animation
  *
- * @see animateValue
- * @see androidx.compose.animation.core.animateFloat
+ * @sample androidx.compose.animation.samples.GestureAnimationSample
+ *
+ * @see Transition.animateValue
  * @see androidx.compose.animation.core.Transition
  * @see androidx.compose.animation.core.updateTransition
  */
@@ -83,11 +83,13 @@
  * . [RepeatMode.Reverse]).
  *
  * If [initialValue] or [targetValue] is changed at any point during the animation, the animation
- * will be restarted with the new [initialValue] and [targetValue]. __Note__: this means
- * continuity will *not* be preserved.
+ * will be restarted with the new initial/targetValue. __Note__: this means animation continuity
+ * will *not* be preserved when changing either [initialValue] or [targetValue].
+ *
+ * @sample androidx.compose.animation.samples.InfiniteTransitionSample
  *
  * @see InfiniteTransition.animateValue
- * @see androidx.compose.animation.core.animateFloat
+ * @see InfiniteRepeatableSpec
  */
 @Composable
 fun InfiniteTransition.animateColor(
diff --git a/compose/compiler/compiler-hosted/integration-tests/build.gradle b/compose/compiler/compiler-hosted/integration-tests/build.gradle
index ccfbd36..c399c67 100644
--- a/compose/compiler/compiler-hosted/integration-tests/build.gradle
+++ b/compose/compiler/compiler-hosted/integration-tests/build.gradle
@@ -33,7 +33,11 @@
     testImplementation(JUNIT)
     testImplementation(ROBOLECTRIC)
 
-    testImplementation("org.jetbrains.kotlin:kotlin-compiler:$KOTLIN_VERSION")
+    testImplementation(
+        project(
+           ":compose:compiler:compiler-hosted:integration-tests:kotlin-compiler-repackaged"
+        )
+    )
 
     testImplementation(KOTLIN_STDLIB)
     testImplementation(project(":compose:androidview:androidview"))
diff --git a/compose/compiler/compiler-hosted/integration-tests/kotlin-compiler-repackaged/build.gradle b/compose/compiler/compiler-hosted/integration-tests/kotlin-compiler-repackaged/build.gradle
new file mode 100644
index 0000000..273b204
--- /dev/null
+++ b/compose/compiler/compiler-hosted/integration-tests/kotlin-compiler-repackaged/build.gradle
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import androidx.build.Publish
+import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
+
+import static androidx.build.dependencies.DependenciesKt.getKOTLIN_VERSION
+
+plugins {
+    id("java")
+    id("AndroidXPlugin")
+}
+
+dependencies {
+    compileOnly("org.jetbrains.kotlin:kotlin-compiler:$KOTLIN_VERSION")
+}
+
+// This task exists to work around https://youtrack.jetbrains.com/issue/KT-44876
+TaskProvider<ShadowJar> shadowJar = tasks.register("repackageCompiler", ShadowJar) { task ->
+    task.configurations = [project.configurations.compileClasspath]
+    task.relocate("kotlinx.collections.immutable", "org.jetbrains.kotlin.kotlinx.collections.immutable")
+    task.destinationDirectory.set(new File(buildDir, "repackaged"))
+    task.archiveVersion.set("")
+}
+
+configurations {
+    apiElements.outgoing.artifacts.clear()
+    runtimeElements.outgoing.artifacts.clear()
+}
+
+artifacts {
+    apiElements(shadowJar)
+    runtimeElements(shadowJar)
+}
+
+androidx {
+    // This module exists to work around https://youtrack.jetbrains.com/issue/KT-44876
+    name = "Repackaged version of Kotlin compiler"
+    publish = Publish.NONE
+    inceptionYear = "2021"
+    description = "Contains the Kotlin compiler repackaged to be compatible with integration tests"
+}
diff --git a/compose/compiler/compiler-hosted/integration-tests/kotlin-compiler-repackaged/lint-baseline.xml b/compose/compiler/compiler-hosted/integration-tests/kotlin-compiler-repackaged/lint-baseline.xml
new file mode 100644
index 0000000..297ae16
--- /dev/null
+++ b/compose/compiler/compiler-hosted/integration-tests/kotlin-compiler-repackaged/lint-baseline.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.2.0-beta02" client="gradle" version="4.2.0-beta02">
+
+</issues>
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ComposerParamSignatureTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ComposerParamSignatureTests.kt
index 73fb195..d93c8be 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ComposerParamSignatureTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ComposerParamSignatureTests.kt
@@ -97,6 +97,37 @@
     }
 
     @Test
+    fun testInterfaceMethodWithComposableParameter(): Unit = validateBytecode(
+        """
+            @Composable
+            fun test1(cc: ControlledComposition) {
+                cc.setContent {}
+            }
+            fun test2(cc: ControlledComposition) {
+                cc.setContent {}
+            }
+        """
+    ) {
+        assert(!it.contains("INVOKEINTERFACE androidx/compose/runtime/ControlledComposition.setContent (Lkotlin/jvm/functions/Function0;)V"))
+    }
+
+    @Test
+    fun testFakeOverrideFromSameModuleButLaterTraversal(): Unit = validateBytecode(
+        """
+            class B : A() {
+                fun test() {
+                    show {}
+                }
+            }
+            open class A {
+                fun show(content: @Composable () -> Unit) {}
+            }
+        """
+    ) {
+        assert(!it.contains("INVOKEINTERFACE androidx/compose/runtime/ControlledComposition.setContent (Lkotlin/jvm/functions/Function0;)V"))
+    }
+
+    @Test
     fun testPrimitiveChangedCalls(): Unit = validateBytecode(
         """
         @Composable fun Foo(
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposePlugin.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposePlugin.kt
index 436a553..c9e61d1 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposePlugin.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposePlugin.kt
@@ -146,6 +146,11 @@
                             " `suppressKotlinVersionCompatibilityCheck` but don't say I didn't" +
                             " warn you!)."
                     )
+
+                    // Return without registering the Compose plugin because the registration
+                    // APIs may have changed and thus throw an exception during registration,
+                    // preventing the diagnostic from being emitted.
+                    return
                 }
             }
 
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableTypeRemapper.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableTypeRemapper.kt
index 4bdb3e6..70e62af 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableTypeRemapper.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableTypeRemapper.kt
@@ -93,6 +93,12 @@
     }
 
     override fun visitSimpleFunction(declaration: IrSimpleFunction): IrSimpleFunction {
+        if (declaration.symbol.isRemappedAndBound()) {
+            return symbolRemapper.getReferencedSimpleFunction(declaration.symbol).owner
+        }
+        if (declaration.symbol.isBoundButNotRemapped()) {
+            symbolRemapper.visitSimpleFunction(declaration)
+        }
         return super.visitSimpleFunction(declaration).also {
             it.correspondingPropertySymbol = declaration.correspondingPropertySymbol
             it.copyMetadataFrom(declaration)
@@ -155,6 +161,18 @@
         return super.visitConstructorCall(expression)
     }
 
+    private fun IrFunction.hasComposableArguments(): Boolean {
+        if (
+            dispatchReceiverParameter?.type?.isComposable() == true ||
+            extensionReceiverParameter?.type?.isComposable() == true
+        ) return true
+
+        for (param in valueParameters) {
+            if (param.type.isComposable()) return true
+        }
+        return false
+    }
+
     @OptIn(ObsoleteDescriptorBasedAPI::class)
     override fun visitCall(expression: IrCall): IrCall {
         val ownerFn = expression.symbol.owner as? IrSimpleFunction
@@ -238,9 +256,42 @@
             }
         }
 
+        if (
+            ownerFn != null &&
+            ownerFn.hasComposableArguments()
+        ) {
+            val newFn = visitSimpleFunction(ownerFn).also {
+                it.overriddenSymbols = ownerFn.overriddenSymbols.map { override ->
+                    if (override.isBound) {
+                        visitSimpleFunction(override.owner).apply {
+                            parent = override.owner.parent
+                        }.symbol
+                    } else {
+                        override
+                    }
+                }
+                it.parent = ownerFn.parent
+                it.patchDeclarationParents(it.parent)
+            }
+            val newCallee = symbolRemapper.getReferencedSimpleFunction(newFn.symbol)
+            return shallowCopyCall(expression, newCallee).apply {
+                copyRemappedTypeArgumentsFrom(expression)
+                transformValueArguments(expression)
+            }
+        }
+
         return super.visitCall(expression)
     }
 
+    private fun IrSimpleFunctionSymbol.isBoundButNotRemapped(): Boolean {
+        return this.isBound && symbolRemapper.getReferencedFunction(this) == this
+    }
+
+    private fun IrSimpleFunctionSymbol.isRemappedAndBound(): Boolean {
+        val symbol = symbolRemapper.getReferencedFunction(this)
+        return symbol.isBound && symbol != this
+    }
+
     /* copied verbatim from DeepCopyIrTreeWithSymbols, except with newCallee as a parameter */
     private fun shallowCopyCall(expression: IrCall, newCallee: IrSimpleFunctionSymbol): IrCall {
         return IrCallImpl(
diff --git a/compose/compiler/settings.gradle b/compose/compiler/settings.gradle
index ab8b4c3..316999f 100644
--- a/compose/compiler/settings.gradle
+++ b/compose/compiler/settings.gradle
@@ -21,6 +21,7 @@
 selectProjectsFromAndroidX({ name ->
     if (name.startsWith(":compose:compiler")) return true
     if (name == ":compose:androidview:androidview") return true
+    if (name == ":compose:internal-lint-checks") return true
     return false
 })
 
diff --git a/compose/desktop/desktop/samples/build.gradle b/compose/desktop/desktop/samples/build.gradle
index 01e355e..dacf54e 100644
--- a/compose/desktop/desktop/samples/build.gradle
+++ b/compose/desktop/desktop/samples/build.gradle
@@ -47,7 +47,7 @@
 
 task run1(type: JavaExec) {
     dependsOn(":compose:desktop:desktop:jar")
-    main = 'androidx.compose.desktop.examples.example1.MainKt'
+    main = 'androidx.compose.desktop.examples.example1.Main_jvmKt'
     systemProperty("skiko.fps.enabled", "true")
     def compilation = kotlin.jvm().compilations["main"]
     classpath =
@@ -57,7 +57,7 @@
 
 task run2(type: JavaExec) {
     dependsOn(":compose:desktop:desktop:jar")
-    main = 'androidx.compose.desktop.examples.example2.MainKt'
+    main = 'androidx.compose.desktop.examples.example2.Main_jvmKt'
     def compilation = kotlin.jvm().compilations["main"]
     classpath =
         compilation.output.allOutputs +
@@ -66,7 +66,7 @@
 
 task run3(type: JavaExec) {
     dependsOn(":compose:desktop:desktop:jar")
-    main = 'androidx.compose.desktop.examples.popupexample.MainKt'
+    main = 'androidx.compose.desktop.examples.popupexample.Main_jvmKt'
     def compilation = kotlin.jvm().compilations["main"]
     classpath =
         compilation.output.allOutputs +
@@ -75,7 +75,7 @@
 
 task run4(type: JavaExec) {
     dependsOn(":compose:desktop:desktop:jar")
-    main = 'androidx.compose.desktop.examples.swingexample.MainKt'
+    main = 'androidx.compose.desktop.examples.swingexample.Main_jvmKt'
     def compilation = kotlin.jvm().compilations["main"]
     classpath =
         compilation.output.allOutputs +
@@ -84,7 +84,7 @@
 
 task runVsync(type: JavaExec) {
     dependsOn(":compose:desktop:desktop:jar")
-    main = 'androidx.compose.desktop.examples.vsynctest.MainKt'
+    main = 'androidx.compose.desktop.examples.vsynctest.Main_jvmKt'
     jvmArgs("-verbose:gc")
     def compilation = kotlin.jvm().compilations["main"]
     classpath =
diff --git a/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/example1/Main.jvm.kt b/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/example1/Main.jvm.kt
index 35bd32c..a0aa344 100644
--- a/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/example1/Main.jvm.kt
+++ b/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/example1/Main.jvm.kt
@@ -46,6 +46,7 @@
 import androidx.compose.foundation.shape.CircleShape
 import androidx.compose.foundation.text.InlineTextContent
 import androidx.compose.foundation.text.appendInlineContent
+import androidx.compose.foundation.text.selection.SelectionContainer
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.material.BottomAppBar
 import androidx.compose.material.Button
@@ -301,31 +302,33 @@
         var overText by remember { mutableStateOf("Move mouse over text:") }
         Text(overText, style = TextStyle(letterSpacing = 10.sp))
 
-        Text(
-            text = "fun <T : Comparable<T>> List<T>.quickSort(): List<T> = when {\n" +
-                "  size < 2 -> this\n" +
-                "  else -> {\n" +
-                "    val pivot = first()\n" +
-                "    val (smaller, greater) = drop(1).partition { it <= pivot }\n" +
-                "    smaller.quickSort() + pivot + greater.quickSort()\n" +
-                "   }\n" +
-                "}",
-            fontFamily = italicFont,
-            modifier = Modifier.padding(10.dp).pointerMoveFilter(
-                onMove = {
-                    overText = "Move position: $it"
-                    false
-                },
-                onEnter = {
-                    overText = "Over enter"
-                    false
-                },
-                onExit = {
-                    overText = "Over exit"
-                    false
-                }
+        SelectionContainer {
+            Text(
+                text = "fun <T : Comparable<T>> List<T>.quickSort(): List<T> = when {\n" +
+                    "  size < 2 -> this\n" +
+                    "  else -> {\n" +
+                    "    val pivot = first()\n" +
+                    "    val (smaller, greater) = drop(1).partition { it <= pivot }\n" +
+                    "    smaller.quickSort() + pivot + greater.quickSort()\n" +
+                    "   }\n" +
+                    "}",
+                fontFamily = italicFont,
+                modifier = Modifier.padding(10.dp).pointerMoveFilter(
+                    onMove = {
+                        overText = "Move position: $it"
+                        false
+                    },
+                    onEnter = {
+                        overText = "Over enter"
+                        false
+                    },
+                    onExit = {
+                        overText = "Over exit"
+                        false
+                    }
+                )
             )
-        )
+        }
 
         Row(verticalAlignment = Alignment.CenterVertically) {
             var lastEvent by remember { mutableStateOf<MouseEvent?>(null) }
diff --git a/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/popupexample/AppContent.jvm.kt b/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/popupexample/AppContent.jvm.kt
index 6371a56..4249b80 100644
--- a/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/popupexample/AppContent.jvm.kt
+++ b/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/popupexample/AppContent.jvm.kt
@@ -503,7 +503,7 @@
     SwingPanel(
         background = Color(55, 55, 55),
         modifier = Modifier.size(200.dp, 35.dp),
-        componentBlock = {
+        factory = {
             JButton(text).apply {
                 addActionListener(object : ActionListener {
                     public override fun actionPerformed(e: ActionEvent) {
diff --git a/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/swingexample/Main.jvm.kt b/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/swingexample/Main.jvm.kt
index 1fc46d1..db7fed4 100644
--- a/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/swingexample/Main.jvm.kt
+++ b/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/swingexample/Main.jvm.kt
@@ -167,7 +167,7 @@
                 Spacer(modifier = Modifier.width(20.dp))
                 SwingPanel(
                     modifier = Modifier.size(200.dp, 39.dp),
-                    componentBlock = {
+                    factory = {
                         actionButton(
                             text = "JComponent",
                             action = {
@@ -183,7 +183,7 @@
                 SwingPanel(
                     background = background,
                     modifier = Modifier.size(200.dp, 39.dp),
-                    componentBlock = { ComposableColoredPanel(Color.Red) }
+                    factory = { ComposableColoredPanel(Color.Red) }
                 )
             }
             Spacer(modifier = Modifier.height(50.dp))
diff --git a/compose/foundation/foundation-layout/api/current.txt b/compose/foundation/foundation-layout/api/current.txt
index 805adfa..15c4829 100644
--- a/compose/foundation/foundation-layout/api/current.txt
+++ b/compose/foundation/foundation-layout/api/current.txt
@@ -119,12 +119,14 @@
   public static final class ColumnScope.Companion implements androidx.compose.foundation.layout.ColumnScope {
   }
 
-  @kotlin.RequiresOptIn(message="The API of this layout is experimental and is likely to change in the future.") public @interface ExperimentalLayout {
+  @kotlin.RequiresOptIn(message="The API of this layout is experimental and is likely to change in the future.") public @interface ExperimentalLayoutApi {
   }
 
   public final class IntrinsicKt {
-    method @androidx.compose.foundation.layout.ExperimentalLayout @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier height(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
-    method @androidx.compose.foundation.layout.ExperimentalLayout @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier width(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier height(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredHeight(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredWidth(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier width(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
   }
 
   public enum IntrinsicSize {
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 805adfa..15c4829 100644
--- a/compose/foundation/foundation-layout/api/public_plus_experimental_current.txt
+++ b/compose/foundation/foundation-layout/api/public_plus_experimental_current.txt
@@ -119,12 +119,14 @@
   public static final class ColumnScope.Companion implements androidx.compose.foundation.layout.ColumnScope {
   }
 
-  @kotlin.RequiresOptIn(message="The API of this layout is experimental and is likely to change in the future.") public @interface ExperimentalLayout {
+  @kotlin.RequiresOptIn(message="The API of this layout is experimental and is likely to change in the future.") public @interface ExperimentalLayoutApi {
   }
 
   public final class IntrinsicKt {
-    method @androidx.compose.foundation.layout.ExperimentalLayout @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier height(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
-    method @androidx.compose.foundation.layout.ExperimentalLayout @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier width(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier height(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredHeight(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredWidth(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier width(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
   }
 
   public enum IntrinsicSize {
diff --git a/compose/foundation/foundation-layout/api/restricted_current.txt b/compose/foundation/foundation-layout/api/restricted_current.txt
index f1b5266..40086c2 100644
--- a/compose/foundation/foundation-layout/api/restricted_current.txt
+++ b/compose/foundation/foundation-layout/api/restricted_current.txt
@@ -76,7 +76,7 @@
   public final class BoxKt {
     method @androidx.compose.runtime.Composable public static inline void Box(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional boolean propagateMinConstraints, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void Box(androidx.compose.ui.Modifier modifier);
-    method @androidx.compose.runtime.Composable @kotlin.PublishedApi internal static androidx.compose.ui.node.MeasureBlocks rememberBoxMeasureBlocks(androidx.compose.ui.Alignment alignment, boolean propagateMinConstraints);
+    method @androidx.compose.runtime.Composable @kotlin.PublishedApi internal static androidx.compose.ui.layout.MeasurePolicy rememberBoxMeasurePolicy(androidx.compose.ui.Alignment alignment, boolean propagateMinConstraints);
   }
 
   @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable public interface BoxScope {
@@ -107,8 +107,8 @@
 
   public final class ColumnKt {
     method @androidx.compose.runtime.Composable public static inline void Column(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable @kotlin.PublishedApi internal static androidx.compose.ui.node.MeasureBlocks columnMeasureBlocks(androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, androidx.compose.ui.Alignment.Horizontal horizontalAlignment);
-    field @kotlin.PublishedApi internal static final androidx.compose.ui.node.MeasureBlocks DefaultColumnMeasureBlocks;
+    method @androidx.compose.runtime.Composable @kotlin.PublishedApi internal static androidx.compose.ui.layout.MeasurePolicy columnMeasurePolicy(androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, androidx.compose.ui.Alignment.Horizontal horizontalAlignment);
+    field @kotlin.PublishedApi internal static final androidx.compose.ui.layout.MeasurePolicy DefaultColumnMeasurePolicy;
   }
 
   @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable public interface ColumnScope {
@@ -122,12 +122,14 @@
   public static final class ColumnScope.Companion implements androidx.compose.foundation.layout.ColumnScope {
   }
 
-  @kotlin.RequiresOptIn(message="The API of this layout is experimental and is likely to change in the future.") public @interface ExperimentalLayout {
+  @kotlin.RequiresOptIn(message="The API of this layout is experimental and is likely to change in the future.") public @interface ExperimentalLayoutApi {
   }
 
   public final class IntrinsicKt {
-    method @androidx.compose.foundation.layout.ExperimentalLayout @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier height(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
-    method @androidx.compose.foundation.layout.ExperimentalLayout @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier width(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier height(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredHeight(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredWidth(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier width(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
   }
 
   public enum IntrinsicSize {
@@ -177,8 +179,8 @@
 
   public final class RowKt {
     method @androidx.compose.runtime.Composable public static inline void Row(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional androidx.compose.ui.Alignment.Vertical verticalAlignment, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable @kotlin.PublishedApi internal static androidx.compose.ui.node.MeasureBlocks rowMeasureBlocks(androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, androidx.compose.ui.Alignment.Vertical verticalAlignment);
-    field @kotlin.PublishedApi internal static final androidx.compose.ui.node.MeasureBlocks DefaultRowMeasureBlocks;
+    method @androidx.compose.runtime.Composable @kotlin.PublishedApi internal static androidx.compose.ui.layout.MeasurePolicy rowMeasurePolicy(androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, androidx.compose.ui.Alignment.Vertical verticalAlignment);
+    field @kotlin.PublishedApi internal static final androidx.compose.ui.layout.MeasurePolicy DefaultRowMeasurePolicy;
   }
 
   @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable public interface RowScope {
diff --git a/compose/foundation/foundation-layout/integration-tests/layout-demos/src/main/java/androidx/compose/foundation/layout/demos/RtlDemo.kt b/compose/foundation/foundation-layout/integration-tests/layout-demos/src/main/java/androidx/compose/foundation/layout/demos/RtlDemo.kt
index 3cdefdd..adb9dbe 100644
--- a/compose/foundation/foundation-layout/integration-tests/layout-demos/src/main/java/androidx/compose/foundation/layout/demos/RtlDemo.kt
+++ b/compose/foundation/foundation-layout/integration-tests/layout-demos/src/main/java/androidx/compose/foundation/layout/demos/RtlDemo.kt
@@ -136,13 +136,13 @@
 private fun TestSiblings() {
     Column {
         Box(
-            boxSize.background(color = Color.Red).alignBy { p -> p.width }
+            boxSize.background(color = Color.Red).alignBy { p -> p.measuredWidth }
         ) {}
         Box(
-            boxSize.background(color = Color.Green).alignBy { p -> p.width / 2 }
+            boxSize.background(color = Color.Green).alignBy { p -> p.measuredWidth / 2 }
         ) {}
         Box(
-            boxSize.background(color = Color.Blue).alignBy { p -> p.width / 4 }
+            boxSize.background(color = Color.Blue).alignBy { p -> p.measuredWidth / 4 }
         ) {}
     }
 }
diff --git a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/ColumnSample.kt b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/ColumnSample.kt
index f2b28bf..66fd1c0 100644
--- a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/ColumnSample.kt
+++ b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/ColumnSample.kt
@@ -92,12 +92,12 @@
         // left edge of the third one.
         Box(
             Modifier.size(80.dp, 40.dp)
-                .alignBy { it.width / 2 }
+                .alignBy { it.measuredWidth / 2 }
                 .background(Color.Blue)
         )
         Box(
             Modifier.size(80.dp, 40.dp)
-                .alignBy { it.width }
+                .alignBy { it.measuredWidth }
                 .background(Color.Magenta)
         )
         Box(
@@ -139,7 +139,7 @@
         // left edge of the third one.
         Box(
             Modifier.size(80.dp, 40.dp)
-                .alignBy { it.width / 2 }
+                .alignBy { it.measuredWidth / 2 }
                 .background(Color.Blue)
         )
         RectangleWithStartEnd(
diff --git a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/IntrinsicSample.kt b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/IntrinsicSample.kt
index 8fdf412..aedd289 100644
--- a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/IntrinsicSample.kt
+++ b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/IntrinsicSample.kt
@@ -20,7 +20,6 @@
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.ExperimentalLayout
 import androidx.compose.foundation.layout.IntrinsicSize
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.aspectRatio
@@ -37,7 +36,6 @@
 
 @Sampled
 @Composable
-@OptIn(ExperimentalLayout::class)
 fun SameWidthBoxes() {
     // Builds a layout containing three Box having the same width as the widest one.
     //
@@ -69,7 +67,6 @@
 
 @Sampled
 @Composable
-@OptIn(ExperimentalLayout::class)
 fun MatchParentDividerForText() {
     // Builds a layout containing two pieces of text separated by a divider, where the divider
     // is sized according to the height of the longest text.
@@ -97,7 +94,6 @@
 
 @Sampled
 @Composable
-@OptIn(ExperimentalLayout::class)
 fun SameWidthTextBoxes() {
     // Builds a layout containing three Text boxes having the same width as the widest one.
     //
@@ -124,7 +120,6 @@
 
 @Sampled
 @Composable
-@OptIn(ExperimentalLayout::class)
 fun MatchParentDividerForAspectRatio() {
     // Builds a layout containing two aspectRatios separated by a divider, where the divider
     // is sized according to the height of the taller aspectRatio.
diff --git a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/RowSample.kt b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/RowSample.kt
index a535211..a324206 100644
--- a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/RowSample.kt
+++ b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/RowSample.kt
@@ -93,7 +93,7 @@
         // effect.
         Box(
             modifier = Modifier.size(80.dp, 40.dp)
-                .alignBy { it.height / 2 }
+                .alignBy { it.measuredHeight / 2 }
                 .background(Color.Magenta)
         )
         Text(
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/AlignmentLineTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/AlignmentLineTest.kt
index 43f64fb..594500e 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/AlignmentLineTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/AlignmentLineTest.kt
@@ -343,7 +343,7 @@
                     Modifier.width(incomingSize)
                         .paddingFrom(testLine, before = before)
                         .onGloballyPositioned {
-                            Assert.assertEquals(beforePx - linePositionPx, it.positionInParent.x)
+                            Assert.assertEquals(beforePx - linePositionPx, it.positionInParent().x)
                             latch.countDown()
                         }
                 )
@@ -354,7 +354,7 @@
                         .onGloballyPositioned {
                             Assert.assertEquals(
                                 incomingSizePx - childSizePx - afterPx + linePositionPx,
-                                it.positionInParent.x
+                                it.positionInParent().x
                             )
                             latch.countDown()
                         }
@@ -386,7 +386,7 @@
                     Modifier.height(incomingSize)
                         .paddingFrom(testLine, before = before)
                         .onGloballyPositioned {
-                            Assert.assertEquals(beforePx - linePositionPx, it.positionInParent.y)
+                            Assert.assertEquals(beforePx - linePositionPx, it.positionInParent().y)
                             latch.countDown()
                         }
                 )
@@ -397,7 +397,7 @@
                         .onGloballyPositioned {
                             Assert.assertEquals(
                                 incomingSizePx - childSizePx - afterPx + linePositionPx,
-                                it.positionInParent.y
+                                it.positionInParent().y
                             )
                             latch.countDown()
                         }
@@ -492,7 +492,7 @@
                     Modifier.height(incomingSize)
                         .paddingFromBaseline(top = before, bottom = after)
                         .onGloballyPositioned {
-                            Assert.assertEquals(beforePx - linePositionPx, it.positionInParent.y)
+                            Assert.assertEquals(beforePx - linePositionPx, it.positionInParent().y)
                             latch.countDown()
                         }
                 ) {
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/BoxTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/BoxTest.kt
index 49d0f47..c0a9995 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/BoxTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/BoxTest.kt
@@ -19,11 +19,13 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.layout.LayoutCoordinates
+import androidx.compose.ui.layout.MeasurePolicy
 import androidx.compose.ui.layout.onGloballyPositioned
 import androidx.compose.ui.layout.onSizeChanged
 import androidx.compose.ui.layout.positionInParent
@@ -425,8 +427,8 @@
             ) {
                 Box(
                     Modifier.requiredSize(innerSize).onGloballyPositioned {
-                        assertEquals(outerSizePx - innerSizePx, it.positionInParent.x)
-                        assertEquals(outerSizePx - innerSizePx, it.positionInParent.y)
+                        assertEquals(outerSizePx - innerSizePx, it.positionInParent().x)
+                        assertEquals(outerSizePx - innerSizePx, it.positionInParent().y)
                         positionedLatch.countDown()
                     }
                 ) {}
@@ -445,8 +447,8 @@
                 Box(
                     Modifier.align(Alignment.BottomEnd).align(Alignment.TopStart)
                         .onGloballyPositioned {
-                            assertEquals(size, it.positionInParent.x)
-                            assertEquals(size, it.positionInParent.y)
+                            assertEquals(size, it.positionInParent().x)
+                            assertEquals(size, it.positionInParent().y)
                             positionedLatch.countDown()
                         }
                 )
@@ -472,16 +474,19 @@
                                 }
                             )
                         }
+                    },
+                    measurePolicy = remember {
+                        MeasurePolicy { measurables, constraints ->
+                            val placeable = measurables.first().measure(constraints)
+                            ++measure
+                            layout(placeable.width, placeable.height) {
+                                placeable.place(0, 0)
+                                ++layout
+                                layoutLatch.countDown()
+                            }
+                        }
                     }
-                ) { measurables, constraints ->
-                    val placeable = measurables.first().measure(constraints)
-                    ++measure
-                    layout(placeable.width, placeable.height) {
-                        placeable.place(0, 0)
-                        ++layout
-                        layoutLatch.countDown()
-                    }
-                }
+                )
             }
         }
         assertTrue(layoutLatch.await(1, TimeUnit.SECONDS))
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/BoxWithConstraintsTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/BoxWithConstraintsTest.kt
index d4fa4ac..62afb5d 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/BoxWithConstraintsTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/BoxWithConstraintsTest.kt
@@ -42,7 +42,7 @@
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.layout.LayoutModifier
 import androidx.compose.ui.layout.Measurable
-import androidx.compose.ui.layout.MeasureBlock
+import androidx.compose.ui.layout.MeasurePolicy
 import androidx.compose.ui.layout.MeasureResult
 import androidx.compose.ui.layout.MeasureScope
 import androidx.compose.ui.layout.onGloballyPositioned
@@ -90,14 +90,14 @@
                     BoxWithConstraints(drawModifier) {
                         paddedConstraints.value = constraints
                         Layout(
-                            measureBlock = { _, childConstraints ->
+                            measurePolicy = { _, childConstraints ->
                                 firstChildConstraints.value = childConstraints
                                 layout(size, size) { }
                             },
                             content = { }
                         )
                         Layout(
-                            measureBlock = { _, chilConstraints ->
+                            measurePolicy = { _, chilConstraints ->
                                 secondChildConstraints.value = chilConstraints
                                 layout(size, size) { }
                             },
@@ -579,7 +579,7 @@
         val zeroConstraints = Constraints.fixed(0, 0)
         show {
             Layout(
-                measureBlock = { measurables, _ ->
+                measurePolicy = { measurables, _ ->
                     layout(0, 0) {
                         // there was a bug when the child of WithConstraints wasn't marking
                         // needsRemeasure and it was only measured because the constraints
@@ -768,8 +768,8 @@
     Layout(
         content = content,
         modifier = modifier,
-        measureBlock = remember<MeasureBlock>(width, height) {
-            { measurables, _ ->
+        measurePolicy = remember(width, height) {
+            MeasurePolicy { measurables, _ ->
                 val constraint = Constraints(maxWidth = width, maxHeight = height)
                 layout(width, height) {
                     measurables.forEach {
@@ -793,8 +793,8 @@
 ) {
     Layout(
         content = content,
-        measureBlock = remember<MeasureBlock>(width, height) {
-            { measurables, _ ->
+        measurePolicy = remember(width, height) {
+            MeasurePolicy { measurables, _ ->
                 val constraint = Constraints(maxWidth = width, maxHeight = height)
                 val placeables = measurables.map { it.measure(constraint) }
                 layout(width, height) {
@@ -841,7 +841,7 @@
 ) {
     Layout(
         modifier = modifier,
-        measureBlock = { measurables, constraints ->
+        measurePolicy = { measurables, constraints ->
             val totalDiff = size * 2
             val targetMinWidth = constraints.minWidth - totalDiff
             val targetMaxWidth = if (constraints.hasBoundedWidth) {
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/IntrinsicTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/IntrinsicTest.kt
index 0ed532c..ed5efc3 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/IntrinsicTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/IntrinsicTest.kt
@@ -20,9 +20,17 @@
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.layout.IntrinsicMeasurable
+import androidx.compose.ui.layout.IntrinsicMeasureScope
 import androidx.compose.ui.layout.LayoutCoordinates
+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.node.Ref
 import androidx.compose.ui.layout.onGloballyPositioned
+import androidx.compose.ui.layout.onSizeChanged
+import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.constrainHeight
@@ -39,7 +47,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalLayout::class)
 class IntrinsicTest : LayoutTest() {
     @Test
     fun testMinIntrinsicWidth() = with(density) {
@@ -413,6 +420,90 @@
     }
 
     @Test
+    fun testRequiredMinIntrinsicWidth() = with(density) {
+        val countDownLatch = CountDownLatch(1)
+        show {
+            Box {
+                ConstrainedBox(
+                    DpConstraints.fixed(100.dp, 100.dp)
+                ) {
+                    FixedIntrinsicsBox(
+                        Modifier.requiredWidth(IntrinsicSize.Min).onSizeChanged {
+                            assertEquals(IntSize(10.dp.roundToPx(), 50.dp.roundToPx()), it)
+                            countDownLatch.countDown()
+                        },
+                        10.dp, 20.dp, 30.dp, 40.dp, 50.dp, 60.dp
+                    )
+                }
+            }
+        }
+        assertTrue(countDownLatch.await(1, TimeUnit.SECONDS))
+    }
+
+    @Test
+    fun testRequiredMinIntrinsicHeight() = with(density) {
+        val countDownLatch = CountDownLatch(1)
+        show {
+            Box {
+                ConstrainedBox(
+                    DpConstraints.fixed(100.dp, 100.dp)
+                ) {
+                    FixedIntrinsicsBox(
+                        Modifier.requiredHeight(IntrinsicSize.Min).onSizeChanged {
+                            assertEquals(IntSize(20.dp.roundToPx(), 40.dp.roundToPx()), it)
+                            countDownLatch.countDown()
+                        },
+                        10.dp, 20.dp, 30.dp, 40.dp, 50.dp, 60.dp
+                    )
+                }
+            }
+        }
+        assertTrue(countDownLatch.await(1, TimeUnit.SECONDS))
+    }
+
+    @Test
+    fun testRequiredMaxIntrinsicWidth() = with(density) {
+        val countDownLatch = CountDownLatch(1)
+        show {
+            Box {
+                ConstrainedBox(
+                    DpConstraints.fixed(100.dp, 100.dp)
+                ) {
+                    FixedIntrinsicsBox(
+                        Modifier.requiredWidth(IntrinsicSize.Max).onSizeChanged {
+                            assertEquals(IntSize(30.dp.roundToPx(), 50.dp.roundToPx()), it)
+                            countDownLatch.countDown()
+                        },
+                        10.dp, 20.dp, 30.dp, 40.dp, 50.dp, 60.dp
+                    )
+                }
+            }
+        }
+        assertTrue(countDownLatch.await(1, TimeUnit.SECONDS))
+    }
+
+    @Test
+    fun testRequiredMaxIntrinsicHeight() = with(density) {
+        val countDownLatch = CountDownLatch(1)
+        show {
+            Box {
+                ConstrainedBox(
+                    DpConstraints.fixed(100.dp, 100.dp)
+                ) {
+                    FixedIntrinsicsBox(
+                        Modifier.requiredHeight(IntrinsicSize.Max).onSizeChanged {
+                            assertEquals(IntSize(20.dp.roundToPx(), 60.dp.roundToPx()), it)
+                            countDownLatch.countDown()
+                        },
+                        10.dp, 20.dp, 30.dp, 40.dp, 50.dp, 60.dp
+                    )
+                }
+            }
+        }
+        assertTrue(countDownLatch.await(1, TimeUnit.SECONDS))
+    }
+
+    @Test
     fun testMinIntrinsicWidth_intrinsicMeasurements() = with(density) {
         testIntrinsics({
             FixedIntrinsicsBox(
@@ -481,17 +572,40 @@
     height: Dp,
     maxIntrinsicHeight: Dp
 ) {
-    Layout(
-        {},
-        minIntrinsicWidthMeasureBlock = { _, _ -> minIntrinsicWidth.roundToPx() },
-        minIntrinsicHeightMeasureBlock = { _, _ -> minIntrinsicHeight.roundToPx() },
-        maxIntrinsicWidthMeasureBlock = { _, _ -> maxIntrinsicWidth.roundToPx() },
-        maxIntrinsicHeightMeasureBlock = { _, _ -> maxIntrinsicHeight.roundToPx() },
-        modifier = modifier
-    ) { _, constraints ->
-        layout(
-            constraints.constrainWidth(width.roundToPx()),
-            constraints.constrainHeight(height.roundToPx())
-        ) {}
+    val measurePolicy = object : MeasurePolicy {
+        override fun MeasureScope.measure(
+            measurables: List<Measurable>,
+            constraints: Constraints
+        ): MeasureResult {
+            return layout(
+                constraints.constrainWidth(width.roundToPx()),
+                constraints.constrainHeight(height.roundToPx())
+            ) {}
+        }
+
+        override fun IntrinsicMeasureScope.minIntrinsicWidth(
+            measurables: List<IntrinsicMeasurable>,
+            height: Int
+        ) = minIntrinsicWidth.roundToPx()
+
+        override fun IntrinsicMeasureScope.minIntrinsicHeight(
+            measurables: List<IntrinsicMeasurable>,
+            width: Int
+        ) = minIntrinsicHeight.roundToPx()
+
+        override fun IntrinsicMeasureScope.maxIntrinsicWidth(
+            measurables: List<IntrinsicMeasurable>,
+            height: Int
+        ) = maxIntrinsicWidth.roundToPx()
+
+        override fun IntrinsicMeasureScope.maxIntrinsicHeight(
+            measurables: List<IntrinsicMeasurable>,
+            width: Int
+        ) = maxIntrinsicHeight.roundToPx()
     }
+    Layout(
+        content = {},
+        modifier = modifier,
+        measurePolicy = measurePolicy
+    )
 }
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/LayoutTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/LayoutTest.kt
index 1b945db..7b3e8ca 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/LayoutTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/LayoutTest.kt
@@ -32,7 +32,13 @@
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.layout.AlignmentLine
+import androidx.compose.ui.layout.IntrinsicMeasurable
+import androidx.compose.ui.layout.IntrinsicMeasureScope
 import androidx.compose.ui.layout.Layout
+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.Placeable
 import androidx.compose.ui.layout.onGloballyPositioned
 import androidx.compose.ui.node.Ref
@@ -158,23 +164,47 @@
         layouts.forEach { layout ->
             val layoutLatch = CountDownLatch(1)
             show {
-                Layout(
-                    layout,
-                    minIntrinsicWidthMeasureBlock = { _, _ -> 0 },
-                    minIntrinsicHeightMeasureBlock = { _, _ -> 0 },
-                    maxIntrinsicWidthMeasureBlock = { _, _ -> 0 },
-                    maxIntrinsicHeightMeasureBlock = { _, _ -> 0 }
-                ) { measurables, _ ->
-                    val measurable = measurables.first()
-                    test(
-                        { h -> measurable.minIntrinsicWidth(h) },
-                        { w -> measurable.minIntrinsicHeight(w) },
-                        { h -> measurable.maxIntrinsicWidth(h) },
-                        { w -> measurable.maxIntrinsicHeight(w) }
-                    )
-                    layoutLatch.countDown()
-                    layout(0, 0) {}
+                val measurePolicy = object : MeasurePolicy {
+                    override fun MeasureScope.measure(
+                        measurables: List<Measurable>,
+                        constraints: Constraints
+                    ): MeasureResult {
+                        val measurable = measurables.first()
+                        test(
+                            { h -> measurable.minIntrinsicWidth(h) },
+                            { w -> measurable.minIntrinsicHeight(w) },
+                            { h -> measurable.maxIntrinsicWidth(h) },
+                            { w -> measurable.maxIntrinsicHeight(w) }
+                        )
+                        layoutLatch.countDown()
+
+                        return layout(0, 0) {}
+                    }
+
+                    override fun IntrinsicMeasureScope.minIntrinsicWidth(
+                        measurables: List<IntrinsicMeasurable>,
+                        height: Int
+                    ) = 0
+
+                    override fun IntrinsicMeasureScope.minIntrinsicHeight(
+                        measurables: List<IntrinsicMeasurable>,
+                        width: Int
+                    ) = 0
+
+                    override fun IntrinsicMeasureScope.maxIntrinsicWidth(
+                        measurables: List<IntrinsicMeasurable>,
+                        height: Int
+                    ) = 0
+
+                    override fun IntrinsicMeasureScope.maxIntrinsicHeight(
+                        measurables: List<IntrinsicMeasurable>,
+                        width: Int
+                    ) = 0
                 }
+                Layout(
+                    content = layout,
+                    measurePolicy = measurePolicy
+                )
             }
             assertTrue(layoutLatch.await(1, TimeUnit.SECONDS))
         }
@@ -213,36 +243,60 @@
     ) {
         with(LocalDensity.current) {
             val pxConstraints = Constraints(constraints)
-            Layout(
-                content,
-                modifier = modifier,
-                minIntrinsicWidthMeasureBlock = { measurables, h ->
-                    val width = measurables.firstOrNull()?.minIntrinsicWidth(h) ?: 0
-                    pxConstraints.constrainWidth(width)
-                },
-                minIntrinsicHeightMeasureBlock = { measurables, w ->
-                    val height = measurables.firstOrNull()?.minIntrinsicHeight(w) ?: 0
-                    pxConstraints.constrainHeight(height)
-                },
-                maxIntrinsicWidthMeasureBlock = { measurables, h ->
-                    val width = measurables.firstOrNull()?.maxIntrinsicWidth(h) ?: 0
-                    pxConstraints.constrainWidth(width)
-                },
-                maxIntrinsicHeightMeasureBlock = { measurables, w ->
-                    val height = measurables.firstOrNull()?.maxIntrinsicHeight(w) ?: 0
-                    pxConstraints.constrainHeight(height)
-                }
-            ) { measurables, incomingConstraints ->
-                val measurable = measurables.firstOrNull()
-                val childConstraints = incomingConstraints.constrain(Constraints(constraints))
-                val placeable = measurable?.measure(childConstraints)
+            val measurePolicy = object : MeasurePolicy {
+                @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
+                override fun MeasureScope.measure(
+                    measurables: List<Measurable>,
+                    incomingConstraints: Constraints
+                ): MeasureResult {
+                    val measurable = measurables.firstOrNull()
+                    val childConstraints = incomingConstraints.constrain(Constraints(constraints))
+                    val placeable = measurable?.measure(childConstraints)
 
-                val layoutWidth = placeable?.width ?: childConstraints.minWidth
-                val layoutHeight = placeable?.height ?: childConstraints.minHeight
-                layout(layoutWidth, layoutHeight) {
-                    placeable?.placeRelative(0, 0)
+                    val layoutWidth = placeable?.width ?: childConstraints.minWidth
+                    val layoutHeight = placeable?.height ?: childConstraints.minHeight
+                    return layout(layoutWidth, layoutHeight) {
+                        placeable?.placeRelative(0, 0)
+                    }
+                }
+
+                override fun IntrinsicMeasureScope.minIntrinsicWidth(
+                    measurables: List<IntrinsicMeasurable>,
+                    height: Int
+                ): Int {
+                    val width = measurables.firstOrNull()?.minIntrinsicWidth(height) ?: 0
+                    return pxConstraints.constrainWidth(width)
+                }
+
+                override fun IntrinsicMeasureScope.minIntrinsicHeight(
+                    measurables: List<IntrinsicMeasurable>,
+                    width: Int
+                ): Int {
+                    val height = measurables.firstOrNull()?.minIntrinsicHeight(width) ?: 0
+                    return pxConstraints.constrainHeight(height)
+                }
+
+                override fun IntrinsicMeasureScope.maxIntrinsicWidth(
+                    measurables: List<IntrinsicMeasurable>,
+                    height: Int
+                ): Int {
+                    val width = measurables.firstOrNull()?.maxIntrinsicWidth(height) ?: 0
+                    return pxConstraints.constrainWidth(width)
+                }
+
+                override fun IntrinsicMeasureScope.maxIntrinsicHeight(
+                    measurables: List<IntrinsicMeasurable>,
+                    width: Int
+                ): Int {
+                    val height = measurables.firstOrNull()?.maxIntrinsicHeight(width) ?: 0
+                    return pxConstraints.constrainHeight(height)
                 }
             }
+            Layout(
+                content = content,
+                modifier = modifier,
+                measurePolicy = measurePolicy
+            )
         }
     }
 
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/RowColumnTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/RowColumnTest.kt
index 0245250..9ca1b6ff 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/RowColumnTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/RowColumnTest.kt
@@ -16,20 +16,25 @@
 
 package androidx.compose.foundation.layout
 
-import androidx.compose.ui.layout.FirstBaseline
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.ui.Alignment
-import androidx.compose.ui.layout.HorizontalAlignmentLine
-import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.layout.VerticalAlignmentLine
 import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.layout.FirstBaseline
+import androidx.compose.ui.layout.HorizontalAlignmentLine
+import androidx.compose.ui.layout.IntrinsicMeasurable
+import androidx.compose.ui.layout.IntrinsicMeasureScope
+import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.layout.LayoutCoordinates
+import androidx.compose.ui.layout.Measurable
+import androidx.compose.ui.layout.MeasurePolicy
+import androidx.compose.ui.layout.MeasureScope
+import androidx.compose.ui.layout.VerticalAlignmentLine
+import androidx.compose.ui.layout.onGloballyPositioned
 import androidx.compose.ui.layout.positionInParent
 import androidx.compose.ui.layout.positionInRoot
 import androidx.compose.ui.node.Ref
-import androidx.compose.ui.layout.onGloballyPositioned
 import androidx.compose.ui.platform.InspectableValue
 import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.platform.ValueElement
@@ -39,17 +44,17 @@
 import androidx.compose.ui.unit.IntSize
 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
+import org.junit.After
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertNotNull
 import org.junit.Assert.assertTrue
+import org.junit.Before
 import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import com.google.common.truth.Truth
-import org.junit.After
-import org.junit.Before
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.TimeUnit
 import kotlin.math.max
@@ -807,7 +812,7 @@
                 Container(
                     width = sizeDp,
                     height = sizeDp,
-                    modifier = Modifier.alignBy { it.height / 2 }
+                    modifier = Modifier.alignBy { it.measuredHeight / 2 }
                         .onGloballyPositioned { coordinates ->
                             childSize[1] = coordinates.size
                             childPosition[1] = coordinates.positionInRoot()
@@ -830,7 +835,7 @@
                 Container(
                     width = sizeDp,
                     height = sizeDp,
-                    modifier = Modifier.alignBy { it.height * 3 / 4 }
+                    modifier = Modifier.alignBy { it.measuredHeight * 3 / 4 }
                         .onGloballyPositioned { coordinates ->
                             childSize[3] = coordinates.size
                             childPosition[3] = coordinates.positionInRoot()
@@ -912,7 +917,7 @@
                 }
                 Container(
                     height = sizeDp,
-                    modifier = Modifier.alignBy { it.height / 2 }
+                    modifier = Modifier.alignBy { it.measuredHeight / 2 }
                         .weight(1f)
                         .onGloballyPositioned { coordinates ->
                             childSize[1] = coordinates.size
@@ -1140,7 +1145,7 @@
                 Container(
                     width = sizeDp,
                     height = sizeDp,
-                    modifier = Modifier.alignBy { it.width }
+                    modifier = Modifier.alignBy { it.measuredWidth }
                         .onGloballyPositioned { coordinates ->
                             childSize[0] = coordinates.size
                             childPosition[0] = coordinates.positionInRoot()
@@ -1238,7 +1243,7 @@
                 }
                 Container(
                     width = sizeDp,
-                    modifier = Modifier.alignBy { it.width / 2 }
+                    modifier = Modifier.alignBy { it.measuredWidth / 2 }
                         .weight(1f)
                         .onGloballyPositioned { coordinates ->
                             childSize[1] = coordinates.size
@@ -2558,13 +2563,13 @@
                 ) {
                     Box(
                         Modifier.requiredSize(size).onGloballyPositioned {
-                            assertEquals(0f, it.positionInParent.x)
+                            assertEquals(0f, it.positionInParent().x)
                             latch.countDown()
                         }
                     )
                     Box(
                         Modifier.requiredSize(size).onGloballyPositioned {
-                            assertEquals(sizePx + spacePx, it.positionInParent.x)
+                            assertEquals(sizePx + spacePx, it.positionInParent().x)
                             latch.countDown()
                         }
                     )
@@ -2594,13 +2599,13 @@
                 ) {
                     Box(
                         Modifier.requiredSize(size).onGloballyPositioned {
-                            assertEquals(rowSizePx - spacePx - sizePx * 2, it.positionInParent.x)
+                            assertEquals(rowSizePx - spacePx - sizePx * 2, it.positionInParent().x)
                             latch.countDown()
                         }
                     )
                     Box(
                         Modifier.requiredSize(size).onGloballyPositioned {
-                            assertEquals(rowSizePx - sizePx, it.positionInParent.x)
+                            assertEquals(rowSizePx - sizePx, it.positionInParent().x)
                             latch.countDown()
                         }
                     )
@@ -2630,21 +2635,21 @@
                 ) {
                     Box(
                         Modifier.size(size).onGloballyPositioned {
-                            assertEquals(0f, it.positionInParent.x)
+                            assertEquals(0f, it.positionInParent().x)
                             assertEquals(sizePx.roundToInt(), it.size.width)
                             latch.countDown()
                         }
                     )
                     Box(
                         Modifier.size(size).onGloballyPositioned {
-                            assertEquals(sizePx + spacePx, it.positionInParent.x)
+                            assertEquals(sizePx + spacePx, it.positionInParent().x)
                             assertEquals((rowSizePx - spacePx - sizePx).roundToInt(), it.size.width)
                             latch.countDown()
                         }
                     )
                     Box(
                         Modifier.size(size).onGloballyPositioned {
-                            assertEquals(rowSizePx, it.positionInParent.x)
+                            assertEquals(rowSizePx, it.positionInParent().x)
                             assertEquals(0, it.size.width)
                             latch.countDown()
                         }
@@ -2673,14 +2678,14 @@
                 ) {
                     Box(
                         Modifier.size(size).onGloballyPositioned {
-                            assertEquals(rowSizePx - sizePx * 2, it.positionInParent.x)
+                            assertEquals(rowSizePx - sizePx * 2, it.positionInParent().x)
                             assertEquals(sizePx.roundToInt(), it.size.width)
                             latch.countDown()
                         }
                     )
                     Box(
                         Modifier.size(size).onGloballyPositioned {
-                            assertEquals(rowSizePx - sizePx, it.positionInParent.x)
+                            assertEquals(rowSizePx - sizePx, it.positionInParent().x)
                             assertEquals(sizePx.roundToInt(), it.size.width)
                             latch.countDown()
                         }
@@ -3031,13 +3036,13 @@
                 ) {
                     Box(
                         Modifier.requiredSize(size).onGloballyPositioned {
-                            assertEquals(0f, it.positionInParent.x)
+                            assertEquals(0f, it.positionInParent().x)
                             latch.countDown()
                         }
                     )
                     Box(
                         Modifier.requiredSize(size).onGloballyPositioned {
-                            assertEquals(sizePx + spacePx, it.positionInParent.y)
+                            assertEquals(sizePx + spacePx, it.positionInParent().y)
                             latch.countDown()
                         }
                     )
@@ -3067,13 +3072,15 @@
                 ) {
                     Box(
                         Modifier.requiredSize(size).onGloballyPositioned {
-                            assertEquals(columnSizePx - spacePx - sizePx * 2, it.positionInParent.y)
+                            assertEquals(
+                                columnSizePx - spacePx - sizePx * 2, it.positionInParent().y
+                            )
                             latch.countDown()
                         }
                     )
                     Box(
                         Modifier.requiredSize(size).onGloballyPositioned {
-                            assertEquals(columnSizePx - sizePx, it.positionInParent.y)
+                            assertEquals(columnSizePx - sizePx, it.positionInParent().y)
                             latch.countDown()
                         }
                     )
@@ -3103,14 +3110,14 @@
                 ) {
                     Box(
                         Modifier.size(size).onGloballyPositioned {
-                            assertEquals(0f, it.positionInParent.y)
+                            assertEquals(0f, it.positionInParent().y)
                             assertEquals(sizePx.roundToInt(), it.size.height)
                             latch.countDown()
                         }
                     )
                     Box(
                         Modifier.size(size).onGloballyPositioned {
-                            assertEquals(sizePx + spacePx, it.positionInParent.y)
+                            assertEquals(sizePx + spacePx, it.positionInParent().y)
                             assertEquals(
                                 (columnSizePx - spacePx - sizePx).roundToInt(), it.size.height
                             )
@@ -3119,7 +3126,7 @@
                     )
                     Box(
                         Modifier.size(size).onGloballyPositioned {
-                            assertEquals(columnSizePx, it.positionInParent.y)
+                            assertEquals(columnSizePx, it.positionInParent().y)
                             assertEquals(0, it.size.height)
                             latch.countDown()
                         }
@@ -3148,13 +3155,13 @@
                 ) {
                     Box(
                         Modifier.requiredSize(size).onGloballyPositioned {
-                            assertEquals(columnSizePx - sizePx * 2, it.positionInParent.y)
+                            assertEquals(columnSizePx - sizePx * 2, it.positionInParent().y)
                             latch.countDown()
                         }
                     )
                     Box(
                         Modifier.requiredSize(size).onGloballyPositioned {
-                            assertEquals(columnSizePx - sizePx, it.positionInParent.y)
+                            assertEquals(columnSizePx - sizePx, it.positionInParent().y)
                             latch.countDown()
                         }
                     )
@@ -3270,7 +3277,7 @@
                     )
                     ConstrainedBox(
                         DpConstraints.fixed(50.toDp(), 40.toDp()),
-                        Modifier.alignBy { it.width },
+                        Modifier.alignBy { it.measuredWidth },
                         content = {}
                     )
                 }
@@ -3916,7 +3923,6 @@
 
         val positionedLatch = CountDownLatch(1)
         show {
-            @OptIn(ExperimentalLayout::class)
             Row(Modifier.requiredWidth(rowWidth).height(IntrinsicSize.Min)) {
                 Container(
                     Modifier.requiredWidth(dividerWidth).fillMaxHeight().onGloballyPositioned {
@@ -3927,13 +3933,36 @@
                         positionedLatch.countDown()
                     }
                 ) {}
+                val measurePolicy = object : MeasurePolicy {
+                    override fun MeasureScope.measure(
+                        measurables: List<Measurable>,
+                        constraints: Constraints
+                    ) = layout(constraints.maxWidth, constraints.maxWidth / 2) {}
+
+                    override fun IntrinsicMeasureScope.minIntrinsicWidth(
+                        measurables: List<IntrinsicMeasurable>,
+                        height: Int
+                    ) = rowWidth.roundToPx() / 10
+
+                    override fun IntrinsicMeasureScope.minIntrinsicHeight(
+                        measurables: List<IntrinsicMeasurable>,
+                        width: Int
+                    ) = width / 2
+
+                    override fun IntrinsicMeasureScope.maxIntrinsicWidth(
+                        measurables: List<IntrinsicMeasurable>,
+                        height: Int
+                    ) = rowWidth.roundToPx() * 2
+
+                    override fun IntrinsicMeasureScope.maxIntrinsicHeight(
+                        measurables: List<IntrinsicMeasurable>,
+                        width: Int
+                    ) = width / 2
+                }
                 Layout(
                     content = {},
-                    minIntrinsicWidthMeasureBlock = { _, _ -> rowWidth.roundToPx() / 10 },
-                    maxIntrinsicWidthMeasureBlock = { _, _ -> rowWidth.roundToPx() * 2 },
-                    minIntrinsicHeightMeasureBlock = { _, w -> w / 2 },
-                    maxIntrinsicHeightMeasureBlock = { _, w -> w / 2 }
-                ) { _, constraints -> layout(constraints.maxWidth, constraints.maxWidth / 2) {} }
+                    measurePolicy = measurePolicy
+                )
             }
         }
 
@@ -3947,7 +3976,6 @@
 
         val positionedLatch = CountDownLatch(1)
         show {
-            @OptIn(ExperimentalLayout::class)
             Column(Modifier.requiredHeight(columnHeight).width(IntrinsicSize.Min)) {
                 Container(
                     Modifier.requiredHeight(dividerHeight).fillMaxWidth().onGloballyPositioned {
@@ -3958,13 +3986,36 @@
                         positionedLatch.countDown()
                     }
                 ) {}
+                val measurePolicy = object : MeasurePolicy {
+                    override fun MeasureScope.measure(
+                        measurables: List<Measurable>,
+                        constraints: Constraints
+                    ) = layout(constraints.maxHeight / 2, constraints.maxHeight) {}
+
+                    override fun IntrinsicMeasureScope.minIntrinsicWidth(
+                        measurables: List<IntrinsicMeasurable>,
+                        height: Int
+                    ) = height / 2
+
+                    override fun IntrinsicMeasureScope.minIntrinsicHeight(
+                        measurables: List<IntrinsicMeasurable>,
+                        width: Int
+                    ) = columnHeight.roundToPx() / 10
+
+                    override fun IntrinsicMeasureScope.maxIntrinsicWidth(
+                        measurables: List<IntrinsicMeasurable>,
+                        height: Int
+                    ) = height / 2
+
+                    override fun IntrinsicMeasureScope.maxIntrinsicHeight(
+                        measurables: List<IntrinsicMeasurable>,
+                        width: Int
+                    ) = columnHeight.roundToPx() * 2
+                }
                 Layout(
                     content = {},
-                    minIntrinsicWidthMeasureBlock = { _, h -> h / 2 },
-                    maxIntrinsicWidthMeasureBlock = { _, h -> h / 2 },
-                    minIntrinsicHeightMeasureBlock = { _, _ -> columnHeight.roundToPx() / 10 },
-                    maxIntrinsicHeightMeasureBlock = { _, _ -> columnHeight.roundToPx() * 2 }
-                ) { _, constraints -> layout(constraints.maxHeight / 2, constraints.maxHeight) {} }
+                    measurePolicy = measurePolicy
+                )
             }
         }
 
@@ -4013,14 +4064,14 @@
         show {
             Row {
                 Container(
-                    modifier = Modifier.alignBy { it.height },
+                    modifier = Modifier.alignBy { it.measuredHeight },
                     width = size,
                     height = size,
                     content = {}
                 )
                 Container(
                     modifier = Modifier.alignBy { 0 }
-                        .alignBy { it.height / 2 }
+                        .alignBy { it.measuredHeight / 2 }
                         .onGloballyPositioned { coordinates ->
                             containerSize.value = coordinates.size
                             containerPosition.value = coordinates.positionInRoot()
@@ -4365,13 +4416,13 @@
                     ) {
                         Box(
                             Modifier.requiredSize(size).onGloballyPositioned {
-                                assertEquals(sizePx + spacePx, it.positionInParent.x)
+                                assertEquals(sizePx + spacePx, it.positionInParent().x)
                                 latch.countDown()
                             }
                         )
                         Box(
                             Modifier.requiredSize(size).onGloballyPositioned {
-                                assertEquals(0f, it.positionInParent.x)
+                                assertEquals(0f, it.positionInParent().x)
                                 latch.countDown()
                             }
                         )
@@ -4478,7 +4529,7 @@
                 Column(Modifier.fillMaxWidth()) {
                     Container(
                         Modifier.size(sizeDp)
-                            .alignBy { it.width }
+                            .alignBy { it.measuredWidth }
                             .onGloballyPositioned { coordinates ->
                                 childPosition[0] = coordinates.positionInRoot()
                                 drawLatch.countDown()
@@ -4488,7 +4539,7 @@
 
                     Container(
                         Modifier.size(sizeDp)
-                            .alignBy { it.width / 2 }
+                            .alignBy { it.measuredHeight / 2 }
                             .onGloballyPositioned { coordinates ->
                                 childPosition[1] = coordinates.positionInRoot()
                                 drawLatch.countDown()
@@ -5306,13 +5357,13 @@
                     ) {
                         Box(
                             Modifier.requiredSize(size).onGloballyPositioned {
-                                assertEquals(0f, it.positionInParent.x)
+                                assertEquals(0f, it.positionInParent().x)
                                 latch.countDown()
                             }
                         )
                         Box(
                             Modifier.requiredSize(size).onGloballyPositioned {
-                                assertEquals(sizePx + spacePx, it.positionInParent.x)
+                                assertEquals(sizePx + spacePx, it.positionInParent().x)
                                 latch.countDown()
                             }
                         )
@@ -5401,10 +5452,9 @@
     Layout(
         content = content,
         modifier = modifier,
-        measureBlock = { _, constraints ->
+        measurePolicy = { _, constraints ->
             val widthPx = max(width.roundToPx(), constraints.minWidth)
-            val heightPx =
-                max(height.roundToPx(), constraints.minHeight)
+            val heightPx = max(height.roundToPx(), constraints.minHeight)
             layout(
                 widthPx, heightPx,
                 mapOf(
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/SizeTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/SizeTest.kt
index 7c80e56..b463ff2 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/SizeTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/SizeTest.kt
@@ -26,6 +26,7 @@
 import androidx.compose.ui.node.Ref
 import androidx.compose.ui.layout.onGloballyPositioned
 import androidx.compose.ui.layout.positionInParent
+import androidx.compose.ui.layout.positionInRoot
 import androidx.compose.ui.platform.InspectableValue
 import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.platform.ValueElement
@@ -37,7 +38,6 @@
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.constrain
 import androidx.compose.ui.unit.dp
-import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
 import org.junit.Assert.assertEquals
@@ -46,11 +46,12 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.TimeUnit
 import kotlin.math.roundToInt
 
-@SmallTest
+@MediumTest
 @RunWith(AndroidJUnit4::class)
 class SizeTest : LayoutTest() {
 
@@ -410,6 +411,41 @@
     }
 
     @Test
+    fun testSize_smallerBoxInLargerBox() = with(density) {
+        val sizeIpx = 64
+        val sizeDp = sizeIpx.toDp()
+
+        val positionedLatch = CountDownLatch(1)
+        val boxSize = Ref<IntSize>()
+        val boxPosition = Ref<Offset>()
+        show {
+            Box(
+                Modifier.wrapContentSize(Alignment.TopStart).requiredSize(sizeDp * 2),
+                propagateMinConstraints = true
+            ) {
+                Box(
+                    Modifier.requiredSize(sizeDp)
+                        .onGloballyPositioned {
+                            boxSize.value = it.size
+                            boxPosition.value = it.positionInRoot()
+                            positionedLatch.countDown()
+                        }
+                )
+            }
+        }
+        assertTrue(positionedLatch.await(1, TimeUnit.SECONDS))
+
+        assertEquals(IntSize(sizeIpx, sizeIpx), boxSize.value)
+        assertEquals(
+            Offset(
+                (sizeIpx / 2).toFloat(),
+                (sizeIpx / 2).toFloat()
+            ),
+            boxPosition.value
+        )
+    }
+
+    @Test
     fun testSize_largerInSmaller() = with(density) {
         val sizeIpx = 64
         val sizeDp = sizeIpx.toDp()
@@ -1512,7 +1548,7 @@
                         }
                     }
                 },
-                measureBlock = { measurables, constraints ->
+                measurePolicy = { measurables, constraints ->
                     val placeable = measurables.first().measure(Constraints())
                     layout(constraints.maxWidth, constraints.maxHeight) {
                         placeable.placeRelative(0, 0)
@@ -1557,7 +1593,7 @@
                         ) {
                         }
                     },
-                    measureBlock = { measurables, incomingConstraints ->
+                    measurePolicy = { measurables, incomingConstraints ->
                         val measurable = measurables.first()
                         val constraints = incomingConstraints.constrain(
                             Constraints(
@@ -1606,7 +1642,7 @@
                         .onGloballyPositioned {
                             assertEquals(
                                 Offset(outerSize - innerSize, outerSize - innerSize),
-                                it.positionInParent
+                                it.positionInParent()
                             )
                             positionedLatch.countDown()
                         }
@@ -1615,7 +1651,7 @@
                     Modifier.wrapContentWidth(Alignment.End, unbounded = true)
                         .requiredSize(innerSize.toDp())
                         .onGloballyPositioned {
-                            assertEquals(outerSize - innerSize, it.positionInParent.x)
+                            assertEquals(outerSize - innerSize, it.positionInParent().x)
                             positionedLatch.countDown()
                         }
                 )
@@ -1623,7 +1659,7 @@
                     Modifier.wrapContentHeight(Alignment.Bottom, unbounded = true)
                         .requiredSize(innerSize.toDp())
                         .onGloballyPositioned {
-                            assertEquals(outerSize - innerSize, it.positionInParent.y)
+                            assertEquals(outerSize - innerSize, it.positionInParent().y)
                             positionedLatch.countDown()
                         }
                 )
@@ -1737,7 +1773,7 @@
                         }
                     }
                 },
-                measureBlock = { measurables, constraints ->
+                measurePolicy = { measurables, constraints ->
                     val placeable = measurables.first().measure(Constraints())
                     layout(constraints.maxWidth, constraints.maxHeight) {
                         placeable.placeRelative(0, 0)
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Box.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Box.kt
index daa7f4d..8bc4548 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Box.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Box.kt
@@ -24,10 +24,9 @@
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.layout.Measurable
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.layout.MeasuringIntrinsicsMeasureBlocks
+import androidx.compose.ui.layout.MeasurePolicy
 import androidx.compose.ui.layout.ParentDataModifier
 import androidx.compose.ui.layout.Placeable
-import androidx.compose.ui.node.MeasureBlocks
 import androidx.compose.ui.platform.InspectorInfo
 import androidx.compose.ui.platform.InspectorValueInfo
 import androidx.compose.ui.platform.NoInspectorInfo
@@ -65,33 +64,33 @@
     propagateMinConstraints: Boolean = false,
     content: @Composable BoxScope.() -> Unit
 ) {
-    val measureBlocks = rememberBoxMeasureBlocks(contentAlignment, propagateMinConstraints)
+    val measurePolicy = rememberBoxMeasurePolicy(contentAlignment, propagateMinConstraints)
     Layout(
         content = { BoxScope.content() },
-        measureBlocks = measureBlocks,
+        measurePolicy = measurePolicy,
         modifier = modifier
     )
 }
 
 @PublishedApi
 @Composable
-internal fun rememberBoxMeasureBlocks(
+internal fun rememberBoxMeasurePolicy(
     alignment: Alignment,
     propagateMinConstraints: Boolean
 ) = remember(alignment) {
     if (alignment == Alignment.TopStart && !propagateMinConstraints) {
-        DefaultBoxMeasureBlocks
+        DefaultBoxMeasurePolicy
     } else {
-        boxMeasureBlocks(alignment, propagateMinConstraints)
+        boxMeasurePolicy(alignment, propagateMinConstraints)
     }
 }
 
-internal val DefaultBoxMeasureBlocks: MeasureBlocks = boxMeasureBlocks(Alignment.TopStart, false)
+internal val DefaultBoxMeasurePolicy: MeasurePolicy = boxMeasurePolicy(Alignment.TopStart, false)
 
-internal fun boxMeasureBlocks(alignment: Alignment, propagateMinConstraints: Boolean) =
-    MeasuringIntrinsicsMeasureBlocks { measurables, constraints ->
+internal fun boxMeasurePolicy(alignment: Alignment, propagateMinConstraints: Boolean) =
+    MeasurePolicy { measurables, constraints ->
         if (measurables.isEmpty()) {
-            return@MeasuringIntrinsicsMeasureBlocks layout(
+            return@MeasurePolicy layout(
                 constraints.minWidth,
                 constraints.minHeight
             ) {}
@@ -119,7 +118,7 @@
                     Constraints.fixed(constraints.minWidth, constraints.minHeight)
                 )
             }
-            return@MeasuringIntrinsicsMeasureBlocks layout(boxWidth, boxHeight) {
+            return@MeasurePolicy layout(boxWidth, boxHeight) {
                 placeInBox(placeable, measurable, layoutDirection, boxWidth, boxHeight, alignment)
             }
         }
@@ -195,10 +194,10 @@
  */
 @Composable
 fun Box(modifier: Modifier) {
-    Layout({}, measureBlocks = EmptyBoxMeasureBlocks, modifier = modifier)
+    Layout({}, measurePolicy = EmptyBoxMeasurePolicy, modifier = modifier)
 }
 
-internal val EmptyBoxMeasureBlocks = MeasuringIntrinsicsMeasureBlocks { _, constraints ->
+internal val EmptyBoxMeasurePolicy = MeasurePolicy { _, constraints ->
     layout(constraints.minWidth, constraints.minHeight) {}
 }
 
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/BoxWithConstraints.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/BoxWithConstraints.kt
index 2754b14..3f2bf57 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/BoxWithConstraints.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/BoxWithConstraints.kt
@@ -55,11 +55,11 @@
     propagateMinConstraints: Boolean = false,
     content: @Composable BoxWithConstraintsScope.() -> Unit
 ) {
-    val measureBlocks = rememberBoxMeasureBlocks(contentAlignment, propagateMinConstraints)
+    val measurePolicy = rememberBoxMeasurePolicy(contentAlignment, propagateMinConstraints)
     SubcomposeLayout(modifier) { constraints ->
         val scope = BoxWithConstraintsScopeImpl(this, constraints)
         val measurables = subcompose(Unit) { scope.content() }
-        measureBlocks.measure(this, measurables, constraints)
+        with(measurePolicy) { measure(measurables, constraints) }
     }
 }
 
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Column.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Column.kt
index 674d2cd..aced672 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Column.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Column.kt
@@ -69,16 +69,16 @@
     horizontalAlignment: Alignment.Horizontal = Alignment.Start,
     content: @Composable ColumnScope.() -> Unit
 ) {
-    val measureBlocks = columnMeasureBlocks(verticalArrangement, horizontalAlignment)
+    val measurePolicy = columnMeasurePolicy(verticalArrangement, horizontalAlignment)
     Layout(
         content = { ColumnScope.content() },
-        measureBlocks = measureBlocks,
+        measurePolicy = measurePolicy,
         modifier = modifier
     )
 }
 
 @PublishedApi
-internal val DefaultColumnMeasureBlocks = rowColumnMeasureBlocks(
+internal val DefaultColumnMeasurePolicy = rowColumnMeasurePolicy(
     orientation = LayoutOrientation.Vertical,
     arrangement = { totalSize, size, _, density, outPosition ->
         with(Arrangement.Top) { density.arrange(totalSize, size, outPosition) }
@@ -90,14 +90,14 @@
 
 @PublishedApi
 @Composable
-internal fun columnMeasureBlocks(
+internal fun columnMeasurePolicy(
     verticalArrangement: Arrangement.Vertical,
     horizontalAlignment: Alignment.Horizontal
 ) = remember(verticalArrangement, horizontalAlignment) {
     if (verticalArrangement == Arrangement.Top && horizontalAlignment == Alignment.Start) {
-        DefaultColumnMeasureBlocks
+        DefaultColumnMeasurePolicy
     } else {
-        rowColumnMeasureBlocks(
+        rowColumnMeasurePolicy(
             orientation = LayoutOrientation.Vertical,
             arrangement = { totalSize, size, _, density, outPosition ->
                 with(verticalArrangement) { density.arrange(totalSize, size, outPosition) }
@@ -152,7 +152,7 @@
     @Stable
     fun Modifier.alignBy(alignmentLine: VerticalAlignmentLine) = this.then(
         SiblingsAlignedModifier.WithAlignmentLine(
-            line = alignmentLine,
+            alignmentLine = alignmentLine,
             inspectorInfo = debugInspectorInfo {
                 name = "alignBy"
                 value = alignmentLine
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayoutApi.kt
similarity index 94%
rename from compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt
rename to compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayoutApi.kt
index 63fdeeb..4b2c4f5 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayoutApi.kt
@@ -17,4 +17,4 @@
 package androidx.compose.foundation.layout
 
 @RequiresOptIn("The API of this layout is experimental and is likely to change in the future.")
-annotation class ExperimentalLayout
+annotation class ExperimentalLayoutApi
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Intrinsic.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Intrinsic.kt
index 8cf81e8..4b382a7 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Intrinsic.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Intrinsic.kt
@@ -42,11 +42,10 @@
  * Example usage for max intrinsic:
  * @sample androidx.compose.foundation.layout.samples.SameWidthTextBoxes
  */
-@ExperimentalLayout
 @Stable
 fun Modifier.width(intrinsicSize: IntrinsicSize) = when (intrinsicSize) {
-    IntrinsicSize.Min -> this.then(PreferredMinIntrinsicWidthModifier)
-    IntrinsicSize.Max -> this.then(PreferredMaxIntrinsicWidthModifier)
+    IntrinsicSize.Min -> this.then(MinIntrinsicWidthModifier)
+    IntrinsicSize.Max -> this.then(MaxIntrinsicWidthModifier)
 }
 
 /**
@@ -63,11 +62,46 @@
  * Example usage for max intrinsic:
  * @sample androidx.compose.foundation.layout.samples.MatchParentDividerForAspectRatio
  */
-@ExperimentalLayout
 @Stable
 fun Modifier.height(intrinsicSize: IntrinsicSize) = when (intrinsicSize) {
-    IntrinsicSize.Min -> this.then(PreferredMinIntrinsicHeightModifier)
-    IntrinsicSize.Max -> this.then(PreferredMaxIntrinsicHeightModifier)
+    IntrinsicSize.Min -> this.then(MinIntrinsicHeightModifier)
+    IntrinsicSize.Max -> this.then(MaxIntrinsicHeightModifier)
+}
+
+/**
+ * Declare the width of the content to be exactly the same as the min or max intrinsic width of
+ * the content. The incoming measurement [Constraints] will not override this value. If the content
+ * intrinsic width does not satisfy the incoming [Constraints], the parent layout will be
+ * reported a size coerced in the [Constraints], and the position of the content will be
+ * automatically offset to be centered on the space assigned to the child by the parent layout under
+ * the assumption that [Constraints] were respected.
+ *
+ * See [height] for options of sizing to intrinsic height.
+ * See [width] and [widthIn] for options to set the preferred width.
+ * See [requiredWidth] and [requiredWidthIn] for other options to set the required width.
+ */
+@Stable
+fun Modifier.requiredWidth(intrinsicSize: IntrinsicSize) = when (intrinsicSize) {
+    IntrinsicSize.Min -> this.then(RequiredMinIntrinsicWidthModifier)
+    IntrinsicSize.Max -> this.then(RequiredMaxIntrinsicWidthModifier)
+}
+
+/**
+ * Declare the height of the content to be exactly the same as the min or max intrinsic height of
+ * the content. The incoming measurement [Constraints] will not override this value. If the content
+ * intrinsic height does not satisfy the incoming [Constraints], the parent layout will be
+ * reported a size coerced in the [Constraints], and the position of the content will be
+ * automatically offset to be centered on the space assigned to the child by the parent layout under
+ * the assumption that [Constraints] were respected.
+ *
+ * See [width] for options of sizing to intrinsic width.
+ * See [height] and [heightIn] for options to set the preferred height.
+ * See [requiredHeight] and [requiredHeightIn] for other options to set the required height.
+ */
+@Stable
+fun Modifier.requiredHeight(intrinsicSize: IntrinsicSize) = when (intrinsicSize) {
+    IntrinsicSize.Min -> this.then(RequiredMinIntrinsicHeightModifier)
+    IntrinsicSize.Max -> this.then(RequiredMaxIntrinsicHeightModifier)
 }
 
 /**
@@ -75,7 +109,7 @@
  */
 enum class IntrinsicSize { Min, Max }
 
-private object PreferredMinIntrinsicWidthModifier : PreferredIntrinsicSizeModifier {
+private object MinIntrinsicWidthModifier : IntrinsicSizeModifier {
     override fun MeasureScope.calculateContentConstraints(
         measurable: Measurable,
         constraints: Constraints
@@ -90,7 +124,7 @@
     ) = measurable.minIntrinsicWidth(height)
 }
 
-private object PreferredMinIntrinsicHeightModifier : PreferredIntrinsicSizeModifier {
+private object MinIntrinsicHeightModifier : IntrinsicSizeModifier {
     override fun MeasureScope.calculateContentConstraints(
         measurable: Measurable,
         constraints: Constraints
@@ -105,7 +139,7 @@
     ) = measurable.minIntrinsicHeight(width)
 }
 
-private object PreferredMaxIntrinsicWidthModifier : PreferredIntrinsicSizeModifier {
+private object MaxIntrinsicWidthModifier : IntrinsicSizeModifier {
     override fun MeasureScope.calculateContentConstraints(
         measurable: Measurable,
         constraints: Constraints
@@ -120,7 +154,7 @@
     ) = measurable.maxIntrinsicWidth(height)
 }
 
-private object PreferredMaxIntrinsicHeightModifier : PreferredIntrinsicSizeModifier {
+private object MaxIntrinsicHeightModifier : IntrinsicSizeModifier {
     override fun MeasureScope.calculateContentConstraints(
         measurable: Measurable,
         constraints: Constraints
@@ -135,7 +169,77 @@
     ) = measurable.maxIntrinsicHeight(width)
 }
 
-private interface PreferredIntrinsicSizeModifier : LayoutModifier {
+private object RequiredMinIntrinsicWidthModifier : IntrinsicSizeModifier {
+    override val enforceIncoming: Boolean = false
+
+    override fun MeasureScope.calculateContentConstraints(
+        measurable: Measurable,
+        constraints: Constraints
+    ): Constraints {
+        val width = measurable.minIntrinsicWidth(constraints.maxHeight)
+        return Constraints.fixedWidth(width)
+    }
+
+    override fun IntrinsicMeasureScope.maxIntrinsicWidth(
+        measurable: IntrinsicMeasurable,
+        height: Int
+    ) = measurable.minIntrinsicWidth(height)
+}
+
+private object RequiredMinIntrinsicHeightModifier : IntrinsicSizeModifier {
+    override val enforceIncoming: Boolean = false
+
+    override fun MeasureScope.calculateContentConstraints(
+        measurable: Measurable,
+        constraints: Constraints
+    ): Constraints {
+        val height = measurable.minIntrinsicHeight(constraints.maxWidth)
+        return Constraints.fixedHeight(height)
+    }
+
+    override fun IntrinsicMeasureScope.maxIntrinsicHeight(
+        measurable: IntrinsicMeasurable,
+        width: Int
+    ) = measurable.minIntrinsicHeight(width)
+}
+
+private object RequiredMaxIntrinsicWidthModifier : IntrinsicSizeModifier {
+    override val enforceIncoming: Boolean = false
+
+    override fun MeasureScope.calculateContentConstraints(
+        measurable: Measurable,
+        constraints: Constraints
+    ): Constraints {
+        val width = measurable.maxIntrinsicWidth(constraints.maxHeight)
+        return Constraints.fixedWidth(width)
+    }
+
+    override fun IntrinsicMeasureScope.minIntrinsicWidth(
+        measurable: IntrinsicMeasurable,
+        height: Int
+    ) = measurable.maxIntrinsicWidth(height)
+}
+
+private object RequiredMaxIntrinsicHeightModifier : IntrinsicSizeModifier {
+    override val enforceIncoming: Boolean = false
+
+    override fun MeasureScope.calculateContentConstraints(
+        measurable: Measurable,
+        constraints: Constraints
+    ): Constraints {
+        val height = measurable.maxIntrinsicHeight(constraints.maxWidth)
+        return Constraints.fixedHeight(height)
+    }
+
+    override fun IntrinsicMeasureScope.minIntrinsicHeight(
+        measurable: IntrinsicMeasurable,
+        width: Int
+    ) = measurable.maxIntrinsicHeight(width)
+}
+
+private interface IntrinsicSizeModifier : LayoutModifier {
+    val enforceIncoming: Boolean get() = true
+
     fun MeasureScope.calculateContentConstraints(
         measurable: Measurable,
         constraints: Constraints
@@ -145,8 +249,9 @@
         measurable: Measurable,
         constraints: Constraints
     ): MeasureResult {
+        val contentConstraints = calculateContentConstraints(measurable, constraints)
         val placeable = measurable.measure(
-            constraints.constrain(calculateContentConstraints(measurable, constraints))
+            if (enforceIncoming) constraints.constrain(contentConstraints) else contentConstraints
         )
         return layout(placeable.width, placeable.height) {
             placeable.placeRelative(IntOffset.Zero)
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Row.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Row.kt
index 008b870c..0a840aa 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Row.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Row.kt
@@ -70,13 +70,10 @@
     verticalAlignment: Alignment.Vertical = Alignment.Top,
     content: @Composable RowScope.() -> Unit
 ) {
-    val measureBlocks = rowMeasureBlocks(
-        horizontalArrangement,
-        verticalAlignment
-    )
+    val measurePolicy = rowMeasurePolicy(horizontalArrangement, verticalAlignment)
     Layout(
         content = { RowScope.content() },
-        measureBlocks = measureBlocks,
+        measurePolicy = measurePolicy,
         modifier = modifier
     )
 }
@@ -85,7 +82,7 @@
  * MeasureBlocks to use when horizontalArrangement and verticalAlignment are not provided.
  */
 @PublishedApi
-internal val DefaultRowMeasureBlocks = rowColumnMeasureBlocks(
+internal val DefaultRowMeasurePolicy = rowColumnMeasurePolicy(
     orientation = LayoutOrientation.Horizontal,
     arrangement = { totalSize, size, layoutDirection, density, outPosition ->
         with(Arrangement.Start) { density.arrange(totalSize, size, layoutDirection, outPosition) }
@@ -97,14 +94,14 @@
 
 @PublishedApi
 @Composable
-internal fun rowMeasureBlocks(
+internal fun rowMeasurePolicy(
     horizontalArrangement: Arrangement.Horizontal,
     verticalAlignment: Alignment.Vertical
 ) = remember(horizontalArrangement, verticalAlignment) {
     if (horizontalArrangement == Arrangement.Start && verticalAlignment == Alignment.Top) {
-        DefaultRowMeasureBlocks
+        DefaultRowMeasurePolicy
     } else {
-        rowColumnMeasureBlocks(
+        rowColumnMeasurePolicy(
             orientation = LayoutOrientation.Horizontal,
             arrangement = { totalSize, size, layoutDirection, density, outPosition ->
                 with(horizontalArrangement) {
@@ -165,7 +162,7 @@
     @Stable
     fun Modifier.alignBy(alignmentLine: HorizontalAlignmentLine) = this.then(
         SiblingsAlignedModifier.WithAlignmentLine(
-            line = alignmentLine,
+            alignmentLine = alignmentLine,
             inspectorInfo = debugInspectorInfo {
                 name = "alignBy"
                 value = alignmentLine
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt
index d7c7cd3..c2603f5 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt
@@ -23,12 +23,14 @@
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.layout.AlignmentLine
 import androidx.compose.ui.layout.IntrinsicMeasurable
-import androidx.compose.ui.layout.IntrinsicMeasureBlock
+import androidx.compose.ui.layout.IntrinsicMeasureScope
+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.Measured
 import androidx.compose.ui.layout.ParentDataModifier
 import androidx.compose.ui.layout.Placeable
-import androidx.compose.ui.layout.measureBlocksOf
-import androidx.compose.ui.node.MeasureBlocks
 import androidx.compose.ui.platform.InspectorInfo
 import androidx.compose.ui.platform.InspectorValueInfo
 import androidx.compose.ui.unit.Constraints
@@ -41,224 +43,247 @@
 import kotlin.math.roundToInt
 import kotlin.math.sign
 
-internal fun rowColumnMeasureBlocks(
+internal fun rowColumnMeasurePolicy(
     orientation: LayoutOrientation,
     arrangement: (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit,
     arrangementSpacing: Dp,
     crossAxisSize: SizeMode,
     crossAxisAlignment: CrossAxisAlignment
-): MeasureBlocks {
+): MeasurePolicy {
     fun Placeable.mainAxisSize() =
         if (orientation == LayoutOrientation.Horizontal) width else height
 
     fun Placeable.crossAxisSize() =
         if (orientation == LayoutOrientation.Horizontal) height else width
 
-    return measureBlocksOf(
-        minIntrinsicWidthMeasureBlock = MinIntrinsicWidthMeasureBlock(orientation),
-        minIntrinsicHeightMeasureBlock = MinIntrinsicHeightMeasureBlock(orientation),
-        maxIntrinsicWidthMeasureBlock = MaxIntrinsicWidthMeasureBlock(orientation),
-        maxIntrinsicHeightMeasureBlock = MaxIntrinsicHeightMeasureBlock(orientation)
-    ) { measurables, outerConstraints ->
-        val constraints = OrientationIndependentConstraints(outerConstraints, orientation)
-        val arrangementSpacingPx = arrangementSpacing.roundToPx()
+    return object : MeasurePolicy {
+        override fun MeasureScope.measure(
+            measurables: List<Measurable>,
+            constraints: Constraints
+        ): MeasureResult {
+            @Suppress("NAME_SHADOWING")
+            val constraints = OrientationIndependentConstraints(constraints, orientation)
+            val arrangementSpacingPx = arrangementSpacing.roundToPx()
 
-        var totalWeight = 0f
-        var fixedSpace = 0
-        var crossAxisSpace = 0
-        var weightChildrenCount = 0
+            var totalWeight = 0f
+            var fixedSpace = 0
+            var crossAxisSpace = 0
+            var weightChildrenCount = 0
 
-        var anyAlignBy = false
-        val placeables = arrayOfNulls<Placeable>(measurables.size)
-        val rowColumnParentData = Array(measurables.size) { measurables[it].data }
+            var anyAlignBy = false
+            val placeables = arrayOfNulls<Placeable>(measurables.size)
+            val rowColumnParentData = Array(measurables.size) { measurables[it].data }
 
-        // First measure children with zero weight.
-        var spaceAfterLastNoWeight = 0
-        for (i in measurables.indices) {
-            val child = measurables[i]
-            val parentData = rowColumnParentData[i]
-            val weight = parentData.weight
-
-            if (weight > 0f) {
-                totalWeight += weight
-                ++weightChildrenCount
-            } else {
-                val mainAxisMax = constraints.mainAxisMax
-                val placeable = child.measure(
-                    // Ask for preferred main axis size.
-                    constraints.copy(
-                        mainAxisMin = 0,
-                        mainAxisMax = if (mainAxisMax == Constraints.Infinity) {
-                            Constraints.Infinity
-                        } else {
-                            mainAxisMax - fixedSpace
-                        },
-                        crossAxisMin = 0
-                    ).toBoxConstraints(orientation)
-                )
-                spaceAfterLastNoWeight = min(
-                    arrangementSpacingPx,
-                    mainAxisMax - fixedSpace - placeable.mainAxisSize()
-                )
-                fixedSpace += placeable.mainAxisSize() + spaceAfterLastNoWeight
-                crossAxisSpace = max(crossAxisSpace, placeable.crossAxisSize())
-                anyAlignBy = anyAlignBy || parentData.isRelative
-                placeables[i] = placeable
-            }
-        }
-
-        var weightedSpace = 0
-        if (weightChildrenCount == 0) {
-            // fixedSpace contains an extra spacing after the last non-weight child.
-            fixedSpace -= spaceAfterLastNoWeight
-        } else {
-            // Measure the rest according to their weights in the remaining main axis space.
-            val targetSpace =
-                if (totalWeight > 0f && constraints.mainAxisMax != Constraints.Infinity) {
-                    constraints.mainAxisMax
-                } else {
-                    constraints.mainAxisMin
-                }
-            val remainingToTarget =
-                targetSpace - fixedSpace - arrangementSpacingPx * (weightChildrenCount - 1)
-
-            val weightUnitSpace = if (totalWeight > 0) remainingToTarget / totalWeight else 0f
-            var remainder = remainingToTarget - rowColumnParentData.sumBy {
-                (weightUnitSpace * it.weight).roundToInt()
-            }
-
+            // First measure children with zero weight.
+            var spaceAfterLastNoWeight = 0
             for (i in measurables.indices) {
-                if (placeables[i] == null) {
-                    val child = measurables[i]
-                    val parentData = rowColumnParentData[i]
-                    val weight = parentData.weight
-                    check(weight > 0) { "All weights <= 0 should have placeables" }
-                    // After the weightUnitSpace rounding, the total space going to be occupied
-                    // can be smaller or larger than remainingToTarget. Here we distribute the
-                    // loss or gain remainder evenly to the first children.
-                    val remainderUnit = remainder.sign
-                    remainder -= remainderUnit
-                    val childMainAxisSize = max(
-                        0,
-                        (weightUnitSpace * weight).roundToInt() + remainderUnit
-                    )
+                val child = measurables[i]
+                val parentData = rowColumnParentData[i]
+                val weight = parentData.weight
+
+                if (weight > 0f) {
+                    totalWeight += weight
+                    ++weightChildrenCount
+                } else {
+                    val mainAxisMax = constraints.mainAxisMax
                     val placeable = child.measure(
-                        OrientationIndependentConstraints(
-                            if (parentData.fill && childMainAxisSize != Constraints.Infinity) {
-                                childMainAxisSize
+                        // Ask for preferred main axis size.
+                        constraints.copy(
+                            mainAxisMin = 0,
+                            mainAxisMax = if (mainAxisMax == Constraints.Infinity) {
+                                Constraints.Infinity
                             } else {
-                                0
+                                mainAxisMax - fixedSpace
                             },
-                            childMainAxisSize,
-                            0,
-                            constraints.crossAxisMax
+                            crossAxisMin = 0
                         ).toBoxConstraints(orientation)
                     )
-                    weightedSpace += placeable.mainAxisSize()
+                    spaceAfterLastNoWeight = min(
+                        arrangementSpacingPx,
+                        mainAxisMax - fixedSpace - placeable.mainAxisSize()
+                    )
+                    fixedSpace += placeable.mainAxisSize() + spaceAfterLastNoWeight
                     crossAxisSpace = max(crossAxisSpace, placeable.crossAxisSize())
                     anyAlignBy = anyAlignBy || parentData.isRelative
                     placeables[i] = placeable
                 }
             }
-        }
 
-        var beforeCrossAxisAlignmentLine = 0
-        var afterCrossAxisAlignmentLine = 0
-        if (anyAlignBy) {
-            for (i in placeables.indices) {
-                val placeable = placeables[i]!!
-                val parentData = rowColumnParentData[i]
-                val alignmentLinePosition = parentData.crossAxisAlignment
-                    ?.calculateAlignmentLinePosition(placeable)
-                if (alignmentLinePosition != null) {
-                    beforeCrossAxisAlignmentLine = max(
-                        beforeCrossAxisAlignmentLine,
-                        alignmentLinePosition.let { if (it != AlignmentLine.Unspecified) it else 0 }
-                    )
-                    afterCrossAxisAlignmentLine = max(
-                        afterCrossAxisAlignmentLine,
-                        placeable.crossAxisSize() -
-                            (
-                                alignmentLinePosition.let {
-                                    if (it != AlignmentLine.Unspecified) {
-                                        it
-                                    } else {
-                                        placeable.crossAxisSize()
-                                    }
-                                }
-                                )
-                    )
-                }
-            }
-        }
-
-        // Compute the Row or Column size and position the children.
-        val mainAxisLayoutSize =
-            if (totalWeight > 0f && constraints.mainAxisMax != Constraints.Infinity) {
-                constraints.mainAxisMax
+            var weightedSpace = 0
+            if (weightChildrenCount == 0) {
+                // fixedSpace contains an extra spacing after the last non-weight child.
+                fixedSpace -= spaceAfterLastNoWeight
             } else {
-                max(fixedSpace + weightedSpace, constraints.mainAxisMin)
-            }
-        val crossAxisLayoutSize = if (constraints.crossAxisMax != Constraints.Infinity &&
-            crossAxisSize == SizeMode.Expand
-        ) {
-            constraints.crossAxisMax
-        } else {
-            max(
-                crossAxisSpace,
-                max(
-                    constraints.crossAxisMin,
-                    beforeCrossAxisAlignmentLine + afterCrossAxisAlignmentLine
-                )
-            )
-        }
-        val layoutWidth = if (orientation == Horizontal) {
-            mainAxisLayoutSize
-        } else {
-            crossAxisLayoutSize
-        }
-        val layoutHeight = if (orientation == Horizontal) {
-            crossAxisLayoutSize
-        } else {
-            mainAxisLayoutSize
-        }
-
-        val mainAxisPositions = IntArray(measurables.size) { 0 }
-        layout(layoutWidth, layoutHeight) {
-            val childrenMainAxisSize = IntArray(measurables.size) { index ->
-                placeables[index]!!.mainAxisSize()
-            }
-            arrangement(
-                mainAxisLayoutSize,
-                childrenMainAxisSize,
-                layoutDirection,
-                this@measureBlocksOf,
-                mainAxisPositions
-            )
-
-            placeables.forEachIndexed { index, placeable ->
-                placeable!!
-                val parentData = rowColumnParentData[index]
-                val childCrossAlignment = parentData.crossAxisAlignment ?: crossAxisAlignment
-
-                val crossAxis = childCrossAlignment.align(
-                    size = crossAxisLayoutSize - placeable.crossAxisSize(),
-                    layoutDirection = if (orientation == Horizontal) {
-                        LayoutDirection.Ltr
+                // Measure the rest according to their weights in the remaining main axis space.
+                val targetSpace =
+                    if (totalWeight > 0f && constraints.mainAxisMax != Constraints.Infinity) {
+                        constraints.mainAxisMax
                     } else {
-                        layoutDirection
-                    },
-                    placeable = placeable,
-                    beforeCrossAxisAlignmentLine = beforeCrossAxisAlignmentLine
+                        constraints.mainAxisMin
+                    }
+                val remainingToTarget =
+                    targetSpace - fixedSpace - arrangementSpacingPx * (weightChildrenCount - 1)
+
+                val weightUnitSpace = if (totalWeight > 0) remainingToTarget / totalWeight else 0f
+                var remainder = remainingToTarget - rowColumnParentData.sumBy {
+                    (weightUnitSpace * it.weight).roundToInt()
+                }
+
+                for (i in measurables.indices) {
+                    if (placeables[i] == null) {
+                        val child = measurables[i]
+                        val parentData = rowColumnParentData[i]
+                        val weight = parentData.weight
+                        check(weight > 0) { "All weights <= 0 should have placeables" }
+                        // After the weightUnitSpace rounding, the total space going to be occupied
+                        // can be smaller or larger than remainingToTarget. Here we distribute the
+                        // loss or gain remainder evenly to the first children.
+                        val remainderUnit = remainder.sign
+                        remainder -= remainderUnit
+                        val childMainAxisSize = max(
+                            0,
+                            (weightUnitSpace * weight).roundToInt() + remainderUnit
+                        )
+                        val placeable = child.measure(
+                            OrientationIndependentConstraints(
+                                if (parentData.fill && childMainAxisSize != Constraints.Infinity) {
+                                    childMainAxisSize
+                                } else {
+                                    0
+                                },
+                                childMainAxisSize,
+                                0,
+                                constraints.crossAxisMax
+                            ).toBoxConstraints(orientation)
+                        )
+                        weightedSpace += placeable.mainAxisSize()
+                        crossAxisSpace = max(crossAxisSpace, placeable.crossAxisSize())
+                        anyAlignBy = anyAlignBy || parentData.isRelative
+                        placeables[i] = placeable
+                    }
+                }
+            }
+
+            var beforeCrossAxisAlignmentLine = 0
+            var afterCrossAxisAlignmentLine = 0
+            if (anyAlignBy) {
+                for (i in placeables.indices) {
+                    val placeable = placeables[i]!!
+                    val parentData = rowColumnParentData[i]
+                    val alignmentLinePosition = parentData.crossAxisAlignment
+                        ?.calculateAlignmentLinePosition(placeable)
+                    if (alignmentLinePosition != null) {
+                        beforeCrossAxisAlignmentLine = max(
+                            beforeCrossAxisAlignmentLine,
+                            alignmentLinePosition.let {
+                                if (it != AlignmentLine.Unspecified) it else 0
+                            }
+                        )
+                        afterCrossAxisAlignmentLine = max(
+                            afterCrossAxisAlignmentLine,
+                            placeable.crossAxisSize() -
+                                (
+                                    alignmentLinePosition.let {
+                                        if (it != AlignmentLine.Unspecified) {
+                                            it
+                                        } else {
+                                            placeable.crossAxisSize()
+                                        }
+                                    }
+                                    )
+                        )
+                    }
+                }
+            }
+
+            // Compute the Row or Column size and position the children.
+            val mainAxisLayoutSize =
+                if (totalWeight > 0f && constraints.mainAxisMax != Constraints.Infinity) {
+                    constraints.mainAxisMax
+                } else {
+                    max(fixedSpace + weightedSpace, constraints.mainAxisMin)
+                }
+            val crossAxisLayoutSize = if (constraints.crossAxisMax != Constraints.Infinity &&
+                crossAxisSize == SizeMode.Expand
+            ) {
+                constraints.crossAxisMax
+            } else {
+                max(
+                    crossAxisSpace,
+                    max(
+                        constraints.crossAxisMin,
+                        beforeCrossAxisAlignmentLine + afterCrossAxisAlignmentLine
+                    )
+                )
+            }
+            val layoutWidth = if (orientation == Horizontal) {
+                mainAxisLayoutSize
+            } else {
+                crossAxisLayoutSize
+            }
+            val layoutHeight = if (orientation == Horizontal) {
+                crossAxisLayoutSize
+            } else {
+                mainAxisLayoutSize
+            }
+
+            val mainAxisPositions = IntArray(measurables.size) { 0 }
+            return layout(layoutWidth, layoutHeight) {
+                val childrenMainAxisSize = IntArray(measurables.size) { index ->
+                    placeables[index]!!.mainAxisSize()
+                }
+                arrangement(
+                    mainAxisLayoutSize,
+                    childrenMainAxisSize,
+                    layoutDirection,
+                    this@measure,
+                    mainAxisPositions
                 )
 
-                if (orientation == Horizontal) {
-                    placeable.place(mainAxisPositions[index], crossAxis)
-                } else {
-                    placeable.place(crossAxis, mainAxisPositions[index])
+                placeables.forEachIndexed { index, placeable ->
+                    placeable!!
+                    val parentData = rowColumnParentData[index]
+                    val childCrossAlignment = parentData.crossAxisAlignment ?: crossAxisAlignment
+
+                    val crossAxis = childCrossAlignment.align(
+                        size = crossAxisLayoutSize - placeable.crossAxisSize(),
+                        layoutDirection = if (orientation == Horizontal) {
+                            LayoutDirection.Ltr
+                        } else {
+                            layoutDirection
+                        },
+                        placeable = placeable,
+                        beforeCrossAxisAlignmentLine = beforeCrossAxisAlignmentLine
+                    )
+
+                    if (orientation == Horizontal) {
+                        placeable.place(mainAxisPositions[index], crossAxis)
+                    } else {
+                        placeable.place(crossAxis, mainAxisPositions[index])
+                    }
                 }
             }
         }
+
+        override fun IntrinsicMeasureScope.minIntrinsicWidth(
+            measurables: List<IntrinsicMeasurable>,
+            height: Int
+        ) = MinIntrinsicWidthMeasureBlock(orientation)(measurables, height)
+
+        override fun IntrinsicMeasureScope.minIntrinsicHeight(
+            measurables: List<IntrinsicMeasurable>,
+            width: Int
+        ) = MinIntrinsicHeightMeasureBlock(orientation)(measurables, width)
+
+        override fun IntrinsicMeasureScope.maxIntrinsicWidth(
+            measurables: List<IntrinsicMeasurable>,
+            height: Int
+        ) = MaxIntrinsicWidthMeasureBlock(orientation)(measurables, height)
+
+        override fun IntrinsicMeasureScope.maxIntrinsicHeight(
+            measurables: List<IntrinsicMeasurable>,
+            width: Int
+        ) = MaxIntrinsicHeightMeasureBlock(orientation)(measurables, width)
     }
 }
 
@@ -389,7 +414,7 @@
         override val isRelative: Boolean
             get() = true
 
-        override fun calculateAlignmentLinePosition(placeable: Placeable): Int? {
+        override fun calculateAlignmentLinePosition(placeable: Placeable): Int {
             return alignmentLineProvider.calculateAlignmentLinePosition(placeable)
         }
 
@@ -401,7 +426,7 @@
         ): Int {
             val alignmentLinePosition =
                 alignmentLineProvider.calculateAlignmentLinePosition(placeable)
-            return if (alignmentLinePosition != null) {
+            return if (alignmentLinePosition != AlignmentLine.Unspecified) {
                 val line = beforeCrossAxisAlignmentLine - alignmentLinePosition
                 if (layoutDirection == LayoutDirection.Rtl) {
                     size - line
@@ -534,86 +559,94 @@
     }
 
 private object IntrinsicMeasureBlocks {
-    val HorizontalMinWidth: IntrinsicMeasureBlock = { measurables, availableHeight ->
-        intrinsicSize(
-            measurables,
-            { h -> minIntrinsicWidth(h) },
-            { w -> maxIntrinsicHeight(w) },
-            availableHeight,
-            LayoutOrientation.Horizontal,
-            LayoutOrientation.Horizontal
-        )
-    }
-    val VerticalMinWidth: IntrinsicMeasureBlock = { measurables, availableHeight ->
-        intrinsicSize(
-            measurables,
-            { h -> minIntrinsicWidth(h) },
-            { w -> maxIntrinsicHeight(w) },
-            availableHeight,
-            LayoutOrientation.Vertical,
-            LayoutOrientation.Horizontal
-        )
-    }
-    val HorizontalMinHeight: IntrinsicMeasureBlock = { measurables, availableWidth ->
-        intrinsicSize(
-            measurables,
-            { w -> minIntrinsicHeight(w) },
-            { h -> maxIntrinsicWidth(h) },
-            availableWidth,
-            LayoutOrientation.Horizontal,
-            LayoutOrientation.Vertical
-        )
-    }
-    val VerticalMinHeight: IntrinsicMeasureBlock = { measurables, availableWidth ->
-        intrinsicSize(
-            measurables,
-            { w -> minIntrinsicHeight(w) },
-            { h -> maxIntrinsicWidth(h) },
-            availableWidth,
-            LayoutOrientation.Vertical,
-            LayoutOrientation.Vertical
-        )
-    }
-    val HorizontalMaxWidth: IntrinsicMeasureBlock = { measurables, availableHeight ->
-        intrinsicSize(
-            measurables,
-            { h -> maxIntrinsicWidth(h) },
-            { w -> maxIntrinsicHeight(w) },
-            availableHeight,
-            LayoutOrientation.Horizontal,
-            LayoutOrientation.Horizontal
-        )
-    }
-    val VerticalMaxWidth: IntrinsicMeasureBlock = { measurables, availableHeight ->
-        intrinsicSize(
-            measurables,
-            { h -> maxIntrinsicWidth(h) },
-            { w -> maxIntrinsicHeight(w) },
-            availableHeight,
-            LayoutOrientation.Vertical,
-            LayoutOrientation.Horizontal
-        )
-    }
-    val HorizontalMaxHeight: IntrinsicMeasureBlock = { measurables, availableWidth ->
-        intrinsicSize(
-            measurables,
-            { w -> maxIntrinsicHeight(w) },
-            { h -> maxIntrinsicWidth(h) },
-            availableWidth,
-            LayoutOrientation.Horizontal,
-            LayoutOrientation.Vertical
-        )
-    }
-    val VerticalMaxHeight: IntrinsicMeasureBlock = { measurables, availableWidth ->
-        intrinsicSize(
-            measurables,
-            { w -> maxIntrinsicHeight(w) },
-            { h -> maxIntrinsicWidth(h) },
-            availableWidth,
-            LayoutOrientation.Vertical,
-            LayoutOrientation.Vertical
-        )
-    }
+    val HorizontalMinWidth: (List<IntrinsicMeasurable>, Int) -> Int =
+        { measurables, availableHeight ->
+            intrinsicSize(
+                measurables,
+                { h -> minIntrinsicWidth(h) },
+                { w -> maxIntrinsicHeight(w) },
+                availableHeight,
+                LayoutOrientation.Horizontal,
+                LayoutOrientation.Horizontal
+            )
+        }
+    val VerticalMinWidth: (List<IntrinsicMeasurable>, Int) -> Int =
+        { measurables, availableHeight ->
+            intrinsicSize(
+                measurables,
+                { h -> minIntrinsicWidth(h) },
+                { w -> maxIntrinsicHeight(w) },
+                availableHeight,
+                LayoutOrientation.Vertical,
+                LayoutOrientation.Horizontal
+            )
+        }
+    val HorizontalMinHeight: (List<IntrinsicMeasurable>, Int) -> Int =
+        { measurables, availableWidth ->
+            intrinsicSize(
+                measurables,
+                { w -> minIntrinsicHeight(w) },
+                { h -> maxIntrinsicWidth(h) },
+                availableWidth,
+                LayoutOrientation.Horizontal,
+                LayoutOrientation.Vertical
+            )
+        }
+    val VerticalMinHeight: (List<IntrinsicMeasurable>, Int) -> Int =
+        { measurables, availableWidth ->
+            intrinsicSize(
+                measurables,
+                { w -> minIntrinsicHeight(w) },
+                { h -> maxIntrinsicWidth(h) },
+                availableWidth,
+                LayoutOrientation.Vertical,
+                LayoutOrientation.Vertical
+            )
+        }
+    val HorizontalMaxWidth: (List<IntrinsicMeasurable>, Int) -> Int =
+        { measurables, availableHeight ->
+            intrinsicSize(
+                measurables,
+                { h -> maxIntrinsicWidth(h) },
+                { w -> maxIntrinsicHeight(w) },
+                availableHeight,
+                LayoutOrientation.Horizontal,
+                LayoutOrientation.Horizontal
+            )
+        }
+    val VerticalMaxWidth: (List<IntrinsicMeasurable>, Int) -> Int =
+        { measurables, availableHeight ->
+            intrinsicSize(
+                measurables,
+                { h -> maxIntrinsicWidth(h) },
+                { w -> maxIntrinsicHeight(w) },
+                availableHeight,
+                LayoutOrientation.Vertical,
+                LayoutOrientation.Horizontal
+            )
+        }
+    val HorizontalMaxHeight: (List<IntrinsicMeasurable>, Int) -> Int =
+        { measurables, availableWidth ->
+            intrinsicSize(
+                measurables,
+                { w -> maxIntrinsicHeight(w) },
+                { h -> maxIntrinsicWidth(h) },
+                availableWidth,
+                LayoutOrientation.Horizontal,
+                LayoutOrientation.Vertical
+            )
+        }
+    val VerticalMaxHeight: (List<IntrinsicMeasurable>, Int) -> Int =
+        { measurables, availableWidth ->
+            intrinsicSize(
+                measurables,
+                { w -> maxIntrinsicHeight(w) },
+                { h -> maxIntrinsicWidth(h) },
+                availableWidth,
+                LayoutOrientation.Vertical,
+                LayoutOrientation.Vertical
+            )
+        }
 }
 
 private fun intrinsicSize(
@@ -735,7 +768,7 @@
         val block: (Measured) -> Int,
         inspectorInfo: InspectorInfo.() -> Unit
     ) : SiblingsAlignedModifier(inspectorInfo) {
-        override fun Density.modifyParentData(parentData: Any?): Any? {
+        override fun Density.modifyParentData(parentData: Any?): Any {
             return ((parentData as? RowColumnParentData) ?: RowColumnParentData()).also {
                 it.crossAxisAlignment =
                     CrossAxisAlignment.Relative(AlignmentLineProvider.Block(block))
@@ -754,25 +787,25 @@
     }
 
     internal class WithAlignmentLine(
-        val line: AlignmentLine,
+        val alignmentLine: AlignmentLine,
         inspectorInfo: InspectorInfo.() -> Unit
     ) : SiblingsAlignedModifier(inspectorInfo) {
-        override fun Density.modifyParentData(parentData: Any?): Any? {
+        override fun Density.modifyParentData(parentData: Any?): Any {
             return ((parentData as? RowColumnParentData) ?: RowColumnParentData()).also {
                 it.crossAxisAlignment =
-                    CrossAxisAlignment.Relative(AlignmentLineProvider.Value(line))
+                    CrossAxisAlignment.Relative(AlignmentLineProvider.Value(alignmentLine))
             }
         }
 
         override fun equals(other: Any?): Boolean {
             if (this === other) return true
             val otherModifier = other as? WithAlignmentLine ?: return false
-            return line == otherModifier.line
+            return alignmentLine == otherModifier.alignmentLine
         }
 
-        override fun hashCode(): Int = line.hashCode()
+        override fun hashCode(): Int = alignmentLine.hashCode()
 
-        override fun toString(): String = "WithAlignmentLine(line=$line)"
+        override fun toString(): String = "WithAlignmentLine(line=$alignmentLine)"
     }
 }
 
@@ -832,18 +865,18 @@
  * Provides the alignment line.
  */
 internal sealed class AlignmentLineProvider {
-    abstract fun calculateAlignmentLinePosition(placeable: Placeable): Int?
+    abstract fun calculateAlignmentLinePosition(placeable: Placeable): Int
     data class Block(val lineProviderBlock: (Measured) -> Int) : AlignmentLineProvider() {
         override fun calculateAlignmentLinePosition(
             placeable: Placeable
-        ): Int? {
-            return lineProviderBlock(Measured(placeable))
+        ): Int {
+            return lineProviderBlock(placeable)
         }
     }
 
-    data class Value(val line: AlignmentLine) : AlignmentLineProvider() {
-        override fun calculateAlignmentLinePosition(placeable: Placeable): Int? {
-            return placeable[line]
+    data class Value(val alignmentLine: AlignmentLine) : AlignmentLineProvider() {
+        override fun calculateAlignmentLinePosition(placeable: Placeable): Int {
+            return placeable[alignmentLine]
         }
     }
 }
diff --git a/compose/foundation/foundation/api/current.txt b/compose/foundation/foundation/api/current.txt
index 4339de0..a41db302 100644
--- a/compose/foundation/foundation/api/current.txt
+++ b/compose/foundation/foundation/api/current.txt
@@ -1,6 +1,9 @@
 // Signature format: 4.0
 package androidx.compose.foundation {
 
+  public final class ActualJvmKt {
+  }
+
   public final class BackgroundKt {
     method public static androidx.compose.ui.Modifier background(androidx.compose.ui.Modifier, androidx.compose.ui.graphics.Brush brush, optional androidx.compose.ui.graphics.Shape shape, optional float alpha);
     method public static androidx.compose.ui.Modifier background-1xq40Q0(androidx.compose.ui.Modifier, long color, optional androidx.compose.ui.graphics.Shape shape);
@@ -30,13 +33,9 @@
 
   public final class ClickableKt {
     method public static androidx.compose.ui.Modifier clickable(androidx.compose.ui.Modifier, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-    method public static androidx.compose.ui.Modifier clickable(androidx.compose.ui.Modifier, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+    method public static androidx.compose.ui.Modifier clickable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
     method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier combinedClickable(androidx.compose.ui.Modifier, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, optional String? onLongClickLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onLongClick, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDoubleClick, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier combinedClickable(androidx.compose.ui.Modifier, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, optional String? onLongClickLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onLongClick, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDoubleClick, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-  }
-
-  public final class ClickableTextKt {
-    method @androidx.compose.runtime.Composable public static void ClickableText(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional boolean softWrap, optional androidx.compose.ui.text.style.TextOverflow overflow, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onClick);
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier combinedClickable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, optional String? onLongClickLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onLongClick, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDoubleClick, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
   }
 
   public final class DarkTheme_androidKt {
@@ -47,7 +46,7 @@
   }
 
   public final class FocusableKt {
-    method public static androidx.compose.ui.Modifier focusable(androidx.compose.ui.Modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState? interactionState);
+    method public static androidx.compose.ui.Modifier focusable(androidx.compose.ui.Modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   public final class ImageKt {
@@ -57,7 +56,7 @@
   }
 
   @androidx.compose.runtime.Stable public interface Indication {
-    method @androidx.compose.runtime.Composable public androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.InteractionState interactionState);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.interaction.InteractionSource interactionSource);
   }
 
   public interface IndicationInstance {
@@ -66,32 +65,7 @@
 
   public final class IndicationKt {
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.Indication> getLocalIndication();
-    method public static androidx.compose.ui.Modifier indication(androidx.compose.ui.Modifier, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication);
-  }
-
-  public interface Interaction {
-  }
-
-  public static final class Interaction.Dragged implements androidx.compose.foundation.Interaction {
-    field public static final androidx.compose.foundation.Interaction.Dragged INSTANCE;
-  }
-
-  public static final class Interaction.Focused implements androidx.compose.foundation.Interaction {
-    field public static final androidx.compose.foundation.Interaction.Focused INSTANCE;
-  }
-
-  public static final class Interaction.Pressed implements androidx.compose.foundation.Interaction {
-    field public static final androidx.compose.foundation.Interaction.Pressed INSTANCE;
-  }
-
-  @androidx.compose.runtime.Stable public final class InteractionState implements androidx.compose.runtime.State<java.util.Set<? extends androidx.compose.foundation.Interaction>> {
-    ctor public InteractionState();
-    method public void addInteraction-Jgxim6Q(androidx.compose.foundation.Interaction interaction, optional androidx.compose.ui.geometry.Offset? position);
-    method public operator boolean contains(androidx.compose.foundation.Interaction interaction);
-    method public java.util.Set<androidx.compose.foundation.Interaction> getValue();
-    method public androidx.compose.ui.geometry.Offset? interactionPositionFor-_m7T9-E(androidx.compose.foundation.Interaction interaction);
-    method public void removeInteraction(androidx.compose.foundation.Interaction interaction);
-    property public java.util.Set<androidx.compose.foundation.Interaction> value;
+    method public static androidx.compose.ui.Modifier indication(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.foundation.Indication? indication);
   }
 
   @kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget}) public @interface InternalFoundationApi {
@@ -124,13 +98,13 @@
     ctor public ScrollState(int initial);
     method public suspend Object? animateScrollTo(int value, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public float dispatchRawDelta(float delta);
-    method public androidx.compose.foundation.InteractionState getInteractionState();
+    method public androidx.compose.foundation.interaction.InteractionSource getInteractionSource();
     method public int getMaxValue();
     method public int getValue();
     method public boolean isScrollInProgress();
     method public suspend Object? scroll(androidx.compose.foundation.MutatePriority scrollPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.ScrollScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public suspend Object? scrollTo(int value, kotlin.coroutines.Continuation<? super java.lang.Float> p);
-    property public final androidx.compose.foundation.InteractionState interactionState;
+    property public final androidx.compose.foundation.interaction.InteractionSource interactionSource;
     property public boolean isScrollInProgress;
     property public final int maxValue;
     property public final int value;
@@ -156,10 +130,10 @@
     method public static suspend Object? awaitTouchSlopOrCancellation-qFc19kk(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onTouchSlopReached, kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange> p);
     method public static suspend Object? awaitVerticalDragOrCancellation-ijcpFGM(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange> p);
     method public static suspend Object? awaitVerticalTouchSlopOrCancellation-qFc19kk(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onTouchSlopReached, kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange> p);
-    method public static suspend Object? detectDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
-    method public static suspend Object? detectDragGesturesAfterLongPress(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
-    method public static suspend Object? detectHorizontalDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onHorizontalDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
-    method public static suspend Object? detectVerticalDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onVerticalDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public static suspend Object? detectDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public static suspend Object? detectDragGesturesAfterLongPress(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public static suspend Object? detectHorizontalDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onHorizontalDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public static suspend Object? detectVerticalDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onVerticalDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public static suspend Object? drag-Pd94rOk(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.pointer.PointerInputChange,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super java.lang.Boolean> p);
     method public static suspend Object? horizontalDrag-Pd94rOk(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.pointer.PointerInputChange,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super java.lang.Boolean> p);
     method public static suspend Object? verticalDrag-Pd94rOk(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.pointer.PointerInputChange,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super java.lang.Boolean> p);
@@ -171,7 +145,7 @@
 
   public final class DraggableKt {
     method public static androidx.compose.foundation.gestures.DraggableState DraggableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onDelta);
-    method public static androidx.compose.ui.Modifier draggable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.DraggableState state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional androidx.compose.foundation.InteractionState? interactionState, optional boolean startDragImmediately, optional kotlin.jvm.functions.Function3<? super kotlinx.coroutines.CoroutineScope,? super androidx.compose.ui.geometry.Offset,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onDragStarted, optional kotlin.jvm.functions.Function3<? super kotlinx.coroutines.CoroutineScope,? super java.lang.Float,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onDragStopped, optional boolean reverseDirection);
+    method public static androidx.compose.ui.Modifier draggable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.DraggableState state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional boolean startDragImmediately, optional kotlin.jvm.functions.Function3<? super kotlinx.coroutines.CoroutineScope,? super androidx.compose.ui.geometry.Offset,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onDragStarted, optional kotlin.jvm.functions.Function3<? super kotlinx.coroutines.CoroutineScope,? super java.lang.Float,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onDragStopped, optional boolean reverseDirection);
     method @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.DraggableState rememberDraggableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onDelta);
   }
 
@@ -219,7 +193,7 @@
   }
 
   public final class ScrollableKt {
-    method public static androidx.compose.ui.Modifier scrollable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.ScrollableState state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.gestures.FlingBehavior? flingBehavior, optional androidx.compose.foundation.InteractionState? interactionState);
+    method public static androidx.compose.ui.Modifier scrollable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.ScrollableState state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.gestures.FlingBehavior? flingBehavior, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   public interface ScrollableState {
@@ -277,6 +251,91 @@
 
 }
 
+package androidx.compose.foundation.interaction {
+
+  public interface DragInteraction extends androidx.compose.foundation.interaction.Interaction {
+  }
+
+  public static final class DragInteraction.Cancel implements androidx.compose.foundation.interaction.DragInteraction {
+    ctor public DragInteraction.Cancel(androidx.compose.foundation.interaction.DragInteraction.Start start);
+    method public androidx.compose.foundation.interaction.DragInteraction.Start getStart();
+    property public final androidx.compose.foundation.interaction.DragInteraction.Start start;
+  }
+
+  public static final class DragInteraction.Start implements androidx.compose.foundation.interaction.DragInteraction {
+    ctor public DragInteraction.Start();
+  }
+
+  public static final class DragInteraction.Stop implements androidx.compose.foundation.interaction.DragInteraction {
+    ctor public DragInteraction.Stop(androidx.compose.foundation.interaction.DragInteraction.Start start);
+    method public androidx.compose.foundation.interaction.DragInteraction.Start getStart();
+    property public final androidx.compose.foundation.interaction.DragInteraction.Start start;
+  }
+
+  public final class DragInteractionKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> collectIsDraggedAsState(androidx.compose.foundation.interaction.InteractionSource);
+  }
+
+  public interface FocusInteraction extends androidx.compose.foundation.interaction.Interaction {
+  }
+
+  public static final class FocusInteraction.Focus implements androidx.compose.foundation.interaction.FocusInteraction {
+    ctor public FocusInteraction.Focus();
+  }
+
+  public static final class FocusInteraction.Unfocus implements androidx.compose.foundation.interaction.FocusInteraction {
+    ctor public FocusInteraction.Unfocus(androidx.compose.foundation.interaction.FocusInteraction.Focus focus);
+    method public androidx.compose.foundation.interaction.FocusInteraction.Focus getFocus();
+    property public final androidx.compose.foundation.interaction.FocusInteraction.Focus focus;
+  }
+
+  public final class FocusInteractionKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> collectIsFocusedAsState(androidx.compose.foundation.interaction.InteractionSource);
+  }
+
+  public interface Interaction {
+  }
+
+  @androidx.compose.runtime.Stable public interface InteractionSource {
+    method public kotlinx.coroutines.flow.Flow<androidx.compose.foundation.interaction.Interaction> getInteractions();
+    property public abstract kotlinx.coroutines.flow.Flow<androidx.compose.foundation.interaction.Interaction> interactions;
+  }
+
+  public final class InteractionSourceKt {
+    method public static androidx.compose.foundation.interaction.MutableInteractionSource MutableInteractionSource();
+  }
+
+  @androidx.compose.runtime.Stable public interface MutableInteractionSource extends androidx.compose.foundation.interaction.InteractionSource {
+    method public suspend Object? emit(androidx.compose.foundation.interaction.Interaction interaction, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public boolean tryEmit(androidx.compose.foundation.interaction.Interaction interaction);
+  }
+
+  public interface PressInteraction extends androidx.compose.foundation.interaction.Interaction {
+  }
+
+  public static final class PressInteraction.Cancel implements androidx.compose.foundation.interaction.PressInteraction {
+    ctor public PressInteraction.Cancel(androidx.compose.foundation.interaction.PressInteraction.Press press);
+    method public androidx.compose.foundation.interaction.PressInteraction.Press getPress();
+    property public final androidx.compose.foundation.interaction.PressInteraction.Press press;
+  }
+
+  public static final class PressInteraction.Press implements androidx.compose.foundation.interaction.PressInteraction {
+    method public long getPressPosition-F1C5BW0();
+    property public final long pressPosition;
+  }
+
+  public static final class PressInteraction.Release implements androidx.compose.foundation.interaction.PressInteraction {
+    ctor public PressInteraction.Release(androidx.compose.foundation.interaction.PressInteraction.Press press);
+    method public androidx.compose.foundation.interaction.PressInteraction.Press getPress();
+    property public final androidx.compose.foundation.interaction.PressInteraction.Press press;
+  }
+
+  public final class PressInteractionKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> collectIsPressedAsState(androidx.compose.foundation.interaction.InteractionSource);
+  }
+
+}
+
 package androidx.compose.foundation.lazy {
 
   public final class CachingItemContentFactoryKt {
@@ -368,14 +427,14 @@
     method public float dispatchRawDelta(float delta);
     method public int getFirstVisibleItemIndex();
     method public int getFirstVisibleItemScrollOffset();
-    method public androidx.compose.foundation.InteractionState getInteractionState();
+    method public androidx.compose.foundation.interaction.InteractionSource getInteractionSource();
     method public androidx.compose.foundation.lazy.LazyListLayoutInfo getLayoutInfo();
     method public boolean isScrollInProgress();
     method public suspend Object? scroll(androidx.compose.foundation.MutatePriority scrollPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.ScrollScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public suspend Object? scrollToItem(int index, optional int scrollOffset, optional kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final int firstVisibleItemIndex;
     property public final int firstVisibleItemScrollOffset;
-    property public final androidx.compose.foundation.InteractionState interactionState;
+    property public final androidx.compose.foundation.interaction.InteractionSource interactionSource;
     property public boolean isScrollInProgress;
     property public final androidx.compose.foundation.lazy.LazyListLayoutInfo layoutInfo;
     field public static final androidx.compose.foundation.lazy.LazyListState.Companion Companion;
@@ -410,16 +469,20 @@
 
 package androidx.compose.foundation.selection {
 
+  public final class SelectableGroupKt {
+    method public static androidx.compose.ui.Modifier selectableGroup(androidx.compose.ui.Modifier);
+  }
+
   public final class SelectableKt {
     method public static androidx.compose.ui.Modifier selectable(androidx.compose.ui.Modifier, boolean selected, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-    method public static androidx.compose.ui.Modifier selectable(androidx.compose.ui.Modifier, boolean selected, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+    method public static androidx.compose.ui.Modifier selectable(androidx.compose.ui.Modifier, boolean selected, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
   }
 
   public final class ToggleableKt {
     method public static androidx.compose.ui.Modifier toggleable(androidx.compose.ui.Modifier, boolean value, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onValueChange);
-    method public static androidx.compose.ui.Modifier toggleable(androidx.compose.ui.Modifier, boolean value, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onValueChange);
+    method public static androidx.compose.ui.Modifier toggleable(androidx.compose.ui.Modifier, boolean value, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onValueChange);
     method public static androidx.compose.ui.Modifier triStateToggleable(androidx.compose.ui.Modifier, androidx.compose.ui.state.ToggleableState state, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-    method public static androidx.compose.ui.Modifier triStateToggleable(androidx.compose.ui.Modifier, androidx.compose.ui.state.ToggleableState state, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+    method public static androidx.compose.ui.Modifier triStateToggleable(androidx.compose.ui.Modifier, androidx.compose.ui.state.ToggleableState state, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
   }
 
 }
@@ -531,8 +594,8 @@
   }
 
   public final class BasicTextFieldKt {
-    method @androidx.compose.runtime.Composable public static void BasicTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.ui.graphics.Brush cursorBrush, optional kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> decorationBox);
-    method @androidx.compose.runtime.Composable public static void BasicTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.ui.graphics.Brush cursorBrush, optional kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> decorationBox);
+    method @androidx.compose.runtime.Composable public static void BasicTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Brush cursorBrush, optional kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> decorationBox);
+    method @androidx.compose.runtime.Composable public static void BasicTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Brush cursorBrush, optional kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> decorationBox);
   }
 
   public final class BasicTextKt {
@@ -540,15 +603,16 @@
     method @androidx.compose.runtime.Composable public static void BasicText(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.style.TextOverflow overflow, optional boolean softWrap, optional int maxLines, optional java.util.Map<java.lang.String,androidx.compose.foundation.text.InlineTextContent> inlineContent);
   }
 
+  public final class ClickableTextKt {
+    method @androidx.compose.runtime.Composable public static void ClickableText(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional boolean softWrap, optional androidx.compose.ui.text.style.TextOverflow overflow, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onClick);
+  }
+
   public final class CoreTextFieldKt {
   }
 
   public final class CoreTextKt {
   }
 
-  public final class InactiveTextFieldKt {
-  }
-
   @androidx.compose.runtime.Immutable public final class InlineTextContent {
     ctor public InlineTextContent(androidx.compose.ui.text.Placeholder placeholder, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> children);
     method public kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit> getChildren();
@@ -639,6 +703,9 @@
   public final class TextLayoutResultProxyKt {
   }
 
+  public final class TouchMode_androidKt {
+  }
+
 }
 
 package androidx.compose.foundation.text.selection {
@@ -660,6 +727,9 @@
   public final class SelectionManagerKt {
   }
 
+  public final class SelectionManager_androidKt {
+  }
+
   public final class SelectionRegistrarKt {
   }
 
diff --git a/compose/foundation/foundation/api/public_plus_experimental_current.txt b/compose/foundation/foundation/api/public_plus_experimental_current.txt
index 4339de0..a41db302 100644
--- a/compose/foundation/foundation/api/public_plus_experimental_current.txt
+++ b/compose/foundation/foundation/api/public_plus_experimental_current.txt
@@ -1,6 +1,9 @@
 // Signature format: 4.0
 package androidx.compose.foundation {
 
+  public final class ActualJvmKt {
+  }
+
   public final class BackgroundKt {
     method public static androidx.compose.ui.Modifier background(androidx.compose.ui.Modifier, androidx.compose.ui.graphics.Brush brush, optional androidx.compose.ui.graphics.Shape shape, optional float alpha);
     method public static androidx.compose.ui.Modifier background-1xq40Q0(androidx.compose.ui.Modifier, long color, optional androidx.compose.ui.graphics.Shape shape);
@@ -30,13 +33,9 @@
 
   public final class ClickableKt {
     method public static androidx.compose.ui.Modifier clickable(androidx.compose.ui.Modifier, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-    method public static androidx.compose.ui.Modifier clickable(androidx.compose.ui.Modifier, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+    method public static androidx.compose.ui.Modifier clickable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
     method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier combinedClickable(androidx.compose.ui.Modifier, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, optional String? onLongClickLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onLongClick, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDoubleClick, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier combinedClickable(androidx.compose.ui.Modifier, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, optional String? onLongClickLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onLongClick, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDoubleClick, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-  }
-
-  public final class ClickableTextKt {
-    method @androidx.compose.runtime.Composable public static void ClickableText(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional boolean softWrap, optional androidx.compose.ui.text.style.TextOverflow overflow, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onClick);
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier combinedClickable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, optional String? onLongClickLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onLongClick, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDoubleClick, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
   }
 
   public final class DarkTheme_androidKt {
@@ -47,7 +46,7 @@
   }
 
   public final class FocusableKt {
-    method public static androidx.compose.ui.Modifier focusable(androidx.compose.ui.Modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState? interactionState);
+    method public static androidx.compose.ui.Modifier focusable(androidx.compose.ui.Modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   public final class ImageKt {
@@ -57,7 +56,7 @@
   }
 
   @androidx.compose.runtime.Stable public interface Indication {
-    method @androidx.compose.runtime.Composable public androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.InteractionState interactionState);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.interaction.InteractionSource interactionSource);
   }
 
   public interface IndicationInstance {
@@ -66,32 +65,7 @@
 
   public final class IndicationKt {
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.Indication> getLocalIndication();
-    method public static androidx.compose.ui.Modifier indication(androidx.compose.ui.Modifier, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication);
-  }
-
-  public interface Interaction {
-  }
-
-  public static final class Interaction.Dragged implements androidx.compose.foundation.Interaction {
-    field public static final androidx.compose.foundation.Interaction.Dragged INSTANCE;
-  }
-
-  public static final class Interaction.Focused implements androidx.compose.foundation.Interaction {
-    field public static final androidx.compose.foundation.Interaction.Focused INSTANCE;
-  }
-
-  public static final class Interaction.Pressed implements androidx.compose.foundation.Interaction {
-    field public static final androidx.compose.foundation.Interaction.Pressed INSTANCE;
-  }
-
-  @androidx.compose.runtime.Stable public final class InteractionState implements androidx.compose.runtime.State<java.util.Set<? extends androidx.compose.foundation.Interaction>> {
-    ctor public InteractionState();
-    method public void addInteraction-Jgxim6Q(androidx.compose.foundation.Interaction interaction, optional androidx.compose.ui.geometry.Offset? position);
-    method public operator boolean contains(androidx.compose.foundation.Interaction interaction);
-    method public java.util.Set<androidx.compose.foundation.Interaction> getValue();
-    method public androidx.compose.ui.geometry.Offset? interactionPositionFor-_m7T9-E(androidx.compose.foundation.Interaction interaction);
-    method public void removeInteraction(androidx.compose.foundation.Interaction interaction);
-    property public java.util.Set<androidx.compose.foundation.Interaction> value;
+    method public static androidx.compose.ui.Modifier indication(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.foundation.Indication? indication);
   }
 
   @kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget}) public @interface InternalFoundationApi {
@@ -124,13 +98,13 @@
     ctor public ScrollState(int initial);
     method public suspend Object? animateScrollTo(int value, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public float dispatchRawDelta(float delta);
-    method public androidx.compose.foundation.InteractionState getInteractionState();
+    method public androidx.compose.foundation.interaction.InteractionSource getInteractionSource();
     method public int getMaxValue();
     method public int getValue();
     method public boolean isScrollInProgress();
     method public suspend Object? scroll(androidx.compose.foundation.MutatePriority scrollPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.ScrollScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public suspend Object? scrollTo(int value, kotlin.coroutines.Continuation<? super java.lang.Float> p);
-    property public final androidx.compose.foundation.InteractionState interactionState;
+    property public final androidx.compose.foundation.interaction.InteractionSource interactionSource;
     property public boolean isScrollInProgress;
     property public final int maxValue;
     property public final int value;
@@ -156,10 +130,10 @@
     method public static suspend Object? awaitTouchSlopOrCancellation-qFc19kk(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onTouchSlopReached, kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange> p);
     method public static suspend Object? awaitVerticalDragOrCancellation-ijcpFGM(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange> p);
     method public static suspend Object? awaitVerticalTouchSlopOrCancellation-qFc19kk(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onTouchSlopReached, kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange> p);
-    method public static suspend Object? detectDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
-    method public static suspend Object? detectDragGesturesAfterLongPress(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
-    method public static suspend Object? detectHorizontalDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onHorizontalDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
-    method public static suspend Object? detectVerticalDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onVerticalDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public static suspend Object? detectDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public static suspend Object? detectDragGesturesAfterLongPress(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public static suspend Object? detectHorizontalDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onHorizontalDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public static suspend Object? detectVerticalDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onVerticalDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public static suspend Object? drag-Pd94rOk(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.pointer.PointerInputChange,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super java.lang.Boolean> p);
     method public static suspend Object? horizontalDrag-Pd94rOk(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.pointer.PointerInputChange,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super java.lang.Boolean> p);
     method public static suspend Object? verticalDrag-Pd94rOk(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.pointer.PointerInputChange,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super java.lang.Boolean> p);
@@ -171,7 +145,7 @@
 
   public final class DraggableKt {
     method public static androidx.compose.foundation.gestures.DraggableState DraggableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onDelta);
-    method public static androidx.compose.ui.Modifier draggable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.DraggableState state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional androidx.compose.foundation.InteractionState? interactionState, optional boolean startDragImmediately, optional kotlin.jvm.functions.Function3<? super kotlinx.coroutines.CoroutineScope,? super androidx.compose.ui.geometry.Offset,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onDragStarted, optional kotlin.jvm.functions.Function3<? super kotlinx.coroutines.CoroutineScope,? super java.lang.Float,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onDragStopped, optional boolean reverseDirection);
+    method public static androidx.compose.ui.Modifier draggable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.DraggableState state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional boolean startDragImmediately, optional kotlin.jvm.functions.Function3<? super kotlinx.coroutines.CoroutineScope,? super androidx.compose.ui.geometry.Offset,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onDragStarted, optional kotlin.jvm.functions.Function3<? super kotlinx.coroutines.CoroutineScope,? super java.lang.Float,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onDragStopped, optional boolean reverseDirection);
     method @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.DraggableState rememberDraggableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onDelta);
   }
 
@@ -219,7 +193,7 @@
   }
 
   public final class ScrollableKt {
-    method public static androidx.compose.ui.Modifier scrollable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.ScrollableState state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.gestures.FlingBehavior? flingBehavior, optional androidx.compose.foundation.InteractionState? interactionState);
+    method public static androidx.compose.ui.Modifier scrollable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.ScrollableState state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.gestures.FlingBehavior? flingBehavior, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   public interface ScrollableState {
@@ -277,6 +251,91 @@
 
 }
 
+package androidx.compose.foundation.interaction {
+
+  public interface DragInteraction extends androidx.compose.foundation.interaction.Interaction {
+  }
+
+  public static final class DragInteraction.Cancel implements androidx.compose.foundation.interaction.DragInteraction {
+    ctor public DragInteraction.Cancel(androidx.compose.foundation.interaction.DragInteraction.Start start);
+    method public androidx.compose.foundation.interaction.DragInteraction.Start getStart();
+    property public final androidx.compose.foundation.interaction.DragInteraction.Start start;
+  }
+
+  public static final class DragInteraction.Start implements androidx.compose.foundation.interaction.DragInteraction {
+    ctor public DragInteraction.Start();
+  }
+
+  public static final class DragInteraction.Stop implements androidx.compose.foundation.interaction.DragInteraction {
+    ctor public DragInteraction.Stop(androidx.compose.foundation.interaction.DragInteraction.Start start);
+    method public androidx.compose.foundation.interaction.DragInteraction.Start getStart();
+    property public final androidx.compose.foundation.interaction.DragInteraction.Start start;
+  }
+
+  public final class DragInteractionKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> collectIsDraggedAsState(androidx.compose.foundation.interaction.InteractionSource);
+  }
+
+  public interface FocusInteraction extends androidx.compose.foundation.interaction.Interaction {
+  }
+
+  public static final class FocusInteraction.Focus implements androidx.compose.foundation.interaction.FocusInteraction {
+    ctor public FocusInteraction.Focus();
+  }
+
+  public static final class FocusInteraction.Unfocus implements androidx.compose.foundation.interaction.FocusInteraction {
+    ctor public FocusInteraction.Unfocus(androidx.compose.foundation.interaction.FocusInteraction.Focus focus);
+    method public androidx.compose.foundation.interaction.FocusInteraction.Focus getFocus();
+    property public final androidx.compose.foundation.interaction.FocusInteraction.Focus focus;
+  }
+
+  public final class FocusInteractionKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> collectIsFocusedAsState(androidx.compose.foundation.interaction.InteractionSource);
+  }
+
+  public interface Interaction {
+  }
+
+  @androidx.compose.runtime.Stable public interface InteractionSource {
+    method public kotlinx.coroutines.flow.Flow<androidx.compose.foundation.interaction.Interaction> getInteractions();
+    property public abstract kotlinx.coroutines.flow.Flow<androidx.compose.foundation.interaction.Interaction> interactions;
+  }
+
+  public final class InteractionSourceKt {
+    method public static androidx.compose.foundation.interaction.MutableInteractionSource MutableInteractionSource();
+  }
+
+  @androidx.compose.runtime.Stable public interface MutableInteractionSource extends androidx.compose.foundation.interaction.InteractionSource {
+    method public suspend Object? emit(androidx.compose.foundation.interaction.Interaction interaction, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public boolean tryEmit(androidx.compose.foundation.interaction.Interaction interaction);
+  }
+
+  public interface PressInteraction extends androidx.compose.foundation.interaction.Interaction {
+  }
+
+  public static final class PressInteraction.Cancel implements androidx.compose.foundation.interaction.PressInteraction {
+    ctor public PressInteraction.Cancel(androidx.compose.foundation.interaction.PressInteraction.Press press);
+    method public androidx.compose.foundation.interaction.PressInteraction.Press getPress();
+    property public final androidx.compose.foundation.interaction.PressInteraction.Press press;
+  }
+
+  public static final class PressInteraction.Press implements androidx.compose.foundation.interaction.PressInteraction {
+    method public long getPressPosition-F1C5BW0();
+    property public final long pressPosition;
+  }
+
+  public static final class PressInteraction.Release implements androidx.compose.foundation.interaction.PressInteraction {
+    ctor public PressInteraction.Release(androidx.compose.foundation.interaction.PressInteraction.Press press);
+    method public androidx.compose.foundation.interaction.PressInteraction.Press getPress();
+    property public final androidx.compose.foundation.interaction.PressInteraction.Press press;
+  }
+
+  public final class PressInteractionKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> collectIsPressedAsState(androidx.compose.foundation.interaction.InteractionSource);
+  }
+
+}
+
 package androidx.compose.foundation.lazy {
 
   public final class CachingItemContentFactoryKt {
@@ -368,14 +427,14 @@
     method public float dispatchRawDelta(float delta);
     method public int getFirstVisibleItemIndex();
     method public int getFirstVisibleItemScrollOffset();
-    method public androidx.compose.foundation.InteractionState getInteractionState();
+    method public androidx.compose.foundation.interaction.InteractionSource getInteractionSource();
     method public androidx.compose.foundation.lazy.LazyListLayoutInfo getLayoutInfo();
     method public boolean isScrollInProgress();
     method public suspend Object? scroll(androidx.compose.foundation.MutatePriority scrollPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.ScrollScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public suspend Object? scrollToItem(int index, optional int scrollOffset, optional kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final int firstVisibleItemIndex;
     property public final int firstVisibleItemScrollOffset;
-    property public final androidx.compose.foundation.InteractionState interactionState;
+    property public final androidx.compose.foundation.interaction.InteractionSource interactionSource;
     property public boolean isScrollInProgress;
     property public final androidx.compose.foundation.lazy.LazyListLayoutInfo layoutInfo;
     field public static final androidx.compose.foundation.lazy.LazyListState.Companion Companion;
@@ -410,16 +469,20 @@
 
 package androidx.compose.foundation.selection {
 
+  public final class SelectableGroupKt {
+    method public static androidx.compose.ui.Modifier selectableGroup(androidx.compose.ui.Modifier);
+  }
+
   public final class SelectableKt {
     method public static androidx.compose.ui.Modifier selectable(androidx.compose.ui.Modifier, boolean selected, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-    method public static androidx.compose.ui.Modifier selectable(androidx.compose.ui.Modifier, boolean selected, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+    method public static androidx.compose.ui.Modifier selectable(androidx.compose.ui.Modifier, boolean selected, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
   }
 
   public final class ToggleableKt {
     method public static androidx.compose.ui.Modifier toggleable(androidx.compose.ui.Modifier, boolean value, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onValueChange);
-    method public static androidx.compose.ui.Modifier toggleable(androidx.compose.ui.Modifier, boolean value, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onValueChange);
+    method public static androidx.compose.ui.Modifier toggleable(androidx.compose.ui.Modifier, boolean value, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onValueChange);
     method public static androidx.compose.ui.Modifier triStateToggleable(androidx.compose.ui.Modifier, androidx.compose.ui.state.ToggleableState state, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-    method public static androidx.compose.ui.Modifier triStateToggleable(androidx.compose.ui.Modifier, androidx.compose.ui.state.ToggleableState state, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+    method public static androidx.compose.ui.Modifier triStateToggleable(androidx.compose.ui.Modifier, androidx.compose.ui.state.ToggleableState state, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
   }
 
 }
@@ -531,8 +594,8 @@
   }
 
   public final class BasicTextFieldKt {
-    method @androidx.compose.runtime.Composable public static void BasicTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.ui.graphics.Brush cursorBrush, optional kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> decorationBox);
-    method @androidx.compose.runtime.Composable public static void BasicTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.ui.graphics.Brush cursorBrush, optional kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> decorationBox);
+    method @androidx.compose.runtime.Composable public static void BasicTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Brush cursorBrush, optional kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> decorationBox);
+    method @androidx.compose.runtime.Composable public static void BasicTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Brush cursorBrush, optional kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> decorationBox);
   }
 
   public final class BasicTextKt {
@@ -540,15 +603,16 @@
     method @androidx.compose.runtime.Composable public static void BasicText(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.style.TextOverflow overflow, optional boolean softWrap, optional int maxLines, optional java.util.Map<java.lang.String,androidx.compose.foundation.text.InlineTextContent> inlineContent);
   }
 
+  public final class ClickableTextKt {
+    method @androidx.compose.runtime.Composable public static void ClickableText(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional boolean softWrap, optional androidx.compose.ui.text.style.TextOverflow overflow, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onClick);
+  }
+
   public final class CoreTextFieldKt {
   }
 
   public final class CoreTextKt {
   }
 
-  public final class InactiveTextFieldKt {
-  }
-
   @androidx.compose.runtime.Immutable public final class InlineTextContent {
     ctor public InlineTextContent(androidx.compose.ui.text.Placeholder placeholder, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> children);
     method public kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit> getChildren();
@@ -639,6 +703,9 @@
   public final class TextLayoutResultProxyKt {
   }
 
+  public final class TouchMode_androidKt {
+  }
+
 }
 
 package androidx.compose.foundation.text.selection {
@@ -660,6 +727,9 @@
   public final class SelectionManagerKt {
   }
 
+  public final class SelectionManager_androidKt {
+  }
+
   public final class SelectionRegistrarKt {
   }
 
diff --git a/compose/foundation/foundation/api/restricted_current.txt b/compose/foundation/foundation/api/restricted_current.txt
index 4339de0..a41db302 100644
--- a/compose/foundation/foundation/api/restricted_current.txt
+++ b/compose/foundation/foundation/api/restricted_current.txt
@@ -1,6 +1,9 @@
 // Signature format: 4.0
 package androidx.compose.foundation {
 
+  public final class ActualJvmKt {
+  }
+
   public final class BackgroundKt {
     method public static androidx.compose.ui.Modifier background(androidx.compose.ui.Modifier, androidx.compose.ui.graphics.Brush brush, optional androidx.compose.ui.graphics.Shape shape, optional float alpha);
     method public static androidx.compose.ui.Modifier background-1xq40Q0(androidx.compose.ui.Modifier, long color, optional androidx.compose.ui.graphics.Shape shape);
@@ -30,13 +33,9 @@
 
   public final class ClickableKt {
     method public static androidx.compose.ui.Modifier clickable(androidx.compose.ui.Modifier, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-    method public static androidx.compose.ui.Modifier clickable(androidx.compose.ui.Modifier, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+    method public static androidx.compose.ui.Modifier clickable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
     method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier combinedClickable(androidx.compose.ui.Modifier, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, optional String? onLongClickLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onLongClick, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDoubleClick, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier combinedClickable(androidx.compose.ui.Modifier, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, optional String? onLongClickLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onLongClick, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDoubleClick, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-  }
-
-  public final class ClickableTextKt {
-    method @androidx.compose.runtime.Composable public static void ClickableText(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional boolean softWrap, optional androidx.compose.ui.text.style.TextOverflow overflow, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onClick);
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier combinedClickable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, optional String? onLongClickLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onLongClick, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDoubleClick, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
   }
 
   public final class DarkTheme_androidKt {
@@ -47,7 +46,7 @@
   }
 
   public final class FocusableKt {
-    method public static androidx.compose.ui.Modifier focusable(androidx.compose.ui.Modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState? interactionState);
+    method public static androidx.compose.ui.Modifier focusable(androidx.compose.ui.Modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   public final class ImageKt {
@@ -57,7 +56,7 @@
   }
 
   @androidx.compose.runtime.Stable public interface Indication {
-    method @androidx.compose.runtime.Composable public androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.InteractionState interactionState);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.interaction.InteractionSource interactionSource);
   }
 
   public interface IndicationInstance {
@@ -66,32 +65,7 @@
 
   public final class IndicationKt {
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.Indication> getLocalIndication();
-    method public static androidx.compose.ui.Modifier indication(androidx.compose.ui.Modifier, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication);
-  }
-
-  public interface Interaction {
-  }
-
-  public static final class Interaction.Dragged implements androidx.compose.foundation.Interaction {
-    field public static final androidx.compose.foundation.Interaction.Dragged INSTANCE;
-  }
-
-  public static final class Interaction.Focused implements androidx.compose.foundation.Interaction {
-    field public static final androidx.compose.foundation.Interaction.Focused INSTANCE;
-  }
-
-  public static final class Interaction.Pressed implements androidx.compose.foundation.Interaction {
-    field public static final androidx.compose.foundation.Interaction.Pressed INSTANCE;
-  }
-
-  @androidx.compose.runtime.Stable public final class InteractionState implements androidx.compose.runtime.State<java.util.Set<? extends androidx.compose.foundation.Interaction>> {
-    ctor public InteractionState();
-    method public void addInteraction-Jgxim6Q(androidx.compose.foundation.Interaction interaction, optional androidx.compose.ui.geometry.Offset? position);
-    method public operator boolean contains(androidx.compose.foundation.Interaction interaction);
-    method public java.util.Set<androidx.compose.foundation.Interaction> getValue();
-    method public androidx.compose.ui.geometry.Offset? interactionPositionFor-_m7T9-E(androidx.compose.foundation.Interaction interaction);
-    method public void removeInteraction(androidx.compose.foundation.Interaction interaction);
-    property public java.util.Set<androidx.compose.foundation.Interaction> value;
+    method public static androidx.compose.ui.Modifier indication(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.foundation.Indication? indication);
   }
 
   @kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget}) public @interface InternalFoundationApi {
@@ -124,13 +98,13 @@
     ctor public ScrollState(int initial);
     method public suspend Object? animateScrollTo(int value, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public float dispatchRawDelta(float delta);
-    method public androidx.compose.foundation.InteractionState getInteractionState();
+    method public androidx.compose.foundation.interaction.InteractionSource getInteractionSource();
     method public int getMaxValue();
     method public int getValue();
     method public boolean isScrollInProgress();
     method public suspend Object? scroll(androidx.compose.foundation.MutatePriority scrollPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.ScrollScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public suspend Object? scrollTo(int value, kotlin.coroutines.Continuation<? super java.lang.Float> p);
-    property public final androidx.compose.foundation.InteractionState interactionState;
+    property public final androidx.compose.foundation.interaction.InteractionSource interactionSource;
     property public boolean isScrollInProgress;
     property public final int maxValue;
     property public final int value;
@@ -156,10 +130,10 @@
     method public static suspend Object? awaitTouchSlopOrCancellation-qFc19kk(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onTouchSlopReached, kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange> p);
     method public static suspend Object? awaitVerticalDragOrCancellation-ijcpFGM(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange> p);
     method public static suspend Object? awaitVerticalTouchSlopOrCancellation-qFc19kk(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onTouchSlopReached, kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange> p);
-    method public static suspend Object? detectDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
-    method public static suspend Object? detectDragGesturesAfterLongPress(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
-    method public static suspend Object? detectHorizontalDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onHorizontalDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
-    method public static suspend Object? detectVerticalDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onVerticalDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public static suspend Object? detectDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public static suspend Object? detectDragGesturesAfterLongPress(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public static suspend Object? detectHorizontalDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onHorizontalDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public static suspend Object? detectVerticalDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onVerticalDrag, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public static suspend Object? drag-Pd94rOk(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.pointer.PointerInputChange,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super java.lang.Boolean> p);
     method public static suspend Object? horizontalDrag-Pd94rOk(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.pointer.PointerInputChange,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super java.lang.Boolean> p);
     method public static suspend Object? verticalDrag-Pd94rOk(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.pointer.PointerInputChange,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super java.lang.Boolean> p);
@@ -171,7 +145,7 @@
 
   public final class DraggableKt {
     method public static androidx.compose.foundation.gestures.DraggableState DraggableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onDelta);
-    method public static androidx.compose.ui.Modifier draggable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.DraggableState state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional androidx.compose.foundation.InteractionState? interactionState, optional boolean startDragImmediately, optional kotlin.jvm.functions.Function3<? super kotlinx.coroutines.CoroutineScope,? super androidx.compose.ui.geometry.Offset,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onDragStarted, optional kotlin.jvm.functions.Function3<? super kotlinx.coroutines.CoroutineScope,? super java.lang.Float,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onDragStopped, optional boolean reverseDirection);
+    method public static androidx.compose.ui.Modifier draggable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.DraggableState state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional boolean startDragImmediately, optional kotlin.jvm.functions.Function3<? super kotlinx.coroutines.CoroutineScope,? super androidx.compose.ui.geometry.Offset,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onDragStarted, optional kotlin.jvm.functions.Function3<? super kotlinx.coroutines.CoroutineScope,? super java.lang.Float,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onDragStopped, optional boolean reverseDirection);
     method @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.DraggableState rememberDraggableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onDelta);
   }
 
@@ -219,7 +193,7 @@
   }
 
   public final class ScrollableKt {
-    method public static androidx.compose.ui.Modifier scrollable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.ScrollableState state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.gestures.FlingBehavior? flingBehavior, optional androidx.compose.foundation.InteractionState? interactionState);
+    method public static androidx.compose.ui.Modifier scrollable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.ScrollableState state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.gestures.FlingBehavior? flingBehavior, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   public interface ScrollableState {
@@ -277,6 +251,91 @@
 
 }
 
+package androidx.compose.foundation.interaction {
+
+  public interface DragInteraction extends androidx.compose.foundation.interaction.Interaction {
+  }
+
+  public static final class DragInteraction.Cancel implements androidx.compose.foundation.interaction.DragInteraction {
+    ctor public DragInteraction.Cancel(androidx.compose.foundation.interaction.DragInteraction.Start start);
+    method public androidx.compose.foundation.interaction.DragInteraction.Start getStart();
+    property public final androidx.compose.foundation.interaction.DragInteraction.Start start;
+  }
+
+  public static final class DragInteraction.Start implements androidx.compose.foundation.interaction.DragInteraction {
+    ctor public DragInteraction.Start();
+  }
+
+  public static final class DragInteraction.Stop implements androidx.compose.foundation.interaction.DragInteraction {
+    ctor public DragInteraction.Stop(androidx.compose.foundation.interaction.DragInteraction.Start start);
+    method public androidx.compose.foundation.interaction.DragInteraction.Start getStart();
+    property public final androidx.compose.foundation.interaction.DragInteraction.Start start;
+  }
+
+  public final class DragInteractionKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> collectIsDraggedAsState(androidx.compose.foundation.interaction.InteractionSource);
+  }
+
+  public interface FocusInteraction extends androidx.compose.foundation.interaction.Interaction {
+  }
+
+  public static final class FocusInteraction.Focus implements androidx.compose.foundation.interaction.FocusInteraction {
+    ctor public FocusInteraction.Focus();
+  }
+
+  public static final class FocusInteraction.Unfocus implements androidx.compose.foundation.interaction.FocusInteraction {
+    ctor public FocusInteraction.Unfocus(androidx.compose.foundation.interaction.FocusInteraction.Focus focus);
+    method public androidx.compose.foundation.interaction.FocusInteraction.Focus getFocus();
+    property public final androidx.compose.foundation.interaction.FocusInteraction.Focus focus;
+  }
+
+  public final class FocusInteractionKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> collectIsFocusedAsState(androidx.compose.foundation.interaction.InteractionSource);
+  }
+
+  public interface Interaction {
+  }
+
+  @androidx.compose.runtime.Stable public interface InteractionSource {
+    method public kotlinx.coroutines.flow.Flow<androidx.compose.foundation.interaction.Interaction> getInteractions();
+    property public abstract kotlinx.coroutines.flow.Flow<androidx.compose.foundation.interaction.Interaction> interactions;
+  }
+
+  public final class InteractionSourceKt {
+    method public static androidx.compose.foundation.interaction.MutableInteractionSource MutableInteractionSource();
+  }
+
+  @androidx.compose.runtime.Stable public interface MutableInteractionSource extends androidx.compose.foundation.interaction.InteractionSource {
+    method public suspend Object? emit(androidx.compose.foundation.interaction.Interaction interaction, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public boolean tryEmit(androidx.compose.foundation.interaction.Interaction interaction);
+  }
+
+  public interface PressInteraction extends androidx.compose.foundation.interaction.Interaction {
+  }
+
+  public static final class PressInteraction.Cancel implements androidx.compose.foundation.interaction.PressInteraction {
+    ctor public PressInteraction.Cancel(androidx.compose.foundation.interaction.PressInteraction.Press press);
+    method public androidx.compose.foundation.interaction.PressInteraction.Press getPress();
+    property public final androidx.compose.foundation.interaction.PressInteraction.Press press;
+  }
+
+  public static final class PressInteraction.Press implements androidx.compose.foundation.interaction.PressInteraction {
+    method public long getPressPosition-F1C5BW0();
+    property public final long pressPosition;
+  }
+
+  public static final class PressInteraction.Release implements androidx.compose.foundation.interaction.PressInteraction {
+    ctor public PressInteraction.Release(androidx.compose.foundation.interaction.PressInteraction.Press press);
+    method public androidx.compose.foundation.interaction.PressInteraction.Press getPress();
+    property public final androidx.compose.foundation.interaction.PressInteraction.Press press;
+  }
+
+  public final class PressInteractionKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> collectIsPressedAsState(androidx.compose.foundation.interaction.InteractionSource);
+  }
+
+}
+
 package androidx.compose.foundation.lazy {
 
   public final class CachingItemContentFactoryKt {
@@ -368,14 +427,14 @@
     method public float dispatchRawDelta(float delta);
     method public int getFirstVisibleItemIndex();
     method public int getFirstVisibleItemScrollOffset();
-    method public androidx.compose.foundation.InteractionState getInteractionState();
+    method public androidx.compose.foundation.interaction.InteractionSource getInteractionSource();
     method public androidx.compose.foundation.lazy.LazyListLayoutInfo getLayoutInfo();
     method public boolean isScrollInProgress();
     method public suspend Object? scroll(androidx.compose.foundation.MutatePriority scrollPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.ScrollScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public suspend Object? scrollToItem(int index, optional int scrollOffset, optional kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final int firstVisibleItemIndex;
     property public final int firstVisibleItemScrollOffset;
-    property public final androidx.compose.foundation.InteractionState interactionState;
+    property public final androidx.compose.foundation.interaction.InteractionSource interactionSource;
     property public boolean isScrollInProgress;
     property public final androidx.compose.foundation.lazy.LazyListLayoutInfo layoutInfo;
     field public static final androidx.compose.foundation.lazy.LazyListState.Companion Companion;
@@ -410,16 +469,20 @@
 
 package androidx.compose.foundation.selection {
 
+  public final class SelectableGroupKt {
+    method public static androidx.compose.ui.Modifier selectableGroup(androidx.compose.ui.Modifier);
+  }
+
   public final class SelectableKt {
     method public static androidx.compose.ui.Modifier selectable(androidx.compose.ui.Modifier, boolean selected, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-    method public static androidx.compose.ui.Modifier selectable(androidx.compose.ui.Modifier, boolean selected, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+    method public static androidx.compose.ui.Modifier selectable(androidx.compose.ui.Modifier, boolean selected, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
   }
 
   public final class ToggleableKt {
     method public static androidx.compose.ui.Modifier toggleable(androidx.compose.ui.Modifier, boolean value, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onValueChange);
-    method public static androidx.compose.ui.Modifier toggleable(androidx.compose.ui.Modifier, boolean value, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onValueChange);
+    method public static androidx.compose.ui.Modifier toggleable(androidx.compose.ui.Modifier, boolean value, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onValueChange);
     method public static androidx.compose.ui.Modifier triStateToggleable(androidx.compose.ui.Modifier, androidx.compose.ui.state.ToggleableState state, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-    method public static androidx.compose.ui.Modifier triStateToggleable(androidx.compose.ui.Modifier, androidx.compose.ui.state.ToggleableState state, androidx.compose.foundation.InteractionState interactionState, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+    method public static androidx.compose.ui.Modifier triStateToggleable(androidx.compose.ui.Modifier, androidx.compose.ui.state.ToggleableState state, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
   }
 
 }
@@ -531,8 +594,8 @@
   }
 
   public final class BasicTextFieldKt {
-    method @androidx.compose.runtime.Composable public static void BasicTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.ui.graphics.Brush cursorBrush, optional kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> decorationBox);
-    method @androidx.compose.runtime.Composable public static void BasicTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.ui.graphics.Brush cursorBrush, optional kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> decorationBox);
+    method @androidx.compose.runtime.Composable public static void BasicTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Brush cursorBrush, optional kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> decorationBox);
+    method @androidx.compose.runtime.Composable public static void BasicTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Brush cursorBrush, optional kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> decorationBox);
   }
 
   public final class BasicTextKt {
@@ -540,15 +603,16 @@
     method @androidx.compose.runtime.Composable public static void BasicText(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.style.TextOverflow overflow, optional boolean softWrap, optional int maxLines, optional java.util.Map<java.lang.String,androidx.compose.foundation.text.InlineTextContent> inlineContent);
   }
 
+  public final class ClickableTextKt {
+    method @androidx.compose.runtime.Composable public static void ClickableText(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional boolean softWrap, optional androidx.compose.ui.text.style.TextOverflow overflow, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onClick);
+  }
+
   public final class CoreTextFieldKt {
   }
 
   public final class CoreTextKt {
   }
 
-  public final class InactiveTextFieldKt {
-  }
-
   @androidx.compose.runtime.Immutable public final class InlineTextContent {
     ctor public InlineTextContent(androidx.compose.ui.text.Placeholder placeholder, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> children);
     method public kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit> getChildren();
@@ -639,6 +703,9 @@
   public final class TextLayoutResultProxyKt {
   }
 
+  public final class TouchMode_androidKt {
+  }
+
 }
 
 package androidx.compose.foundation.text.selection {
@@ -660,6 +727,9 @@
   public final class SelectionManagerKt {
   }
 
+  public final class SelectionManager_androidKt {
+  }
+
   public final class SelectionRegistrarKt {
   }
 
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/FoundationDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/FoundationDemos.kt
index 3d73cbf..90a8a00 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/FoundationDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/FoundationDemos.kt
@@ -17,8 +17,8 @@
 package androidx.compose.foundation.demos
 
 import androidx.compose.foundation.samples.ControlledScrollableRowSample
-import androidx.compose.foundation.samples.MultipleInteractionStateSample
-import androidx.compose.foundation.samples.PriorityInteractionStateSample
+import androidx.compose.foundation.samples.InteractionSourceFlowSample
+import androidx.compose.foundation.samples.SimpleInteractionSourceSample
 import androidx.compose.foundation.samples.VerticalScrollExample
 import androidx.compose.integration.demos.common.ComposableDemo
 import androidx.compose.integration.demos.common.DemoCategory
@@ -31,10 +31,8 @@
         ComposableDemo("Controlled Scrollable Row") { ControlledScrollableRowSample() },
         ComposableDemo("Draw Modifiers") { DrawModifiersDemo() },
         DemoCategory("Lazy lists", LazyListDemos),
-        ComposableDemo("Priority InteractionState") { PriorityInteractionStateSample() },
-        ComposableDemo("Multiple-interaction InteractionState") {
-            MultipleInteractionStateSample()
-        },
+        ComposableDemo("Simple InteractionSource") { SimpleInteractionSourceSample() },
+        ComposableDemo("Flow InteractionSource") { InteractionSourceFlowSample() },
         DemoCategory("Suspending Gesture Detectors", CoroutineGestureDemos),
         ComposableDemo("NestedScroll") { NestedScrollDemo() },
     )
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 666640ed..f3f7a3e 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
@@ -22,16 +22,15 @@
 import androidx.compose.animation.core.calculateTargetValue
 import androidx.compose.animation.defaultDecayAnimationSpec
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.Interaction
 import androidx.compose.foundation.background
 import androidx.compose.foundation.border
 import androidx.compose.foundation.gestures.FlingBehavior
 import androidx.compose.foundation.gestures.ScrollScope
 import androidx.compose.foundation.gestures.animateScrollBy
+import androidx.compose.foundation.interaction.collectIsDraggedAsState
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.ExperimentalLayout
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxHeight
@@ -140,7 +139,6 @@
     }
 }
 
-@OptIn(ExperimentalLayout::class)
 @Composable
 private fun ListHoistedStateDemo() {
     val state = rememberLazyListState()
@@ -231,7 +229,7 @@
                 fontSize = 20.sp
             )
             Text(
-                "Dragging: ${state.interactionState.contains(Interaction.Dragged)}, " +
+                "Dragging: ${state.interactionSource.collectIsDraggedAsState().value}, " +
                     "Flinging: ${state.isScrollInProgress}",
                 fontSize = 20.sp
             )
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/CapitalizationAutoCorrectDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/CapitalizationAutoCorrectDemo.kt
index b81ae6d..7d485a6 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/CapitalizationAutoCorrectDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/CapitalizationAutoCorrectDemo.kt
@@ -23,12 +23,13 @@
 import androidx.compose.foundation.text.KeyboardActions
 import androidx.compose.foundation.text.KeyboardOptions
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
 import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.SolidColor
-import androidx.compose.ui.text.SoftwareKeyboardController
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.input.KeyboardCapitalization
 import androidx.compose.ui.text.input.KeyboardType
@@ -84,20 +85,20 @@
     }
 }
 
+@OptIn(ExperimentalComposeUiApi::class)
 @Composable
 private fun MyTextField(data: ImeOptionsData) {
-    val controller = remember { mutableStateOf<SoftwareKeyboardController?>(null) }
-    val state = rememberSaveable(stateSaver = TextFieldValue.Saver) {
+    var state by rememberSaveable(stateSaver = TextFieldValue.Saver) {
         mutableStateOf(TextFieldValue())
     }
+    // TODO(b/1583763): re-add software keyboard controller when replacement API is added
     BasicTextField(
         modifier = demoTextFieldModifiers.defaultMinSize(100.dp),
-        value = state.value,
+        value = state,
         keyboardOptions = data.keyboardOptions,
-        keyboardActions = KeyboardActions { controller.value?.hideSoftwareKeyboard() },
-        onValueChange = { state.value = it },
+        keyboardActions = KeyboardActions { /* hide keyboard */ },
+        onValueChange = { state = it },
         textStyle = TextStyle(fontSize = fontSize8),
-        onTextInputStarted = { controller.value = it },
         cursorBrush = SolidColor(Color.Red)
     )
 }
\ No newline at end of file
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputField.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputField.kt
index c760846..8437b8b 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputField.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputField.kt
@@ -28,12 +28,10 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.platform.LocalLayoutDirection
-import androidx.compose.ui.text.SoftwareKeyboardController
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.KeyboardType
@@ -81,7 +79,7 @@
     singleLine: Boolean = false,
     text: String = ""
 ) {
-    val controller = remember { mutableStateOf<SoftwareKeyboardController?>(null) }
+    // TODO(b/1583763): re-add software keyboard controller when replacement API is added
     val state = rememberSaveable { mutableStateOf(text) }
     BasicTextField(
         modifier = demoTextFieldModifiers,
@@ -91,10 +89,9 @@
             keyboardType = keyboardType,
             imeAction = imeAction
         ),
-        keyboardActions = KeyboardActions { controller.value?.hideSoftwareKeyboard() },
+        keyboardActions = KeyboardActions { /* hide keyboard */ },
         onValueChange = { state.value = it },
         textStyle = TextStyle(fontSize = fontSize8),
-        onTextInputStarted = { controller.value = it },
     )
 }
 
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeVariousInputField.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeVariousInputField.kt
index 48bf8cd..ca905b4 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeVariousInputField.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeVariousInputField.kt
@@ -16,8 +16,10 @@
 
 package androidx.compose.foundation.demos.text
 
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.collectIsDraggedAsState
+import androidx.compose.foundation.interaction.collectIsFocusedAsState
+import androidx.compose.foundation.interaction.collectIsPressedAsState
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxWidth
@@ -240,8 +242,8 @@
             }
         }
         item {
-            TagLine(tag = "TextField InteractionState")
-            InteractionStateTextField()
+            TagLine(tag = "TextField MutableInteractionSource")
+            InteractionSourceTextField()
         }
     }
 }
@@ -289,21 +291,30 @@
 }
 
 @Composable
-private fun InteractionStateTextField() {
+private fun InteractionSourceTextField() {
     val state = rememberSaveable(stateSaver = TextFieldValue.Saver) {
         mutableStateOf(TextFieldValue())
     }
-    val interactionState = remember { InteractionState() }
+    val interactionSource = remember { MutableInteractionSource() }
 
     Column(demoTextFieldModifiers) {
-        Text("Pressed?: ${interactionState.contains(Interaction.Pressed)}", fontSize = fontSize4)
-        Text("Focused?: ${interactionState.contains(Interaction.Focused)}", fontSize = fontSize4)
-        Text("Dragged?: ${interactionState.contains(Interaction.Dragged)}", fontSize = fontSize4)
+        Text(
+            "Pressed?: ${interactionSource.collectIsPressedAsState().value}",
+            fontSize = fontSize4
+        )
+        Text(
+            "Focused?: ${interactionSource.collectIsFocusedAsState().value}",
+            fontSize = fontSize4
+        )
+        Text(
+            "Dragged?: ${interactionSource.collectIsDraggedAsState().value}",
+            fontSize = fontSize4
+        )
         BasicTextField(
             modifier = Modifier.fillMaxWidth(),
             value = state.value,
             singleLine = true,
-            interactionState = interactionState,
+            interactionSource = interactionSource,
             onValueChange = { state.value = it },
             textStyle = TextStyle(fontSize = fontSize8)
         )
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/InteractiveText.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/InteractiveText.kt
index 0cd5ec8..ef7dc92 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/InteractiveText.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/InteractiveText.kt
@@ -16,7 +16,7 @@
 
 package androidx.compose.foundation.demos.text
 
-import androidx.compose.foundation.ClickableText
+import androidx.compose.foundation.text.ClickableText
 import androidx.compose.foundation.layout.Column
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/KeyboardSingleLineDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/KeyboardSingleLineDemo.kt
index 7ebe525..76a99ec 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/KeyboardSingleLineDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/KeyboardSingleLineDemo.kt
@@ -24,11 +24,9 @@
 import androidx.compose.foundation.text.KeyboardOptions
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.SolidColor
-import androidx.compose.ui.text.SoftwareKeyboardController
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.KeyboardType
@@ -116,7 +114,7 @@
 
 @Composable
 private fun MyTextField(data: ImeOptionsData) {
-    val controller = remember { mutableStateOf<SoftwareKeyboardController?>(null) }
+    // TODO(b/1583763): re-add software keyboard controller when replacement API is added
     val state = rememberSaveable(stateSaver = TextFieldValue.Saver) {
         mutableStateOf(TextFieldValue())
     }
@@ -124,11 +122,10 @@
         modifier = demoTextFieldModifiers.defaultMinSize(100.dp),
         value = state.value,
         keyboardOptions = data.keyboardOptions,
-        keyboardActions = KeyboardActions { controller.value?.hideSoftwareKeyboard() },
+        keyboardActions = KeyboardActions { /* hide keyboard */ },
         singleLine = data.singleLine,
         onValueChange = { state.value = it },
         textStyle = TextStyle(fontSize = fontSize8),
-        onTextInputStarted = { controller.value = it },
         cursorBrush = SolidColor(Color.Red)
     )
 }
\ No newline at end of file
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ClickableTextSample.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ClickableTextSample.kt
index 94afca1..2cc6ff7 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ClickableTextSample.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ClickableTextSample.kt
@@ -18,7 +18,7 @@
 
 import android.util.Log
 import androidx.annotation.Sampled
-import androidx.compose.foundation.ClickableText
+import androidx.compose.foundation.text.ClickableText
 import androidx.compose.foundation.gestures.detectTapGestures
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
@@ -55,7 +55,7 @@
     onLongClick: (offset: Int) -> Unit
 ) {
     val layoutResult = remember { mutableStateOf<TextLayoutResult?>(null) }
-    val gesture = Modifier.pointerInput(Unit) {
+    val gesture = Modifier.pointerInput(onLongClick) {
         detectTapGestures(
             onLongPress = { pos ->
                 layoutResult.value?.let { layout ->
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/FocusableSample.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/FocusableSample.kt
index 1024bb9..f5ab3bc 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/FocusableSample.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/FocusableSample.kt
@@ -17,9 +17,9 @@
 package androidx.compose.foundation.samples
 
 import androidx.annotation.Sampled
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.focusable
+import androidx.compose.foundation.interaction.collectIsFocusedAsState
 import androidx.compose.foundation.layout.Column
 import androidx.compose.material.Button
 import androidx.compose.material.Text
@@ -34,11 +34,11 @@
 fun FocusableSample() {
     // initialize focus reference to be able to request focus programmatically
     val focusRequester = FocusRequester()
-    // interaction state to track changes of the component's interactions (like "focused")
-    val interactionState = remember { InteractionState() }
+    // MutableInteractionSource to track changes of the component's interactions (like "focused")
+    val interactionSource = remember { MutableInteractionSource() }
 
     // text below will change when we focus it via button click
-    val isFocused = interactionState.contains(Interaction.Focused)
+    val isFocused = interactionSource.collectIsFocusedAsState().value
     val text = if (isFocused) {
         "Focused! tap anywhere to free the focus"
     } else {
@@ -51,7 +51,7 @@
             modifier = Modifier
                 // add focusRequester modifier before the focusable (or even in the parent)
                 .focusRequester(focusRequester)
-                .focusable(interactionState = interactionState)
+                .focusable(interactionSource = interactionSource)
         )
         Button(onClick = { focusRequester.requestFocus() }) {
             Text("Bring focus to the text above")
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/IndicationSamples.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/IndicationSamples.kt
index 0b37029..e96b066 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/IndicationSamples.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/IndicationSamples.kt
@@ -17,7 +17,7 @@
 package androidx.compose.foundation.samples
 
 import androidx.annotation.Sampled
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.LocalIndication
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.indication
@@ -25,8 +25,8 @@
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.requiredHeight
 import androidx.compose.foundation.layout.padding
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.material.Text
+import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
@@ -35,13 +35,16 @@
 @Composable
 @Sampled
 fun IndicationSample() {
-    val interactionState = remember { InteractionState() }
+    val interactionSource = remember { MutableInteractionSource() }
     Column {
         Text(
             text = "Click me and my neighbour will indicate as well!",
             modifier = Modifier
-                // clickable will update interaction state and show ripple
-                .clickable(interactionState = interactionState, indication = rememberRipple()) {
+                // clickable will dispatch events using MutableInteractionSource and show ripple
+                .clickable(
+                    interactionSource = interactionSource,
+                    indication = rememberRipple()
+                ) {
                     /**do something */
                 }
                 .padding(10.dp)
@@ -51,8 +54,8 @@
             text = "I'm neighbour and I indicate when you click the other one",
             modifier = Modifier
                 // this element doesn't have a click, but will show default indication from the
-                // CompositionLocal as it accepts same interaction state
-                .indication(interactionState, LocalIndication.current)
+                // CompositionLocal as it accepts the same MutableInteractionSource
+                .indication(interactionSource, LocalIndication.current)
                 .padding(10.dp)
         )
     }
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/InteractionSourceSample.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/InteractionSourceSample.kt
new file mode 100644
index 0000000..4b8fb36
--- /dev/null
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/InteractionSourceSample.kt
@@ -0,0 +1,205 @@
+/*
+ * 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.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.interaction.DragInteraction
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.LocalIndication
+import androidx.compose.foundation.interaction.PressInteraction
+import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.draggable
+import androidx.compose.foundation.gestures.rememberDraggableState
+import androidx.compose.foundation.indication
+import androidx.compose.foundation.interaction.collectIsDraggedAsState
+import androidx.compose.foundation.interaction.collectIsPressedAsState
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.material.LocalTextStyle
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
+import kotlinx.coroutines.flow.collect
+
+@Sampled
+@Composable
+fun SimpleInteractionSourceSample() {
+    // Hoist the MutableInteractionSource that we will provide to interactions
+    val interactionSource = remember { MutableInteractionSource() }
+
+    // Provide the MutableInteractionSource instances to the interactions we want to observe state
+    // changes for
+    val draggable = Modifier.draggable(
+        interactionSource = interactionSource,
+        orientation = Orientation.Horizontal,
+        state = rememberDraggableState { /* update some business state here */ }
+    )
+
+    val clickable = Modifier.clickable(
+        interactionSource = interactionSource,
+        indication = LocalIndication.current
+    ) { /* update some business state here */ }
+
+    // Observe changes to the binary state for these interactions
+    val isDragged by interactionSource.collectIsDraggedAsState()
+    val isPressed by interactionSource.collectIsPressedAsState()
+
+    // Use the state to change our UI
+    val (text, color) = when {
+        isDragged && isPressed -> "Dragged and pressed" to Color.Red
+        isDragged -> "Dragged" to Color.Green
+        isPressed -> "Pressed" to Color.Blue
+        // Default / baseline state
+        else -> "Drag me horizontally, or press me!" to Color.Black
+    }
+
+    Box(
+        Modifier
+            .fillMaxSize()
+            .wrapContentSize()
+            .size(width = 240.dp, height = 80.dp)
+    ) {
+        Box(
+            Modifier
+                .fillMaxSize()
+                .then(clickable)
+                .then(draggable)
+                .border(BorderStroke(3.dp, color))
+                .padding(3.dp)
+        ) {
+            Text(
+                text, style = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
+                modifier = Modifier.fillMaxSize().wrapContentSize()
+            )
+        }
+    }
+}
+
+@Sampled
+@Composable
+fun InteractionSourceFlowSample() {
+    // Hoist the MutableInteractionSource that we will provide to interactions
+    val interactionSource = remember { MutableInteractionSource() }
+
+    // Provide the MutableInteractionSource instances to the interactions we want to observe state
+    // changes for
+    val draggable = Modifier.draggable(
+        interactionSource = interactionSource,
+        orientation = Orientation.Horizontal,
+        state = rememberDraggableState { /* update some business state here */ }
+    )
+
+    val clickable = Modifier.clickable(
+        interactionSource = interactionSource,
+        // This component is a compound component where part of it is clickable and part of it is
+        // draggable. As a result we want to show indication for the _whole_ component, and not
+        // just for clickable area. We set `null` indication here and provide an explicit
+        // Modifier.indication instance later that will draw indication for the whole component.
+        indication = null
+    ) { /* update some business state here */ }
+
+    // SnapshotStateList we will use to track incoming Interactions in the order they are emitted
+    val interactions = remember { mutableStateListOf<Interaction>() }
+
+    // Collect Interactions - if they are new, add them to `interactions`. If they represent stop /
+    // cancel events for existing Interactions, remove them from `interactions` so it will only
+    // contain currently active `interactions`.
+    LaunchedEffect(interactionSource) {
+        interactionSource.interactions.collect { interaction ->
+            when (interaction) {
+                is PressInteraction.Press -> interactions.add(interaction)
+                is PressInteraction.Release -> interactions.remove(interaction.press)
+                is PressInteraction.Cancel -> interactions.remove(interaction.press)
+                is DragInteraction.Start -> interactions.add(interaction)
+                is DragInteraction.Stop -> interactions.remove(interaction.start)
+                is DragInteraction.Cancel -> interactions.remove(interaction.start)
+            }
+        }
+    }
+
+    // Display some text based on the most recent Interaction stored in `interactions`
+    val text = when (interactions.lastOrNull()) {
+        is DragInteraction.Start -> "Dragged"
+        is PressInteraction.Press -> "Pressed"
+        else -> "No state"
+    }
+
+    Column(
+        Modifier
+            .fillMaxSize()
+            .wrapContentSize()
+    ) {
+        Row(
+            // Draw indication for the whole component, based on the Interactions dispatched by
+            // our hoisted MutableInteractionSource
+            Modifier.indication(
+                interactionSource = interactionSource,
+                indication = LocalIndication.current
+            )
+        ) {
+            Box(
+                Modifier
+                    .size(width = 240.dp, height = 80.dp)
+                    .then(clickable)
+                    .border(BorderStroke(3.dp, Color.Blue))
+                    .padding(3.dp)
+            ) {
+                val pressed = interactions.any { it is PressInteraction.Press }
+                Text(
+                    text = if (pressed) "Pressed" else "Not pressed",
+                    style = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
+                    modifier = Modifier.fillMaxSize().wrapContentSize()
+                )
+            }
+            Box(
+                Modifier
+                    .size(width = 240.dp, height = 80.dp)
+                    .then(draggable)
+                    .border(BorderStroke(3.dp, Color.Red))
+                    .padding(3.dp)
+            ) {
+                val dragged = interactions.any { it is DragInteraction.Start }
+                Text(
+                    text = if (dragged) "Dragged" else "Not dragged",
+                    style = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
+                    modifier = Modifier.fillMaxSize().wrapContentSize()
+                )
+            }
+        }
+        Text(
+            text = text,
+            style = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
+            modifier = Modifier.fillMaxSize().wrapContentSize()
+        )
+    }
+}
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/InteractionStateSample.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/InteractionStateSample.kt
deleted file mode 100644
index 63cdd2d..0000000
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/InteractionStateSample.kt
+++ /dev/null
@@ -1,167 +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.samples
-
-import androidx.annotation.Sampled
-import androidx.compose.foundation.BorderStroke
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
-import androidx.compose.foundation.LocalIndication
-import androidx.compose.foundation.border
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.foundation.gestures.draggable
-import androidx.compose.foundation.gestures.rememberDraggableState
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.wrapContentSize
-import androidx.compose.material.LocalTextStyle
-import androidx.compose.material.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.text.style.TextAlign
-import androidx.compose.ui.unit.dp
-
-@Sampled
-@Composable
-fun PriorityInteractionStateSample() {
-    val interactionState = remember { InteractionState() }
-
-    val draggable = Modifier.draggable(
-        orientation = Orientation.Horizontal,
-        interactionState = interactionState,
-        state = rememberDraggableState { /* update some business state here */ }
-    )
-
-    // Use InteractionState to determine how this component should appear during transient UI states
-    // In this example we are using a 'priority' system, such that we ignore multiple states, and
-    // don't care about the most recent state - Dragged is more important than Pressed.
-    val (text, color) = when {
-        Interaction.Dragged in interactionState -> "Dragged" to Color.Red
-        Interaction.Pressed in interactionState -> "Pressed" to Color.Blue
-        // Default / baseline state
-        else -> "Drag me horizontally, or press me!" to Color.Black
-    }
-
-    Box(
-        Modifier
-            .fillMaxSize()
-            .wrapContentSize()
-            .size(width = 240.dp, height = 80.dp)
-    ) {
-        Box(
-            Modifier
-                .fillMaxSize()
-                .clickable(
-                    interactionState = interactionState,
-                    indication = LocalIndication.current
-                ) { /* do nothing */ }
-                .then(draggable)
-                .border(BorderStroke(3.dp, color))
-                .padding(3.dp)
-        ) {
-            Text(
-                text, style = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
-                modifier = Modifier.fillMaxSize().wrapContentSize()
-            )
-        }
-    }
-}
-
-@Sampled
-@Composable
-fun MultipleInteractionStateSample() {
-    val interactionState = remember { InteractionState() }
-
-    val draggable = Modifier.draggable(
-        orientation = Orientation.Horizontal,
-        interactionState = interactionState,
-        state = rememberDraggableState { /* update some business state here */ }
-    )
-
-    val clickable = Modifier.clickable(
-        interactionState = interactionState,
-        indication = LocalIndication.current
-    ) {
-        /* update some business state here */
-    }
-
-    // In this example we have a complex component that can be in multiple states at the same time
-    // (both pressed and dragged, since different areas of the same component can be pressed and
-    // dragged at the same time), and we want to use only the most recent state to show the visual
-    // state of the component. This could be with a visual overlay, or similar. Note that the most
-    // recent state is the _last_ state added to interactionState, so we want to start from the end,
-    // hence we use `lastOrNull` and not `firstOrNull`.
-    val latestState = interactionState.value.lastOrNull {
-        // We only care about pressed and dragged states here, so ignore everything else
-        it is Interaction.Dragged || it is Interaction.Pressed
-    }
-
-    val text = when (latestState) {
-        Interaction.Dragged -> "Dragged"
-        Interaction.Pressed -> "Pressed"
-        else -> "No state"
-    }
-
-    Column(
-        Modifier
-            .fillMaxSize()
-            .wrapContentSize()
-    ) {
-        Row {
-            Box(
-                Modifier
-                    .size(width = 240.dp, height = 80.dp)
-                    .then(clickable)
-                    .border(BorderStroke(3.dp, Color.Blue))
-                    .padding(3.dp)
-            ) {
-                val pressed = Interaction.Pressed in interactionState
-                Text(
-                    text = if (pressed) "Pressed" else "Not pressed",
-                    style = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
-                    modifier = Modifier.fillMaxSize().wrapContentSize()
-                )
-            }
-            Box(
-                Modifier
-                    .size(width = 240.dp, height = 80.dp)
-                    .then(draggable)
-                    .border(BorderStroke(3.dp, Color.Red))
-                    .padding(3.dp)
-            ) {
-                val dragged = Interaction.Dragged in interactionState
-                Text(
-                    text = if (dragged) "Dragged" else "Not dragged",
-                    style = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
-                    modifier = Modifier.fillMaxSize().wrapContentSize()
-                )
-            }
-        }
-        Text(
-            text = text,
-            style = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
-            modifier = Modifier.fillMaxSize().wrapContentSize()
-        )
-    }
-}
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ClickableTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ClickableTest.kt
index 79a2dc8..b53e3ce 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ClickableTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ClickableTest.kt
@@ -16,11 +16,15 @@
 
 package androidx.compose.foundation
 
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.text.BasicText
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.InspectableValue
@@ -49,6 +53,9 @@
 import androidx.test.filters.LargeTest
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
 import org.junit.After
 import org.junit.Before
 import org.junit.Rule
@@ -409,48 +416,65 @@
     }
 
     @Test
-    fun clickableTest_interactionState() {
-        val interactionState = InteractionState()
+    fun clickableTest_interactionSource() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         rule.setContent {
+            scope = rememberCoroutineScope()
             Box {
                 BasicText(
                     "ClickableText",
                     modifier = Modifier
                         .testTag("myClickable")
                         .combinedClickable(
-                            interactionState = interactionState,
+                            interactionSource = interactionSource,
                             indication = null
                         ) {}
                 )
             }
         }
 
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Pressed)
+            assertThat(interactions).isEmpty()
         }
 
         rule.onNodeWithTag("myClickable")
             .performGesture { down(center) }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).contains(Interaction.Pressed)
+            assertThat(interactions).hasSize(1)
+            assertThat(interactions.first()).isInstanceOf(PressInteraction.Press::class.java)
         }
 
         rule.onNodeWithTag("myClickable")
             .performGesture { up() }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Pressed)
+            assertThat(interactions).hasSize(2)
+            assertThat(interactions.first()).isInstanceOf(PressInteraction.Press::class.java)
+            assertThat(interactions[1]).isInstanceOf(PressInteraction.Release::class.java)
+            assertThat((interactions[1] as PressInteraction.Release).press)
+                .isEqualTo(interactions[0])
         }
     }
 
     @Test
-    fun clickableTest_interactionState_resetWhenDisposed() {
-        val interactionState = InteractionState()
+    fun clickableTest_interactionSource_resetWhenDisposed() {
+        val interactionSource = MutableInteractionSource()
         var emitClickableText by mutableStateOf(true)
 
+        var scope: CoroutineScope? = null
+
         rule.setContent {
+            scope = rememberCoroutineScope()
             Box {
                 if (emitClickableText) {
                     BasicText(
@@ -458,7 +482,7 @@
                         modifier = Modifier
                             .testTag("myClickable")
                             .combinedClickable(
-                                interactionState = interactionState,
+                                interactionSource = interactionSource,
                                 indication = null
                             ) {}
                     )
@@ -466,15 +490,22 @@
             }
         }
 
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Pressed)
+            assertThat(interactions).isEmpty()
         }
 
         rule.onNodeWithTag("myClickable")
             .performGesture { down(center) }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).contains(Interaction.Pressed)
+            assertThat(interactions).hasSize(1)
+            assertThat(interactions.first()).isInstanceOf(PressInteraction.Press::class.java)
         }
 
         // Dispose clickable
@@ -483,7 +514,11 @@
         }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Pressed)
+            assertThat(interactions).hasSize(2)
+            assertThat(interactions.first()).isInstanceOf(PressInteraction.Press::class.java)
+            assertThat(interactions[1]).isInstanceOf(PressInteraction.Cancel::class.java)
+            assertThat((interactions[1] as PressInteraction.Cancel).press)
+                .isEqualTo(interactions[0])
         }
     }
 
@@ -618,7 +653,7 @@
         rule.setContent {
             val modifier = Modifier.combinedClickable(
                 onClick = onClick,
-                interactionState = remember { InteractionState() },
+                interactionSource = remember { MutableInteractionSource() },
                 indication = null
             ) as InspectableValue
             assertThat(modifier.nameFallback).isEqualTo("combinedClickable")
@@ -632,7 +667,7 @@
                 "onLongClick",
                 "onLongClickLabel",
                 "indication",
-                "interactionState"
+                "interactionSource"
             )
         }
     }
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/DraggableTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/DraggableTest.kt
index 0fb987b..b83b957 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/DraggableTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/DraggableTest.kt
@@ -23,12 +23,16 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.composed
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.interaction.DragInteraction
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.ui.platform.InspectableValue
 import androidx.compose.ui.platform.isDebugInspectorInfoEnabled
 import androidx.compose.ui.platform.testTag
@@ -45,6 +49,9 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
 import org.junit.After
 import org.junit.Before
 import org.junit.Rule
@@ -322,18 +329,27 @@
     }
 
     @Test
-    fun draggable_interactionState() {
-        val interactionState = InteractionState()
+    fun draggable_interactionSource() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         setDraggableContent {
+            scope = rememberCoroutineScope()
             Modifier.draggable(
                 Orientation.Horizontal,
-                interactionState = interactionState
+                interactionSource = interactionSource
             ) {}
         }
 
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Dragged)
+            assertThat(interactions).isEmpty()
         }
 
         rule.onNodeWithTag(draggableBoxTag)
@@ -343,7 +359,8 @@
             }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).contains(Interaction.Dragged)
+            assertThat(interactions).hasSize(1)
+            assertThat(interactions.first()).isInstanceOf(DragInteraction.Start::class.java)
         }
 
         rule.onNodeWithTag(draggableBoxTag)
@@ -352,16 +369,23 @@
             }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Dragged)
+            assertThat(interactions).hasSize(2)
+            assertThat(interactions.first()).isInstanceOf(DragInteraction.Start::class.java)
+            assertThat(interactions[1]).isInstanceOf(DragInteraction.Stop::class.java)
+            assertThat((interactions[1] as DragInteraction.Stop).start)
+                .isEqualTo(interactions[0])
         }
     }
 
     @Test
-    fun draggable_interactionState_resetWhenDisposed() {
-        val interactionState = InteractionState()
+    fun draggable_interactionSource_resetWhenDisposed() {
+        val interactionSource = MutableInteractionSource()
         var emitDraggableBox by mutableStateOf(true)
 
+        var scope: CoroutineScope? = null
+
         rule.setContent {
+            scope = rememberCoroutineScope()
             Box {
                 if (emitDraggableBox) {
                     Box(
@@ -370,15 +394,21 @@
                             .size(100.dp)
                             .draggable(
                                 orientation = Orientation.Horizontal,
-                                interactionState = interactionState
+                                interactionSource = interactionSource
                             ) {}
                     )
                 }
             }
         }
 
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Dragged)
+            assertThat(interactions).isEmpty()
         }
 
         rule.onNodeWithTag(draggableBoxTag)
@@ -388,7 +418,8 @@
             }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).contains(Interaction.Dragged)
+            assertThat(interactions).hasSize(1)
+            assertThat(interactions.first()).isInstanceOf(DragInteraction.Start::class.java)
         }
 
         // Dispose draggable
@@ -397,7 +428,11 @@
         }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Dragged)
+            assertThat(interactions).hasSize(2)
+            assertThat(interactions.first()).isInstanceOf(DragInteraction.Start::class.java)
+            assertThat(interactions[1]).isInstanceOf(DragInteraction.Cancel::class.java)
+            assertThat((interactions[1] as DragInteraction.Cancel).start)
+                .isEqualTo(interactions[0])
         }
     }
 
@@ -414,7 +449,7 @@
                 "orientation",
                 "enabled",
                 "reverseDirection",
-                "interactionState",
+                "interactionSource",
                 "startDragImmediately",
                 "onDragStarted",
                 "onDragStopped",
@@ -441,7 +476,7 @@
         orientation: Orientation,
         enabled: Boolean = true,
         reverseDirection: Boolean = false,
-        interactionState: InteractionState? = null,
+        interactionSource: MutableInteractionSource? = null,
         startDragImmediately: Boolean = false,
         onDragStarted: (startedPosition: Offset) -> Unit = {},
         onDragStopped: (velocity: Float) -> Unit = {},
@@ -452,7 +487,7 @@
             orientation = orientation,
             enabled = enabled,
             reverseDirection = reverseDirection,
-            interactionState = interactionState,
+            interactionSource = interactionSource,
             startDragImmediately = startDragImmediately,
             onDragStarted = { onDragStarted(it) },
             onDragStopped = { onDragStopped(it) },
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/FocusableTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/FocusableTest.kt
index 0384749..05a1c5f 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/FocusableTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/FocusableTest.kt
@@ -16,10 +16,14 @@
 
 package androidx.compose.foundation
 
+import androidx.compose.foundation.interaction.FocusInteraction
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.text.BasicText
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
@@ -39,6 +43,9 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
 import org.junit.After
 import org.junit.Before
 import org.junit.Rule
@@ -137,17 +144,21 @@
 
     @ExperimentalComposeUiApi
     @Test
-    fun focusableTest_interactionState() {
-        val interactionState = InteractionState()
+    fun focusableTest_interactionSource() {
+        val interactionSource = MutableInteractionSource()
         val (focusRequester, otherFocusRequester) = FocusRequester.createRefs()
+
+        var scope: CoroutineScope? = null
+
         rule.setContent {
+            scope = rememberCoroutineScope()
             Box {
                 BasicText(
                     "focusableText",
                     modifier = Modifier
                         .testTag(focusTag)
                         .focusRequester(focusRequester)
-                        .focusable(interactionState = interactionState)
+                        .focusable(interactionSource = interactionSource)
                 )
                 BasicText(
                     "otherFocusableText",
@@ -158,8 +169,14 @@
             }
         }
 
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
         rule.runOnIdle {
-            Truth.assertThat(interactionState.value).doesNotContain(Interaction.Focused)
+            Truth.assertThat(interactions).isEmpty()
         }
 
         rule.runOnIdle {
@@ -167,7 +184,8 @@
         }
 
         rule.runOnIdle {
-            Truth.assertThat(interactionState.value).contains(Interaction.Focused)
+            Truth.assertThat(interactions).hasSize(1)
+            Truth.assertThat(interactions.first()).isInstanceOf(FocusInteraction.Focus::class.java)
         }
 
         rule.runOnIdle {
@@ -175,17 +193,25 @@
         }
 
         rule.runOnIdle {
-            Truth.assertThat(interactionState.value).doesNotContain(Interaction.Focused)
+            Truth.assertThat(interactions).hasSize(2)
+            Truth.assertThat(interactions.first()).isInstanceOf(FocusInteraction.Focus::class.java)
+            Truth.assertThat(interactions[1])
+                .isInstanceOf(FocusInteraction.Unfocus::class.java)
+            Truth.assertThat((interactions[1] as FocusInteraction.Unfocus).focus)
+                .isEqualTo(interactions[0])
         }
     }
 
     @Test
-    fun focusableTest_interactionState_resetWhenDisposed() {
-        val interactionState = InteractionState()
+    fun focusableTest_interactionSource_resetWhenDisposed() {
+        val interactionSource = MutableInteractionSource()
         val focusRequester = FocusRequester()
         var emitFocusableText by mutableStateOf(true)
 
+        var scope: CoroutineScope? = null
+
         rule.setContent {
+            scope = rememberCoroutineScope()
             Box {
                 if (emitFocusableText) {
                     BasicText(
@@ -193,14 +219,20 @@
                         modifier = Modifier
                             .testTag(focusTag)
                             .focusRequester(focusRequester)
-                            .focusable(interactionState = interactionState)
+                            .focusable(interactionSource = interactionSource)
                     )
                 }
             }
         }
 
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
         rule.runOnIdle {
-            Truth.assertThat(interactionState.value).doesNotContain(Interaction.Focused)
+            Truth.assertThat(interactions).isEmpty()
         }
 
         rule.runOnIdle {
@@ -208,7 +240,8 @@
         }
 
         rule.runOnIdle {
-            Truth.assertThat(interactionState.value).contains(Interaction.Focused)
+            Truth.assertThat(interactions).hasSize(1)
+            Truth.assertThat(interactions.first()).isInstanceOf(FocusInteraction.Focus::class.java)
         }
 
         // Dispose focusable, Interaction should be gone
@@ -217,7 +250,12 @@
         }
 
         rule.runOnIdle {
-            Truth.assertThat(interactionState.value).doesNotContain(Interaction.Focused)
+            Truth.assertThat(interactions).hasSize(2)
+            Truth.assertThat(interactions.first()).isInstanceOf(FocusInteraction.Focus::class.java)
+            Truth.assertThat(interactions[1])
+                .isInstanceOf(FocusInteraction.Unfocus::class.java)
+            Truth.assertThat((interactions[1] as FocusInteraction.Unfocus).focus)
+                .isEqualTo(interactions[0])
         }
     }
 
@@ -230,7 +268,7 @@
             Truth.assertThat(modifier.inspectableElements.map { it.name }.asIterable())
                 .containsExactly(
                     "enabled",
-                    "interactionState"
+                    "interactionSource"
                 )
         }
     }
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/IndicationTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/IndicationTest.kt
index f53d422..0887889 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/IndicationTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/IndicationTest.kt
@@ -16,13 +16,17 @@
 
 package androidx.compose.foundation
 
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.InteractionSource
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.size
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateListOf
 import androidx.compose.runtime.remember
-import androidx.compose.ui.graphics.drawscope.ContentDrawScope
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.drawscope.ContentDrawScope
 import androidx.compose.ui.platform.InspectableValue
 import androidx.compose.ui.platform.isDebugInspectorInfoEnabled
 import androidx.compose.ui.platform.testTag
@@ -36,9 +40,11 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
 import org.junit.After
 import org.junit.Before
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -66,39 +72,49 @@
 
     @Test
     fun indication_receivesInitialState() {
-        val state = InteractionState()
+        val dispatcher = MutableInteractionSource()
         val countDownLatch = CountDownLatch(1)
         val indication = makeIndication {
-            // just wait for initial draw with empty interaction
-            if (it.value.isEmpty()) {
-                countDownLatch.countDown()
-            }
+            countDownLatch.countDown()
         }
         rule.setContent {
-            Box(Modifier.testTag(testTag).size(100.dp).indication(state, indication))
+            Box(Modifier.testTag(testTag).size(100.dp).indication(dispatcher, indication))
         }
         assertThat(countDownLatch.await(1000, TimeUnit.MILLISECONDS)).isTrue()
     }
 
     @Test
     fun indication_click_receivesStateUpdates() {
-        // indicaiton should be called 3 times: 0 indication, press, and after click 0 again
+        // indication should be called 3 times: 0 indication, press, and after click 0 again
         val countDownLatch = CountDownLatch(3)
+        val interactions = mutableStateListOf<Interaction>()
+
+        val interactionSource = MutableInteractionSource()
+
         val indication = makeIndication {
-            it.value // value read
+            interactions.lastOrNull() // value read
             countDownLatch.countDown()
         }
+
+        var scope: CoroutineScope? = null
+
         rule.setContent {
+            scope = rememberCoroutineScope()
             Box(
                 Modifier
                     .testTag(testTag)
                     .size(100.dp)
                     .clickable(
-                        interactionState = remember { InteractionState() },
+                        interactionSource = interactionSource,
                         indication = indication,
                     ) {}
             )
         }
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
         assertThat(countDownLatch.count).isEqualTo(2)
         rule.onNodeWithTag(testTag)
             .assertExists()
@@ -116,75 +132,16 @@
         assertThat(countDownLatch.await(1000, TimeUnit.MILLISECONDS)).isTrue()
     }
 
-    @Test
-    @Ignore("b/155466122: multitouch is not supported yet")
-    fun indication_multiplyPress_firstWins() {
-        var lastPosition: Offset? = null
-        val indication = makeIndication {
-            it.value // value read
-            lastPosition = it.interactionPositionFor(Interaction.Pressed)
-        }
-        rule.setContent {
-            Box(
-                Modifier
-                    .testTag(testTag)
-                    .size(100.dp)
-                    .clickable(
-                        interactionState = remember { InteractionState() },
-                        indication = indication
-                    ) { }
-            )
-        }
-        assertThat(lastPosition).isNull()
-        var position1: Offset? = null
-        rule.onNodeWithTag(testTag)
-            .assertExists()
-            .performGesture {
-                position1 = Offset(center.x, center.y + 20f)
-                // pointer 1, when we have multitouch
-                down(position1!!)
-            }
-        rule.runOnIdle {
-            assertThat(lastPosition).isEqualTo(position1!!)
-        }
-        rule.onNodeWithTag(testTag)
-            .assertExists()
-            .performGesture {
-                val position2 = Offset(center.x + 20f, center.y)
-                // pointer 2, when we have multitouch
-                down(position2)
-            }
-        // should be still position1
-        rule.runOnIdle {
-            assertThat(lastPosition).isEqualTo(position1!!)
-        }
-        rule.onNodeWithTag(testTag)
-            .assertExists()
-            .performGesture {
-                // pointer 1, when we have multitouch
-                up()
-            }
-        rule.runOnIdle {
-            assertThat(lastPosition).isNull()
-        }
-        rule.onNodeWithTag(testTag)
-            .assertExists()
-            .performGesture {
-                // pointer 2, when we have multitouch
-                up()
-            }
-    }
-
-    private fun makeIndication(onDraw: (InteractionState) -> Unit): Indication {
+    private fun makeIndication(onDraw: () -> Unit): Indication {
         return object : Indication {
             @Composable
             override fun rememberUpdatedInstance(
-                interactionState: InteractionState
+                interactionSource: InteractionSource
             ): IndicationInstance {
-                return remember(interactionState) {
+                return remember(interactionSource) {
                     object : IndicationInstance {
                         override fun ContentDrawScope.drawIndication() {
-                            onDraw(interactionState)
+                            onDraw()
                         }
                     }
                 }
@@ -194,16 +151,16 @@
 
     @Test
     fun testInspectorValue() {
-        val state = InteractionState()
-        val indication = makeIndication({})
+        val state = MutableInteractionSource()
+        val indication = makeIndication {}
         rule.setContent {
             val modifier = Modifier.indication(state, indication) as InspectableValue
             assertThat(modifier.nameFallback).isEqualTo("indication")
             assertThat(modifier.valueOverride).isNull()
             assertThat(modifier.inspectableElements.map { it.name }.asIterable()).containsExactly(
                 "indication",
-                "interactionState"
+                "interactionSource"
             )
         }
     }
-}
\ No newline at end of file
+}
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/InteractionSourceTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/InteractionSourceTest.kt
new file mode 100644
index 0000000..bd9609b
--- /dev/null
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/InteractionSourceTest.kt
@@ -0,0 +1,361 @@
+/*
+ * 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
+
+import androidx.compose.foundation.interaction.DragInteraction
+import androidx.compose.foundation.interaction.FocusInteraction
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
+import androidx.compose.foundation.interaction.collectIsDraggedAsState
+import androidx.compose.foundation.interaction.collectIsFocusedAsState
+import androidx.compose.foundation.interaction.collectIsPressedAsState
+import androidx.compose.runtime.State
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.TestCoroutineScope
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@ExperimentalFoundationApi
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class InteractionSourceTest {
+
+    @get:Rule
+    val rule = createComposeRule()
+
+    private object TestInteraction1 : Interaction
+    private object TestInteraction2 : Interaction
+    private object TestInteraction3 : Interaction
+
+    @OptIn(ExperimentalCoroutinesApi::class)
+    @Test
+    fun emittingInteractionsInOrder() {
+        val interactionSource = MutableInteractionSource()
+
+        val interactions = mutableListOf<Interaction>()
+
+        val scope = TestCoroutineScope()
+
+        scope.launch {
+            interactionSource.interactions.collect {
+                interactions.add(it)
+            }
+        }
+        scope.launch {
+            interactionSource.emit(TestInteraction1)
+            interactionSource.emit(TestInteraction2)
+
+            assertThat(interactions)
+                .containsExactlyElementsIn(
+                    listOf(TestInteraction1, TestInteraction2)
+                )
+                .inOrder()
+
+            interactionSource.emit(TestInteraction3)
+
+            assertThat(interactions)
+                .containsExactlyElementsIn(
+                    listOf(TestInteraction1, TestInteraction2, TestInteraction3)
+                )
+                .inOrder()
+        }
+    }
+
+    @Test
+    fun isDragged() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
+        var isDragged: State<Boolean>? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            isDragged = interactionSource.collectIsDraggedAsState()
+        }
+
+        rule.runOnIdle {
+            assertThat(isDragged!!.value).isFalse()
+        }
+
+        var dragStart: DragInteraction.Start? = null
+
+        scope!!.launch {
+            dragStart = DragInteraction.Start()
+            interactionSource.emit(dragStart!!)
+        }
+
+        rule.runOnIdle {
+            assertThat(isDragged!!.value).isTrue()
+        }
+
+        scope!!.launch {
+            interactionSource.emit(DragInteraction.Stop(dragStart!!))
+        }
+
+        rule.runOnIdle {
+            assertThat(isDragged!!.value).isFalse()
+        }
+    }
+
+    @Test
+    fun isDragged_multipleDrags() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
+        var isDragged: State<Boolean>? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            isDragged = interactionSource.collectIsDraggedAsState()
+        }
+
+        rule.runOnIdle {
+            assertThat(isDragged!!.value).isFalse()
+        }
+
+        var dragStart: DragInteraction.Start? = null
+
+        scope!!.launch {
+            dragStart = DragInteraction.Start()
+            interactionSource.emit(dragStart!!)
+        }
+
+        rule.runOnIdle {
+            assertThat(isDragged!!.value).isTrue()
+        }
+
+        var dragStart2: DragInteraction.Start? = null
+
+        scope!!.launch {
+            dragStart2 = DragInteraction.Start()
+            interactionSource.emit(dragStart2!!)
+        }
+
+        rule.runOnIdle {
+            assertThat(isDragged!!.value).isTrue()
+        }
+
+        scope!!.launch {
+            interactionSource.emit(DragInteraction.Stop(dragStart!!))
+        }
+
+        rule.runOnIdle {
+            assertThat(isDragged!!.value).isTrue()
+        }
+
+        scope!!.launch {
+            interactionSource.emit(DragInteraction.Cancel(dragStart2!!))
+        }
+
+        rule.runOnIdle {
+            assertThat(isDragged!!.value).isFalse()
+        }
+    }
+
+    @Test
+    fun isFocused() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
+        var isFocused: State<Boolean>? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            isFocused = interactionSource.collectIsFocusedAsState()
+        }
+
+        rule.runOnIdle {
+            assertThat(isFocused!!.value).isFalse()
+        }
+
+        var focus: FocusInteraction.Focus? = null
+
+        scope!!.launch {
+            focus = FocusInteraction.Focus()
+            interactionSource.emit(focus!!)
+        }
+
+        rule.runOnIdle {
+            assertThat(isFocused!!.value).isTrue()
+        }
+
+        scope!!.launch {
+            interactionSource.emit(FocusInteraction.Unfocus(focus!!))
+        }
+
+        rule.runOnIdle {
+            assertThat(isFocused!!.value).isFalse()
+        }
+    }
+
+    @Test
+    fun isFocused_multipleFocuses() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
+        var isFocused: State<Boolean>? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            isFocused = interactionSource.collectIsFocusedAsState()
+        }
+
+        rule.runOnIdle {
+            assertThat(isFocused!!.value).isFalse()
+        }
+
+        var focus: FocusInteraction.Focus? = null
+
+        scope!!.launch {
+            focus = FocusInteraction.Focus()
+            interactionSource.emit(focus!!)
+        }
+
+        rule.runOnIdle {
+            assertThat(isFocused!!.value).isTrue()
+        }
+
+        var focus2: FocusInteraction.Focus? = null
+
+        scope!!.launch {
+            focus2 = FocusInteraction.Focus()
+            interactionSource.emit(focus2!!)
+        }
+
+        rule.runOnIdle {
+            assertThat(isFocused!!.value).isTrue()
+        }
+
+        scope!!.launch {
+            interactionSource.emit(FocusInteraction.Unfocus(focus!!))
+        }
+
+        rule.runOnIdle {
+            assertThat(isFocused!!.value).isTrue()
+        }
+
+        scope!!.launch {
+            interactionSource.emit(FocusInteraction.Unfocus(focus2!!))
+        }
+
+        rule.runOnIdle {
+            assertThat(isFocused!!.value).isFalse()
+        }
+    }
+
+    @Test
+    fun isPressed() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
+        var isPressed: State<Boolean>? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            isPressed = interactionSource.collectIsPressedAsState()
+        }
+
+        rule.runOnIdle {
+            assertThat(isPressed!!.value).isFalse()
+        }
+
+        var press: PressInteraction.Press? = null
+
+        scope!!.launch {
+            press = PressInteraction.Press(Offset.Zero)
+            interactionSource.emit(press!!)
+        }
+
+        rule.runOnIdle {
+            assertThat(isPressed!!.value).isTrue()
+        }
+
+        scope!!.launch {
+            interactionSource.emit(PressInteraction.Release(press!!))
+        }
+
+        rule.runOnIdle {
+            assertThat(isPressed!!.value).isFalse()
+        }
+    }
+
+    @Test
+    fun isPressed_multiplePresses() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
+        var isPressed: State<Boolean>? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            isPressed = interactionSource.collectIsPressedAsState()
+        }
+
+        rule.runOnIdle {
+            assertThat(isPressed!!.value).isFalse()
+        }
+
+        var press: PressInteraction.Press? = null
+
+        scope!!.launch {
+            press = PressInteraction.Press(Offset.Zero)
+            interactionSource.emit(press!!)
+        }
+
+        rule.runOnIdle {
+            assertThat(isPressed!!.value).isTrue()
+        }
+
+        var press2: PressInteraction.Press? = null
+
+        scope!!.launch {
+            press2 = PressInteraction.Press(Offset.Zero)
+            interactionSource.emit(press2!!)
+        }
+
+        rule.runOnIdle {
+            assertThat(isPressed!!.value).isTrue()
+        }
+
+        scope!!.launch {
+            interactionSource.emit(PressInteraction.Release(press!!))
+        }
+
+        rule.runOnIdle {
+            assertThat(isPressed!!.value).isTrue()
+        }
+
+        scope!!.launch {
+            interactionSource.emit(PressInteraction.Cancel(press2!!))
+        }
+
+        rule.runOnIdle {
+            assertThat(isPressed!!.value).isFalse()
+        }
+    }
+}
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ScrollableTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ScrollableTest.kt
index fb74142..fef0896 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ScrollableTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ScrollableTest.kt
@@ -25,6 +25,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
 import androidx.compose.testutils.advanceClockOnMainThreadMillis
 import androidx.compose.testutils.runBlockingWithManualClock
@@ -36,6 +37,9 @@
 import androidx.compose.ui.input.nestedscroll.NestedScrollSource
 import androidx.compose.ui.input.nestedscroll.nestedScroll
 import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.interaction.DragInteraction
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.ui.platform.InspectableValue
 import androidx.compose.ui.platform.isDebugInspectorInfoEnabled
 import androidx.compose.ui.platform.testTag
@@ -55,6 +59,9 @@
 import androidx.test.filters.LargeTest
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.yield
 import org.junit.After
@@ -742,8 +749,8 @@
 
     @Test
     @OptIn(ExperimentalTestApi::class)
-    fun scrollable_interactionState() = runBlocking {
-        val interactionState = InteractionState()
+    fun scrollable_interactionSource() = runBlocking {
+        val interactionSource = MutableInteractionSource()
         var total = 0f
         val controller = ScrollableState(
             consumeScrollDelta = {
@@ -752,16 +759,25 @@
             }
         )
 
+        var scope: CoroutineScope? = null
+
         setScrollableContent {
+            scope = rememberCoroutineScope()
             Modifier.scrollable(
-                interactionState = interactionState,
+                interactionSource = interactionSource,
                 orientation = Orientation.Horizontal,
                 state = controller
             )
         }
 
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Dragged)
+            assertThat(interactions).isEmpty()
         }
 
         rule.onNodeWithTag(scrollableBoxTag)
@@ -771,7 +787,8 @@
             }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).contains(Interaction.Dragged)
+            assertThat(interactions).hasSize(1)
+            assertThat(interactions.first()).isInstanceOf(DragInteraction.Start::class.java)
         }
 
         rule.onNodeWithTag(scrollableBoxTag)
@@ -780,14 +797,18 @@
             }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Dragged)
+            assertThat(interactions).hasSize(2)
+            assertThat(interactions.first()).isInstanceOf(DragInteraction.Start::class.java)
+            assertThat(interactions[1]).isInstanceOf(DragInteraction.Stop::class.java)
+            assertThat((interactions[1] as DragInteraction.Stop).start)
+                .isEqualTo(interactions[0])
         }
     }
 
     @Test
     @OptIn(ExperimentalTestApi::class)
-    fun scrollable_interactionState_resetWhenDisposed() = runBlocking {
-        val interactionState = InteractionState()
+    fun scrollable_interactionSource_resetWhenDisposed() = runBlocking {
+        val interactionSource = MutableInteractionSource()
         var emitScrollableBox by mutableStateOf(true)
         var total = 0f
         val controller = ScrollableState(
@@ -797,7 +818,10 @@
             }
         )
 
+        var scope: CoroutineScope? = null
+
         rule.setContent {
+            scope = rememberCoroutineScope()
             Box {
                 if (emitScrollableBox) {
                     Box(
@@ -805,7 +829,7 @@
                             .testTag(scrollableBoxTag)
                             .size(100.dp)
                             .scrollable(
-                                interactionState = interactionState,
+                                interactionSource = interactionSource,
                                 orientation = Orientation.Horizontal,
                                 state = controller
                             )
@@ -814,8 +838,14 @@
             }
         }
 
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Dragged)
+            assertThat(interactions).isEmpty()
         }
 
         rule.onNodeWithTag(scrollableBoxTag)
@@ -825,7 +855,8 @@
             }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).contains(Interaction.Dragged)
+            assertThat(interactions).hasSize(1)
+            assertThat(interactions.first()).isInstanceOf(DragInteraction.Start::class.java)
         }
 
         // Dispose scrollable
@@ -834,7 +865,11 @@
         }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Dragged)
+            assertThat(interactions).hasSize(2)
+            assertThat(interactions.first()).isInstanceOf(DragInteraction.Start::class.java)
+            assertThat(interactions[1]).isInstanceOf(DragInteraction.Cancel::class.java)
+            assertThat((interactions[1] as DragInteraction.Cancel).start)
+                .isEqualTo(interactions[0])
         }
     }
 
@@ -853,7 +888,7 @@
                 "enabled",
                 "reverseDirection",
                 "flingBehavior",
-                "interactionState",
+                "interactionSource",
             )
         }
     }
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/SelectableTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/SelectableTest.kt
index 6d35fc9b..2100042 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/SelectableTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/SelectableTest.kt
@@ -16,12 +16,16 @@
 
 package androidx.compose.foundation
 
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.selection.selectable
 import androidx.compose.foundation.text.BasicText
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.InspectableValue
@@ -44,6 +48,9 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
 import org.junit.After
 import org.junit.Before
 import org.junit.Rule
@@ -124,15 +131,18 @@
     }
 
     @Test
-    fun selectableTest_interactionState() {
-        val interactionState = InteractionState()
+    fun selectableTest_interactionSource() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         rule.setContent {
+            scope = rememberCoroutineScope()
             Box {
                 Box(
                     Modifier.selectable(
                         selected = true,
-                        interactionState = interactionState,
+                        interactionSource = interactionSource,
                         indication = null,
                         onClick = {}
                     )
@@ -142,37 +152,51 @@
             }
         }
 
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Pressed)
+            assertThat(interactions).isEmpty()
         }
 
         rule.onNodeWithText("SelectableText")
             .performGesture { down(center) }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).contains(Interaction.Pressed)
+            assertThat(interactions).hasSize(1)
+            assertThat(interactions.first()).isInstanceOf(PressInteraction.Press::class.java)
         }
 
         rule.onNodeWithText("SelectableText")
             .performGesture { up() }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Pressed)
+            assertThat(interactions).hasSize(2)
+            assertThat(interactions.first()).isInstanceOf(PressInteraction.Press::class.java)
+            assertThat(interactions[1]).isInstanceOf(PressInteraction.Release::class.java)
+            assertThat((interactions[1] as PressInteraction.Release).press)
+                .isEqualTo(interactions[0])
         }
     }
 
     @Test
-    fun selectableTest_interactionState_resetWhenDisposed() {
-        val interactionState = InteractionState()
+    fun selectableTest_interactionSource_resetWhenDisposed() {
+        val interactionSource = MutableInteractionSource()
         var emitSelectableText by mutableStateOf(true)
 
+        var scope: CoroutineScope? = null
+
         rule.setContent {
+            scope = rememberCoroutineScope()
             Box {
                 if (emitSelectableText) {
                     Box(
                         Modifier.selectable(
                             selected = true,
-                            interactionState = interactionState,
+                            interactionSource = interactionSource,
                             indication = null,
                             onClick = {}
                         )
@@ -183,15 +207,22 @@
             }
         }
 
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Pressed)
+            assertThat(interactions).isEmpty()
         }
 
         rule.onNodeWithText("SelectableText")
             .performGesture { down(center) }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).contains(Interaction.Pressed)
+            assertThat(interactions).hasSize(1)
+            assertThat(interactions.first()).isInstanceOf(PressInteraction.Press::class.java)
         }
 
         // Dispose selectable
@@ -200,7 +231,11 @@
         }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Pressed)
+            assertThat(interactions).hasSize(2)
+            assertThat(interactions.first()).isInstanceOf(PressInteraction.Press::class.java)
+            assertThat(interactions[1]).isInstanceOf(PressInteraction.Cancel::class.java)
+            assertThat((interactions[1] as PressInteraction.Cancel).press)
+                .isEqualTo(interactions[0])
         }
     }
 
@@ -224,7 +259,7 @@
         rule.setContent {
             val modifier = Modifier.selectable(
                 false,
-                interactionState = remember { InteractionState() },
+                interactionSource = remember { MutableInteractionSource() },
                 indication = null
             ) {} as InspectableValue
             assertThat(modifier.nameFallback).isEqualTo("selectable")
@@ -233,7 +268,7 @@
                 "selected",
                 "enabled",
                 "role",
-                "interactionState",
+                "interactionSource",
                 "indication",
                 "onClick"
             )
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ToggleableTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ToggleableTest.kt
index 0e54518..096b95f 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ToggleableTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ToggleableTest.kt
@@ -16,6 +16,9 @@
 
 package androidx.compose.foundation
 
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.selection.toggleable
@@ -24,6 +27,7 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.InspectableValue
@@ -50,6 +54,9 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
 import org.junit.After
 import org.junit.Before
 import org.junit.Rule
@@ -209,15 +216,18 @@
     }
 
     @Test
-    fun toggleableTest_interactionState() {
-        val interactionState = InteractionState()
+    fun toggleableTest_interactionSource() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         rule.setContent {
+            scope = rememberCoroutineScope()
             Box {
                 Box(
                     Modifier.toggleable(
                         value = true,
-                        interactionState = interactionState,
+                        interactionSource = interactionSource,
                         indication = null,
                         onValueChange = {}
                     )
@@ -227,37 +237,51 @@
             }
         }
 
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Pressed)
+            assertThat(interactions).isEmpty()
         }
 
         rule.onNodeWithText("ToggleableText")
             .performGesture { down(center) }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).contains(Interaction.Pressed)
+            assertThat(interactions).hasSize(1)
+            assertThat(interactions.first()).isInstanceOf(PressInteraction.Press::class.java)
         }
 
         rule.onNodeWithText("ToggleableText")
             .performGesture { up() }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Pressed)
+            assertThat(interactions).hasSize(2)
+            assertThat(interactions.first()).isInstanceOf(PressInteraction.Press::class.java)
+            assertThat(interactions[1]).isInstanceOf(PressInteraction.Release::class.java)
+            assertThat((interactions[1] as PressInteraction.Release).press)
+                .isEqualTo(interactions[0])
         }
     }
 
     @Test
-    fun toggleableTest_interactionState_resetWhenDisposed() {
-        val interactionState = InteractionState()
+    fun toggleableTest_interactionSource_resetWhenDisposed() {
+        val interactionSource = MutableInteractionSource()
         var emitToggleableText by mutableStateOf(true)
 
+        var scope: CoroutineScope? = null
+
         rule.setContent {
+            scope = rememberCoroutineScope()
             Box {
                 if (emitToggleableText) {
                     Box(
                         Modifier.toggleable(
                             value = true,
-                            interactionState = interactionState,
+                            interactionSource = interactionSource,
                             indication = null,
                             onValueChange = {}
                         )
@@ -268,15 +292,22 @@
             }
         }
 
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Pressed)
+            assertThat(interactions).isEmpty()
         }
 
         rule.onNodeWithText("ToggleableText")
             .performGesture { down(center) }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).contains(Interaction.Pressed)
+            assertThat(interactions).hasSize(1)
+            assertThat(interactions.first()).isInstanceOf(PressInteraction.Press::class.java)
         }
 
         // Dispose toggleable
@@ -285,7 +316,11 @@
         }
 
         rule.runOnIdle {
-            assertThat(interactionState.value).doesNotContain(Interaction.Pressed)
+            assertThat(interactions).hasSize(2)
+            assertThat(interactions.first()).isInstanceOf(PressInteraction.Press::class.java)
+            assertThat(interactions[1]).isInstanceOf(PressInteraction.Cancel::class.java)
+            assertThat((interactions[1] as PressInteraction.Cancel).press)
+                .isEqualTo(interactions[0])
         }
     }
 
@@ -310,7 +345,7 @@
             val modifier = Modifier.toggleable(
                 value = true,
                 onValueChange = {},
-                interactionState = remember { InteractionState() },
+                interactionSource = remember { MutableInteractionSource() },
                 indication = null
             ) as InspectableValue
             assertThat(modifier.nameFallback).isEqualTo("toggleable")
@@ -320,7 +355,7 @@
                 "enabled",
                 "role",
                 "indication",
-                "interactionState",
+                "interactionSource",
                 "onValueChange",
             )
         }
@@ -347,7 +382,7 @@
         rule.setContent {
             val modifier = Modifier.triStateToggleable(
                 state = ToggleableState.On,
-                interactionState = remember { InteractionState() },
+                interactionSource = remember { MutableInteractionSource() },
                 indication = null,
                 onClick = {}
             )
@@ -359,7 +394,7 @@
                 "enabled",
                 "role",
                 "indication",
-                "interactionState",
+                "interactionSource",
                 "onClick",
             )
         }
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnTest.kt
index 699ac95..47de002 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnTest.kt
@@ -37,6 +37,7 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
+import androidx.compose.testutils.assertIsEqualTo
 import androidx.compose.testutils.runBlockingWithManualClock
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
@@ -50,7 +51,6 @@
 import androidx.compose.ui.test.assertCountEquals
 import androidx.compose.ui.test.assertHeightIsEqualTo
 import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.assertIsEqualTo
 import androidx.compose.ui.test.assertIsNotDisplayed
 import androidx.compose.ui.test.assertPositionInRootIsEqualTo
 import androidx.compose.ui.test.assertTopPositionInRootIsEqualTo
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowTest.kt
index 5bee718..c5403a7 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowTest.kt
@@ -31,6 +31,7 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
+import androidx.compose.testutils.assertIsEqualTo
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.drawBehind
@@ -39,7 +40,6 @@
 import androidx.compose.ui.test.SemanticsNodeInteraction
 import androidx.compose.ui.test.assertHeightIsEqualTo
 import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.assertIsEqualTo
 import androidx.compose.ui.test.assertLeftPositionInRootIsEqualTo
 import androidx.compose.ui.test.assertPositionInRootIsEqualTo
 import androidx.compose.ui.test.assertWidthIsEqualTo
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ClickableTextTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/ClickableTextTest.kt
similarity index 67%
rename from compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ClickableTextTest.kt
rename to compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/ClickableTextTest.kt
index 66d2fdc..1ffef6c 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ClickableTextTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/ClickableTextTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package androidx.compose.foundation
+package androidx.compose.foundation.text
 
+import androidx.compose.runtime.mutableStateOf
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.junit4.createComposeRule
@@ -55,4 +56,27 @@
             verify(onClick, times(1)).invoke(any())
         }
     }
+
+    @Test
+    fun onclick_callback_whenCallbackIsUpdated() {
+        val onClick1: (Int) -> Unit = mock()
+        val onClick2: (Int) -> Unit = mock()
+        val use2 = mutableStateOf(false)
+        rule.setContent {
+            ClickableText(
+                modifier = Modifier.testTag("clickableText"),
+                text = AnnotatedString("android"),
+                onClick = if (use2.value) onClick2 else onClick1
+            )
+        }
+        use2.value = true
+        rule.waitForIdle()
+
+        rule.onNodeWithTag("clickableText").performClick()
+
+        rule.runOnIdle {
+            verify(onClick1, times(0)).invoke(any())
+            verify(onClick2, times(1)).invoke(any())
+        }
+    }
 }
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextFieldInputServiceIntegrationTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextFieldInputServiceIntegrationTest.kt
index 31c4a5f..53219e1 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextFieldInputServiceIntegrationTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextFieldInputServiceIntegrationTest.kt
@@ -25,7 +25,6 @@
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performClick
-import androidx.compose.ui.text.InternalTextApi
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.KeyboardCapitalization
 import androidx.compose.ui.text.input.ImeOptions
@@ -52,7 +51,6 @@
     @get:Rule
     val rule = createComposeRule()
 
-    @OptIn(InternalTextApi::class)
     @Test
     fun textField_ImeOptions_isPassedTo_platformTextInputService() {
         val platformTextInputService = mock<PlatformTextInputService>()
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextFieldInteractionsTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextFieldInteractionsTest.kt
index afd2fa4..11c2173 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextFieldInteractionsTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextFieldInteractionsTest.kt
@@ -16,12 +16,16 @@
 
 package androidx.compose.foundation.text
 
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.DragInteraction
+import androidx.compose.foundation.interaction.FocusInteraction
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.foundation.focusable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.focus.FocusRequester
 import androidx.compose.ui.focus.focusRequester
@@ -41,6 +45,9 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -57,185 +64,304 @@
     @Test
     fun coreTextField_interaction_pressed() {
         val state = mutableStateOf(TextFieldValue(""))
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+        var scope: CoroutineScope? = null
         rule.setContent {
+            scope = rememberCoroutineScope()
             BasicTextField(
                 modifier = Modifier.testTag(testTag),
                 value = state.value,
                 onValueChange = { state.value = it },
-                interactionState = interactionState
+                interactionSource = interactionSource
             )
         }
-        assertThat(interactionState.value).doesNotContain(Interaction.Pressed)
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
+        rule.runOnIdle {
+            assertThat(interactions).isEmpty()
+        }
         rule.onNodeWithTag(testTag)
             .performGesture {
                 down(center)
             }
-        assertThat(interactionState.value).contains(Interaction.Pressed)
+        rule.runOnIdle {
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions.filterIsInstance<PressInteraction.Press>()).hasSize(1)
+        }
         rule.onNodeWithTag(testTag)
             .performGesture {
                 up()
             }
-        assertThat(interactionState.value).doesNotContain(Interaction.Pressed)
+        rule.runOnIdle {
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions.filterIsInstance<PressInteraction.Press>()).hasSize(1)
+            assertThat(interactions.filterIsInstance<PressInteraction.Release>()).hasSize(1)
+        }
     }
 
     @Test
     fun coreTextField_interaction_pressed_removedWhenCancelled() {
         val state = mutableStateOf(TextFieldValue(""))
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+        var scope: CoroutineScope? = null
         rule.setContent {
+            scope = rememberCoroutineScope()
             BasicTextField(
                 modifier = Modifier.testTag(testTag),
                 value = state.value,
                 onValueChange = { state.value = it },
-                interactionState = interactionState
+                interactionSource = interactionSource
             )
         }
-        assertThat(interactionState.value).doesNotContain(Interaction.Pressed)
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
+        rule.runOnIdle {
+            assertThat(interactions).isEmpty()
+        }
         rule.onNodeWithTag(testTag)
             .performGesture {
                 down(center)
             }
-        assertThat(interactionState.value).contains(Interaction.Pressed)
+        rule.runOnIdle {
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions.filterIsInstance<PressInteraction.Press>()).hasSize(1)
+        }
         rule.onNodeWithTag(testTag)
             .performGesture {
                 cancel()
             }
-        assertThat(interactionState.value).doesNotContain(Interaction.Pressed)
+        rule.runOnIdle {
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions.filterIsInstance<PressInteraction.Press>()).hasSize(1)
+            assertThat(interactions.filterIsInstance<PressInteraction.Cancel>()).hasSize(1)
+        }
     }
 
     @Test
     fun coreTextField_interaction_focused() {
         val state = mutableStateOf(TextFieldValue(""))
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
         val focusRequester = FocusRequester()
+        var scope: CoroutineScope? = null
         rule.setContent {
+            scope = rememberCoroutineScope()
             BasicTextField(
                 modifier = Modifier.testTag(testTag),
                 value = state.value,
                 onValueChange = { state.value = it },
-                interactionState = interactionState
+                interactionSource = interactionSource
             )
             Box(
                 modifier = Modifier.requiredSize(10.dp).focusRequester(focusRequester).focusable(),
             )
         }
-        assertThat(interactionState.value).doesNotContain(Interaction.Focused)
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
+        rule.runOnIdle {
+            assertThat(interactions).isEmpty()
+        }
         rule.onNodeWithTag(testTag)
             .performClick()
-        assertThat(interactionState.value).contains(Interaction.Focused)
+        rule.runOnIdle {
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions.filterIsInstance<FocusInteraction.Focus>()).hasSize(1)
+        }
         rule.runOnIdle {
             // request focus on the box so TextField will lose it
             focusRequester.requestFocus()
         }
-        assertThat(interactionState.value).doesNotContain(Interaction.Focused)
+        rule.runOnIdle {
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions.filterIsInstance<FocusInteraction.Focus>()).hasSize(1)
+            assertThat(interactions.filterIsInstance<FocusInteraction.Unfocus>()).hasSize(1)
+        }
     }
 
     @Test
     fun coreTextField_interaction_horizontally_dragged() {
         val state = mutableStateOf(TextFieldValue("test ".repeat(100)))
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+        var scope: CoroutineScope? = null
         rule.setContent {
+            scope = rememberCoroutineScope()
             BasicTextField(
                 modifier = Modifier.testTag(testTag),
                 value = state.value,
                 singleLine = true,
                 onValueChange = { state.value = it },
-                interactionState = interactionState
+                interactionSource = interactionSource
             )
         }
-        assertThat(interactionState.value).doesNotContain(Interaction.Dragged)
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
+        rule.runOnIdle {
+            assertThat(interactions).isEmpty()
+        }
         rule.onNodeWithTag(testTag)
             .performGesture {
                 down(center)
                 moveBy(Offset(x = 100f, y = 0f))
             }
-        assertThat(interactionState.value).contains(Interaction.Dragged)
+        rule.runOnIdle {
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions.filterIsInstance<DragInteraction.Start>()).hasSize(1)
+        }
         rule.onNodeWithTag(testTag)
             .performGesture {
                 up()
             }
-        assertThat(interactionState.value).doesNotContain(Interaction.Dragged)
+        rule.runOnIdle {
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions.filterIsInstance<DragInteraction.Start>()).hasSize(1)
+            assertThat(interactions.filterIsInstance<DragInteraction.Stop>()).hasSize(1)
+        }
     }
 
     @Test
     fun coreTextField_interaction_dragged_horizontally_cancelled() {
         val state = mutableStateOf(TextFieldValue("test ".repeat(100)))
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+        var scope: CoroutineScope? = null
         rule.setContent {
+            scope = rememberCoroutineScope()
             BasicTextField(
                 modifier = Modifier.testTag(testTag),
                 value = state.value,
                 singleLine = true,
                 onValueChange = { state.value = it },
-                interactionState = interactionState
+                interactionSource = interactionSource
             )
         }
-        assertThat(interactionState.value).doesNotContain(Interaction.Dragged)
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
+        rule.runOnIdle {
+            assertThat(interactions).isEmpty()
+        }
         rule.onNodeWithTag(testTag)
             .performGesture {
                 down(center)
                 moveBy(Offset(x = 100f, y = 0f))
             }
-        assertThat(interactionState.value).contains(Interaction.Dragged)
+        rule.runOnIdle {
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions.filterIsInstance<DragInteraction.Start>()).hasSize(1)
+        }
         rule.onNodeWithTag(testTag)
             .performGesture {
                 cancel()
             }
-        assertThat(interactionState.value).doesNotContain(Interaction.Dragged)
+        rule.runOnIdle {
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions.filterIsInstance<DragInteraction.Start>()).hasSize(1)
+            assertThat(interactions.filterIsInstance<DragInteraction.Stop>()).hasSize(1)
+        }
     }
 
     @Test
     fun coreTextField_interaction_vertically_dragged() {
         val state = mutableStateOf(TextFieldValue("test\n".repeat(10)))
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+        var scope: CoroutineScope? = null
         rule.setContent {
+            scope = rememberCoroutineScope()
             BasicTextField(
                 modifier = Modifier.requiredSize(50.dp).testTag(testTag),
                 value = state.value,
                 maxLines = 3,
                 onValueChange = { state.value = it },
-                interactionState = interactionState
+                interactionSource = interactionSource
             )
         }
-        assertThat(interactionState.value).doesNotContain(Interaction.Dragged)
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
+        rule.runOnIdle {
+            assertThat(interactions).isEmpty()
+        }
         rule.onNodeWithTag(testTag)
             .performGesture {
                 down(center)
                 moveBy(Offset(x = 0f, y = 150f))
             }
-        assertThat(interactionState.value).contains(Interaction.Dragged)
+        rule.runOnIdle {
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions.filterIsInstance<DragInteraction.Start>()).hasSize(1)
+        }
         rule.onNodeWithTag(testTag)
             .performGesture {
                 up()
             }
-        assertThat(interactionState.value).doesNotContain(Interaction.Dragged)
+        rule.runOnIdle {
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions.filterIsInstance<DragInteraction.Start>()).hasSize(1)
+            assertThat(interactions.filterIsInstance<DragInteraction.Stop>()).hasSize(1)
+        }
     }
 
     @Test
     fun coreTextField_interaction_dragged_vertically_cancelled() {
         val state = mutableStateOf(TextFieldValue("test\n".repeat(10)))
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+        var scope: CoroutineScope? = null
         rule.setContent {
+            scope = rememberCoroutineScope()
             BasicTextField(
                 modifier = Modifier.requiredSize(50.dp).testTag(testTag),
                 value = state.value,
                 maxLines = 3,
                 onValueChange = { state.value = it },
-                interactionState = interactionState
+                interactionSource = interactionSource
             )
         }
-        assertThat(interactionState.value).doesNotContain(Interaction.Dragged)
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
+        rule.runOnIdle {
+            assertThat(interactions).isEmpty()
+        }
         rule.onNodeWithTag(testTag)
             .performGesture {
                 down(center)
                 moveBy(Offset(x = 0f, y = 150f))
             }
-        assertThat(interactionState.value).contains(Interaction.Dragged)
+        rule.runOnIdle {
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions.filterIsInstance<DragInteraction.Start>()).hasSize(1)
+        }
         rule.onNodeWithTag(testTag)
             .performGesture {
                 cancel()
             }
-        assertThat(interactionState.value).doesNotContain(Interaction.Dragged)
+        rule.runOnIdle {
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions.filterIsInstance<DragInteraction.Start>()).hasSize(1)
+            assertThat(interactions.filterIsInstance<DragInteraction.Stop>()).hasSize(1)
+        }
     }
 }
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextLayoutTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextLayoutTest.kt
index caaa0a0..ec22415 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextLayoutTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextLayoutTest.kt
@@ -22,8 +22,14 @@
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.layout.FirstBaseline
+import androidx.compose.ui.layout.IntrinsicMeasurable
+import androidx.compose.ui.layout.IntrinsicMeasureScope
 import androidx.compose.ui.layout.LastBaseline
 import androidx.compose.ui.layout.Layout
+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.onGloballyPositioned
 import androidx.compose.ui.node.Ref
 import androidx.compose.ui.text.AnnotatedString
@@ -130,33 +136,62 @@
             val text = @Composable {
                 TestingText("aa aa ")
             }
-            Layout(
-                text,
-                minIntrinsicWidthMeasureBlock = { _, _ -> 0 },
-                minIntrinsicHeightMeasureBlock = { _, _ -> 0 },
-                maxIntrinsicWidthMeasureBlock = { _, _ -> 0 },
-                maxIntrinsicHeightMeasureBlock = { _, _ -> 0 }
-            ) { measurables, _ ->
-                val textMeasurable = measurables.first()
-                // Min width.
-                assertThat(textWidth).isEqualTo(textMeasurable.minIntrinsicWidth(0))
-                // Min height.
-                assertThat(textMeasurable.minIntrinsicHeight(textWidth)).isGreaterThan(textHeight)
-                assertThat(textHeight).isEqualTo(textMeasurable.minIntrinsicHeight(doubleTextWidth))
-                assertThat(textHeight)
-                    .isEqualTo(textMeasurable.minIntrinsicHeight(Constraints.Infinity))
-                // Max width.
-                assertThat(doubleTextWidth).isEqualTo(textMeasurable.maxIntrinsicWidth(0))
-                // Max height.
-                assertThat(textMeasurable.maxIntrinsicHeight(textWidth)).isGreaterThan(textHeight)
-                assertThat(textHeight).isEqualTo(textMeasurable.maxIntrinsicHeight(doubleTextWidth))
-                assertThat(textHeight)
-                    .isEqualTo(textMeasurable.maxIntrinsicHeight(Constraints.Infinity))
+            val measurePolicy = remember {
+                object : MeasurePolicy {
+                    override fun MeasureScope.measure(
+                        measurables: List<Measurable>,
+                        constraints: Constraints
+                    ): MeasureResult {
+                        val textMeasurable = measurables.first()
+                        // Min width.
+                        assertThat(textWidth).isEqualTo(textMeasurable.minIntrinsicWidth(0))
+                        // Min height.
+                        assertThat(textMeasurable.minIntrinsicHeight(textWidth))
+                            .isGreaterThan(textHeight)
+                        assertThat(textHeight)
+                            .isEqualTo(textMeasurable.minIntrinsicHeight(doubleTextWidth))
+                        assertThat(textHeight)
+                            .isEqualTo(textMeasurable.minIntrinsicHeight(Constraints.Infinity))
+                        // Max width.
+                        assertThat(doubleTextWidth).isEqualTo(textMeasurable.maxIntrinsicWidth(0))
+                        // Max height.
+                        assertThat(textMeasurable.maxIntrinsicHeight(textWidth))
+                            .isGreaterThan(textHeight)
+                        assertThat(textHeight)
+                            .isEqualTo(textMeasurable.maxIntrinsicHeight(doubleTextWidth))
+                        assertThat(textHeight)
+                            .isEqualTo(textMeasurable.maxIntrinsicHeight(Constraints.Infinity))
 
-                intrinsicsLatch.countDown()
+                        intrinsicsLatch.countDown()
 
-                layout(0, 0) {}
+                        return layout(0, 0) {}
+                    }
+
+                    override fun IntrinsicMeasureScope.minIntrinsicWidth(
+                        measurables: List<IntrinsicMeasurable>,
+                        height: Int
+                    ) = 0
+
+                    override fun IntrinsicMeasureScope.minIntrinsicHeight(
+                        measurables: List<IntrinsicMeasurable>,
+                        width: Int
+                    ) = 0
+
+                    override fun IntrinsicMeasureScope.maxIntrinsicWidth(
+                        measurables: List<IntrinsicMeasurable>,
+                        height: Int
+                    ) = 0
+
+                    override fun IntrinsicMeasureScope.maxIntrinsicHeight(
+                        measurables: List<IntrinsicMeasurable>,
+                        width: Int
+                    ) = 0
+                }
             }
+            Layout(
+                content = text,
+                measurePolicy = measurePolicy
+            )
         }
         assertThat(intrinsicsLatch.await(1, TimeUnit.SECONDS)).isTrue()
     }
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 b6c2a5c..dc3fb45 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
@@ -52,6 +52,7 @@
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.FlakyTest
 import androidx.test.filters.LargeTest
 import com.google.common.truth.Truth.assertThat
 import com.nhaarman.mockitokotlin2.mock
@@ -83,6 +84,8 @@
     private val boxSize = 40.dp
 
     private val hapticFeedback = mock<HapticFeedback>()
+
+    @FlakyTest(bugId = 179770443)
     @Test
     fun click_anywhere_to_cancel() {
         // Setup. Long press to create a selection.
@@ -119,6 +122,7 @@
         }
     }
 
+    @FlakyTest(bugId = 179770443)
     @Test
     fun select_anotherContainer_cancelOld() {
         // Setup. Long press to create a selection.
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/TextSelectionColorsScreenshotTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/TextSelectionColorsScreenshotTest.kt
index db69c09..f067ec3 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/TextSelectionColorsScreenshotTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/TextSelectionColorsScreenshotTest.kt
@@ -43,6 +43,7 @@
 import androidx.compose.ui.text.style.ResolvedTextDirection
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.FlakyTest
 import androidx.test.filters.LargeTest
 import androidx.test.filters.SdkSuppress
 import androidx.test.screenshot.AndroidXScreenshotTestRule
@@ -67,6 +68,7 @@
     @get:Rule
     val screenshotRule = AndroidXScreenshotTestRule(GOLDEN_UI)
 
+    @FlakyTest(bugId = 179770443)
     @Test
     fun text_defaultSelectionColors() {
         rule.setContent {
@@ -85,6 +87,7 @@
             .assertAgainstGolden(screenshotRule, "text_defaultSelectionColors")
     }
 
+    @FlakyTest(bugId = 179770443)
     @Test
     fun text_customSelectionColors() {
         rule.setContent {
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/InactiveTextFieldTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/InactiveTextFieldTest.kt
deleted file mode 100644
index 98a2f91..0000000
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/InactiveTextFieldTest.kt
+++ /dev/null
@@ -1,126 +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.textfield
-
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
-import androidx.compose.foundation.layout.requiredWidth
-import androidx.compose.foundation.text.InactiveTextField
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.composed
-import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusRequester
-import androidx.compose.ui.platform.testTag
-import androidx.compose.foundation.text.selection.LocalSelectionRegistrar
-import androidx.compose.ui.test.assertIsEnabled
-import androidx.compose.ui.test.assertIsFocused
-import androidx.compose.ui.test.assertIsNotEnabled
-import androidx.compose.ui.test.junit4.createComposeRule
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.text.input.TextFieldValue
-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
-
-@RunWith(AndroidJUnit4::class)
-@MediumTest
-class InactiveTextFieldTest {
-    @get:Rule
-    val rule = createComposeRule()
-
-    private val text = TextFieldValue("test")
-    private val tag = "InactiveTextField"
-
-    @Test
-    fun inactiveTextField_disabled_noFocus() {
-        val interactionState = InteractionState()
-        val focusRequester = FocusRequester()
-        rule.setContent {
-            InactiveTextField(
-                value = text,
-                modifier = Modifier.testTag(tag).focusRequester(focusRequester),
-                enabled = false,
-                interactionState = interactionState
-            )
-        }
-
-        rule.runOnIdle {
-            focusRequester.requestFocus()
-            assertThat(interactionState.contains(Interaction.Focused)).isFalse()
-        }
-
-        rule.onNodeWithTag(tag)
-            .assertIsNotEnabled()
-    }
-
-    @Test
-    fun inactiveTextField_enabled_focusable() {
-        val interactionState = InteractionState()
-        val focusRequester = FocusRequester()
-        rule.setContent {
-            InactiveTextField(
-                value = text,
-                modifier = Modifier.testTag(tag).focusRequester(focusRequester),
-                enabled = true,
-                interactionState = interactionState
-            )
-        }
-        rule.runOnIdle {
-            assertThat(interactionState.contains(Interaction.Focused)).isFalse()
-        }
-
-        rule.runOnIdle {
-            focusRequester.requestFocus()
-            assertThat(interactionState.contains(Interaction.Focused)).isTrue()
-        }
-        rule.onNodeWithTag(tag)
-            .assertIsFocused()
-            .assertIsEnabled()
-    }
-
-    @Test
-    fun inactiveTextField_disabled_noSelection() {
-        rule.setContent {
-            InactiveTextField(
-                value = text,
-                modifier = Modifier.testTag(tag).requiredWidth(100.dp).composed {
-                    assertThat(LocalSelectionRegistrar.current).isNull()
-                    Modifier
-                },
-                enabled = false
-            )
-        }
-    }
-
-    @Test
-    fun inactiveTextField_enabled_selectable() {
-        rule.setContent {
-            InactiveTextField(
-                value = text,
-                modifier = Modifier.composed {
-                    assertThat(LocalSelectionRegistrar.current).isNotNull()
-                    Modifier
-                },
-                enabled = true
-            )
-        }
-    }
-}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/SoftwareKeyboardTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/SoftwareKeyboardTest.kt
deleted file mode 100644
index 12bf1c3..0000000
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/SoftwareKeyboardTest.kt
+++ /dev/null
@@ -1,83 +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.textfield
-
-import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.text.BasicTextField
-import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.LocalTextInputService
-import androidx.compose.ui.test.hasSetTextAction
-import androidx.compose.ui.test.junit4.createComposeRule
-import androidx.compose.ui.test.performClick
-import androidx.compose.ui.text.SoftwareKeyboardController
-import androidx.compose.ui.text.input.TextInputService
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.MediumTest
-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.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@MediumTest
-@RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalFoundationApi::class)
-class SoftwareKeyboardTest {
-    @get:Rule
-    val rule = createComposeRule()
-
-    @Test
-    fun textField_onTextLayoutCallback() {
-        val textInputService = mock<TextInputService>()
-        val inputSessionToken = 10 // any positive number is fine.
-
-        whenever(textInputService.startInput(any(), any(), any(), any()))
-            .thenReturn(inputSessionToken)
-
-        val onTextInputStarted: (SoftwareKeyboardController) -> Unit = mock()
-        rule.setContent {
-            CompositionLocalProvider(
-                LocalTextInputService provides textInputService
-            ) {
-                val state = remember { mutableStateOf("") }
-                BasicTextField(
-                    value = state.value,
-                    modifier = Modifier.fillMaxSize(),
-                    onValueChange = {
-                        state.value = it
-                    },
-                    onTextInputStarted = onTextInputStarted
-                )
-            }
-        }
-
-        // Perform click to focus in.
-        rule.onNode(hasSetTextAction())
-            .performClick()
-
-        rule.runOnIdle {
-            verify(onTextInputStarted, times(1)).invoke(any())
-        }
-    }
-}
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 467fc71..58ec5d0 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
@@ -32,6 +32,7 @@
 import androidx.compose.ui.text.input.DeleteSurroundingTextCommand
 import androidx.compose.ui.text.input.EditCommand
 import androidx.compose.ui.text.input.FinishComposingTextCommand
+import androidx.compose.ui.text.input.PlatformTextInputService
 import androidx.compose.ui.text.input.SetComposingRegionCommand
 import androidx.compose.ui.text.input.SetComposingTextCommand
 import androidx.compose.ui.text.input.SetSelectionCommand
@@ -47,7 +48,6 @@
 import com.nhaarman.mockitokotlin2.mock
 import com.nhaarman.mockitokotlin2.times
 import com.nhaarman.mockitokotlin2.verify
-import com.nhaarman.mockitokotlin2.whenever
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
@@ -66,11 +66,8 @@
 
     @Before
     fun setUp() {
-        val textInputService = mock<TextInputService>()
-        val inputSessionToken = 10 // any positive number is fine.
-
-        whenever(textInputService.startInput(any(), any(), any(), any()))
-            .thenReturn(inputSessionToken)
+        val platformTextInputService = mock<PlatformTextInputService>()
+        val textInputService = TextInputService(platformTextInputService)
 
         rule.setContent {
             CompositionLocalProvider(
@@ -101,7 +98,7 @@
         rule.runOnIdle {
             // Verify startInput is called and capture the callback.
             val onEditCommandCaptor = argumentCaptor<(List<EditCommand>) -> Unit>()
-            verify(textInputService, times(1)).startInput(
+            verify(platformTextInputService, times(1)).startInput(
                 value = any(),
                 imeOptions = any(),
                 onEditCommand = onEditCommandCaptor.capture(),
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldScrollTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldScrollTest.kt
index ddf60aa..93cd20a 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldScrollTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldScrollTest.kt
@@ -18,7 +18,7 @@
 
 import android.os.Build
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.ScrollState
 import androidx.compose.foundation.background
 import androidx.compose.foundation.gestures.Orientation
@@ -360,15 +360,15 @@
     @Test
     fun textFieldScrollable_testInspectorValue() {
         val position = TextFieldScrollerPosition(Orientation.Vertical, 10f)
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
         rule.setContent {
             val modifier =
-                Modifier.textFieldScrollable(position, interactionState) as InspectableValue
+                Modifier.textFieldScrollable(position, interactionSource) as InspectableValue
             assertThat(modifier.nameFallback).isEqualTo("textFieldScrollable")
             assertThat(modifier.valueOverride).isNull()
             assertThat(modifier.inspectableElements.map { it.name }.asIterable()).containsExactly(
                 "scrollerPosition",
-                "interactionState",
+                "interactionSource",
                 "enabled"
             )
         }
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 91a9e23..1867880 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
@@ -21,12 +21,13 @@
 
 import android.os.Build
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.FocusInteraction
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
@@ -36,11 +37,12 @@
 import androidx.compose.foundation.text.BasicTextField
 import androidx.compose.foundation.text.KeyboardOptions
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.testutils.assertShape
@@ -87,6 +89,7 @@
 import androidx.compose.ui.text.input.EditCommand
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.PasswordVisualTransformation
+import androidx.compose.ui.text.input.PlatformTextInputService
 import androidx.compose.ui.text.input.TextFieldValue
 import androidx.compose.ui.text.input.TextFieldValue.Companion.Saver
 import androidx.compose.ui.text.input.TextInputService
@@ -100,11 +103,12 @@
 import com.nhaarman.mockitokotlin2.any
 import com.nhaarman.mockitokotlin2.argumentCaptor
 import com.nhaarman.mockitokotlin2.atLeastOnce
-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 kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -120,7 +124,7 @@
 
     @Test
     fun textField_focusInSemantics() {
-        val inputService = mock<TextInputService>()
+        val inputService = TextInputService(mock())
 
         var isFocused = false
         rule.setContent {
@@ -157,11 +161,8 @@
 
     @Test
     fun textField_commitTexts() {
-        val textInputService = mock<TextInputService>()
-        val inputSessionToken = 10 // any positive number is fine.
-
-        whenever(textInputService.startInput(any(), any(), any(), any()))
-            .thenReturn(inputSessionToken)
+        val platformTextInputService = mock<PlatformTextInputService>()
+        val textInputService = TextInputService(platformTextInputService)
 
         rule.setContent {
             CompositionLocalProvider(
@@ -177,7 +178,7 @@
         rule.runOnIdle {
             // Verify startInput is called and capture the callback.
             val onEditCommandCaptor = argumentCaptor<(List<EditCommand>) -> Unit>()
-            verify(textInputService, times(1)).startInput(
+            verify(platformTextInputService, times(1)).startInput(
                 value = any(),
                 imeOptions = any(),
                 onEditCommand = onEditCommandCaptor.capture(),
@@ -204,8 +205,8 @@
 
         rule.runOnIdle {
             val stateCaptor = argumentCaptor<TextFieldValue>()
-            verify(textInputService, atLeastOnce())
-                .updateState(eq(inputSessionToken), any(), stateCaptor.capture())
+            verify(platformTextInputService, atLeastOnce())
+                .updateState(any(), stateCaptor.capture())
 
             // Don't care about the intermediate state update. It should eventually be "1a2b3".
             assertThat(stateCaptor.lastValue.text).isEqualTo("1a2b3")
@@ -228,11 +229,8 @@
 
     @Test
     fun textField_commitTexts_state_may_not_set() {
-        val textInputService = mock<TextInputService>()
-        val inputSessionToken = 10 // any positive number is fine.
-
-        whenever(textInputService.startInput(any(), any(), any(), any()))
-            .thenReturn(inputSessionToken)
+        val platformTextInputService = mock<PlatformTextInputService>()
+        val textInputService = TextInputService(platformTextInputService)
 
         rule.setContent {
             CompositionLocalProvider(
@@ -248,7 +246,7 @@
         rule.runOnIdle {
             // Verify startInput is called and capture the callback.
             val onEditCommandCaptor = argumentCaptor<(List<EditCommand>) -> Unit>()
-            verify(textInputService, times(1)).startInput(
+            verify(platformTextInputService, times(1)).startInput(
                 value = any(),
                 imeOptions = any(),
                 onEditCommand = onEditCommandCaptor.capture(),
@@ -275,8 +273,8 @@
 
         rule.runOnIdle {
             val stateCaptor = argumentCaptor<TextFieldValue>()
-            verify(textInputService, atLeastOnce())
-                .updateState(eq(inputSessionToken), any(), stateCaptor.capture())
+            verify(platformTextInputService, atLeastOnce())
+                .updateState(any(), stateCaptor.capture())
 
             // Don't care about the intermediate state update. It should eventually be "123" since
             // the rejects if the incoming model contains alphabets.
@@ -286,11 +284,8 @@
 
     @Test
     fun textField_onTextLayoutCallback() {
-        val textInputService = mock<TextInputService>()
-        val inputSessionToken = 10 // any positive number is fine.
-
-        whenever(textInputService.startInput(any(), any(), any(), any()))
-            .thenReturn(inputSessionToken)
+        val platformTextInputService = mock<PlatformTextInputService>()
+        val textInputService = TextInputService(platformTextInputService)
 
         val onTextLayout: (TextLayoutResult) -> Unit = mock()
         rule.setContent {
@@ -315,7 +310,7 @@
         rule.runOnIdle {
             // Verify startInput is called and capture the callback.
             val onEditCommandCaptor = argumentCaptor<(List<EditCommand>) -> Unit>()
-            verify(textInputService, times(1)).startInput(
+            verify(platformTextInputService, times(1)).startInput(
                 value = any(),
                 imeOptions = any(),
                 onEditCommand = onEditCommandCaptor.capture(),
@@ -677,8 +672,12 @@
 
     @Test
     fun decorationBox_clickable() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
+
         rule.setContent {
+            scope = rememberCoroutineScope()
             Column {
                 BasicTextField(
                     value = "test",
@@ -693,13 +692,19 @@
                             it()
                         }
                     },
-                    interactionState = interactionState
+                    interactionSource = interactionSource
                 )
             }
         }
 
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
         rule.runOnIdle {
-            assertThat(interactionState.contains(Interaction.Focused)).isFalse()
+            assertThat(interactions).isEmpty()
         }
 
         // click outside core text field area
@@ -709,7 +714,8 @@
             }
 
         rule.runOnIdle {
-            assertThat(interactionState.contains(Interaction.Focused)).isTrue()
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions.filterIsInstance<FocusInteraction.Focus>()).hasSize(1)
         }
     }
 }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/TouchMode.android.kt
similarity index 79%
rename from compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt
rename to compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/TouchMode.android.kt
index bae8c9a..bd1aeb1 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/TouchMode.android.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-package androidx.compose.ui.input.pointer
+package androidx.compose.foundation.text
 
-@MouseTemporaryApi
-expect val isMouseInput: Boolean
\ No newline at end of file
+internal actual val isInTouchMode = true
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.android.kt
similarity index 65%
copy from compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt
copy to compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.android.kt
index 63fdeeb..0227ab0 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.android.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
-package androidx.compose.foundation.layout
+package androidx.compose.foundation.text.selection
 
-@RequiresOptIn("The API of this layout is experimental and is likely to change in the future.")
-annotation class ExperimentalLayout
+import androidx.compose.ui.input.key.KeyEvent
+
+// TODO(b/139322105) Implement for Android when hardware keyboard is implemented
+internal actual fun isCopyKeyEvent(keyEvent: KeyEvent) = false
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Clickable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Clickable.kt
index 6051969..95c6335 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Clickable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Clickable.kt
@@ -17,9 +17,13 @@
 package androidx.compose.foundation
 
 import androidx.compose.foundation.gestures.detectTapGestures
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.rememberUpdatedState
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.composed
@@ -33,6 +37,7 @@
 import androidx.compose.ui.semantics.onLongClick
 import androidx.compose.ui.semantics.role
 import androidx.compose.ui.semantics.semantics
+import kotlinx.coroutines.launch
 
 /**
  * Configure component to receive clicks via input or accessibility "click" event.
@@ -40,8 +45,8 @@
  * Add this modifier to the element to make it clickable within its bounds and show a default
  * indication when it's pressed.
  *
- * This version has no [InteractionState] or [Indication] parameters, default indication from
- * [LocalIndication] will be used. To specify [InteractionState] or [Indication], use another
+ * This version has no [MutableInteractionSource] or [Indication] parameters, default indication from
+ * [LocalIndication] will be used. To specify [MutableInteractionSource] or [Indication], use another
  * overload.
  *
  * If you need to support double click or long click alongside the single click, consider
@@ -76,7 +81,7 @@
         onClick = onClick,
         role = role,
         indication = LocalIndication.current,
-        interactionState = remember { InteractionState() }
+        interactionSource = remember { MutableInteractionSource() }
     )
 }
 
@@ -91,9 +96,9 @@
  *
  * @sample androidx.compose.foundation.samples.ClickableSample
  *
- * @param interactionState [InteractionState] that will be updated when this Clickable is
- * pressed, using [Interaction.Pressed]. Only initial (first) press will be recorded and added to
- * [InteractionState]
+ * @param interactionSource [MutableInteractionSource] that will be used to dispatch
+ * [PressInteraction.Press] when this clickable is pressed. Only the initial (first) press will be
+ * recorded and dispatched with [MutableInteractionSource].
  * @param indication indication to be shown when modified element is pressed. Be default,
  * indication from [LocalIndication] will be used. Pass `null` to show no indication, or
  * current value from [LocalIndication] to show theme default
@@ -106,7 +111,7 @@
  */
 @Suppress("DEPRECATION")
 fun Modifier.clickable(
-    interactionState: InteractionState,
+    interactionSource: MutableInteractionSource,
     indication: Indication?,
     enabled: Boolean = true,
     onClickLabel: String? = null,
@@ -114,21 +119,60 @@
     onClick: () -> Unit
 ) = composed(
     factory = {
+        val scope = rememberCoroutineScope()
+        val pressedInteraction = remember { mutableStateOf<PressInteraction.Press?>(null) }
         val interactionUpdate =
             if (enabled) {
                 Modifier.pressIndicatorGestureFilter(
-                    onStart = { interactionState.addInteraction(Interaction.Pressed, it) },
-                    onStop = { interactionState.removeInteraction(Interaction.Pressed) },
-                    onCancel = { interactionState.removeInteraction(Interaction.Pressed) }
+                    onStart = {
+                        scope.launch {
+                            // Remove any old interactions if we didn't fire stop / cancel properly
+                            pressedInteraction.value?.let { oldValue ->
+                                val interaction = PressInteraction.Cancel(oldValue)
+                                interactionSource.emit(interaction)
+                                pressedInteraction.value = null
+                            }
+                            val interaction = PressInteraction.Press(it)
+                            interactionSource.emit(interaction)
+                            pressedInteraction.value = interaction
+                        }
+                    },
+                    onStop = {
+                        scope.launch {
+                            pressedInteraction.value?.let {
+                                val interaction = PressInteraction.Release(it)
+                                interactionSource.emit(interaction)
+                                pressedInteraction.value = null
+                            }
+                        }
+                    },
+                    onCancel = {
+                        scope.launch {
+                            pressedInteraction.value?.let {
+                                val interaction = PressInteraction.Cancel(it)
+                                interactionSource.emit(interaction)
+                                pressedInteraction.value = null
+                            }
+                        }
+                    }
                 )
             } else {
                 Modifier
             }
         val tap = if (enabled) tapGestureFilter(onTap = { onClick() }) else Modifier
+        DisposableEffect(interactionSource) {
+            onDispose {
+                pressedInteraction.value?.let { oldValue ->
+                    val interaction = PressInteraction.Cancel(oldValue)
+                    interactionSource.tryEmit(interaction)
+                    pressedInteraction.value = null
+                }
+            }
+        }
         Modifier
             .genericClickableWithoutGesture(
                 gestureModifiers = Modifier.then(interactionUpdate).then(tap),
-                interactionState = interactionState,
+                interactionSource = interactionSource,
                 indication = indication,
                 enabled = enabled,
                 onClickLabel = onClickLabel,
@@ -145,7 +189,7 @@
         properties["role"] = role
         properties["onClick"] = onClick
         properties["indication"] = indication
-        properties["interactionState"] = interactionState
+        properties["interactionSource"] = interactionSource
     }
 )
 
@@ -157,9 +201,9 @@
  *
  * If you need only click handling, and no double or long clicks, consider using [clickable]
  *
- * This version has no [InteractionState] or [Indication] parameters, default indication from
- * [LocalIndication] will be used. To specify [InteractionState] or [Indication], use another
- * overload.
+ * This version has no [MutableInteractionSource] or [Indication] parameters, default indication
+ * from [LocalIndication] will be used. To specify [MutableInteractionSource] or [Indication],
+ * use another overload.
  *
  * @sample androidx.compose.foundation.samples.ClickableSample
  *
@@ -203,7 +247,7 @@
         onClick = onClick,
         role = role,
         indication = LocalIndication.current,
-        interactionState = remember { InteractionState() }
+        interactionSource = remember { MutableInteractionSource() }
     )
 }
 
@@ -219,9 +263,9 @@
  *
  * @sample androidx.compose.foundation.samples.ClickableSample
  *
- * @param interactionState [InteractionState] that will be updated when this Clickable is
- * pressed, using [Interaction.Pressed]. Only initial (first) press will be recorded and added to
- * [InteractionState]
+ * @param interactionSource [MutableInteractionSource] that will be used to emit
+ * [PressInteraction.Press] when this clickable is pressed. Only the initial (first) press will be
+ * recorded and emitted with [MutableInteractionSource].
  * @param indication indication to be shown when modified element is pressed. Be default,
  * indication from [LocalIndication] will be used. Pass `null` to show no indication, or
  * current value from [LocalIndication] to show theme default
@@ -237,7 +281,7 @@
  */
 @ExperimentalFoundationApi
 fun Modifier.combinedClickable(
-    interactionState: InteractionState,
+    interactionSource: MutableInteractionSource,
     indication: Indication?,
     enabled: Boolean = true,
     onClickLabel: String? = null,
@@ -248,8 +292,10 @@
     onClick: () -> Unit
 ) = composed(
     factory = {
+        val scope = rememberCoroutineScope()
         val onClickState = rememberUpdatedState(onClick)
-        val interactionStateState = rememberUpdatedState(interactionState)
+        val interactionSourceState = rememberUpdatedState(interactionSource)
+        val pressedInteraction = remember { mutableStateOf<PressInteraction.Press?>(null) }
         val gesture = if (enabled) {
             Modifier.pointerInput(onDoubleClick, onLongClick) {
                 detectTapGestures(
@@ -264,9 +310,25 @@
                         null
                     },
                     onPress = {
-                        interactionStateState.value.addInteraction(Interaction.Pressed, it)
+                        scope.launch {
+                            // Remove any old interactions if we didn't fire stop / cancel properly
+                            pressedInteraction.value?.let { oldValue ->
+                                val interaction = PressInteraction.Cancel(oldValue)
+                                interactionSourceState.value.emit(interaction)
+                                pressedInteraction.value = null
+                            }
+                            val interaction = PressInteraction.Press(it)
+                            interactionSourceState.value.emit(interaction)
+                            pressedInteraction.value = interaction
+                        }
                         tryAwaitRelease()
-                        interactionStateState.value.removeInteraction(Interaction.Pressed)
+                        scope.launch {
+                            pressedInteraction.value?.let { oldValue ->
+                                val interaction = PressInteraction.Release(oldValue)
+                                interactionSourceState.value.emit(interaction)
+                                pressedInteraction.value = null
+                            }
+                        }
                     },
                     onTap = { onClickState.value.invoke() }
                 )
@@ -274,10 +336,21 @@
         } else {
             Modifier
         }
+        DisposableEffect(interactionSource) {
+            onDispose {
+                scope.launch {
+                    pressedInteraction.value?.let { oldValue ->
+                        val interaction = PressInteraction.Cancel(oldValue)
+                        interactionSourceState.value.emit(interaction)
+                        pressedInteraction.value = null
+                    }
+                }
+            }
+        }
         Modifier
             .genericClickableWithoutGesture(
                 gestureModifiers = gesture,
-                interactionState = interactionState,
+                interactionSource = interactionSource,
                 indication = indication,
                 enabled = enabled,
                 onClickLabel = onClickLabel,
@@ -297,7 +370,7 @@
         properties["onLongClick"] = onLongClick
         properties["onLongClickLabel"] = onLongClickLabel
         properties["indication"] = indication
-        properties["interactionState"] = interactionState
+        properties["interactionSource"] = interactionSource
     }
 )
 
@@ -305,7 +378,7 @@
 @Suppress("ComposableModifierFactory")
 internal fun Modifier.genericClickableWithoutGesture(
     gestureModifiers: Modifier,
-    interactionState: InteractionState,
+    interactionSource: MutableInteractionSource,
     indication: Indication?,
     enabled: Boolean = true,
     onClickLabel: String? = null,
@@ -327,13 +400,8 @@
             disabled()
         }
     }
-    DisposableEffect(interactionState) {
-        onDispose {
-            interactionState.removeInteraction(Interaction.Pressed)
-        }
-    }
     return this
         .then(semanticModifier)
-        .indication(interactionState, indication)
+        .indication(interactionSource, indication)
         .then(gestureModifiers)
 }
\ No newline at end of file
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Expect.kt
similarity index 66%
copy from compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt
copy to compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Expect.kt
index 63fdeeb..703fdd5 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Expect.kt
@@ -1,5 +1,7 @@
+// ktlint-disable filename
+
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +16,11 @@
  * limitations under the License.
  */
 
-package androidx.compose.foundation.layout
+package androidx.compose.foundation
 
-@RequiresOptIn("The API of this layout is experimental and is likely to change in the future.")
-annotation class ExperimentalLayout
+expect class AtomicReference<V>(value: V) {
+    fun get(): V
+    fun set(value: V)
+    fun getAndSet(value: V): V
+    fun compareAndSet(expect: V, newValue: V): Boolean
+}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Focusable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Focusable.kt
index 26ee83c..71f3598 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Focusable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Focusable.kt
@@ -16,10 +16,13 @@
 
 package androidx.compose.foundation
 
+import androidx.compose.foundation.interaction.FocusInteraction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.composed
@@ -29,6 +32,7 @@
 import androidx.compose.ui.platform.debugInspectorInfo
 import androidx.compose.ui.semantics.focused
 import androidx.compose.ui.semantics.semantics
+import kotlinx.coroutines.launch
 
 /**
  * Configure component to be focusable via focus system or accessibility "focus" event.
@@ -38,28 +42,40 @@
  * @sample androidx.compose.foundation.samples.FocusableSample
  *
  * @param enabled Controls the enabled state. When `false`, element won't participate in the focus
- * @param interactionState [InteractionState] that will be updated to contain [Interaction.Focused]
- * when this focusable is focused
+ * @param interactionSource [MutableInteractionSource] that will be used to emit
+ * [FocusInteraction.Focus] when this element is being focused.
  */
 fun Modifier.focusable(
     enabled: Boolean = true,
-    interactionState: InteractionState? = null,
+    interactionSource: MutableInteractionSource? = null,
 ) = composed(
     inspectorInfo = debugInspectorInfo {
         name = "focusable"
         properties["enabled"] = enabled
-        properties["interactionState"] = interactionState
+        properties["interactionSource"] = interactionSource
     }
 ) {
+    val scope = rememberCoroutineScope()
+    val focusedInteraction = remember { mutableStateOf<FocusInteraction.Focus?>(null) }
     var isFocused by remember { mutableStateOf(false) }
-    DisposableEffect(Unit) {
+    DisposableEffect(interactionSource) {
         onDispose {
-            interactionState?.removeInteraction(Interaction.Focused)
+            focusedInteraction.value?.let { oldValue ->
+                val interaction = FocusInteraction.Unfocus(oldValue)
+                interactionSource?.tryEmit(interaction)
+                focusedInteraction.value = null
+            }
         }
     }
     DisposableEffect(enabled) {
         if (!enabled) {
-            interactionState?.removeInteraction(Interaction.Focused)
+            scope.launch {
+                focusedInteraction.value?.let { oldValue ->
+                    val interaction = FocusInteraction.Unfocus(oldValue)
+                    interactionSource?.emit(interaction)
+                    focusedInteraction.value = null
+                }
+            }
         }
         onDispose { }
     }
@@ -72,9 +88,24 @@
             .onFocusChanged {
                 isFocused = it.isFocused
                 if (isFocused) {
-                    interactionState?.addInteraction(Interaction.Focused)
+                    scope.launch {
+                        focusedInteraction.value?.let { oldValue ->
+                            val interaction = FocusInteraction.Unfocus(oldValue)
+                            interactionSource?.emit(interaction)
+                            focusedInteraction.value = null
+                        }
+                        val interaction = FocusInteraction.Focus()
+                        interactionSource?.emit(interaction)
+                        focusedInteraction.value = interaction
+                    }
                 } else {
-                    interactionState?.removeInteraction(Interaction.Focused)
+                    scope.launch {
+                        focusedInteraction.value?.let { oldValue ->
+                            val interaction = FocusInteraction.Unfocus(oldValue)
+                            interactionSource?.emit(interaction)
+                            focusedInteraction.value = null
+                        }
+                    }
                 }
             }
             .focusModifier()
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Indication.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Indication.kt
index a694453..61f30c1 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Indication.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Indication.kt
@@ -16,8 +16,11 @@
 
 package androidx.compose.foundation
 
+import androidx.compose.foundation.interaction.InteractionSource
+import androidx.compose.foundation.interaction.collectIsPressedAsState
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Stable
+import androidx.compose.runtime.State
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.staticCompositionLocalOf
 import androidx.compose.ui.graphics.drawscope.ContentDrawScope
@@ -43,21 +46,22 @@
 interface Indication {
 
     /**
-     * [remember]s a new [IndicationInstance], and updates its state when [interactionState]
-     * changes. Typically this will be called by [indication], so one [IndicationInstance] will be
-     * used for one component that draws [Indication], such as a button.
+     * [remember]s a new [IndicationInstance], and updates its state based on [Interaction]s
+     * emitted via [interactionSource] . Typically this will be called by [indication],
+     * so one [IndicationInstance] will be used for one component that draws [Indication], such
+     * as a button.
      *
-     * Implementations of this function should observe state changes inside [interactionState],
-     * using them to launch animations / state changes inside [IndicationInstance] that will then
-     * be reflected inside [IndicationInstance.drawIndication].
+     * Implementations of this function should observe [Interaction]s using [interactionSource],
+     * using them to launch animations / state changes inside [IndicationInstance] that will
+     * then be reflected inside [IndicationInstance.drawIndication].
      *
-     * @param interactionState the [InteractionState] containing the current interactions the
-     * returned [IndicationInstance] should represent
-     * @return an [IndicationInstance] that represents the current interactions present in
-     * [interactionState]
+     * @param interactionSource the [InteractionSource] representing the stream of
+     * [Interaction]s the returned [IndicationInstance] should represent
+     * @return an [IndicationInstance] that represents the stream of [Interaction]s emitted by
+     * [interactionSource]
      */
     @Composable
-    fun rememberUpdatedInstance(interactionState: InteractionState): IndicationInstance
+    fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance
 }
 
 /**
@@ -89,19 +93,19 @@
  *
  * @sample androidx.compose.foundation.samples.IndicationSample
  *
- * @param interactionState [InteractionState] that will be used by [indication] to draw visual
- * effects - this [InteractionState] represents the combined state of all interactions currently
- * present on this component.
+ * @param interactionSource [InteractionSource] that will be used by [indication] to draw
+ * visual effects - this [InteractionSource] represents the stream of [Interaction]s for this
+ * component.
  * @param indication [Indication] used to draw visual effects. If `null`, no visual effects will
  * be shown for this component.
  */
 fun Modifier.indication(
-    interactionState: InteractionState,
+    interactionSource: InteractionSource,
     indication: Indication?
 ) = composed(
     factory = {
         val resolvedIndication = indication ?: NoIndication
-        val instance = resolvedIndication.rememberUpdatedInstance(interactionState)
+        val instance = resolvedIndication.rememberUpdatedInstance(interactionSource)
         remember(instance) {
             IndicationModifier(instance)
         }
@@ -109,7 +113,7 @@
     inspectorInfo = debugInspectorInfo {
         name = "indication"
         properties["indication"] = indication
-        properties["interactionState"] = interactionState
+        properties["interactionSource"] = interactionSource
     }
 )
 
@@ -132,7 +136,7 @@
     }
 
     @Composable
-    override fun rememberUpdatedInstance(interactionState: InteractionState): IndicationInstance {
+    override fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance {
         return NoIndicationInstance
     }
 }
@@ -143,19 +147,22 @@
 private object DefaultDebugIndication : Indication {
 
     private class DefaultDebugIndicationInstance(
-        private val interactionState: InteractionState
+        private val isPressed: State<Boolean>
     ) : IndicationInstance {
         override fun ContentDrawScope.drawIndication() {
             drawContent()
-            if (interactionState.contains(Interaction.Pressed)) {
+            if (isPressed.value) {
                 drawRect(color = Color.Black.copy(alpha = 0.3f), size = size)
             }
         }
     }
 
     @Composable
-    override fun rememberUpdatedInstance(interactionState: InteractionState): IndicationInstance {
-        return remember(interactionState) { DefaultDebugIndicationInstance(interactionState) }
+    override fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance {
+        val isPressed = interactionSource.collectIsPressedAsState()
+        return remember(interactionSource) {
+            DefaultDebugIndicationInstance(isPressed)
+        }
     }
 }
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Interaction.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Interaction.kt
deleted file mode 100644
index 8f4b9b6..0000000
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Interaction.kt
+++ /dev/null
@@ -1,56 +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
-
-/**
- * An Interaction represents transient UI state for a component, typically separate from the
- * actual 'business' state that a component may control. For example, a button typically fires an
- * `onClick` callback when the button is pressed and released, but it will still want to show
- * that it is being pressed before this callback is fired. This transient state is represented by
- * an Interaction, in this case [Pressed]. Using Interactions allows you to build
- * components that respond to these transient, component-owned state changes.
- *
- * The current interactions present on a given component are typically represented with an
- * [InteractionState]. See [InteractionState] for more information on consuming [Interaction]s,
- * and associated sample usage.
- */
-interface Interaction {
-    /**
-     * An interaction corresponding to a dragged state on a component.
-     *
-     * See [draggable][androidx.compose.foundation.gestures.draggable]
-     */
-    object Dragged : Interaction
-
-    /**
-     * An interaction corresponding to a pressed state on a component.
-     *
-     * See [clickable]
-     */
-    object Pressed : Interaction
-
-    /**
-     * An interaction corresponding to a focused state on a component.
-     *
-     * See [focusable]
-     */
-    object Focused : Interaction
-
-    /* TODO: b/152525426 add these states
-    object Hovered : Interaction
-    */
-}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/InteractionState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/InteractionState.kt
deleted file mode 100644
index 6e188f5..0000000
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/InteractionState.kt
+++ /dev/null
@@ -1,100 +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
-
-import androidx.compose.runtime.Stable
-import androidx.compose.runtime.State
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.geometry.Offset
-
-/**
- * InteractionState represents a [Set] of [Interaction]s present on a given component. This
- * allows you to build higher level components comprised of lower level interactions such as
- * [clickable] and [androidx.compose.foundation.gestures.draggable], and react to [Interaction]
- * changes driven by these components in one place. For [Interaction]s with an associated
- * position, such as [Interaction.Pressed], you can retrieve this position by using
- * [interactionPositionFor].
- *
- * Creating an [InteractionState] and passing it to these lower level interactions will cause a
- * recomposition when there are changes to the state of [Interaction], such as when a [clickable]
- * becomes [Interaction.Pressed].
- *
- * For cases when you are only interested in one [Interaction], or you have a priority for cases
- * when multiple [Interaction]s are present, you can use [contains], such as in the following
- * example:
- *
- * @sample androidx.compose.foundation.samples.PriorityInteractionStateSample
- *
- * Often it is important to respond to the most recently added [Interaction], as this corresponds
- * to the user's most recent interaction with a component. To enable such cases, [value] is
- * guaranteed to have its ordering preserved, with the most recent [Interaction] added to the end.
- * As a result, you can simply iterate / filter [value] from the end, until you find an
- * [Interaction] you are interested in, such as in the following example:
- *
- * @sample androidx.compose.foundation.samples.MultipleInteractionStateSample
- */
-@Stable
-class InteractionState : State<Set<Interaction>> {
-
-    private var map: Map<Interaction, Offset?> by mutableStateOf(emptyMap())
-
-    /**
-     * The [Set] containing all [Interaction]s present in this [InteractionState]. Note that this
-     * set is ordered, and the most recently added [Interaction] will be the last element in the
-     * set. For representing the most recent [Interaction] in a component, you should iterate over
-     * the set in reversed order, until you find an [Interaction] that you are interested in.
-     */
-    override val value: Set<Interaction>
-        get() = map.keys
-
-    /**
-     * Adds the provided [interaction] to this InteractionState.
-     * Since InteractionState represents a [Set], duplicate [interaction]s will not be added, and
-     * hence will not cause a recomposition.
-     *
-     * @param interaction interaction to add
-     * @param position position at which the interaction occurred, if relevant. For example, for
-     * [Interaction.Pressed], this will be the position of the pointer input that triggered the
-     * pressed state.
-     */
-    fun addInteraction(interaction: Interaction, position: Offset? = null) {
-        if (interaction !in this) map = map + (interaction to position)
-    }
-
-    /**
-     * Removes the provided [interaction], if it is present, from this InteractionState.
-     */
-    fun removeInteraction(interaction: Interaction) {
-        if (interaction in this) map = map - interaction
-    }
-
-    /**
-     * Returns the position for a particular [Interaction], if there is a position associated
-     * with the interaction.
-     *
-     * @return position associated with the interaction, or `null` if the interaction is not
-     * present in this state, or there is no associated position with the given interaction.
-     */
-    fun interactionPositionFor(interaction: Interaction): Offset? = map[interaction]
-
-    /**
-     * @return whether the provided [interaction] exists inside this InteractionState.
-     */
-    operator fun contains(interaction: Interaction): Boolean = map.contains(interaction)
-}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/MutatorMutex.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/MutatorMutex.kt
index 781a0a3..07cfb24 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/MutatorMutex.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/MutatorMutex.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.foundation
 
-import androidx.compose.runtime.AtomicReference
 import androidx.compose.runtime.Stable
 import kotlinx.coroutines.CancellationException
 import kotlinx.coroutines.Job
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt
index 07861ad..9bf1b53 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt
@@ -26,6 +26,8 @@
 import androidx.compose.foundation.gestures.animateScrollBy
 import androidx.compose.foundation.gestures.scrollBy
 import androidx.compose.foundation.gestures.scrollable
+import androidx.compose.foundation.interaction.InteractionSource
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.getValue
@@ -106,11 +108,13 @@
         }
 
     /**
-     * [InteractionState] that will be updated when the element with this state is being scrolled
-     * by dragging, using [Interaction.Dragged]. If you want to know whether the fling (or smooth
-     * scroll) is in progress, use [ScrollState.isScrollInProgress].
+     * [InteractionSource] that will be used to dispatch drag events when this
+     * list is being dragged. If you want to know whether the fling (or smooth scroll) is in
+     * progress, use [isScrollInProgress].
      */
-    val interactionState: InteractionState = InteractionState()
+    val interactionSource: InteractionSource get() = internalInteractionSource
+
+    internal val internalInteractionSource: MutableInteractionSource = MutableInteractionSource()
 
     private var _maxValueState = mutableStateOf(Int.MAX_VALUE, structuralEqualityPolicy())
 
@@ -283,7 +287,7 @@
             // if rtl and horizontal, do not reverse to make it right-to-left
             reverseDirection = if (!isVertical && isRtl) reverseScrolling else !reverseScrolling,
             enabled = isScrollable,
-            interactionState = state.interactionState,
+            interactionSource = state.internalInteractionSource,
             flingBehavior = flingBehavior,
             state = state
         )
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/DragGestureDetector.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/DragGestureDetector.kt
index 8d76a5c..8d15297 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/DragGestureDetector.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/DragGestureDetector.kt
@@ -176,7 +176,8 @@
  * Gesture detector that waits for pointer down and touch slop in any direction and then
  * calls [onDrag] for each drag event. It follows the touch slop detection of
  * [awaitTouchSlopOrCancellation], so [onDrag] must consume the position change
- * if it wants to accept the drag motion. [onDragEnd] is called after all pointers are up
+ * if it wants to accept the drag motion. [onDragStart] will be called when touch slop in passed
+ * with the last known pointer position provided. [onDragEnd] is called after all pointers are up
  * and [onDragCancel] is called if another gesture has consumed pointer input, canceling
  * this gesture.
  *
@@ -185,8 +186,10 @@
  *
  * @see detectVerticalDragGestures
  * @see detectHorizontalDragGestures
+ * @see detectDragGesturesAfterLongPress to detect gestures after long press
  */
 suspend fun PointerInputScope.detectDragGestures(
+    onDragStart: (Offset) -> Unit = { },
     onDragEnd: () -> Unit = { },
     onDragCancel: () -> Unit = { },
     onDrag: (change: PointerInputChange, dragAmount: Offset) -> Unit
@@ -199,6 +202,7 @@
                 drag = awaitTouchSlopOrCancellation(down.id, onDrag)
             } while (drag != null && !drag.positionChangeConsumed())
             if (drag != null) {
+                onDragStart.invoke(drag.position)
                 if (
                     !drag(drag.id) {
                         onDrag(it, it.positionChange())
@@ -228,9 +232,9 @@
  * @see detectDragGestures
  */
 suspend fun PointerInputScope.detectDragGesturesAfterLongPress(
+    onDragStart: (Offset) -> Unit = { },
     onDragEnd: () -> Unit = { },
     onDragCancel: () -> Unit = { },
-    onDragStart: (Offset) -> Unit = { },
     onDrag: (change: PointerInputChange, dragAmount: Offset) -> Unit
 ) {
     forEachGesture {
@@ -346,7 +350,8 @@
  * Gesture detector that waits for pointer down and touch slop in the vertical direction and then
  * calls [onVerticalDrag] for each vertical drag event. It follows the touch slop detection of
  * [awaitVerticalTouchSlopOrCancellation], so [onVerticalDrag] must consume the position change
- * if it wants to accept the drag motion. [onDragEnd] is called after all pointers are up
+ * if it wants to accept the drag motion. [onDragStart] will be called when touch slop in passed
+ * with the last known pointer position provided. [onDragEnd] is called after all pointers are up
  * and [onDragCancel] is called if another gesture has consumed pointer input, canceling
  * this gesture.
  *
@@ -361,6 +366,7 @@
  * @see detectHorizontalDragGestures
  */
 suspend fun PointerInputScope.detectVerticalDragGestures(
+    onDragStart: (Offset) -> Unit = { },
     onDragEnd: () -> Unit = { },
     onDragCancel: () -> Unit = { },
     onVerticalDrag: (change: PointerInputChange, dragAmount: Float) -> Unit
@@ -370,6 +376,7 @@
             val down = awaitFirstDown(requireUnconsumed = false)
             val drag = awaitVerticalTouchSlopOrCancellation(down.id, onVerticalDrag)
             if (drag != null) {
+                onDragStart.invoke(drag.position)
                 if (
                     verticalDrag(drag.id) {
                         onVerticalDrag(it, it.positionChange().y)
@@ -469,8 +476,9 @@
  * Gesture detector that waits for pointer down and touch slop in the horizontal direction and
  * then calls [onHorizontalDrag] for each horizontal drag event. It follows the touch slop
  * detection of [awaitHorizontalTouchSlopOrCancellation], so [onHorizontalDrag] must consume the position
- * change if it wants to accept the drag motion. [onDragEnd] is called after all pointers are up
- * and [onDragCancel] is called if another gesture has consumed pointer input, canceling
+ * change if it wants to accept the drag motion. [onDragStart] will be called when touch slop in
+ * passed with the last known pointer position provided. [onDragEnd] is called after all pointers
+ * are up and [onDragCancel] is called if another gesture has consumed pointer input, canceling
  * this gesture.
  *
  * This gesture detector will coordinate with [detectVerticalDragGestures] and
@@ -484,6 +492,7 @@
  * @see detectDragGestures
  */
 suspend fun PointerInputScope.detectHorizontalDragGestures(
+    onDragStart: (Offset) -> Unit = { },
     onDragEnd: () -> Unit = { },
     onDragCancel: () -> Unit = { },
     onHorizontalDrag: (change: PointerInputChange, dragAmount: Float) -> Unit
@@ -493,6 +502,7 @@
             val down = awaitFirstDown(requireUnconsumed = false)
             val drag = awaitHorizontalTouchSlopOrCancellation(down.id, onHorizontalDrag)
             if (drag != null) {
+                onDragStart.invoke(drag.position)
                 if (
                     horizontalDrag(drag.id) {
                         onHorizontalDrag(it, it.positionChange().x)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Draggable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Draggable.kt
index d8dab8c..67e0d67 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Draggable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Draggable.kt
@@ -16,13 +16,15 @@
 
 package androidx.compose.foundation.gestures
 
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.DragInteraction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.MutatePriority
 import androidx.compose.foundation.MutatorMutex
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.State
+import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberUpdatedState
 import androidx.compose.ui.Modifier
@@ -37,6 +39,7 @@
 import androidx.compose.ui.platform.debugInspectorInfo
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
 import kotlin.coroutines.cancellation.CancellationException
 import kotlin.math.sign
 
@@ -141,8 +144,8 @@
  * interpreted by the user land logic.
  * @param orientation orientation of the drag
  * @param enabled whether or not drag is enabled
- * @param interactionState [InteractionState] that will be updated when this draggable is
- * being dragged, using [Interaction.Dragged].
+ * @param interactionSource [MutableInteractionSource] that will be used to emit
+ * [DragInteraction.Start] when this draggable is being dragged.
  * @param startDragImmediately when set to true, draggable will start dragging immediately and
  * prevent other gesture detectors from reacting to "down" events (in order to block composed
  * press-based gestures).  This is intended to allow end users to "catch" an animating widget by
@@ -160,7 +163,7 @@
     state: DraggableState,
     orientation: Orientation,
     enabled: Boolean = true,
-    interactionState: InteractionState? = null,
+    interactionSource: MutableInteractionSource? = null,
     startDragImmediately: Boolean = false,
     onDragStarted: suspend CoroutineScope.(startedPosition: Offset) -> Unit = {},
     onDragStopped: suspend CoroutineScope.(velocity: Float) -> Unit = {},
@@ -171,23 +174,27 @@
         properties["orientation"] = orientation
         properties["enabled"] = enabled
         properties["reverseDirection"] = reverseDirection
-        properties["interactionState"] = interactionState
+        properties["interactionSource"] = interactionSource
         properties["startDragImmediately"] = startDragImmediately
         properties["onDragStarted"] = onDragStarted
         properties["onDragStopped"] = onDragStopped
         properties["state"] = state
     }
 ) {
-    DisposableEffect(interactionState) {
+    val draggedInteraction = remember { mutableStateOf<DragInteraction.Start?>(null) }
+    DisposableEffect(interactionSource) {
         onDispose {
-            interactionState?.removeInteraction(Interaction.Dragged)
+            draggedInteraction.value?.let { interaction ->
+                interactionSource?.tryEmit(DragInteraction.Cancel(interaction))
+                draggedInteraction.value = null
+            }
         }
     }
     val orientationState = rememberUpdatedState(orientation)
     val enabledState = rememberUpdatedState(enabled)
     val reverseDirectionState = rememberUpdatedState(reverseDirection)
     val startImmediatelyState = rememberUpdatedState(startDragImmediately)
-    val interactionStateState = rememberUpdatedState(interactionState)
+    val interactionSourceState = rememberUpdatedState(interactionSource)
     val onDragStartedState = rememberUpdatedState(onDragStarted)
     val updatedDraggableState = rememberUpdatedState(state)
     val onDragStoppedState = rememberUpdatedState(onDragStopped)
@@ -196,7 +203,8 @@
             dragForEachGesture(
                 orientation = orientationState,
                 enabled = enabledState,
-                interactionState = interactionStateState,
+                interactionSource = interactionSourceState,
+                dragStartInteraction = draggedInteraction,
                 reverseDirection = reverseDirectionState,
                 startDragImmediately = startImmediatelyState,
                 onDragStarted = onDragStartedState,
@@ -212,7 +220,8 @@
     orientation: State<Orientation>,
     enabled: State<Boolean>,
     reverseDirection: State<Boolean>,
-    interactionState: State<InteractionState?>,
+    interactionSource: State<MutableInteractionSource?>,
+    dragStartInteraction: MutableState<DragInteraction.Start?>,
     startDragImmediately: State<Boolean>,
     onDragStarted: State<suspend CoroutineScope.(startedPosition: Offset) -> Unit>,
     onDragStopped: State<suspend CoroutineScope.(velocity: Float) -> Unit>,
@@ -284,7 +293,16 @@
                         overSlopOffset * sign(drag.position.run { if (isVertical()) y else x })
                     if (enabledWhenInteractionAdded) {
                         onDragStarted.value.invoke(this@coroutineScope, adjustedStart)
-                        interactionState.value?.addInteraction(Interaction.Dragged)
+                        launch {
+                            dragStartInteraction.value?.let { oldInteraction ->
+                                interactionSource.value?.emit(
+                                    DragInteraction.Cancel(oldInteraction)
+                                )
+                            }
+                            val interaction = DragInteraction.Start()
+                            interactionSource.value?.emit(interaction)
+                            dragStartInteraction.value = interaction
+                        }
                     }
                     dragState.value.drag(dragPriority = MutatePriority.UserInput) {
                         isDragSuccessful = performDrag(initialDelta, drag, velocityTracker)
@@ -293,7 +311,14 @@
                     isDragSuccessful = false
                 } finally {
                     if (enabledWhenInteractionAdded) {
-                        interactionState.value?.removeInteraction(Interaction.Dragged)
+                        launch {
+                            dragStartInteraction.value?.let { interaction ->
+                                interactionSource.value?.emit(
+                                    DragInteraction.Stop(interaction)
+                                )
+                                dragStartInteraction.value = null
+                            }
+                        }
                     }
                     val velocity =
                         if (isDragSuccessful) {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt
index bc7ebd8..319f91f 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt
@@ -20,13 +20,14 @@
 import androidx.compose.animation.core.DecayAnimationSpec
 import androidx.compose.animation.core.animateDecay
 import androidx.compose.animation.defaultDecayAnimationSpec
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
 import androidx.compose.foundation.MutatePriority
 import androidx.compose.foundation.gestures.Orientation.Horizontal
 import androidx.compose.foundation.gestures.Orientation.Vertical
+import androidx.compose.foundation.interaction.DragInteraction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.State
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
@@ -40,6 +41,7 @@
 import androidx.compose.ui.input.nestedscroll.nestedScroll
 import androidx.compose.ui.input.pointer.PointerInputChange
 import androidx.compose.ui.input.pointer.PointerInputScope
+import androidx.compose.ui.input.pointer.PointerType
 import androidx.compose.ui.input.pointer.consumePositionChange
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.input.pointer.positionChange
@@ -47,6 +49,7 @@
 import androidx.compose.ui.platform.debugInspectorInfo
 import androidx.compose.ui.unit.Velocity
 import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.launch
 import kotlin.math.abs
 
@@ -70,8 +73,8 @@
  * behave like bottom to top and left to right will behave like right to left.
  * @param flingBehavior logic describing fling behavior when drag has finished with velocity. If
  * `null`, default from [ScrollableDefaults.flingBehavior] will be used.
- * @param interactionState [InteractionState] that will be updated when this draggable is
- * being dragged, using [Interaction.Dragged].
+ * @param interactionSource [MutableInteractionSource] that will be used to emit
+ * drag events when this scrollable is being dragged.
  */
 fun Modifier.scrollable(
     state: ScrollableState,
@@ -79,7 +82,7 @@
     enabled: Boolean = true,
     reverseDirection: Boolean = false,
     flingBehavior: FlingBehavior? = null,
-    interactionState: InteractionState? = null
+    interactionSource: MutableInteractionSource? = null
 ): Modifier = composed(
     inspectorInfo = debugInspectorInfo {
         name = "scrollable"
@@ -88,12 +91,12 @@
         properties["enabled"] = enabled
         properties["reverseDirection"] = reverseDirection
         properties["flingBehavior"] = flingBehavior
-        properties["interactionState"] = interactionState
+        properties["interactionSource"] = interactionSource
     },
     factory = {
         fun Float.reverseIfNeeded(): Float = if (reverseDirection) this * -1 else this
         touchScrollImplementation(
-            interactionState,
+            interactionSource,
             orientation,
             reverseDirection,
             state,
@@ -134,16 +137,20 @@
 @Suppress("ComposableModifierFactory")
 @Composable
 private fun Modifier.touchScrollImplementation(
-    interactionState: InteractionState?,
+    interactionSource: MutableInteractionSource?,
     orientation: Orientation,
     reverseDirection: Boolean,
     controller: ScrollableState,
     flingBehavior: FlingBehavior?,
     enabled: Boolean
 ): Modifier {
-    DisposableEffect(interactionState) {
+    val draggedInteraction = remember { mutableStateOf<DragInteraction.Start?>(null) }
+    DisposableEffect(interactionSource) {
         onDispose {
-            interactionState?.removeInteraction(Interaction.Dragged)
+            draggedInteraction.value?.let { interaction ->
+                interactionSource?.tryEmit(DragInteraction.Cancel(interaction))
+                draggedInteraction.value = null
+            }
         }
     }
 
@@ -161,13 +168,14 @@
     val orientationState = rememberUpdatedState(orientation)
     val enabledState = rememberUpdatedState(enabled)
     val controllerState = rememberUpdatedState(controller)
-    val interactionStateState = rememberUpdatedState(interactionState)
+    val interactionSourceState = rememberUpdatedState(interactionSource)
     return dragForEachGesture(
         orientation = orientationState,
         enabled = enabledState,
         scrollableState = controllerState,
         nestedScrollDispatcher = nestedScrollDispatcher,
-        interactionState = interactionStateState,
+        interactionSource = interactionSourceState,
+        dragStartInteraction = draggedInteraction,
         scrollLogic = scrollLogic
     ).nestedScroll(nestedScrollConnection, nestedScrollDispatcher.value)
 }
@@ -179,7 +187,8 @@
     enabled: State<Boolean>,
     scrollableState: State<ScrollableState>,
     nestedScrollDispatcher: State<NestedScrollDispatcher>,
-    interactionState: State<InteractionState?>,
+    interactionSource: State<MutableInteractionSource?>,
+    dragStartInteraction: MutableState<DragInteraction.Start?>,
     scrollLogic: State<ScrollingLogic>
 ): Modifier {
     fun isVertical() = orientation.value == Vertical
@@ -190,7 +199,7 @@
         var initialDelta = 0f
         return awaitPointerEventScope {
             val down = awaitFirstDown(requireUnconsumed = false)
-            if (!enabled.value) {
+            if (!enabled.value || down.type == PointerType.Mouse) {
                 null to initialDelta
             } else if (scrollableState.value.isScrollInProgress) {
                 // since we start immediately we don't wait for slop and set initial delta to 0
@@ -217,6 +226,18 @@
         velocityTracker: VelocityTracker,
     ): Boolean {
         var result = false
+
+        fun ScrollScope.touchDragTick(event: PointerInputChange) {
+            velocityTracker.addPosition(event.uptimeMillis, event.position)
+            val delta = event.positionChange().axisValue()
+            if (enabled.value) {
+                with(scrollLogic.value) {
+                    dispatchScroll(delta, NestedScrollSource.Drag)
+                }
+            }
+            event.consumePositionChange()
+        }
+
         try {
             scrollableState.value.scroll(MutatePriority.UserInput) {
                 awaitPointerEventScope {
@@ -227,14 +248,9 @@
                     }
                     velocityTracker.addPosition(drag.uptimeMillis, drag.position)
                     val dragTick = { event: PointerInputChange ->
-                        velocityTracker.addPosition(event.uptimeMillis, event.position)
-                        val delta = event.positionChange().axisValue()
-                        if (enabled.value) {
-                            with(scrollLogic.value) {
-                                dispatchScroll(delta, NestedScrollSource.Drag)
-                            }
+                        if (event.type != PointerType.Mouse) {
+                            touchDragTick(event)
                         }
-                        event.consumePositionChange()
                     }
                     result = if (isVertical()) {
                         verticalDrag(drag.id, dragTick)
@@ -265,11 +281,31 @@
                     // remember enabled state when we add interaction to remove later if needed
                     val enabledWhenInteractionAdded = enabled.value
                     if (enabledWhenInteractionAdded) {
-                        interactionState.value?.addInteraction(Interaction.Dragged)
+                        coroutineScope {
+                            launch {
+                                dragStartInteraction.value?.let { oldInteraction ->
+                                    interactionSource.value?.emit(
+                                        DragInteraction.Cancel(oldInteraction)
+                                    )
+                                }
+                                val interaction = DragInteraction.Start()
+                                interactionSource.value?.emit(interaction)
+                                dragStartInteraction.value = interaction
+                            }
+                        }
                     }
                     val isDragSuccessful = mainDragCycle(startEvent, initialDelta, velocityTracker)
                     if (enabledWhenInteractionAdded) {
-                        interactionState.value?.removeInteraction(Interaction.Dragged)
+                        coroutineScope {
+                            launch {
+                                dragStartInteraction.value?.let { interaction ->
+                                    interactionSource.value?.emit(
+                                        DragInteraction.Stop(interaction)
+                                    )
+                                    dragStartInteraction.value = null
+                                }
+                            }
+                        }
                     }
                     if (isDragSuccessful) {
                         nestedScrollDispatcher.value.coroutineScope.launch {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/interaction/DragInteraction.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/interaction/DragInteraction.kt
new file mode 100644
index 0000000..6f93c2a
--- /dev/null
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/interaction/DragInteraction.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.foundation.interaction
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.State
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.remember
+import kotlinx.coroutines.flow.collect
+
+// An interface, not a sealed class, to allow adding new types here in a safe way (and not break
+// exhaustive when clauses)
+/**
+ * An interaction related to drag events.
+ *
+ * @see androidx.compose.foundation.gestures.draggable
+ * @see Start
+ * @see Stop
+ * @see Cancel
+ */
+interface DragInteraction : Interaction {
+    /**
+     * An interaction representing a drag event on a component.
+     *
+     * @see androidx.compose.foundation.gestures.draggable
+     * @see Stop
+     * @see Cancel
+     */
+    class Start : DragInteraction
+
+    /**
+     * An interaction representing the stopping of a [Start] event on a component.
+     *
+     * @property start the source [Start] interaction that is being stopped
+     *
+     * @see androidx.compose.foundation.gestures.draggable
+     * @see Start
+     */
+    class Stop(val start: Start) : DragInteraction
+
+    /**
+     * An interaction representing the cancellation of a [Start] event on a component.
+     *
+     * @property start the source [Start] interaction that is being cancelled
+     *
+     * @see androidx.compose.foundation.gestures.draggable
+     * @see Start
+     */
+    class Cancel(val start: Start) : DragInteraction
+}
+
+/**
+ * Subscribes to this [MutableInteractionSource] and returns a [State] representing whether this
+ * component is dragged or not.
+ *
+ * [DragInteraction] is typically set by interactions
+ * such as [androidx.compose.foundation.gestures.draggable] and
+ * [androidx.compose.foundation.gestures.scrollable], and higher level components such as
+ * [androidx.compose.foundation.lazy.LazyRow], available through
+ * [androidx.compose.foundation.lazy.LazyListState.interactionSource].
+ *
+ * @return [State] representing whether this component is being dragged or not
+ */
+@Composable
+fun InteractionSource.collectIsDraggedAsState(): State<Boolean> {
+    val dragInteractions = remember { mutableStateListOf<DragInteraction.Start>() }
+    LaunchedEffect(this) {
+        interactions.collect { interaction ->
+            when (interaction) {
+                is DragInteraction.Start -> dragInteractions.add(interaction)
+                is DragInteraction.Stop -> dragInteractions.remove(interaction.start)
+                is DragInteraction.Cancel -> dragInteractions.remove(interaction.start)
+            }
+        }
+    }
+    return derivedStateOf { dragInteractions.isNotEmpty() }
+}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/interaction/FocusInteraction.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/interaction/FocusInteraction.kt
new file mode 100644
index 0000000..3689050
--- /dev/null
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/interaction/FocusInteraction.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.foundation.interaction
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.State
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.remember
+import kotlinx.coroutines.flow.collect
+
+// An interface, not a sealed class, to allow adding new types here in a safe way (and not break
+// exhaustive when clauses)
+/**
+ * An interaction related to focus events.
+ *
+ * @see androidx.compose.foundation.focusable
+ * @see Focus
+ * @see Unfocus
+ */
+interface FocusInteraction : Interaction {
+    /**
+     * An interaction representing a focus event on a component.
+     *
+     * @see androidx.compose.foundation.focusable
+     * @see Unfocus
+     */
+    class Focus : FocusInteraction
+
+    /**
+     * An interaction representing a [Focus] event being released on a component.
+     *
+     * @property focus the source [Focus] interaction that is being released
+     *
+     * @see androidx.compose.foundation.focusable
+     * @see Focus
+     */
+    class Unfocus(val focus: Focus) : FocusInteraction
+}
+
+/**
+ * Subscribes to this [MutableInteractionSource] and returns a [State] representing whether this
+ * component is focused or not.
+ *
+ * [FocusInteraction] is typically set by [androidx.compose.foundation.focusable] and focusable
+ * components, such as [androidx.compose.foundation.text.BasicTextField].
+ *
+ * @return [State] representing whether this component is being focused or not
+ */
+@Composable
+fun InteractionSource.collectIsFocusedAsState(): State<Boolean> {
+    val focusInteractions = remember { mutableStateListOf<FocusInteraction.Focus>() }
+    LaunchedEffect(this) {
+        interactions.collect { interaction ->
+            when (interaction) {
+                is FocusInteraction.Focus -> focusInteractions.add(interaction)
+                is FocusInteraction.Unfocus -> focusInteractions.remove(interaction.focus)
+            }
+        }
+    }
+    return derivedStateOf { focusInteractions.isNotEmpty() }
+}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/interaction/Interaction.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/interaction/Interaction.kt
new file mode 100644
index 0000000..5b7a78d
--- /dev/null
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/interaction/Interaction.kt
@@ -0,0 +1,33 @@
+/*
+ * 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.interaction
+
+/**
+ * An Interaction represents transient UI state for a component, typically separate from the
+ * actual 'business' state that a component may control. For example, a button typically fires an
+ * `onClick` callback when the button is pressed and released, but it may still want to show
+ * that it is being pressed before this callback is fired. This transient state is represented by
+ * an Interaction, in this case [PressInteraction.Press]. Using Interactions allows you to build
+ * components that respond to these transient, component-owned state changes.
+ *
+ * To emit / observe current Interactions, see [MutableInteractionSource], which represents a
+ * stream of Interactions present for a given component.
+ *
+ * @see InteractionSource
+ * @see MutableInteractionSource
+ */
+interface Interaction
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/interaction/InteractionSource.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/interaction/InteractionSource.kt
new file mode 100644
index 0000000..4b6c65b
--- /dev/null
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/interaction/InteractionSource.kt
@@ -0,0 +1,144 @@
+/*
+ * 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.interaction
+
+import androidx.compose.runtime.Stable
+import androidx.compose.runtime.State
+import androidx.compose.runtime.remember
+import kotlinx.coroutines.channels.BufferOverflow
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableSharedFlow
+
+/**
+ * InteractionSource represents a stream of [Interaction]s corresponding to events emitted by a
+ * component. These [Interaction]s can be used to change how components appear in different
+ * states, such as when a component is pressed or dragged.
+ *
+ * A common use case is [androidx.compose.foundation.indication], where
+ * [androidx.compose.foundation.Indication] implementations can subscribe to an [InteractionSource]
+ * to draw indication for different [Interaction]s, such as a ripple effect for
+ * [PressInteraction.Press] and a state overlay for [DragInteraction.Start].
+ *
+ * For simple cases where you are interested in the binary state of an [Interaction], such as
+ * whether a component is pressed or not, you can use [InteractionSource.collectIsPressedAsState] and other
+ * extension functions that subscribe and return a [Boolean] [State] representing whether the
+ * component is in this state or not.
+ *
+ * @sample androidx.compose.foundation.samples.SimpleInteractionSourceSample
+ *
+ * For more complex cases, such as when building an [androidx.compose.foundation.Indication], the
+ * order of the events can change how a component / indication should be drawn. For example, if a
+ * component is being dragged and then becomes focused, the most recent [Interaction] is
+ * [FocusInteraction.Focus], so the component should appear in a focused state to signal this
+ * event to the user.
+ *
+ * InteractionSource exposes [interactions] to support these use cases - a
+ * [Flow] representing the stream of all emitted [Interaction]s. This also provides more
+ * information, such as the press position of [PressInteraction.Press], so you can show an effect
+ * at the specific point the component was pressed, and whether the press was
+ * [PressInteraction.Release] or [PressInteraction.Cancel], for cases when a component
+ * should behave differently if the press was released normally or interrupted by another gesture.
+ *
+ * You can collect from [interactions] as you would with any other [Flow]:
+ *
+ * @sample androidx.compose.foundation.samples.InteractionSourceFlowSample
+ *
+ * To emit [Interaction]s so that consumers can react to them, see [MutableInteractionSource].
+ *
+ * @see MutableInteractionSource
+ * @see Interaction
+ */
+@Stable
+interface InteractionSource {
+    /**
+     * [Flow] representing the stream of all [Interaction]s emitted through this
+     * [InteractionSource]. This can be used to see [Interaction]s emitted in order, and with
+     * additional metadata, such as the press position for [PressInteraction.Press].
+     *
+     * @sample androidx.compose.foundation.samples.InteractionSourceFlowSample
+     */
+    val interactions: Flow<Interaction>
+}
+
+/**
+ * MutableInteractionSource represents a stream of [Interaction]s corresponding to events emitted
+ * by a component. These [Interaction]s can be used to change how components appear
+ * in different states, such as when a component is pressed or dragged.
+ *
+ * Lower level interaction APIs such as [androidx.compose.foundation.clickable] and
+ * [androidx.compose.foundation.gestures.draggable] have an [MutableInteractionSource] parameter,
+ * which allows you to hoist an [MutableInteractionSource] and combine multiple interactions into
+ * one event stream.
+ *
+ * MutableInteractionSource exposes [emit] and [tryEmit] functions. These emit the provided
+ * [Interaction] to the underlying [interactions] [Flow], allowing consumers to react to these
+ * new [Interaction]s.
+ *
+ * An instance of MutableInteractionSource can be created by using the
+ * [MutableInteractionSource] factory function. This instance should be [remember]ed before it is
+ * passed to other components that consume it.
+ *
+ * @see InteractionSource
+ * @see Interaction
+ */
+@Stable
+interface MutableInteractionSource : InteractionSource {
+    /**
+     * Emits [interaction] into [interactions].
+     * This method is not thread-safe and should not be invoked concurrently.
+     *
+     * @see tryEmit
+     */
+    suspend fun emit(interaction: Interaction)
+
+    /**
+     * Tries to emit [interaction] into [interactions] without suspending. It returns `true` if the
+     * value was emitted successfully.
+     *
+     * @see emit
+     */
+    fun tryEmit(interaction: Interaction): Boolean
+}
+
+/**
+ * Return a new [MutableInteractionSource] that can be hoisted and provided to components,
+ * allowing listening to [Interaction] changes inside those components.
+ *
+ * This should be [remember]ed before it is provided to components, so it can maintain its state
+ * across compositions.
+ *
+ * @see InteractionSource
+ * @see MutableInteractionSource
+ */
+fun MutableInteractionSource(): MutableInteractionSource = MutableInteractionSourceImpl()
+
+@Stable
+private class MutableInteractionSourceImpl : MutableInteractionSource {
+    // TODO: consider replay for new indication instances during events?
+    override val interactions = MutableSharedFlow<Interaction>(
+        extraBufferCapacity = 16,
+        onBufferOverflow = BufferOverflow.DROP_OLDEST,
+    )
+
+    override suspend fun emit(interaction: Interaction) {
+        interactions.emit(interaction)
+    }
+
+    override fun tryEmit(interaction: Interaction): Boolean {
+        return interactions.tryEmit(interaction)
+    }
+}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/interaction/PressInteraction.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/interaction/PressInteraction.kt
new file mode 100644
index 0000000..71720b8b
--- /dev/null
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/interaction/PressInteraction.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.foundation.interaction
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.State
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.geometry.Offset
+import kotlinx.coroutines.flow.collect
+
+// An interface, not a sealed class, to allow adding new types here in a safe way (and not break
+// exhaustive when clauses)
+/**
+ * An interaction related to press events.
+ *
+ * @see androidx.compose.foundation.clickable
+ * @see Press
+ * @see Release
+ * @see Cancel
+ */
+interface PressInteraction : Interaction {
+    /**
+     * An interaction representing a press event on a component.
+     *
+     * @property pressPosition the [Offset] describing where this press event occurred within the
+     * component
+     *
+     * @see androidx.compose.foundation.clickable
+     * @see Release
+     * @see Cancel
+     */
+    class Press(val pressPosition: Offset) : PressInteraction
+
+    /**
+     * An interaction representing the release of a [Press] event on a component.
+     *
+     * @property press the source [Press] interaction that is being released
+     *
+     * @see androidx.compose.foundation.clickable
+     * @see Press
+     */
+    class Release(val press: Press) : PressInteraction
+
+    /**
+     * An interaction representing the cancellation of a [Press] event on a component.
+     *
+     * @property press the source [Press] interaction that is being cancelled
+     *
+     * @see androidx.compose.foundation.clickable
+     * @see Press
+     */
+    class Cancel(val press: Press) : PressInteraction
+}
+
+/**
+ * Subscribes to this [MutableInteractionSource] and returns a [State] representing whether this
+ * component is pressed or not.
+ *
+ * [PressInteraction] is typically set by [androidx.compose.foundation.clickable] and clickable
+ * higher level components, such as buttons.
+ *
+ * @return [State] representing whether this component is being pressed or not
+ */
+@Composable
+fun InteractionSource.collectIsPressedAsState(): State<Boolean> {
+    val pressInteractions = remember { mutableStateListOf<PressInteraction.Press>() }
+    LaunchedEffect(this) {
+        interactions.collect { interaction ->
+            when (interaction) {
+                is PressInteraction.Press -> pressInteractions.add(interaction)
+                is PressInteraction.Release -> pressInteractions.remove(interaction.press)
+                is PressInteraction.Cancel -> pressInteractions.remove(interaction.press)
+            }
+        }
+    }
+    return derivedStateOf { pressInteractions.isNotEmpty() }
+}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
index 32f0936..3a9e7ff 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
@@ -33,6 +33,7 @@
 import androidx.compose.ui.draw.clipToBounds
 import androidx.compose.ui.layout.SubcomposeLayout
 import androidx.compose.ui.platform.LocalLayoutDirection
+import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.LayoutDirection
 
 internal class ItemContent(
@@ -83,7 +84,7 @@
             .scrollable(
                 orientation = if (isVertical) Orientation.Vertical else Orientation.Horizontal,
                 reverseDirection = reverseScrollDirection,
-                interactionState = state.interactionState,
+                interactionSource = state.internalInteractionSource,
                 flingBehavior = flingBehavior,
                 state = state
             )
@@ -93,6 +94,9 @@
     ) { constraints ->
         constraints.assertNotNestingScrollableContainers(isVertical)
 
+        // Update the state's cached Density
+        state.density = Density(density, fontScale)
+
         // this will update the scope object if the constrains have been changed
         cachingItemContentFactory.updateItemScope(this, constraints)
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListScrolling.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListScrolling.kt
index 930cc29..ea2398a 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListScrolling.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListScrolling.kt
@@ -20,13 +20,13 @@
 import androidx.compose.animation.core.AnimationState
 import androidx.compose.animation.core.animateTo
 import androidx.compose.animation.core.spring
+import androidx.compose.ui.unit.dp
 import kotlin.coroutines.cancellation.CancellationException
 
 private class ItemFoundInScroll(val item: LazyListItemInfo) : CancellationException()
 
-// TODO: these need to be Dp somehow
-private val TargetDistance = 5000
-private val BoundDistance = 3000
+private val TargetDistance = 2500.dp
+private val BoundDistance = 1500.dp
 
 internal suspend fun LazyListState.doSmoothScrollToItem(
     index: Int,
@@ -37,6 +37,8 @@
         it.index == index
     }
     scroll {
+        val targetDistancePx = with(density) { TargetDistance.toPx() }
+        val boundDistancePx = with(density) { BoundDistance.toPx() }
         var prevValue = 0f
         val anim = AnimationState(0f)
         var target: Float
@@ -52,23 +54,23 @@
                 val bound: Float
                 // Magic constants for teleportation chosen arbitrarily by experiment
                 if (forward) {
-                    if (anim.value >= TargetDistance * 2 &&
+                    if (anim.value >= targetDistancePx * 2 &&
                         index - layoutInfo.visibleItemsInfo.last().index > 100
                     ) {
                         // Teleport
                         snapToItemIndexInternal(index = index - 100, scrollOffset = 0)
                     }
-                    target = anim.value + TargetDistance
-                    bound = anim.value + BoundDistance
+                    target = anim.value + targetDistancePx
+                    bound = anim.value + boundDistancePx
                 } else {
-                    if (anim.value >= TargetDistance * -2 &&
+                    if (anim.value >= targetDistancePx * -2 &&
                         layoutInfo.visibleItemsInfo.first().index - index > 100
                     ) {
                         // Teleport
                         snapToItemIndexInternal(index = index + 100, scrollOffset = 0)
                     }
-                    target = anim.value - TargetDistance
-                    bound = anim.value - BoundDistance
+                    target = anim.value - targetDistancePx
+                    bound = anim.value - boundDistancePx
                 }
                 anim.animateTo(
                     target,
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
index 1fc23caf..f66b331 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
@@ -17,8 +17,8 @@
 package androidx.compose.foundation.lazy
 
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.InteractionSource
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.MutatePriority
 import androidx.compose.foundation.gestures.ScrollScope
 import androidx.compose.foundation.gestures.ScrollableState
@@ -30,6 +30,7 @@
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.layout.Remeasurement
 import androidx.compose.ui.layout.RemeasurementModifier
+import androidx.compose.ui.unit.Density
 import kotlin.math.abs
 
 /**
@@ -96,11 +97,13 @@
     val layoutInfo: LazyListLayoutInfo get() = layoutInfoState.value
 
     /**
-     * interactionState [InteractionState] that will be updated when component with this
-     * state is being scrolled by dragging, using [Interaction.Dragged]. If you want to know whether
-     * the fling (or animated scroll) is in progress, use [isScrollInProgress].
+     * [InteractionSource] that will be used to dispatch drag events when this
+     * list is being dragged. If you want to know whether the fling (or animated scroll) is in
+     * progress, use [isScrollInProgress].
      */
-    val interactionState: InteractionState = InteractionState()
+    val interactionSource: InteractionSource get() = internalInteractionSource
+
+    internal val internalInteractionSource: MutableInteractionSource = MutableInteractionSource()
 
     /**
      * The amount of scroll to be consumed in the next layout pass.  Scrolling forward is negative
@@ -120,6 +123,11 @@
     internal val firstVisibleItemScrollOffsetNonObservable: Int get() = scrollPosition.scrollOffset
 
     /**
+     * Needed for [animateScrollToItem].  Updated on every measure.
+     */
+    internal var density: Density = Density(1f, 1f)
+
+    /**
      * The ScrollableController instance. We keep it as we need to call stopAnimation on it once
      * we reached the end of the list.
      */
@@ -241,7 +249,9 @@
      *
      * @param index the index to which to scroll
      * @param scrollOffset the offset that the item should end up after the scroll (same as
-     * [snapToItemIndex]) - note that it is an offset *backwards*, not forward
+     * [scrollToItem]) - note that positive offset refers to forward scroll, so in a
+     * top-to-bottom list, positive offset will scroll the item further upward (taking it partly
+     * offscreen)
      */
     suspend fun animateScrollToItem(
         /*@IntRange(from = 0)*/
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Selectable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Selectable.kt
index 7101059..582ea60 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Selectable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Selectable.kt
@@ -17,8 +17,7 @@
 package androidx.compose.foundation.selection
 
 import androidx.compose.foundation.Indication
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.LocalIndication
 import androidx.compose.foundation.Strings
 import androidx.compose.foundation.clickable
@@ -33,15 +32,17 @@
 
 /**
  * Configure component to be selectable, usually as a part of a mutually exclusive group, where
- * only one item can be selected at any point in time. A typical example of mutually exclusive set
- * is a RadioGroup or a row of Tabs.
+ * only one item can be selected at any point in time.
+ * A typical example of mutually exclusive set is a RadioGroup or a row of Tabs. To ensure
+ * correct accessibility behavior, make sure to pass [Modifier.selectableGroup] modifier into the
+ * RadioGroup or the row.
  *
  * If you want to make an item support on/off capabilities without being part of a set, consider
  * using [Modifier.toggleable]
  *
- * This version has no [InteractionState] or [Indication] parameters, default indication from
- * [LocalIndication] will be used. To specify [InteractionState] or [Indication], use another
- * overload.
+ * This version has no [MutableInteractionSource] or [Indication] parameters, default
+ * indication from [LocalIndication] will be used. To specify [MutableInteractionSource] or
+ * [Indication], use another overload.
  *
  * @sample androidx.compose.foundation.samples.SelectableSample
  *
@@ -70,7 +71,7 @@
         selected = selected,
         enabled = enabled,
         role = role,
-        interactionState = remember { InteractionState() },
+        interactionSource = remember { MutableInteractionSource() },
         indication = LocalIndication.current,
         onClick = onClick
     )
@@ -78,20 +79,22 @@
 
 /**
  * Configure component to be selectable, usually as a part of a mutually exclusive group, where
- * only one item can be selected at any point in time. A typical example of mutually exclusive set
- * is a RadioGroup or a row of Tabs.
+ * only one item can be selected at any point in time.
+ * A typical example of mutually exclusive set is a RadioGroup or a row of Tabs. To ensure
+ * correct accessibility behavior, make sure to pass [Modifier.selectableGroup] modifier into the
+ * RadioGroup or the row.
  *
  * If you want to make an item support on/off capabilities without being part of a set, consider
  * using [Modifier.toggleable]
  *
- * This version requires both [InteractionState] and [Indication] to work properly. Use another
+ * This version requires both [MutableInteractionSource] and [Indication] to work properly. Use another
  * overload if you don't need these parameters.
  *
  * @sample androidx.compose.foundation.samples.SelectableSample
  *
  * @param selected whether or not this item is selected in a mutually exclusion set
- * @param interactionState [InteractionState] that will be updated when this element is
- * pressed, using [Interaction.Pressed]
+ * @param interactionSource [MutableInteractionSource] that will be used to emit
+ * press events when this selectable is being pressed.
  * @param indication indication to be shown when the modified element is pressed. By default,
  * the indication from [LocalIndication] will be used. Set to `null` to show no indication, or
  * current value from [LocalIndication] to show theme default
@@ -103,7 +106,7 @@
  */
 fun Modifier.selectable(
     selected: Boolean,
-    interactionState: InteractionState,
+    interactionSource: MutableInteractionSource,
     indication: Indication?,
     enabled: Boolean = true,
     role: Role? = null,
@@ -113,7 +116,7 @@
         Modifier.clickable(
             enabled = enabled,
             role = role,
-            interactionState = interactionState,
+            interactionSource = interactionSource,
             indication = indication,
             onClick = onClick
         ).semantics {
@@ -126,7 +129,7 @@
         properties["selected"] = selected
         properties["enabled"] = enabled
         properties["role"] = role
-        properties["interactionState"] = interactionState
+        properties["interactionSource"] = interactionSource
         properties["indication"] = indication
         properties["onClick"] = onClick
     }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/SelectableGroup.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/SelectableGroup.kt
new file mode 100644
index 0000000..e433162
--- /dev/null
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/SelectableGroup.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.foundation.selection
+
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.semantics.selectableGroup
+import androidx.compose.ui.semantics.semantics
+
+/**
+ * Use this modifier to group a list of [selectable] items
+ * like Tabs or RadioButtons together for accessibility purpose.
+ *
+ * @see selectableGroup
+ */
+fun Modifier.selectableGroup() = this.semantics(true) {
+    selectableGroup()
+}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Toggleable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Toggleable.kt
index bc09caf..9e500518 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Toggleable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Toggleable.kt
@@ -17,13 +17,15 @@
 package androidx.compose.foundation.selection
 
 import androidx.compose.foundation.Indication
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.LocalIndication
+import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.foundation.Strings
 import androidx.compose.foundation.indication
 import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.composed
 import androidx.compose.foundation.legacygestures.pressIndicatorGestureFilter
@@ -40,12 +42,13 @@
 import androidx.compose.ui.state.ToggleableState.Indeterminate
 import androidx.compose.ui.state.ToggleableState.Off
 import androidx.compose.ui.state.ToggleableState.On
+import kotlinx.coroutines.launch
 
 /**
  * Configure component to make it toggleable via input and accessibility events
  *
- * This version has no [InteractionState] or [Indication] parameters, default indication from
- * [LocalIndication] will be used. To specify [InteractionState] or [Indication], use another
+ * This version has no [MutableInteractionSource] or [Indication] parameters, default indication from
+ * [LocalIndication] will be used. To specify [MutableInteractionSource] or [Indication], use another
  * overload.
  *
  * @sample androidx.compose.foundation.samples.ToggleableSample
@@ -79,7 +82,7 @@
         onClick = { onValueChange(!value) },
         enabled = enabled,
         role = role,
-        interactionState = remember { InteractionState() },
+        interactionSource = remember { MutableInteractionSource() },
         indication = LocalIndication.current
     )
 }
@@ -87,7 +90,7 @@
 /**
  * Configure component to make it toggleable via input and accessibility events.
  *
- * This version requires both [InteractionState] and [Indication] to work properly. Use another
+ * This version requires both [MutableInteractionSource] and [Indication] to work properly. Use another
  * overload if you don't need these parameters.
  *
  * @sample androidx.compose.foundation.samples.ToggleableSample
@@ -95,8 +98,8 @@
  * @see [Modifier.triStateToggleable] if you require support for an indeterminate state.
  *
  * @param value whether Toggleable is on or off
- * @param interactionState [InteractionState] that will be updated when this toggleable is
- * pressed, using [Interaction.Pressed]
+ * @param interactionSource [MutableInteractionSource] that will be used to emit
+ * [PressInteraction.Press] when this toggleable is being pressed.
  * @param indication indication to be shown when modified element is pressed. Be default,
  * indication from [LocalIndication] will be used. Pass `null` to show no indication, or
  * current value from [LocalIndication] to show theme default
@@ -109,7 +112,7 @@
  */
 fun Modifier.toggleable(
     value: Boolean,
-    interactionState: InteractionState,
+    interactionSource: MutableInteractionSource,
     indication: Indication?,
     enabled: Boolean = true,
     role: Role? = null,
@@ -120,7 +123,7 @@
         properties["value"] = value
         properties["enabled"] = enabled
         properties["role"] = role
-        properties["interactionState"] = interactionState
+        properties["interactionSource"] = interactionSource
         properties["indication"] = indication
         properties["onValueChange"] = onValueChange
     },
@@ -130,7 +133,7 @@
             onClick = { onValueChange(!value) },
             enabled = enabled,
             role = role,
-            interactionState = interactionState,
+            interactionSource = interactionSource,
             indication = indication
         )
     }
@@ -143,9 +146,9 @@
  * TriStateToggleable should be used when there are dependent Toggleables associated to this
  * component and those can have different values.
  *
- * This version has no [InteractionState] or [Indication] parameters, default indication from
- * [LocalIndication] will be used. To specify [InteractionState] or [Indication], use another
- * overload.
+ * This version has no [MutableInteractionSource] or [Indication] parameters, default indication
+ * from [LocalIndication] will be used. To specify [MutableInteractionSource] or [Indication],
+ * use another overload.
  *
  * @sample androidx.compose.foundation.samples.TriStateToggleableSample
  *
@@ -176,7 +179,7 @@
         state,
         enabled,
         role,
-        remember { InteractionState() },
+        remember { MutableInteractionSource() },
         LocalIndication.current,
         onClick
     )
@@ -189,7 +192,7 @@
  * TriStateToggleable should be used when there are dependent Toggleables associated to this
  * component and those can have different values.
  *
- * This version requires both [InteractionState] and [Indication] to work properly. Use another
+ * This version requires both [MutableInteractionSource] and [Indication] to work properly. Use another
  * overload if you don't need these parameters.
  *
  * @sample androidx.compose.foundation.samples.TriStateToggleableSample
@@ -197,8 +200,8 @@
  * @see [Modifier.toggleable] if you want to support only two states: on and off
  *
  * @param state current value for the component
- * @param interactionState [InteractionState] that will be updated when this toggleable is
- * pressed, using [Interaction.Pressed]
+ * @param interactionSource [MutableInteractionSource] that will be used to emit
+ * [PressInteraction.Press] when this triStateToggleable is being pressed.
  * @param indication indication to be shown when modified element is pressed. Be default,
  * indication from [LocalIndication] will be used. Pass `null` to show no indication, or
  * current value from [LocalIndication] to show theme default
@@ -210,7 +213,7 @@
  */
 fun Modifier.triStateToggleable(
     state: ToggleableState,
-    interactionState: InteractionState,
+    interactionSource: MutableInteractionSource,
     indication: Indication?,
     enabled: Boolean = true,
     role: Role? = null,
@@ -221,12 +224,12 @@
         properties["state"] = state
         properties["enabled"] = enabled
         properties["role"] = role
-        properties["interactionState"] = interactionState
+        properties["interactionSource"] = interactionSource
         properties["indication"] = indication
         properties["onClick"] = onClick
     },
     factory = {
-        toggleableImpl(state, enabled, role, interactionState, indication, onClick)
+        toggleableImpl(state, enabled, role, interactionSource, indication, onClick)
     }
 )
 
@@ -235,10 +238,12 @@
     state: ToggleableState,
     enabled: Boolean,
     role: Role? = null,
-    interactionState: InteractionState,
+    interactionSource: MutableInteractionSource,
     indication: Indication?,
     onClick: () -> Unit
 ): Modifier = composed {
+    val scope = rememberCoroutineScope()
+    val pressedInteraction = remember { mutableStateOf<PressInteraction.Press?>(null) }
     // TODO(pavlis): Handle multiple states for Semantics
     val semantics = Modifier.semantics(mergeDescendants = true) {
         if (role != null) {
@@ -259,23 +264,55 @@
     val interactionUpdate =
         if (enabled) {
             Modifier.pressIndicatorGestureFilter(
-                onStart = { interactionState.addInteraction(Interaction.Pressed, it) },
-                onStop = { interactionState.removeInteraction(Interaction.Pressed) },
-                onCancel = { interactionState.removeInteraction(Interaction.Pressed) }
+                onStart = {
+                    scope.launch {
+                        // Remove any old interactions if we didn't fire stop / cancel properly
+                        pressedInteraction.value?.let { oldValue ->
+                            val interaction = PressInteraction.Cancel(oldValue)
+                            interactionSource.emit(interaction)
+                            pressedInteraction.value = null
+                        }
+                        val interaction = PressInteraction.Press(it)
+                        interactionSource.emit(interaction)
+                        pressedInteraction.value = interaction
+                    }
+                },
+                onStop = {
+                    scope.launch {
+                        pressedInteraction.value?.let {
+                            val interaction = PressInteraction.Release(it)
+                            interactionSource.emit(interaction)
+                            pressedInteraction.value = null
+                        }
+                    }
+                },
+                onCancel = {
+                    scope.launch {
+                        pressedInteraction.value?.let {
+                            val interaction = PressInteraction.Cancel(it)
+                            interactionSource.emit(interaction)
+                            pressedInteraction.value = null
+                        }
+                    }
+                }
             )
         } else {
             Modifier
         }
     val click = if (enabled) Modifier.tapGestureFilter { onClick() } else Modifier
 
-    DisposableEffect(interactionState) {
+    DisposableEffect(interactionSource) {
         onDispose {
-            interactionState.removeInteraction(Interaction.Pressed)
+            pressedInteraction.value?.let { oldValue ->
+                val interaction = PressInteraction.Cancel(oldValue)
+                interactionSource.tryEmit(interaction)
+                pressedInteraction.value = null
+            }
         }
     }
     this
         .then(semantics)
-        .indication(interactionState, indication)
+        .indication(interactionSource, indication)
         .then(interactionUpdate)
         .then(click)
 }
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/BasicText.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/BasicText.kt
index 3d0fd88..1098a4f 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/BasicText.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/BasicText.kt
@@ -27,6 +27,8 @@
 
 /**
  * Basic element that displays text and provides semantics / accessibility information.
+ * Typically you will instead want to use [androidx.compose.material.Text], which is
+ * a higher level Text element that contains semantics and consumes style information from a theme.
  *
  * @param text The text to be displayed.
  * @param modifier [Modifier] to apply to this layout node.
@@ -63,6 +65,8 @@
 
 /**
  * Basic element that displays text and provides semantics / accessibility information.
+ * Typically you will instead want to use [androidx.compose.material.Text], which is
+ * a higher level Text element that contains semantics and consumes style information from a theme.
  *
  * @param text The text to be displayed.
  * @param modifier [Modifier] to apply to this layout node.
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/BasicTextField.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/BasicTextField.kt
index 0751e09..0fbe466 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/BasicTextField.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/BasicTextField.kt
@@ -16,8 +16,8 @@
 
 package androidx.compose.foundation.text
 
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
@@ -27,7 +27,6 @@
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.SolidColor
-import androidx.compose.ui.text.SoftwareKeyboardController
 import androidx.compose.ui.text.TextLayoutResult
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.input.ImeAction
@@ -97,14 +96,10 @@
  * @param visualTransformation The visual transformation filter for changing the visual
  * representation of the input. By default no visual transformation is applied.
  * @param onTextLayout Callback that is executed when a new text layout is calculated.
- * @param onTextInputStarted Callback that is executed when the initialization has done for
- * communicating with platform text input service, e.g. software keyboard on Android. Called with
- * [SoftwareKeyboardController] instance which can be used for requesting input show/hide software
- * keyboard.
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this TextField. You can create and pass in your own remembered [InteractionState]
- * if you want to read the [InteractionState] and customize the appearance / behavior of this
- * TextField in different [Interaction]s.
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this TextField. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this TextField in different [Interaction]s.
  * @param cursorBrush [Brush] to paint cursor with. If [SolidColor] with [Color.Unspecified]
  * provided, there will be no cursor drawn
  * @param decorationBox Composable lambda that allows to add decorations around text field, such
@@ -128,8 +123,7 @@
     maxLines: Int = Int.MAX_VALUE,
     visualTransformation: VisualTransformation = VisualTransformation.None,
     onTextLayout: (TextLayoutResult) -> Unit = {},
-    onTextInputStarted: (SoftwareKeyboardController) -> Unit = {},
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     cursorBrush: Brush = SolidColor(Color.Black),
     decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit =
         @Composable { innerTextField -> innerTextField() }
@@ -154,9 +148,8 @@
         maxLines = maxLines,
         visualTransformation = visualTransformation,
         onTextLayout = onTextLayout,
-        onTextInputStarted = onTextInputStarted,
         cursorBrush = cursorBrush,
-        interactionState = interactionState,
+        interactionSource = interactionSource,
         singleLine = singleLine,
         decorationBox = decorationBox
     )
@@ -223,14 +216,10 @@
  * @param visualTransformation The visual transformation filter for changing the visual
  * representation of the input. By default no visual transformation is applied.
  * @param onTextLayout Callback that is executed when a new text layout is calculated.
- * @param onTextInputStarted Callback that is executed when the initialization has done for
- * communicating with platform text input service, e.g. software keyboard on Android. Called with
- * [SoftwareKeyboardController] instance which can be used for requesting input show/hide software
- * keyboard.
- * @param interactionState The [InteractionState] representing the different [Interaction]s
- * present on this TextField. You can create and pass in your own remembered [InteractionState]
- * if you want to read the [InteractionState] and customize the appearance / behavior of this
- * TextField in different [Interaction]s.
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this TextField. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this TextField in different [Interaction]s.
  * @param cursorBrush [Brush] to paint cursor with. If [SolidColor] with [Color.Unspecified]
  * provided, there will be no cursor drawn
  * @param decorationBox Composable lambda that allows to add decorations around text field, such
@@ -254,8 +243,7 @@
     maxLines: Int = Int.MAX_VALUE,
     visualTransformation: VisualTransformation = VisualTransformation.None,
     onTextLayout: (TextLayoutResult) -> Unit = {},
-    onTextInputStarted: (SoftwareKeyboardController) -> Unit = {},
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     cursorBrush: Brush = SolidColor(Color.Black),
     decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit =
         @Composable { innerTextField -> innerTextField() }
@@ -267,8 +255,7 @@
         textStyle = textStyle,
         visualTransformation = visualTransformation,
         onTextLayout = onTextLayout,
-        interactionState = interactionState,
-        onTextInputStarted = onTextInputStarted,
+        interactionSource = interactionSource,
         cursorBrush = cursorBrush,
         imeOptions = keyboardOptions.toImeOptions(singleLine = singleLine),
         keyboardActions = keyboardActions,
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/ClickableText.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/ClickableText.kt
similarity index 94%
rename from compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/ClickableText.kt
rename to compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/ClickableText.kt
index 466a527..bd0af82 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/ClickableText.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/ClickableText.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,10 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package androidx.compose.foundation
+package androidx.compose.foundation.text
 
 import androidx.compose.foundation.gestures.detectTapGestures
-import androidx.compose.foundation.text.BasicText
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
@@ -70,7 +69,7 @@
     onClick: (Int) -> Unit
 ) {
     val layoutResult = remember { mutableStateOf<TextLayoutResult?>(null) }
-    val pressIndicator = Modifier.pointerInput(Unit) {
+    val pressIndicator = Modifier.pointerInput(onClick) {
         detectTapGestures { pos ->
             layoutResult.value?.let { layoutResult ->
                 onClick(layoutResult.getOffsetForPosition(pos))
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreText.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreText.kt
index bd21d2c..7f72f56 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreText.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreText.kt
@@ -17,6 +17,7 @@
 
 package androidx.compose.foundation.text
 
+import androidx.compose.foundation.legacygestures.DragObserver
 import androidx.compose.foundation.text.selection.MultiWidgetSelectionDelegate
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
@@ -36,11 +37,15 @@
 import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
 import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.layout.FirstBaseline
-import androidx.compose.ui.layout.IntrinsicMeasureBlock
+import androidx.compose.ui.layout.IntrinsicMeasurable
+import androidx.compose.ui.layout.IntrinsicMeasureScope
 import androidx.compose.ui.layout.LastBaseline
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.layout.LayoutCoordinates
-import androidx.compose.ui.layout.MeasureBlock
+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.onGloballyPositioned
 import androidx.compose.ui.layout.positionInWindow
 import androidx.compose.ui.platform.LocalDensity
@@ -72,7 +77,7 @@
 /**
  * CoreText is a low level element that displays text with multiple different styles. The text to
  * display is described using a [AnnotatedString]. Typically you will instead want to use
- * [androidx.compose.foundation.text.BasicText], which is a higher level Text element that contains
+ * [androidx.compose.material.Text], which is a higher level Text element that contains
  * semantics and consumes style information from a theme.
  *
  * @param text AnnotatedString encoding a styled text.
@@ -153,21 +158,27 @@
             .then(controller.modifiers)
             .then(
                 if (selectionRegistrar != null) {
-                    Modifier.longPressDragGestureFilter(
-                        longPressDragObserver(
-                            state = state,
-                            selectionRegistrar = selectionRegistrar
+                    if (isInTouchMode) {
+                        Modifier.longPressDragGestureFilter(
+                            longPressDragObserver(
+                                state = state,
+                                selectionRegistrar = selectionRegistrar
+                            )
                         )
-                    )
+                    } else {
+                        Modifier.mouseDragGestureFilter(
+                            mouseSelectionObserver(
+                                state = state,
+                                selectionRegistrar = selectionRegistrar
+                            ),
+                            enabled = true
+                        )
+                    }
                 } else {
                     Modifier
                 }
             ),
-        minIntrinsicWidthMeasureBlock = controller.minIntrinsicWidth,
-        minIntrinsicHeightMeasureBlock = controller.minIntrinsicHeight,
-        maxIntrinsicWidthMeasureBlock = controller.maxIntrinsicWidth,
-        maxIntrinsicHeightMeasureBlock = controller.maxIntrinsicHeight,
-        measureBlock = controller.measure
+        measurePolicy = controller.measurePolicy
     )
 
     DisposableEffect(selectionRegistrar, effect = controller.commit)
@@ -237,87 +248,103 @@
         }
     }
 
-    val minIntrinsicWidth: IntrinsicMeasureBlock = { _, _ ->
-        state.textDelegate.layoutIntrinsics(layoutDirection)
-        state.textDelegate.minIntrinsicWidth
-    }
+    val measurePolicy = object : MeasurePolicy {
+        override fun MeasureScope.measure(
+            measurables: List<Measurable>,
+            constraints: Constraints
+        ): MeasureResult {
+            val layoutResult = state.textDelegate.layout(
+                constraints,
+                layoutDirection,
+                state.layoutResult
+            )
+            if (state.layoutResult != layoutResult) {
+                state.onTextLayout(layoutResult)
 
-    val minIntrinsicHeight: IntrinsicMeasureBlock = { _, width ->
-        // given the width constraint, determine the min height
-        state.textDelegate
-            .layout(Constraints(0, width, 0, Constraints.Infinity), layoutDirection)
-            .size.height
-    }
-
-    val maxIntrinsicWidth: IntrinsicMeasureBlock = { _, _ ->
-        state.textDelegate.layoutIntrinsics(layoutDirection)
-        state.textDelegate.maxIntrinsicWidth
-    }
-
-    val maxIntrinsicHeight: IntrinsicMeasureBlock = { _, width ->
-        state.textDelegate
-            .layout(Constraints(0, width, 0, Constraints.Infinity), layoutDirection)
-            .size.height
-    }
-
-    val measure: MeasureBlock = { measurables, constraints ->
-        val layoutResult = state.textDelegate.layout(
-            constraints,
-            layoutDirection,
-            state.layoutResult
-        )
-        if (state.layoutResult != layoutResult) {
-            state.onTextLayout(layoutResult)
-
-            state.layoutResult?.let { prevLayoutResult ->
-                // If the input text of this CoreText has changed, notify the SelectionContainer.
-                if (prevLayoutResult.layoutInput.text != layoutResult.layoutInput.text) {
-                    state.selectable?.let { selectable ->
-                        selectionRegistrar?.notifySelectableChange(selectable)
+                state.layoutResult?.let { prevLayoutResult ->
+                    // If the input text of this CoreText has changed, notify the SelectionContainer.
+                    if (prevLayoutResult.layoutInput.text != layoutResult.layoutInput.text) {
+                        state.selectable?.let { selectable ->
+                            selectionRegistrar?.notifySelectableChange(selectable)
+                        }
                     }
                 }
             }
-        }
-        state.layoutResult = layoutResult
+            state.layoutResult = layoutResult
 
-        check(measurables.size >= layoutResult.placeholderRects.size)
-        val placeables = layoutResult.placeholderRects.mapIndexedNotNull { index, rect ->
-            // PlaceholderRect will be null if it's ellipsized. In that case, the corresponding
-            // inline children won't be measured or placed.
-            rect?.let {
-                Pair(
-                    measurables[index].measure(
-                        Constraints(
-                            maxWidth = floor(it.width).toInt(),
-                            maxHeight = floor(it.height).toInt()
-                        )
-                    ),
-                    IntOffset(it.left.roundToInt(), it.top.roundToInt())
+            check(measurables.size >= layoutResult.placeholderRects.size)
+            val placeables = layoutResult.placeholderRects.mapIndexedNotNull { index, rect ->
+                // PlaceholderRect will be null if it's ellipsized. In that case, the corresponding
+                // inline children won't be measured or placed.
+                rect?.let {
+                    Pair(
+                        measurables[index].measure(
+                            Constraints(
+                                maxWidth = floor(it.width).toInt(),
+                                maxHeight = floor(it.height).toInt()
+                            )
+                        ),
+                        IntOffset(it.left.roundToInt(), it.top.roundToInt())
+                    )
+                }
+            }
+
+            return layout(
+                layoutResult.size.width,
+                layoutResult.size.height,
+                // Provide values for the alignment lines defined by text - the first
+                // and last baselines of the text. These can be used by parent layouts
+                // to position this text or align this and other texts by baseline.
+                //
+                // Note: we use round to make Int but any rounding doesn't work well here since
+                // the layout system works with integer pixels but baseline can be in a middle of
+                // the pixel. So any rounding doesn't offer the pixel perfect baseline. We use
+                // round just because the Android framework is doing float-to-int conversion with
+                // round.
+                // https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/jni/android/graphics/Paint.cpp;l=635?q=Paint.cpp
+                mapOf(
+                    FirstBaseline to layoutResult.firstBaseline.roundToInt(),
+                    LastBaseline to layoutResult.lastBaseline.roundToInt()
                 )
+            ) {
+                placeables.fastForEach { placeable ->
+                    placeable.first.placeRelative(placeable.second)
+                }
             }
         }
 
-        layout(
-            layoutResult.size.width,
-            layoutResult.size.height,
-            // Provide values for the alignment lines defined by text - the first
-            // and last baselines of the text. These can be used by parent layouts
-            // to position this text or align this and other texts by baseline.
-            //
-            // Note: we use round to make Int but any rounding doesn't work well here since
-            // the layout system works with integer pixels but baseline can be in a middle of
-            // the pixel. So any rounding doesn't offer the pixel perfect baseline. We use
-            // round just because the Android framework is doing float-to-int conversion with
-            // round.
-            // https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/jni/android/graphics/Paint.cpp;l=635?q=Paint.cpp
-            mapOf(
-                FirstBaseline to layoutResult.firstBaseline.roundToInt(),
-                LastBaseline to layoutResult.lastBaseline.roundToInt()
-            )
-        ) {
-            placeables.fastForEach { placeable ->
-                placeable.first.placeRelative(placeable.second)
-            }
+        override fun IntrinsicMeasureScope.minIntrinsicWidth(
+            measurables: List<IntrinsicMeasurable>,
+            height: Int
+        ): Int {
+            state.textDelegate.layoutIntrinsics(layoutDirection)
+            return state.textDelegate.minIntrinsicWidth
+        }
+
+        override fun IntrinsicMeasureScope.minIntrinsicHeight(
+            measurables: List<IntrinsicMeasurable>,
+            width: Int
+        ): Int {
+            return state.textDelegate
+                .layout(Constraints(0, width, 0, Constraints.Infinity), layoutDirection)
+                .size.height
+        }
+
+        override fun IntrinsicMeasureScope.maxIntrinsicWidth(
+            measurables: List<IntrinsicMeasurable>,
+            height: Int
+        ): Int {
+            state.textDelegate.layoutIntrinsics(layoutDirection)
+            return state.textDelegate.maxIntrinsicWidth
+        }
+
+        override fun IntrinsicMeasureScope.maxIntrinsicHeight(
+            measurables: List<IntrinsicMeasurable>,
+            width: Int
+        ): Int {
+            return state.textDelegate
+                .layout(Constraints(0, width, 0, Constraints.Infinity), layoutDirection)
+                .size.height
         }
     }
 
@@ -503,3 +530,46 @@
         }
     }
 }
+
+@Suppress("DEPRECATION") // DragObserver
+internal fun mouseSelectionObserver(
+    state: TextState,
+    selectionRegistrar: SelectionRegistrar?
+): DragObserver {
+    var dragBeginPosition = Offset.Zero
+
+    var dragTotalDistance = Offset.Zero
+    return object : DragObserver {
+        override fun onStart(downPosition: Offset) {
+            state.layoutCoordinates?.let {
+                if (!it.isAttached) return
+
+                selectionRegistrar?.notifySelectionUpdateStart(
+                    layoutCoordinates = it,
+                    startPosition = downPosition
+                )
+
+                dragBeginPosition = downPosition
+            }
+
+            if (state.selectionRange == null) return
+            dragTotalDistance = Offset.Zero
+        }
+
+        override fun onDrag(dragDistance: Offset): Offset {
+            state.layoutCoordinates?.let {
+                if (!it.isAttached) return Offset.Zero
+                if (state.selectionRange == null) return Offset.Zero
+
+                dragTotalDistance += dragDistance
+
+                selectionRegistrar?.notifySelectionUpdate(
+                    layoutCoordinates = it,
+                    startPosition = dragBeginPosition,
+                    endPosition = dragBeginPosition + dragTotalDistance
+                )
+            }
+            return dragDistance
+        }
+    }
+}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt
index fd36b57..14de931 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt
@@ -17,9 +17,9 @@
 
 package androidx.compose.foundation.text
 
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
 import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.text.selection.LocalTextSelectionColors
 import androidx.compose.foundation.text.selection.SimpleLayout
@@ -44,8 +44,6 @@
 import androidx.compose.ui.graphics.Paint
 import androidx.compose.ui.graphics.SolidColor
 import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
-import androidx.compose.ui.input.pointer.MouseTemporaryApi
-import androidx.compose.ui.input.pointer.isMouseInput
 import androidx.compose.ui.layout.FirstBaseline
 import androidx.compose.ui.layout.LastBaseline
 import androidx.compose.ui.layout.Layout
@@ -73,8 +71,6 @@
 import androidx.compose.ui.semantics.setText
 import androidx.compose.ui.semantics.textSelectionRange
 import androidx.compose.ui.text.AnnotatedString
-import androidx.compose.ui.text.InternalTextApi
-import androidx.compose.ui.text.SoftwareKeyboardController
 import androidx.compose.ui.text.TextLayoutResult
 import androidx.compose.ui.text.TextRange
 import androidx.compose.ui.text.TextStyle
@@ -82,11 +78,11 @@
 import androidx.compose.ui.text.input.EditProcessor
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.ImeOptions
-import androidx.compose.ui.text.input.NO_SESSION
 import androidx.compose.ui.text.input.OffsetMapping
 import androidx.compose.ui.text.input.PasswordVisualTransformation
 import androidx.compose.ui.text.input.TextFieldValue
 import androidx.compose.ui.text.input.TextInputService
+import androidx.compose.ui.text.input.TextInputSession
 import androidx.compose.ui.text.input.VisualTransformation
 import androidx.compose.ui.unit.Density
 import kotlin.math.max
@@ -121,20 +117,13 @@
  * @param onValueChange Called when the input service updates the values in [TextFieldValue].
  * @param modifier optional [Modifier] for this text field.
  * @param textStyle Style configuration that applies at character level such as color, font etc.
- * @param onImeActionPerformed Called when the input service requested an IME action. When the
- * input service emitted an IME action, this callback is called with the emitted IME action. Note
- * that this IME action may be different from what you specified in [imeAction].
  * @param visualTransformation The visual transformation filter for changing the visual
  * representation of the input. By default no visual transformation is applied.
  * @param onTextLayout Callback that is executed when a new text layout is calculated.
- * @param onTextInputStarted Callback that is executed when the initialization has done for
- * communicating with platform text input service, e.g. software keyboard on Android. Called with
- * [SoftwareKeyboardController] instance which can be used for requesting input show/hide software
- * keyboard.
- * @param interactionState The [InteractionState] representing the different [Interaction]s
- * present on this TextField. You can create and pass in your own remembered [InteractionState]
- * if you want to read the [InteractionState] and customize the appearance / behavior of this
- * TextField in different [Interaction]s.
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this CoreTextField. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this CoreTextField in different [Interaction]s.
  * @param cursorBrush [Brush] to paint cursor with. If [SolidColor] with [Color.Unspecified]
  * provided, there will be no cursor drawn
  * @param softWrap Whether the text should break at soft line breaks. If false, the glyphs in the
@@ -158,7 +147,7 @@
  * innerTextField exactly once.
  */
 @Composable
-@OptIn(MouseTemporaryApi::class, InternalTextApi::class, InternalFoundationTextApi::class)
+@OptIn(InternalFoundationTextApi::class)
 internal fun CoreTextField(
     value: TextFieldValue,
     onValueChange: (TextFieldValue) -> Unit,
@@ -166,8 +155,7 @@
     textStyle: TextStyle = TextStyle.Default,
     visualTransformation: VisualTransformation = VisualTransformation.None,
     onTextLayout: (TextLayoutResult) -> Unit = {},
-    onTextInputStarted: (SoftwareKeyboardController) -> Unit = {},
-    interactionState: InteractionState? = null,
+    interactionSource: MutableInteractionSource? = null,
     cursorBrush: Brush = SolidColor(Color.Unspecified),
     softWrap: Boolean = true,
     maxLines: Int = Int.MAX_VALUE,
@@ -241,7 +229,8 @@
         state.keyboardActionRunner.runAction(imeAction)
     }
 
-    state.processor.onNewState(value, textInputService, state.inputSession)
+    // notify the EditProcessor of value every recomposition
+    state.processor.reset(value, state.inputSession)
 
     val manager = remember { TextFieldSelectionManager() }
     manager.offsetMapping = offsetMapping
@@ -259,7 +248,7 @@
     val focusModifier = Modifier.textFieldFocusModifier(
         enabled = enabled,
         focusRequester = focusRequester,
-        interactionState = interactionState
+        interactionSource = interactionSource
     ) {
         if (state.hasFocus == it.isFocused) {
             return@textFieldFocusModifier
@@ -274,7 +263,6 @@
                 imeOptions,
                 onValueChangeWrapper,
                 onImeActionPerformedWrapper,
-                onTextInputStarted,
                 offsetMapping
             )
         }
@@ -284,7 +272,7 @@
     val focusRequestTapModifier = Modifier.focusRequestTapModifier(
         enabled = enabled,
         onTap = { offset ->
-            tapToFocus(state, focusRequester, textInputService, !readOnly)
+            tapToFocus(state, focusRequester, !readOnly)
             if (state.hasFocus) {
                 if (!state.selectionIsOn) {
                     state.layoutResult?.let { layoutResult ->
@@ -306,15 +294,15 @@
     val selectionModifier =
         Modifier.longPressDragGestureFilter(manager.touchSelectionObserver, enabled)
 
-    val pointerModifier = if (isMouseInput) {
+    val pointerModifier = if (isInTouchMode) {
+        Modifier.pressGestureFilter(interactionSource = interactionSource, enabled = enabled)
+            .then(selectionModifier)
+            .then(focusRequestTapModifier)
+    } else {
         Modifier.mouseDragGestureFilter(
             manager.mouseSelectionObserver(onStart = { focusRequester.requestFocus() }),
             enabled = enabled
         )
-    } else {
-        Modifier.pressGestureFilter(interactionState = interactionState, enabled = enabled)
-            .then(selectionModifier)
-            .then(focusRequestTapModifier)
     }
 
     val drawModifier = Modifier.drawBehind {
@@ -344,16 +332,17 @@
                 state.showSelectionHandleEnd = manager.isSelectionHandleInVisibleBound(false)
             }
             state.layoutResult?.let { layoutResult ->
-                TextFieldDelegate.notifyFocusedRect(
-                    value,
-                    state.textDelegate,
-                    layoutResult.value,
-                    it,
-                    textInputService,
-                    state.inputSession,
-                    state.hasFocus,
-                    offsetMapping
-                )
+                state.inputSession?.let { inputSession ->
+                    TextFieldDelegate.notifyFocusedRect(
+                        value,
+                        state.textDelegate,
+                        layoutResult.value,
+                        it,
+                        inputSession,
+                        state.hasFocus,
+                        offsetMapping
+                    )
+                }
             }
         }
         state.layoutResult?.innerTextFieldCoordinates = it
@@ -409,7 +398,7 @@
         onClick {
             // according to the documentation, we still need to provide proper semantics actions
             // even if the state is 'disabled'
-            tapToFocus(state, focusRequester, textInputService, !readOnly)
+            tapToFocus(state, focusRequester, !readOnly)
             true
         }
         onLongClick {
@@ -446,7 +435,7 @@
     // Modifiers that should be applied to the outer text field container. Usually those include
     // gesture and semantics modifiers.
     val decorationBoxModifier = modifier
-        .textFieldScrollable(scrollerPosition, interactionState, enabled)
+        .textFieldScrollable(scrollerPosition, interactionSource, enabled)
         .then(pointerModifier)
         .then(semanticsModifier)
         .then(focusModifier)
@@ -502,7 +491,7 @@
                         state.selectionIsOn &&
                         state.layoutCoordinates != null &&
                         state.layoutCoordinates!!.isAttached &&
-                        !isMouseInput
+                        isInTouchMode
                 )
             }
         }
@@ -511,12 +500,12 @@
 
 internal expect fun Modifier.textFieldKeyboardModifier(manager: TextFieldSelectionManager): Modifier
 
-@OptIn(InternalTextApi::class, InternalFoundationTextApi::class)
+@OptIn(InternalFoundationTextApi::class)
 internal class TextFieldState(
     var textDelegate: TextDelegate
 ) {
     val processor = EditProcessor()
-    var inputSession = NO_SESSION
+    var inputSession: TextInputSession? = null
 
     /**
      * This should be a state as every time we update the value we need to redraw it.
@@ -619,13 +608,12 @@
 private fun tapToFocus(
     state: TextFieldState,
     focusRequester: FocusRequester,
-    textInputService: TextInputService?,
     allowKeyboard: Boolean
 ) {
     if (!state.hasFocus) {
         focusRequester.requestFocus()
     } else if (allowKeyboard) {
-        textInputService?.showSoftwareKeyboard(state.inputSession)
+        state.inputSession?.showSoftwareKeyboard()
     }
 }
 
@@ -636,7 +624,6 @@
     imeOptions: ImeOptions,
     onValueChange: (TextFieldValue) -> Unit,
     onImeActionPerformed: (ImeAction) -> Unit,
-    onTextInputStarted: (SoftwareKeyboardController) -> Unit,
     offsetMapping: OffsetMapping
 ) {
     if (state.hasFocus) {
@@ -647,32 +634,26 @@
             imeOptions,
             onValueChange,
             onImeActionPerformed
-        )
-        if (state.inputSession != NO_SESSION) {
-            onTextInputStarted(SoftwareKeyboardController(textInputService, state.inputSession))
-        }
-        state.layoutCoordinates?.let { coords ->
-            state.layoutResult?.let { layoutResult ->
-                TextFieldDelegate.notifyFocusedRect(
-                    value,
-                    state.textDelegate,
-                    layoutResult.value,
-                    coords,
-                    textInputService,
-                    state.inputSession,
-                    state.hasFocus,
-                    offsetMapping
-                )
+        ).also { newSession ->
+            state.layoutCoordinates?.let { coords ->
+                state.layoutResult?.let { layoutResult ->
+                    TextFieldDelegate.notifyFocusedRect(
+                        value,
+                        state.textDelegate,
+                        layoutResult.value,
+                        coords,
+                        newSession,
+                        state.hasFocus,
+                        offsetMapping
+                    )
+                }
             }
         }
     } else {
-        TextFieldDelegate.onBlur(
-            textInputService,
-            state.inputSession,
-            state.processor,
-            false,
-            onValueChange
-        )
+        state.inputSession?.let { session ->
+            TextFieldDelegate.onBlur(session, state.processor, onValueChange)
+        }
+        state.inputSession = null
     }
 }
 
@@ -716,4 +697,4 @@
             }
         }
     } else manager.hideSelectionToolbar()
-}
\ No newline at end of file
+}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/InactiveTextField.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/InactiveTextField.kt
deleted file mode 100644
index 791a40a..0000000
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/InactiveTextField.kt
+++ /dev/null
@@ -1,74 +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.text
-
-import androidx.compose.foundation.InteractionState
-import androidx.compose.foundation.focusable
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
-import androidx.compose.foundation.text.selection.DisableSelection
-import androidx.compose.foundation.text.selection.SelectionContainer
-import androidx.compose.ui.semantics.disabled
-import androidx.compose.ui.semantics.semantics
-import androidx.compose.ui.text.TextLayoutResult
-import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.text.input.TextFieldValue
-import androidx.compose.ui.text.input.VisualTransformation
-
-/**
- * Implements disabled and readonly text field using Text.
- */
-@Composable
-internal fun InactiveTextField(
-    value: TextFieldValue,
-    modifier: Modifier = Modifier,
-    enabled: Boolean = true,
-    textStyle: TextStyle = TextStyle.Default,
-    singleLine: Boolean = false,
-    maxLines: Int = Int.MAX_VALUE,
-    visualTransformation: VisualTransformation = VisualTransformation.None,
-    onTextLayout: (TextLayoutResult) -> Unit = {},
-    interactionState: InteractionState? = null
-) {
-    val transformedText = remember(value, visualTransformation) {
-        visualTransformation.filter(value.annotatedString)
-    }.text
-
-    val text: @Composable (Modifier) -> Unit = @Composable { textModifier ->
-        BasicText(
-            text = transformedText,
-            modifier = textModifier.semantics {
-                if (!enabled) disabled()
-            },
-            softWrap = !singleLine,
-            maxLines = if (singleLine) 1 else maxLines,
-            style = textStyle,
-            onTextLayout = onTextLayout
-        )
-    }
-    val textModifier = modifier.focusable(enabled, interactionState)
-    if (enabled) {
-        SelectionContainer(textModifier) {
-            text(Modifier)
-        }
-    } else {
-        DisableSelection {
-            text(textModifier)
-        }
-    }
-}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/InlineTextContent.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/InlineTextContent.kt
index cc6c7fa7..039037a 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/InlineTextContent.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/InlineTextContent.kt
@@ -27,12 +27,22 @@
 // value of alternate text.
 private const val REPLACEMENT_CHAR = "\uFFFD"
 /**
- * Append an inline content into the AnnotatedString.
- * @param id The id of this inline content, it is referred by the [androidx.compose.foundation.text.CoreText]
- * parameter inlineContent to replace the [alternateText] to the corresponding composable.
+ * Used to insert composables into the text layout. This method can be used together with the
+ * inlineContent parameter of [BasicText]. It will append the [alternateText] to this
+ * [AnnotatedString] and also mark this range of text to be replaced by a composable.
+ * [BasicText] will try to find an [InlineTextContent] in the map defined by inlineContent whose
+ * key equals to [id], and it will use the [InlineTextContent.children] to replace this range of
+ * text.
+ *
+ * @sample androidx.compose.foundation.samples.InlineTextContentSample
+ * @see InlineTextContent
+ * @see BasicText
+ *
+ * @param id The id used to look up the [InlineTextContent], it is referred by the inlineContent
+ * parameter of [BasicText] to replace the [alternateText] to the corresponding composable.
  * @param alternateText The text to be replaced by the inline content. It's displayed when
- * the inlineContent parameter of [androidx.compose.foundation.text.CoreText] doesn't contain [id]. Accessibility
- * features will also use this text to describe the inline content.
+ * the inlineContent parameter of [BasicText] doesn't contain [id].
+ * Accessibility features will also use this text to describe the inline content.
  * @throws IllegalArgumentException if [alternateText] has zero length.
  */
 fun AnnotatedString.Builder.appendInlineContent(
@@ -54,10 +64,10 @@
  * space. In this [placeholder], the size of the content and how it will be aligned within the
  * text line is defined. When the children composable is measured, its size given in
  * [Placeholder.width] and [Placeholder.height] will be converted into
- * [androidx.compose.ui.unit.Constraints] and passed through [androidx.compose.ui.Layout].
+ * [androidx.compose.ui.unit.Constraints] and passed through [androidx.compose.ui.layout.Layout].
  *
  * @sample androidx.compose.foundation.samples.InlineTextContentSample
- * @see CoreText
+ * @see BasicText
  * @see Placeholder
  */
 @Immutable
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldDelegate.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldDelegate.kt
index 72e81b90..4eb9523 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldDelegate.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldDelegate.kt
@@ -23,7 +23,6 @@
 import androidx.compose.ui.graphics.Paint
 import androidx.compose.ui.layout.LayoutCoordinates
 import androidx.compose.ui.text.AnnotatedString
-import androidx.compose.ui.text.InternalTextApi
 import androidx.compose.ui.text.Paragraph
 import androidx.compose.ui.text.SpanStyle
 import androidx.compose.ui.text.TextLayoutResult
@@ -33,13 +32,12 @@
 import androidx.compose.ui.text.font.Font
 import androidx.compose.ui.text.input.EditCommand
 import androidx.compose.ui.text.input.EditProcessor
-import androidx.compose.ui.text.input.INVALID_SESSION
 import androidx.compose.ui.text.input.ImeAction
-import androidx.compose.ui.text.input.InputSessionToken
 import androidx.compose.ui.text.input.ImeOptions
 import androidx.compose.ui.text.input.OffsetMapping
 import androidx.compose.ui.text.input.TextFieldValue
 import androidx.compose.ui.text.input.TextInputService
+import androidx.compose.ui.text.input.TextInputSession
 import androidx.compose.ui.text.input.TransformedText
 import androidx.compose.ui.text.style.TextDecoration
 import androidx.compose.ui.unit.Constraints
@@ -87,7 +85,7 @@
 
 private fun Float.toIntPx(): Int = ceil(this).roundToInt()
 
-@OptIn(InternalFoundationTextApi::class, InternalTextApi::class)
+@OptIn(InternalFoundationTextApi::class)
 internal class TextFieldDelegate {
     companion object {
         /**
@@ -143,8 +141,7 @@
          * @param value The editor model
          * @param textDelegate The text delegate
          * @param layoutCoordinates The layout coordinates
-         * @param textInputService The text input service
-         * @param token The current input session token.
+         * @param textInputSession The current input session.
          * @param hasFocus True if focus is gained.
          * @param offsetMapping The mapper from/to editing buffer to/from visible text.
          */
@@ -154,8 +151,7 @@
             textDelegate: TextDelegate,
             textLayoutResult: TextLayoutResult,
             layoutCoordinates: LayoutCoordinates,
-            textInputService: TextInputService,
-            token: InputSessionToken,
+            textInputSession: TextInputSession,
             hasFocus: Boolean,
             offsetMapping: OffsetMapping
         ) {
@@ -181,8 +177,7 @@
             }
             val globalLT = layoutCoordinates.localToRoot(Offset(bbox.left, bbox.top))
 
-            textInputService.notifyFocusedRect(
-                token,
+            textInputSession.notifyFocusedRect(
                 Rect(Offset(globalLT.x, globalLT.y), Size(bbox.width, bbox.height))
             )
         }
@@ -200,7 +195,7 @@
             editProcessor: EditProcessor,
             onValueChange: (TextFieldValue) -> Unit
         ) {
-            onValueChange(editProcessor.onEditCommands(ops))
+            onValueChange(editProcessor.apply(ops))
         }
 
         /**
@@ -223,7 +218,7 @@
             val offset = offsetMapping.transformedToOriginal(
                 textLayoutResult.getOffsetForPosition(position)
             )
-            onValueChange(editProcessor.mBufferState.copy(selection = TextRange(offset)))
+            onValueChange(editProcessor.toTextFieldValue().copy(selection = TextRange(offset)))
         }
 
         /**
@@ -238,46 +233,41 @@
          */
         @JvmStatic
         internal fun onFocus(
-            textInputService: TextInputService?,
+            textInputService: TextInputService,
             value: TextFieldValue,
             editProcessor: EditProcessor,
             imeOptions: ImeOptions,
             onValueChange: (TextFieldValue) -> Unit,
             onImeActionPerformed: (ImeAction) -> Unit
-        ): InputSessionToken {
-            val inputSessionToken = textInputService?.startInput(
+        ): TextInputSession {
+            val textInputSession = textInputService.startInput(
                 value = value.copy(),
                 imeOptions = imeOptions,
                 onEditCommand = { onEditCommand(it, editProcessor, onValueChange) },
                 onImeActionPerformed = onImeActionPerformed
-            ) ?: INVALID_SESSION
+            )
 
-            textInputService?.showSoftwareKeyboard(inputSessionToken)
+            textInputSession.showSoftwareKeyboard()
 
-            return inputSessionToken
+            return textInputSession
         }
 
         /**
          * Called when the composable loses input focus
          *
-         * @param textInputService The text input service
-         * @param token The current input session token.
+         * @param textInputSession The current input session.
          * @param editProcessor The edit processor
          * @param onValueChange The callback called when the new editor state arrives.
          */
         @JvmStatic
         internal fun onBlur(
-            textInputService: TextInputService?,
-            token: InputSessionToken,
+            textInputSession: TextInputSession,
             editProcessor: EditProcessor,
-            hasNextClient: Boolean,
             onValueChange: (TextFieldValue) -> Unit
         ) {
-            onValueChange(editProcessor.mBufferState.commitComposition())
-            textInputService?.stopInput(token)
-            if (!hasNextClient) {
-                textInputService?.hideSoftwareKeyboard(token)
-            }
+            onValueChange(editProcessor.toTextFieldValue().copy(composition = null))
+            textInputSession.hideSoftwareKeyboard()
+            textInputSession.dispose()
         }
 
         /**
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldGestureModifiers.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldGestureModifiers.kt
index 7087aaf..af50a91 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldGestureModifiers.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldGestureModifiers.kt
@@ -18,7 +18,7 @@
 
 package androidx.compose.foundation.text
 
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.focusable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.focus.FocusRequester
@@ -45,12 +45,12 @@
 internal fun Modifier.textFieldFocusModifier(
     enabled: Boolean,
     focusRequester: FocusRequester,
-    interactionState: InteractionState?,
+    interactionSource: MutableInteractionSource?,
     onFocusChanged: (FocusState) -> Unit
 ) = this
     .focusRequester(focusRequester)
     .onFocusChanged(onFocusChanged)
-    .focusable(interactionState = interactionState, enabled = enabled)
+    .focusable(interactionSource = interactionSource, enabled = enabled)
 
 // Mouse
 internal fun Modifier.mouseDragGestureFilter(
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldPressGestureFilter.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldPressGestureFilter.kt
index 9225346..493e81c 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldPressGestureFilter.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldPressGestureFilter.kt
@@ -16,35 +16,67 @@
 
 package androidx.compose.foundation.text
 
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.composed
+import kotlinx.coroutines.launch
 import androidx.compose.foundation.legacygestures.pressIndicatorGestureFilter
 
 /**
- * Required for the press [InteractionState] consistency for TextField.
+ * Required for the press [MutableInteractionSource] consistency for TextField.
  */
 @Suppress("ModifierInspectorInfo", "DEPRECATION")
 internal fun Modifier.pressGestureFilter(
-    interactionState: InteractionState?,
+    interactionSource: MutableInteractionSource?,
     enabled: Boolean = true
 ): Modifier = if (enabled) composed {
-    DisposableEffect(interactionState) {
+    val scope = rememberCoroutineScope()
+    val pressedInteraction = remember { mutableStateOf<PressInteraction.Press?>(null) }
+    DisposableEffect(interactionSource) {
         onDispose {
-            interactionState?.removeInteraction(Interaction.Pressed)
+            pressedInteraction.value?.let { oldValue ->
+                val interaction = PressInteraction.Cancel(oldValue)
+                interactionSource?.tryEmit(interaction)
+                pressedInteraction.value = null
+            }
         }
     }
     pressIndicatorGestureFilter(
         onStart = {
-            interactionState?.addInteraction(Interaction.Pressed, it)
+            scope.launch {
+                // Remove any old interactions if we didn't fire stop / cancel properly
+                pressedInteraction.value?.let { oldValue ->
+                    val interaction = PressInteraction.Cancel(oldValue)
+                    interactionSource?.emit(interaction)
+                    pressedInteraction.value = null
+                }
+                val interaction = PressInteraction.Press(it)
+                interactionSource?.emit(interaction)
+                pressedInteraction.value = interaction
+            }
         },
         onStop = {
-            interactionState?.removeInteraction(Interaction.Pressed)
+            scope.launch {
+                pressedInteraction.value?.let {
+                    val interaction = PressInteraction.Release(it)
+                    interactionSource?.emit(interaction)
+                    pressedInteraction.value = null
+                }
+            }
         },
         onCancel = {
-            interactionState?.removeInteraction(Interaction.Pressed)
+            scope.launch {
+                pressedInteraction.value?.let {
+                    val interaction = PressInteraction.Cancel(it)
+                    interactionSource?.emit(interaction)
+                    pressedInteraction.value = null
+                }
+            }
         }
     )
 } else this
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldScroll.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldScroll.kt
index 9e138c8..fd4438b 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldScroll.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldScroll.kt
@@ -16,7 +16,7 @@
 
 package androidx.compose.foundation.text
 
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.gestures.rememberScrollableState
 import androidx.compose.foundation.gestures.scrollable
@@ -51,13 +51,13 @@
 // Scrollable
 internal fun Modifier.textFieldScrollable(
     scrollerPosition: TextFieldScrollerPosition,
-    interactionState: InteractionState? = null,
+    interactionSource: MutableInteractionSource? = null,
     enabled: Boolean = true
 ) = composed(
     inspectorInfo = debugInspectorInfo {
         name = "textFieldScrollable"
         properties["scrollerPosition"] = scrollerPosition
-        properties["interactionState"] = interactionState
+        properties["interactionSource"] = interactionSource
         properties["enabled"] = enabled
     }
 ) {
@@ -79,7 +79,7 @@
         orientation = scrollerPosition.orientation,
         reverseDirection = reverseDirection,
         state = controller,
-        interactionState = interactionState,
+        interactionSource = interactionSource,
         enabled = enabled && scrollerPosition.maximum != 0f
     )
     scroll
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TouchMode.kt
similarity index 68%
copy from compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt
copy to compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TouchMode.kt
index 63fdeeb..234b500 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TouchMode.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,10 @@
  * limitations under the License.
  */
 
-package androidx.compose.foundation.layout
+package androidx.compose.foundation.text
 
-@RequiresOptIn("The API of this layout is experimental and is likely to change in the future.")
-annotation class ExperimentalLayout
+/**
+ * This is a temporary workaround and should be removed after proper mouse handling is settled
+ * (b/171402426).
+ */
+internal expect val isInTouchMode: Boolean
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionContainer.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionContainer.kt
index 2da6d0d..d107f34 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionContainer.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionContainer.kt
@@ -16,14 +16,16 @@
 
 package androidx.compose.foundation.text.selection
 
-import androidx.compose.foundation.Interaction
+import androidx.compose.foundation.text.isInTouchMode
+import androidx.compose.foundation.interaction.collectIsFocusedAsState
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
+import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
 import androidx.compose.foundation.legacygestures.dragGestureFilter
 import androidx.compose.ui.platform.LocalClipboardManager
@@ -68,6 +70,7 @@
  * The selection composable wraps composables and let them to be selectable. It paints the selection
  * area with start and end handles.
  */
+@OptIn(ExperimentalComposeUiApi::class)
 @Suppress("ComposableLambdaParameterNaming", "DEPRECATION")
 @Composable
 internal fun SelectionContainer(
@@ -87,13 +90,15 @@
     manager.textToolbar = LocalTextToolbar.current
     manager.onSelectionChange = onSelectionChange
     manager.selection = selection
+    manager.touchMode = isInTouchMode
 
     CompositionLocalProvider(LocalSelectionRegistrar provides registrarImpl) {
         // Get the layout coordinates of the selection container. This is for hit test of
         // cross-composable selection.
         SimpleLayout(modifier = modifier.then(manager.modifier)) {
             children()
-            if (manager.interactionState.contains(Interaction.Focused)) {
+            val isFocused = manager.interactionSource.collectIsFocusedAsState()
+            if (isInTouchMode && isFocused.value) {
                 manager.selection?.let {
                     for (isStartHandle in listOf(true, false)) {
                         SelectionHandle(
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.kt
index a955465..d630533 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.kt
@@ -18,7 +18,7 @@
 
 package androidx.compose.foundation.text.selection
 
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.focusable
 import androidx.compose.runtime.State
 import androidx.compose.runtime.getValue
@@ -35,6 +35,8 @@
 import androidx.compose.foundation.legacygestures.DragObserver
 import androidx.compose.ui.hapticfeedback.HapticFeedback
 import androidx.compose.ui.hapticfeedback.HapticFeedbackType
+import androidx.compose.ui.input.key.KeyEvent
+import androidx.compose.ui.input.key.onKeyEvent
 import androidx.compose.ui.layout.LayoutCoordinates
 import androidx.compose.ui.layout.boundsInWindow
 import androidx.compose.ui.layout.onGloballyPositioned
@@ -61,6 +63,11 @@
         }
 
     /**
+     * Is touch mode active
+     */
+    var touchMode: Boolean = true
+
+    /**
      * The manager will invoke this every time it comes to the conclusion that the selection should
      * change. The expectation is that this callback will end up causing `setSelection` to get
      * called. This is what makes this a "controlled component".
@@ -88,9 +95,9 @@
     var focusRequester: FocusRequester = FocusRequester()
 
     /**
-     * InteractionState corresponds to the focusRequester, it will return trun.
+     * MutableInteractionSource for the selection container, containing focus interactions.
      */
-    val interactionState: InteractionState = InteractionState()
+    val interactionSource: MutableInteractionSource = MutableInteractionSource()
 
     /**
      * Modifier for selection container.
@@ -103,7 +110,15 @@
                 onRelease()
             }
         }
-        .focusable(interactionState = interactionState)
+        .focusable(interactionSource = interactionSource)
+        .onKeyEvent {
+            if (isCopyKeyEvent(it)) {
+                copy()
+                true
+            } else {
+                false
+            }
+        }
 
     /**
      * Layout Coordinates of the selection container.
@@ -162,7 +177,7 @@
                 startPosition = convertToContainerCoordinates(layoutCoordinates, startPosition),
                 endPosition = convertToContainerCoordinates(layoutCoordinates, startPosition),
                 isStartHandle = true,
-                longPress = true
+                longPress = touchMode
             )
             hideSelectionToolbar()
             focusRequester.requestFocus()
@@ -174,7 +189,7 @@
                     startPosition = convertToContainerCoordinates(layoutCoordinates, startPosition),
                     endPosition = convertToContainerCoordinates(layoutCoordinates, endPosition),
                     isStartHandle = false,
-                    longPress = true
+                    longPress = touchMode
                 )
             }
 
@@ -543,6 +558,8 @@
     return lhs?.merge(rhs) ?: rhs
 }
 
+internal expect fun isCopyKeyEvent(keyEvent: KeyEvent): Boolean
+
 internal fun getCurrentSelectedText(
     selectable: Selectable,
     selection: Selection
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/ActualDesktop.kt
similarity index 72%
copy from compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt
copy to compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/ActualDesktop.kt
index bae8c9a..7e01354 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/ActualDesktop.kt
@@ -1,5 +1,7 @@
+// ktlint-disable filename
+
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +16,6 @@
  * limitations under the License.
  */
 
-package androidx.compose.ui.input.pointer
+package androidx.compose.foundation
 
-@MouseTemporaryApi
-expect val isMouseInput: Boolean
\ No newline at end of file
+internal actual typealias AtomicReference<V> = java.util.concurrent.atomic.AtomicReference<V>
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/Scrollbar.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/Scrollbar.desktop.kt
index 7f10c00..eab10ec 100644
--- a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/Scrollbar.desktop.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/Scrollbar.desktop.kt
@@ -29,6 +29,7 @@
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
 import androidx.compose.runtime.staticCompositionLocalOf
 import androidx.compose.ui.Modifier
@@ -37,12 +38,14 @@
 import androidx.compose.foundation.legacygestures.DragObserver
 import androidx.compose.foundation.legacygestures.pressIndicatorGestureFilter
 import androidx.compose.foundation.legacygestures.rawDragGestureFilter
+import androidx.compose.foundation.interaction.DragInteraction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.RectangleShape
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.input.pointer.pointerMoveFilter
 import androidx.compose.ui.layout.Layout
-import androidx.compose.ui.layout.MeasuringIntrinsicsMeasureBlocks
+import androidx.compose.ui.layout.MeasurePolicy
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Dp
@@ -50,6 +53,7 @@
 import androidx.compose.ui.unit.constrainWidth
 import androidx.compose.ui.unit.dp
 import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
 import kotlin.math.roundToInt
 import kotlin.math.sign
@@ -110,20 +114,20 @@
  * @param adapter [ScrollbarAdapter] that will be used to communicate with scrollable component
  * @param modifier the modifier to apply to this layout
  * @param style [ScrollbarStyle] to define visual style of scrollbar
- * @param interactionState [InteractionState] that will be updated when the element with this
- * state is being dragged, using [Interaction.Dragged]
+ * @param interactionSource [MutableInteractionSource] that will be used to dispatch
+ * [DragInteraction.Start] when this Scrollbar is being dragged.
  */
 @Composable
 fun VerticalScrollbar(
     adapter: ScrollbarAdapter,
     modifier: Modifier = Modifier,
     style: ScrollbarStyle = ScrollbarStyleAmbient.current,
-    interactionState: InteractionState = remember { InteractionState() }
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
 ) = Scrollbar(
     adapter,
     modifier,
     style,
-    interactionState,
+    interactionSource,
     isVertical = true
 )
 
@@ -150,36 +154,41 @@
  * @param adapter [ScrollbarAdapter] that will be used to communicate with scrollable component
  * @param modifier the modifier to apply to this layout
  * @param style [ScrollbarStyle] to define visual style of scrollbar
- * @param interactionState [InteractionState] that will be updated when the element with this
- * state is being dragged, using [Interaction.Dragged]
+ * @param interactionSource [MutableInteractionSource] that will be used to dispatch
+ * [DragInteraction.Start] when this Scrollbar is being dragged.
  */
 @Composable
 fun HorizontalScrollbar(
     adapter: ScrollbarAdapter,
     modifier: Modifier = Modifier,
     style: ScrollbarStyle = ScrollbarStyleAmbient.current,
-    interactionState: InteractionState = remember { InteractionState() }
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
 ) = Scrollbar(
     adapter,
     modifier,
     style,
-    interactionState,
+    interactionSource,
     isVertical = false
 )
 
 // TODO(demin): do we need to stop dragging if cursor is beyond constraints?
-// TODO(demin): add Interaction.Hovered to interactionState
+// TODO(demin): add Interaction.Hovered to interactionSource
 @Composable
 private fun Scrollbar(
     adapter: ScrollbarAdapter,
     modifier: Modifier = Modifier,
     style: ScrollbarStyle,
-    interactionState: InteractionState,
+    interactionSource: MutableInteractionSource,
     isVertical: Boolean
 ) = with(LocalDensity.current) {
-    DisposableEffect(interactionState) {
+    val scope = rememberCoroutineScope()
+    val dragInteraction = remember { mutableStateOf<DragInteraction.Start?>(null) }
+    DisposableEffect(interactionSource) {
         onDispose {
-            interactionState.removeInteraction(Interaction.Dragged)
+            dragInteraction.value?.let { interaction ->
+                interactionSource.tryEmit(DragInteraction.Cancel(interaction))
+                dragInteraction.value = null
+            }
         }
     }
 
@@ -192,27 +201,50 @@
     }
 
     val scrollThickness = style.thickness.roundToPx()
-    val measureBlocks = if (isVertical) {
+    val measurePolicy = if (isVertical) {
         remember(sliderAdapter, scrollThickness) {
-            verticalMeasureBlocks(sliderAdapter, { containerSize = it }, scrollThickness)
+            verticalMeasurePolicy(sliderAdapter, { containerSize = it }, scrollThickness)
         }
     } else {
         remember(sliderAdapter, scrollThickness) {
-            horizontalMeasureBlocks(sliderAdapter, { containerSize = it }, scrollThickness)
+            horizontalMeasurePolicy(sliderAdapter, { containerSize = it }, scrollThickness)
         }
     }
 
     val dragObserver = object : DragObserver {
         override fun onStart(downPosition: Offset) {
-            interactionState.addInteraction(Interaction.Dragged)
+            scope.launch {
+                dragInteraction.value?.let { oldInteraction ->
+                    interactionSource.emit(
+                        DragInteraction.Cancel(oldInteraction)
+                    )
+                }
+                val interaction = DragInteraction.Start()
+                interactionSource.emit(interaction)
+                dragInteraction.value = interaction
+            }
         }
 
         override fun onStop(velocity: Offset) {
-            interactionState.removeInteraction(Interaction.Dragged)
+            scope.launch {
+                dragInteraction.value?.let { interaction ->
+                    interactionSource.emit(
+                        DragInteraction.Stop(interaction)
+                    )
+                    dragInteraction.value = null
+                }
+            }
         }
 
         override fun onCancel() {
-            interactionState.removeInteraction(Interaction.Dragged)
+            scope.launch {
+                dragInteraction.value?.let { interaction ->
+                    interactionSource.emit(
+                        DragInteraction.Cancel(interaction)
+                    )
+                    dragInteraction.value = null
+                }
+            }
         }
 
         override fun onDrag(dragDistance: Offset): Offset {
@@ -236,13 +268,13 @@
                     .rawDragGestureFilter(dragObserver)
             )
         },
-        measureBlocks,
         modifier
             .pointerMoveFilter(
                 onExit = { isHover = false; true },
                 onEnter = { isHover = true; true }
             )
-            .scrollOnPressOutsideSlider(isVertical, sliderAdapter, adapter, containerSize)
+            .scrollOnPressOutsideSlider(isVertical, sliderAdapter, adapter, containerSize),
+        measurePolicy
     )
 }
 
@@ -474,11 +506,11 @@
     val bounds get() = position..position + size
 }
 
-private fun verticalMeasureBlocks(
+private fun verticalMeasurePolicy(
     sliderAdapter: SliderAdapter,
     setContainerSize: (Int) -> Unit,
     scrollThickness: Int
-) = MeasuringIntrinsicsMeasureBlocks { measurables, constraints ->
+) = MeasurePolicy { measurables, constraints ->
     setContainerSize(constraints.maxHeight)
     val height = sliderAdapter.size.toInt()
     val placeable = measurables.first().measure(
@@ -492,11 +524,11 @@
     }
 }
 
-private fun horizontalMeasureBlocks(
+private fun horizontalMeasurePolicy(
     sliderAdapter: SliderAdapter,
     setContainerSize: (Int) -> Unit,
     scrollThickness: Int
-) = MeasuringIntrinsicsMeasureBlocks { measurables, constraints ->
+) = MeasurePolicy { measurables, constraints ->
     setContainerSize(constraints.maxWidth)
     val width = sliderAdapter.size.toInt()
     val placeable = measurables.first().measure(
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/TouchMode.desktop.kt
similarity index 79%
copy from compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt
copy to compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/TouchMode.desktop.kt
index bae8c9a..091b942 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/TouchMode.desktop.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-package androidx.compose.ui.input.pointer
+package androidx.compose.foundation.text
 
-@MouseTemporaryApi
-expect val isMouseInput: Boolean
\ No newline at end of file
+internal actual val isInTouchMode = false
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/DesktopSelection.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/DesktopSelection.desktop.kt
index efc4ceb..e69de29 100644
--- a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/DesktopSelection.desktop.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/DesktopSelection.desktop.kt
@@ -1,125 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-@file:Suppress("DEPRECATION")
-
-package androidx.compose.foundation.text.selection
-
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.ui.layout.Layout
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.composed
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.foundation.legacygestures.DragObserver
-import androidx.compose.foundation.legacygestures.rawDragGestureFilter
-import androidx.compose.foundation.legacygestures.rawPressStartGestureFilter
-import androidx.compose.ui.layout.onGloballyPositioned
-import androidx.compose.ui.platform.SelectionTrackerAmbient
-import kotlin.math.max
-
-@Composable
-private fun Wrap(modifier: Modifier = Modifier, content: @Composable () -> Unit) {
-    Layout(content = content, modifier = modifier) { measurables, constraints ->
-        val placeables = measurables.map { measurable ->
-            measurable.measure(constraints)
-        }
-
-        val width = placeables.fold(0) { maxWidth, placeable ->
-            max(maxWidth, (placeable.width))
-        }
-
-        val height = placeables.fold(0) { minWidth, placeable ->
-            max(minWidth, (placeable.height))
-        }
-
-        layout(width, height) {
-            placeables.forEach { placeable ->
-                placeable.place(0, 0)
-            }
-        }
-    }
-}
-
-@Composable
-fun DesktopSelectionContainer(content: @Composable () -> Unit) {
-    val selection = remember { mutableStateOf<Selection?>(null) }
-    DesktopSelectionContainer(
-        selection = selection.value,
-        onSelectionChange = { selection.value = it },
-        content = content
-    )
-}
-
-private fun Modifier.selectionFilter(observer: DragObserver): Modifier = composed {
-    val glue = remember { DragGlue(observer) }
-    rawDragGestureFilter(glue, glue::started)
-        .rawPressStartGestureFilter(glue::startDrag, true)
-}
-
-private class DragGlue(val observer: DragObserver) : DragObserver by observer {
-    var started = false
-
-    fun startDrag(downPosition: Offset) {
-        started = true
-        observer.onStart(downPosition)
-    }
-
-    override fun onStop(velocity: Offset) {
-        started = false
-        observer.onStop(velocity)
-    }
-
-    override fun onCancel() {
-        started = false
-        observer.onCancel()
-    }
-}
-
-@Composable
-internal fun DesktopSelectionContainer(
-    selection: Selection?,
-    onSelectionChange: (Selection?) -> Unit,
-    content: @Composable () -> Unit
-) {
-    val registrarImpl = remember { SelectionRegistrarImpl() }
-    val manager = remember { DesktopSelectionManager(registrarImpl) }
-
-    val selectionTracker = SelectionTrackerAmbient.current
-
-    manager.onSelectionChange = {
-        selectionTracker.getSelectedText = { manager.getSelectedText() }
-        onSelectionChange(it)
-    }
-    manager.selection = selection
-
-    val gestureModifiers =
-        Modifier.selectionFilter(manager.observer)
-
-    val modifier = remember {
-        gestureModifiers.onGloballyPositioned {
-            manager.containerLayoutCoordinates = it
-        }
-    }
-
-    CompositionLocalProvider(LocalSelectionRegistrar provides registrarImpl) {
-        Wrap(modifier) {
-            content()
-        }
-    }
-}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/DesktopSelectionManager.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/DesktopSelectionManager.desktop.kt
index 4b8a513..e69de29 100644
--- a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/DesktopSelectionManager.desktop.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/DesktopSelectionManager.desktop.kt
@@ -1,122 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-@file:Suppress("DEPRECATION")
-
-package androidx.compose.foundation.text.selection
-
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.foundation.legacygestures.DragObserver
-import androidx.compose.ui.layout.LayoutCoordinates
-import androidx.compose.ui.text.AnnotatedString
-import androidx.compose.ui.platform.ClipboardManager
-
-internal class DesktopSelectionManager(private val selectionRegistrar: SelectionRegistrarImpl) {
-    private var dragBeginPosition = Offset.Zero
-
-    private var dragTotalDistance = Offset.Zero
-
-    var containerLayoutCoordinates: LayoutCoordinates? = null
-
-    var clipboardManager: ClipboardManager? = null
-    var onSelectionChange: (Selection?) -> Unit = {}
-    var selection: Selection? = null
-
-    val observer = Observer()
-
-    inner class Observer : DragObserver {
-        override fun onStart(downPosition: Offset) {
-            mergeSelections(
-                startPosition = Offset(-1f, -1f),
-                endPosition = Offset(-1f, -1f),
-                previousSelection = selection
-            )
-            if (selection != null) onSelectionChange(null)
-            dragBeginPosition = downPosition
-            dragTotalDistance = Offset.Zero
-        }
-
-        override fun onDrag(dragDistance: Offset): Offset {
-            dragTotalDistance += dragDistance
-            val newSelection = mergeSelections(
-                startPosition = dragBeginPosition,
-                endPosition = dragBeginPosition + dragTotalDistance,
-                previousSelection = selection
-            )
-
-            if (newSelection != selection) onSelectionChange(newSelection)
-            return dragDistance
-        }
-    }
-
-    internal fun mergeSelections(
-        startPosition: Offset,
-        endPosition: Offset,
-        longPress: Boolean = false,
-        previousSelection: Selection? = null,
-        isStartHandle: Boolean = true
-    ): Selection? {
-
-        val newSelection = selectionRegistrar.sort(requireContainerCoordinates())
-            .fold(null) { mergedSelection: Selection?, handler: Selectable ->
-                merge(
-                    mergedSelection,
-                    handler.getSelection(
-                        startPosition = startPosition,
-                        endPosition = endPosition,
-                        containerLayoutCoordinates = requireContainerCoordinates(),
-                        longPress = longPress,
-                        previousSelection = previousSelection,
-                        isStartHandle = isStartHandle
-                    )
-                )
-            }
-        return newSelection
-    }
-
-    internal fun requireContainerCoordinates(): LayoutCoordinates {
-        val coordinates = containerLayoutCoordinates
-        require(coordinates != null)
-        require(coordinates.isAttached)
-        return coordinates
-    }
-
-    internal fun getSelectedText(): AnnotatedString? {
-        val selectables = selectionRegistrar.sort(requireContainerCoordinates())
-        var selectedText: AnnotatedString? = null
-
-        selection?.let {
-            for (handler in selectables) {
-                // Continue if the current selectable is before the selection starts.
-                if (handler != it.start.selectable && handler != it.end.selectable &&
-                    selectedText == null
-                ) continue
-
-                val currentSelectedText = getCurrentSelectedText(
-                    selectable = handler,
-                    selection = it
-                )
-                selectedText = selectedText?.plus(currentSelectedText) ?: currentSelectedText
-
-                // Break if the current selectable is the last selected selectable.
-                if (handler == it.end.selectable && !it.handlesCrossed ||
-                    handler == it.start.selectable && it.handlesCrossed
-                ) break
-            }
-        }
-        return selectedText
-    }
-}
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/DesktopSelectionRegistrar.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/DesktopSelectionRegistrar.desktop.kt
index cc8b58e..e69de29 100644
--- a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/DesktopSelectionRegistrar.desktop.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/DesktopSelectionRegistrar.desktop.kt
@@ -1,103 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.foundation.text.selection
-
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.layout.LayoutCoordinates
-
-// based on androidx.compose.foundation.text.selection.SelectionRegistrarImpl
-internal class DesktopSelectionRegistrar : SelectionRegistrar {
-    internal var sorted: Boolean = false
-
-    private val _selectables = mutableListOf<Selectable>()
-    internal val selectables: List<Selectable>
-        get() = _selectables
-
-    internal var onPositionChangeCallback: (() -> Unit)? = null
-    internal var onUpdateSelectionCallback: ((LayoutCoordinates, Offset, Offset) -> Unit)? = null
-
-    override fun subscribe(selectable: Selectable): Selectable {
-        _selectables.add(selectable)
-        sorted = false
-        return selectable
-    }
-
-    override fun unsubscribe(selectable: Selectable) {
-        _selectables.remove(selectable)
-    }
-
-    fun sort(containerLayoutCoordinates: LayoutCoordinates): List<Selectable> {
-        if (!sorted) {
-            _selectables.sortWith(
-                Comparator { a: Selectable, b: Selectable ->
-                    val layoutCoordinatesA = a.getLayoutCoordinates()
-                    val layoutCoordinatesB = b.getLayoutCoordinates()
-
-                    val positionA =
-                        if (layoutCoordinatesA != null) containerLayoutCoordinates.localPositionOf(
-                            layoutCoordinatesA,
-                            Offset.Zero
-                        )
-                        else Offset.Zero
-                    val positionB =
-                        if (layoutCoordinatesB != null) containerLayoutCoordinates.localPositionOf(
-                            layoutCoordinatesB,
-                            Offset.Zero
-                        )
-                        else Offset.Zero
-
-                    if (positionA.y == positionB.y) compareValues(positionA.x, positionB.x)
-                    else compareValues(positionA.y, positionB.y)
-                }
-            )
-            sorted = true
-        }
-        return selectables
-    }
-
-    override fun notifyPositionChange() {
-        sorted = false
-        onPositionChangeCallback?.invoke()
-    }
-
-    override fun notifySelectionUpdateStart(
-        layoutCoordinates: LayoutCoordinates,
-        startPosition: Offset
-    ) {
-        onUpdateSelectionCallback?.invoke(
-            layoutCoordinates,
-            startPosition,
-            startPosition
-        )
-    }
-
-    override fun notifySelectionUpdate(
-        layoutCoordinates: LayoutCoordinates,
-        startPosition: Offset,
-        endPosition: Offset
-    ) {
-        onUpdateSelectionCallback?.invoke(
-            layoutCoordinates,
-            startPosition,
-            endPosition
-        )
-    }
-
-    override fun notifySelectionUpdateEnd() { /* do nothing */ }
-
-    override fun notifySelectableChange(selectable: Selectable) { /* do nothing */ }
-}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.desktop.kt
new file mode 100644
index 0000000..2005428
--- /dev/null
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.desktop.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.foundation.text.selection
+
+import androidx.compose.ui.input.key.Key
+import androidx.compose.ui.input.key.KeyEvent
+import androidx.compose.ui.input.key.isCtrlPressed
+import androidx.compose.ui.input.key.isMetaPressed
+import androidx.compose.ui.input.key.key
+import androidx.compose.ui.platform.DesktopPlatform
+
+// this doesn't sounds very sustainable
+// it would end up being a function for any conceptual keyevent (selectall, cut, copy, paste)
+// TODO(b/1564937)
+internal actual fun isCopyKeyEvent(keyEvent: KeyEvent) =
+    keyEvent.key == Key.C && when (DesktopPlatform.Current) {
+        DesktopPlatform.MacOS -> keyEvent.isMetaPressed
+        else -> keyEvent.isCtrlPressed
+    } || keyEvent.key == Key.Copy
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 d80eec53..b81bdd8 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
@@ -96,7 +96,7 @@
         )
         whenever(state.layoutResult!!.getOffsetForPosition(dragLastPosition)).thenReturn(dragOffset)
 
-        state.processor.onNewState(value, null, state.inputSession)
+        state.processor.reset(value, state.inputSession)
     }
 
     @Test
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt b/compose/foundation/foundation/src/jvmMain/kotlin/androidx/compose/foundation/ActualJvm.kt
similarity index 72%
copy from compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt
copy to compose/foundation/foundation/src/jvmMain/kotlin/androidx/compose/foundation/ActualJvm.kt
index bae8c9a..7e01354 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt
+++ b/compose/foundation/foundation/src/jvmMain/kotlin/androidx/compose/foundation/ActualJvm.kt
@@ -1,5 +1,7 @@
+// ktlint-disable filename
+
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +16,6 @@
  * limitations under the License.
  */
 
-package androidx.compose.ui.input.pointer
+package androidx.compose.foundation
 
-@MouseTemporaryApi
-expect val isMouseInput: Boolean
\ No newline at end of file
+internal actual typealias AtomicReference<V> = java.util.concurrent.atomic.AtomicReference<V>
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/InteractionStateTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/InteractionStateTest.kt
deleted file mode 100644
index 0c6969a..0000000
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/InteractionStateTest.kt
+++ /dev/null
@@ -1,60 +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
-
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@RunWith(JUnit4::class)
-class InteractionStateTest {
-
-    private object TestInteraction1 : Interaction
-    private object TestInteraction2 : Interaction
-    private object TestInteraction3 : Interaction
-
-    @Test
-    fun orderingIsPreserved() {
-        val state = InteractionState()
-
-        state.addInteraction(TestInteraction1)
-        state.addInteraction(TestInteraction2)
-
-        assertThat(state.value)
-            .containsExactlyElementsIn(
-                listOf(TestInteraction1, TestInteraction2)
-            )
-            .inOrder()
-
-        state.addInteraction(TestInteraction3)
-
-        assertThat(state.value)
-            .containsExactlyElementsIn(
-                listOf(TestInteraction1, TestInteraction2, TestInteraction3)
-            )
-            .inOrder()
-
-        state.removeInteraction(TestInteraction2)
-
-        assertThat(state.value)
-            .containsExactlyElementsIn(
-                listOf(TestInteraction1, TestInteraction3)
-            )
-            .inOrder()
-    }
-}
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/gestures/DragGestureDetectorTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/gestures/DragGestureDetectorTest.kt
index d673471..7635daa 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/gestures/DragGestureDetectorTest.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/gestures/DragGestureDetectorTest.kt
@@ -51,12 +51,14 @@
     private var dragDistance = 0f
     private var dragged = false
     private var gestureEnded = false
+    private var gestureStarted = false
     private var gestureCanceled = false
     private var consumePositiveOnly = false
     private var sloppyDetector = false
 
     private val DragTouchSlopUtil = SuspendingGestureTestUtil(width = 100, height = 100) {
         detectDragGestures(
+            onDragStart = { gestureStarted = true },
             onDragEnd = { gestureEnded = true },
             onDragCancel = { gestureCanceled = true }
         ) { change, dragAmount ->
@@ -71,6 +73,7 @@
 
     private val VerticalTouchSlopUtil = SuspendingGestureTestUtil(width = 100, height = 100) {
         detectVerticalDragGestures(
+            onDragStart = { gestureStarted = true },
             onDragEnd = { gestureEnded = true },
             onDragCancel = { gestureCanceled = true }
         ) { change, dragAmount ->
@@ -84,6 +87,7 @@
 
     private val HorizontalTouchSlopUtil = SuspendingGestureTestUtil(width = 100, height = 100) {
         detectHorizontalDragGestures(
+            onDragStart = { gestureStarted = true },
             onDragEnd = { gestureEnded = true },
             onDragCancel = { gestureCanceled = true }
         ) { change, dragAmount ->
@@ -107,6 +111,7 @@
                     }
                 }
                 if (slopChange != null || sloppyDetector) {
+                    gestureStarted = true
                     var pointer = if (sloppyDetector) down.id else slopChange!!.id
                     do {
                         val change = awaitVerticalDragOrCancellation(pointer)
@@ -139,6 +144,7 @@
                         }
                     }
                 if (slopChange != null || sloppyDetector) {
+                    gestureStarted = true
                     var pointer = if (sloppyDetector) down.id else slopChange!!.id
                     do {
                         val change = awaitHorizontalDragOrCancellation(pointer)
@@ -171,6 +177,7 @@
                     }
                 }
                 if (slopChange != null || sloppyDetector) {
+                    gestureStarted = true
                     var pointer = if (sloppyDetector) down.id else slopChange!!.id
                     do {
                         val change = awaitDragOrCancellation(pointer)
@@ -241,6 +248,7 @@
     @Test
     fun normalDrag() = util.executeInComposition {
         val move = down().moveBy(dragMotion)
+        assertTrue(gestureStarted)
         assertTrue(dragged)
         assertEquals(0f, dragDistance)
         val move2 = move.moveBy(dragMotion)
@@ -257,11 +265,13 @@
     fun crossDrag() = util.executeInComposition {
         if (!twoAxisDrag) {
             down().moveBy(crossDragMotion).up()
+            assertFalse(gestureStarted)
             assertFalse(dragged)
             assertFalse(gestureEnded)
 
             // now try a normal drag to ensure that it is still working.
             down().moveBy(dragMotion).up()
+            assertTrue(gestureStarted)
             assertTrue(dragged)
             assertEquals(0f, dragDistance)
             assertTrue(gestureEnded)
@@ -279,6 +289,7 @@
         // second finger shouldn't cause a drag. It should follow finger1
         val moveFinger2 = finger2.moveBy(dragMotion)
 
+        assertFalse(gestureStarted)
         assertFalse(dragged)
 
         // now it should move to finger 2
@@ -301,6 +312,7 @@
 
         finger1.moveBy(dragMotion).up()
 
+        assertTrue(gestureStarted)
         assertTrue(dragged)
         assertEquals(0f, dragDistance)
         assertFalse(gestureEnded)
@@ -317,6 +329,7 @@
     @Test
     fun cancelDragDuringSlop() = util.executeInComposition {
         down().moveBy(dragMotion) { consumeAllChanges() }.moveBy(dragMotion).up()
+        assertFalse(gestureStarted)
         assertFalse(dragged)
         assertFalse(gestureEnded)
         assertFalse(gestureCanceled) // only canceled if the touch slop was crossed first
@@ -328,6 +341,7 @@
     @Test
     fun cancelDragAfterSlop() = util.executeInComposition {
         down().moveBy(dragMotion).moveBy(dragMotion) { consumeAllChanges() }.up()
+        assertTrue(gestureStarted)
         assertTrue(dragged)
         assertFalse(gestureEnded)
         assertTrue(gestureCanceled)
@@ -349,6 +363,7 @@
                 }
             )
                 .up()
+            assertTrue(gestureStarted)
             assertTrue(dragged)
             assertTrue(gestureEnded)
             assertFalse(gestureCanceled)
@@ -367,9 +382,11 @@
 
             val back = down().moveBy(-dragMotion)
 
+            assertFalse(gestureStarted)
             assertFalse(dragged)
             back.moveBy(dragMotion).up()
 
+            assertTrue(gestureStarted)
             assertTrue(dragged)
         } finally {
             consumePositiveOnly = false
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextFieldDelegateTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextFieldDelegateTest.kt
index a5a54a2..d17ef23 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextFieldDelegateTest.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextFieldDelegateTest.kt
@@ -23,7 +23,6 @@
 import androidx.compose.ui.layout.AlignmentLine
 import androidx.compose.ui.layout.LayoutCoordinates
 import androidx.compose.ui.text.AnnotatedString
-import androidx.compose.ui.text.InternalTextApi
 import androidx.compose.ui.text.MultiParagraphIntrinsics
 import androidx.compose.ui.text.SpanStyle
 import androidx.compose.ui.text.TextLayoutResult
@@ -36,6 +35,7 @@
 import androidx.compose.ui.text.input.OffsetMapping
 import androidx.compose.ui.text.input.TextFieldValue
 import androidx.compose.ui.text.input.TextInputService
+import androidx.compose.ui.text.input.TextInputSession
 import androidx.compose.ui.text.input.TransformedText
 import androidx.compose.ui.text.input.VisualTransformation
 import androidx.compose.ui.text.style.TextDecoration
@@ -43,6 +43,7 @@
 import com.google.common.truth.Truth.assertThat
 import com.nhaarman.mockitokotlin2.any
 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
@@ -54,7 +55,7 @@
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
 
-@OptIn(InternalTextApi::class, InternalFoundationTextApi::class)
+@OptIn(InternalFoundationTextApi::class)
 @RunWith(JUnit4::class)
 class TextFieldDelegateTest {
 
@@ -97,7 +98,7 @@
         val position = Offset(100f, 200f)
         val offset = 10
         val editorState = TextFieldValue(text = "Hello, World", selection = TextRange(1))
-        whenever(processor.mBufferState).thenReturn(editorState)
+        whenever(processor.toTextFieldValue()).thenReturn(editorState)
         whenever(textLayoutResultProxy.getOffsetForPosition(position)).thenReturn(offset)
 
         TextFieldDelegate.setCursorOffset(
@@ -123,7 +124,17 @@
             imeAction = ImeAction.Search
         )
 
-        TextFieldDelegate.onFocus(
+        val textInputSession: TextInputSession = mock()
+        whenever(
+            textInputService.startInput(
+                eq(editorState),
+                eq(imeOptions),
+                any(),
+                eq(onEditorActionPerformed)
+            )
+        ).thenReturn(textInputSession)
+
+        val actual = TextFieldDelegate.onFocus(
             textInputService = textInputService,
             value = editorState,
             editProcessor = processor,
@@ -143,58 +154,29 @@
             eq(onEditorActionPerformed)
         )
 
-        verify(textInputService).showSoftwareKeyboard(any())
-    }
-
-    @Test
-    fun on_blur() {
-        val inputSessionToken = 10 // We are not using this value in this test.
-
-        val editorState = TextFieldValue(
-            text = "Hello, World",
-            selection = TextRange(1),
-            composition = TextRange(3, 5)
-        )
-        whenever(processor.mBufferState).thenReturn(editorState)
-
-        TextFieldDelegate.onBlur(
-            textInputService,
-            inputSessionToken,
-            processor,
-            true,
-            onValueChange
-        )
-
-        verify(textInputService).stopInput(eq(inputSessionToken))
-        verify(textInputService, never()).hideSoftwareKeyboard(any())
-        verify(onValueChange, times(1)).invoke(
-            eq(editorState.commitComposition())
-        )
+        verify(actual).showSoftwareKeyboard()
+        assertThat(actual).isEqualTo(textInputSession)
     }
 
     @Test
     fun on_blur_with_hiding() {
-        val inputSessionToken = 10 // We are not using this value in this test.
-
         val editorState = TextFieldValue(
             text = "Hello, World",
             selection = TextRange(1),
             composition = TextRange(3, 5)
         )
-        whenever(processor.mBufferState).thenReturn(editorState)
+        whenever(processor.toTextFieldValue()).thenReturn(editorState)
 
-        TextFieldDelegate.onBlur(
-            textInputService,
-            inputSessionToken,
-            processor,
-            false, // There is no next focused client. Hide the keyboard.
-            onValueChange
-        )
+        val textInputSession = mock<TextInputSession>()
 
-        verify(textInputService).stopInput(eq(inputSessionToken))
-        verify(textInputService).hideSoftwareKeyboard(eq(inputSessionToken))
+        TextFieldDelegate.onBlur(textInputSession, processor, onValueChange)
+
+        inOrder(textInputSession) {
+            verify(textInputSession).hideSoftwareKeyboard()
+            verify(textInputSession).dispose()
+        }
         verify(onValueChange, times(1)).invoke(
-            eq(editorState.commitComposition())
+            eq(editorState.copy(composition = null))
         )
     }
 
@@ -207,35 +189,34 @@
             rootOffset = point
         )
         val editorState = TextFieldValue(text = "Hello, World", selection = TextRange(1))
-        val inputSessionToken = 10 // We are not using this value in this test.
+        val textInputSession: TextInputSession = mock()
+
         TextFieldDelegate.notifyFocusedRect(
             editorState,
             mDelegate,
             textLayoutResult,
             layoutCoordinates,
-            textInputService,
-            inputSessionToken,
+            textInputSession,
             true /* hasFocus */,
             OffsetMapping.Identity
         )
-        verify(textInputService).notifyFocusedRect(eq(inputSessionToken), any())
+        verify(textInputSession).notifyFocusedRect(any())
     }
 
     @Test
     fun notify_focused_rect_without_focus() {
         val editorState = TextFieldValue(text = "Hello, World", selection = TextRange(1))
-        val inputSessionToken = 10 // We are not using this value in this test.
+        val textInputSession: TextInputSession = mock()
         TextFieldDelegate.notifyFocusedRect(
             editorState,
             mDelegate,
             textLayoutResult,
             layoutCoordinates,
-            textInputService,
-            inputSessionToken,
+            textInputSession,
             false /* hasFocus */,
             OffsetMapping.Identity
         )
-        verify(textInputService, never()).notifyFocusedRect(any(), any())
+        verify(textInputSession, never()).notifyFocusedRect(any())
     }
 
     @Test
@@ -247,18 +228,17 @@
             rootOffset = point
         )
         val editorState = TextFieldValue(text = "Hello, World", selection = TextRange(12))
-        val inputSessionToken = 10 // We are not using this value in this test.
+        val textInputSession: TextInputSession = mock()
         TextFieldDelegate.notifyFocusedRect(
             editorState,
             mDelegate,
             textLayoutResult,
             layoutCoordinates,
-            textInputService,
-            inputSessionToken,
+            textInputSession,
             true /* hasFocus */,
             OffsetMapping.Identity
         )
-        verify(textInputService).notifyFocusedRect(eq(inputSessionToken), any())
+        verify(textInputSession).notifyFocusedRect(any())
     }
 
     @Test
@@ -266,24 +246,24 @@
         val rect = Rect(0f, 1f, 2f, 3f)
         val point = Offset(5f, 6f)
         val editorState = TextFieldValue(text = "Hello, World", selection = TextRange(1, 3))
-        val inputSessionToken = 10 // We are not using this value in this test.
+
         whenever(textLayoutResult.getBoundingBox(any())).thenReturn(rect)
         layoutCoordinates = MockCoordinates(
             rootOffset = point
         )
+        val textInputSession: TextInputSession = mock()
 
         TextFieldDelegate.notifyFocusedRect(
             editorState,
             mDelegate,
             textLayoutResult,
             layoutCoordinates,
-            textInputService,
-            inputSessionToken,
+            textInputSession,
             true /* hasFocus */,
             skippingOffsetMap
         )
         verify(textLayoutResult).getBoundingBox(6)
-        verify(textInputService).notifyFocusedRect(eq(inputSessionToken), any())
+        verify(textInputSession).notifyFocusedRect(any())
     }
 
     @Test
@@ -291,7 +271,7 @@
         val position = Offset(100f, 200f)
         val offset = 10
         val editorState = TextFieldValue(text = "Hello, World", selection = TextRange(1))
-        whenever(processor.mBufferState).thenReturn(editorState)
+        whenever(processor.toTextFieldValue()).thenReturn(editorState)
         whenever(textLayoutResultProxy.getOffsetForPosition(position)).thenReturn(offset)
 
         TextFieldDelegate.setCursorOffset(
@@ -396,10 +376,9 @@
             get() = null
         override val isAttached: Boolean
             get() = true
-        override fun globalToLocal(global: Offset): Offset = localOffset
+
         override fun windowToLocal(relativeToWindow: Offset): Offset = localOffset
 
-        override fun localToGlobal(local: Offset): Offset = globalOffset
         override fun localToWindow(relativeToLocal: Offset): Offset = globalOffset
 
         override fun localToRoot(relativeToLocal: Offset): Offset = rootOffset
@@ -408,15 +387,11 @@
             relativeToSource: Offset
         ): Offset = Offset.Zero
 
-        override fun childToLocal(child: LayoutCoordinates, childLocal: Offset): Offset =
-            Offset.Zero
-
-        override fun childBoundingBox(child: LayoutCoordinates): Rect = Rect.Zero
         override fun localBoundingBoxOf(
             sourceCoordinates: LayoutCoordinates,
             clipBounds: Boolean
         ): Rect = Rect.Zero
 
-        override fun get(line: AlignmentLine): Int = 0
+        override fun get(alignmentLine: AlignmentLine): Int = 0
     }
 }
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/InlineAnswer.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/InlineAnswer.kt
index 2692681..a7a24f8 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/InlineAnswer.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/InlineAnswer.kt
@@ -17,6 +17,7 @@
 package androidx.compose.foundation.text.selection
 
 import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.util.packFloats
 import org.mockito.invocation.InvocationOnMock
 import org.mockito.stubbing.Answer
 import org.mockito.stubbing.OngoingStubbing
@@ -26,5 +27,5 @@
 }
 
 infix fun <T> OngoingStubbing<T>.doAnswer(offset: Offset): OngoingStubbing<T> {
-    return thenAnswer(LongAnswer(offset.packedValue))
+    return thenAnswer(LongAnswer(packFloats(offset.x, offset.y)))
 }
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/MockCoordinates.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/MockCoordinates.kt
index 22da226..344ce0b 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/MockCoordinates.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/MockCoordinates.kt
@@ -48,21 +48,11 @@
     override val parentCoordinates: LayoutCoordinates?
         get() = null
 
-    override fun globalToLocal(global: Offset): Offset {
-        globalToLocalParams += global
-        return localOffset
-    }
-
     override fun windowToLocal(relativeToWindow: Offset): Offset {
         windowToLocalParams += relativeToWindow
         return localOffset
     }
 
-    override fun localToGlobal(local: Offset): Offset {
-        localToGlobalParams += local
-        return globalOffset
-    }
-
     override fun localToWindow(relativeToLocal: Offset): Offset {
         localToWindowParams += relativeToLocal
         return windowOffset
@@ -81,16 +71,10 @@
         return childToLocalOffset
     }
 
-    override fun childToLocal(child: LayoutCoordinates, childLocal: Offset): Offset {
-        childToLocalParams += child to childLocal
-        return childToLocalOffset
-    }
-
-    override fun childBoundingBox(child: LayoutCoordinates): Rect = Rect.Zero
     override fun localBoundingBoxOf(
         sourceCoordinates: LayoutCoordinates,
         clipBounds: Boolean
     ): Rect = Rect.Zero
 
-    override fun get(line: AlignmentLine): Int = 0
+    override fun get(alignmentLine: AlignmentLine): Int = 0
 }
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionManagerDragTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionManagerDragTest.kt
index 893abd6..c435e0d 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionManagerDragTest.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionManagerDragTest.kt
@@ -17,7 +17,9 @@
 package androidx.compose.foundation.text.selection
 
 import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.layout.LayoutCoordinates
+import androidx.compose.ui.text.AnnotatedString
 import androidx.compose.ui.text.style.ResolvedTextDirection
 import androidx.compose.ui.unit.IntSize
 import com.google.common.truth.Truth.assertThat
@@ -34,8 +36,9 @@
 
 @RunWith(JUnit4::class)
 class SelectionManagerDragTest {
+
     private val selectionRegistrar = SelectionRegistrarImpl()
-    private val selectable = mock<Selectable>()
+    private val selectable = FakeSelectable()
     private val selectionManager = SelectionManager(selectionRegistrar)
 
     private val size = IntSize(500, 600)
@@ -92,17 +95,7 @@
     @Before
     fun setup() {
         selectionRegistrar.subscribe(selectable)
-
-        whenever(
-            selectable.getSelection(
-                startPosition = Offset(any()),
-                endPosition = Offset(any()),
-                containerLayoutCoordinates = any(),
-                longPress = any(),
-                previousSelection = any(),
-                isStartHandle = any()
-            )
-        ).thenReturn(fakeResultSelection)
+        selectable.selectionToReturn = fakeResultSelection
 
         whenever(startSelectable.getLayoutCoordinates()).thenReturn(startLayoutCoordinates)
         whenever(endSelectable.getLayoutCoordinates()).thenReturn(endLayoutCoordinates)
@@ -138,8 +131,7 @@
     }
 
     @Test
-    fun handleDragObserver_onDrag_startHandle_reuse_endHandle_calls_getSelection_change_selection
-    () {
+    fun handleDragObserver_onDrag_startHandle_reuse_endHandle_calls_getSelection_change() {
         val startOffset = Offset(30f, 50f)
         val dragDistance = Offset(100f, 100f)
         selectionManager.handleDragObserver(isStartHandle = true).onStart(startOffset)
@@ -151,23 +143,23 @@
                 sourceCoordinates = endLayoutCoordinates,
                 relativeToSource = getAdjustedCoordinates(Offset.Zero)
             )
-        verify(selectable, times(1))
-            .getSelection(
-                startPosition = childToLocalOffset + dragDistance,
-                endPosition = childToLocalOffset,
-                containerLayoutCoordinates = selectionManager.requireContainerCoordinates(),
-                longPress = false,
-                isStartHandle = true,
-                previousSelection = fakeInitialSelection
-            )
+
+        assertThat(selectable.getSelectionCalledTimes).isEqualTo(1)
+        assertThat(selectable.lastStartPosition).isEqualTo(childToLocalOffset + dragDistance)
+        assertThat(selectable.lastEndPosition).isEqualTo(childToLocalOffset)
+        assertThat(selectable.lastContainerLayoutCoordinates)
+            .isEqualTo(selectionManager.requireContainerCoordinates())
+        assertThat(selectable.lastLongPress).isEqualTo(false)
+        assertThat(selectable.lastIsStartHandle).isEqualTo(true)
+        assertThat(selectable.lastPreviousSelection).isEqualTo(fakeInitialSelection)
+
         assertThat(selection).isEqualTo(fakeResultSelection)
         verify(spyLambda, times(1)).invoke(fakeResultSelection)
         assertThat(result).isEqualTo(dragDistance)
     }
 
     @Test
-    fun handleDragObserver_onDrag_endHandle_reuse_startHandle_calls_getSelection_change_selection
-    () {
+    fun handleDragObserver_onDrag_endHandle_reuse_startHandle_calls_getSelection_change() {
         val startOffset = Offset(30f, 50f)
         val dragDistance = Offset(100f, 100f)
         selectionManager.handleDragObserver(isStartHandle = false).onStart(startOffset)
@@ -179,15 +171,16 @@
                 sourceCoordinates = startLayoutCoordinates,
                 relativeToSource = getAdjustedCoordinates(Offset.Zero)
             )
-        verify(selectable, times(1))
-            .getSelection(
-                startPosition = childToLocalOffset,
-                endPosition = childToLocalOffset + dragDistance,
-                containerLayoutCoordinates = selectionManager.requireContainerCoordinates(),
-                longPress = false,
-                isStartHandle = false,
-                previousSelection = fakeInitialSelection
-            )
+
+        assertThat(selectable.getSelectionCalledTimes).isEqualTo(1)
+        assertThat(selectable.lastStartPosition).isEqualTo(childToLocalOffset)
+        assertThat(selectable.lastEndPosition).isEqualTo(childToLocalOffset + dragDistance)
+        assertThat(selectable.lastContainerLayoutCoordinates)
+            .isEqualTo(selectionManager.requireContainerCoordinates())
+        assertThat(selectable.lastLongPress).isEqualTo(false)
+        assertThat(selectable.lastIsStartHandle).isEqualTo(false)
+        assertThat(selectable.lastPreviousSelection).isEqualTo(fakeInitialSelection)
+
         assertThat(selection).isEqualTo(fakeResultSelection)
         verify(spyLambda, times(1)).invoke(fakeResultSelection)
         assertThat(result).isEqualTo(dragDistance)
@@ -197,3 +190,49 @@
         return Offset(position.x, position.y - 1f)
     }
 }
+
+internal class FakeSelectable : Selectable {
+    var lastStartPosition: Offset? = null
+    var lastEndPosition: Offset? = null
+    var lastContainerLayoutCoordinates: LayoutCoordinates? = null
+    var lastLongPress: Boolean? = null
+    var lastPreviousSelection: Selection? = null
+    var lastIsStartHandle: Boolean? = null
+    var getSelectionCalledTimes = 0
+    var getTextCalledTimes = 0
+    var selectionToReturn: Selection? = null
+    var textToReturn: AnnotatedString? = null
+
+    override fun getSelection(
+        startPosition: Offset,
+        endPosition: Offset,
+        containerLayoutCoordinates: LayoutCoordinates,
+        longPress: Boolean,
+        previousSelection: Selection?,
+        isStartHandle: Boolean
+    ): Selection? {
+        getSelectionCalledTimes++
+        lastStartPosition = startPosition
+        lastEndPosition = endPosition
+        lastContainerLayoutCoordinates = containerLayoutCoordinates
+        lastLongPress = longPress
+        lastPreviousSelection = previousSelection
+        lastIsStartHandle = isStartHandle
+        return selectionToReturn
+    }
+
+    override fun getText(): AnnotatedString {
+        getTextCalledTimes++
+        return textToReturn!!
+    }
+
+    override fun getLayoutCoordinates(): LayoutCoordinates? = null
+
+    override fun getHandlePosition(selection: Selection, isStartHandle: Boolean): Offset {
+        TODO("Not yet implemented")
+    }
+
+    override fun getBoundingBox(offset: Int): Rect {
+        TODO("Not yet implemented")
+    }
+}
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionManagerTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionManagerTest.kt
index 39055e4..d96c2df 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionManagerTest.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionManagerTest.kt
@@ -43,12 +43,11 @@
 @RunWith(JUnit4::class)
 class SelectionManagerTest {
     private val selectionRegistrar = spy(SelectionRegistrarImpl())
-    private val selectable = mock<Selectable>()
+    private val selectable = FakeSelectable()
     private val selectionManager = SelectionManager(selectionRegistrar)
 
     private val containerLayoutCoordinates = mock<LayoutCoordinates> {
         on { isAttached } doReturn true
-        on { localPositionOf(any(), Offset(any())) } doAnswer Offset.Zero
     }
     private val startSelectable = mock<Selectable>()
     private val endSelectable = mock<Selectable>()
@@ -97,25 +96,24 @@
 
     @Test
     fun mergeSelections_single_selectable_calls_getSelection_once() {
+        val fakeNewSelection = mock<Selection>()
+
+        selectable.selectionToReturn = fakeNewSelection
+
         selectionManager.mergeSelections(
             startPosition = startCoordinates,
             endPosition = endCoordinates,
             previousSelection = fakeSelection
         )
 
-        val fakeNewSelection = mock<Selection>()
+        assertThat(selectable.getSelectionCalledTimes).isEqualTo(1)
+        assertThat(selectable.lastStartPosition).isEqualTo(startCoordinates)
+        assertThat(selectable.lastEndPosition).isEqualTo(endCoordinates)
+        assertThat(selectable.lastContainerLayoutCoordinates)
+            .isEqualTo(selectionManager.requireContainerCoordinates())
+        assertThat(selectable.lastLongPress).isEqualTo(false)
+        assertThat(selectable.lastPreviousSelection).isEqualTo(fakeSelection)
 
-        whenever(selectable.getSelection(Offset(any()), Offset(any()), any(), any(), any(), any()))
-            .thenReturn(fakeNewSelection)
-
-        verify(selectable, times(1))
-            .getSelection(
-                startPosition = startCoordinates,
-                endPosition = endCoordinates,
-                containerLayoutCoordinates = selectionManager.requireContainerCoordinates(),
-                longPress = false,
-                previousSelection = fakeSelection
-            )
         verify(
             hapticFeedback,
             times(1)
@@ -133,14 +131,14 @@
             previousSelection = fakeSelection
         )
 
-        verify(selectable, times(1))
-            .getSelection(
-                startPosition = startCoordinates,
-                endPosition = endCoordinates,
-                containerLayoutCoordinates = selectionManager.requireContainerCoordinates(),
-                longPress = false,
-                previousSelection = fakeSelection
-            )
+        assertThat(selectable.getSelectionCalledTimes).isEqualTo(1)
+        assertThat(selectable.lastStartPosition).isEqualTo(startCoordinates)
+        assertThat(selectable.lastEndPosition).isEqualTo(endCoordinates)
+        assertThat(selectable.lastContainerLayoutCoordinates)
+            .isEqualTo(selectionManager.requireContainerCoordinates())
+        assertThat(selectable.lastLongPress).isEqualTo(false)
+        assertThat(selectable.lastPreviousSelection).isEqualTo(fakeSelection)
+
         verify(selectable_another, times(1))
             .getSelection(
                 startPosition = startCoordinates,
@@ -157,9 +155,8 @@
 
     @Test
     fun mergeSelections_selection_does_not_change_hapticFeedBack_Not_triggered() {
-        val selection: Selection? = mock()
-        whenever(selectable.getSelection(Offset(any()), Offset(any()), any(), any(), any(), any()))
-            .thenReturn(selection)
+        val selection: Selection = mock()
+        selectable.selectionToReturn = selection
 
         selectionManager.mergeSelections(
             startPosition = startCoordinates,
@@ -178,7 +175,7 @@
         selectionManager.selection = null
 
         assertThat(selectionManager.getSelectedText()).isNull()
-        verify(selectable, times(0)).getText()
+        assertThat(selectable.getTextCalledTimes).isEqualTo(0)
     }
 
     @Test
@@ -187,7 +184,7 @@
         val annotatedString = AnnotatedString(text = text)
         val startOffset = text.indexOf('e')
         val endOffset = text.indexOf('m')
-        whenever(selectable.getText()).thenReturn(annotatedString)
+        selectable.textToReturn = annotatedString
         selectionManager.selection = Selection(
             start = Selection.AnchorInfo(
                 direction = ResolvedTextDirection.Ltr,
@@ -204,7 +201,7 @@
 
         assertThat(selectionManager.getSelectedText())
             .isEqualTo(annotatedString.subSequence(startOffset, endOffset))
-        verify(selectable, times(1)).getText()
+        assertThat(selectable.getTextCalledTimes).isEqualTo(1)
     }
 
     @Test
@@ -213,7 +210,7 @@
         val annotatedString = AnnotatedString(text = text)
         val startOffset = text.indexOf('m')
         val endOffset = text.indexOf('x')
-        whenever(selectable.getText()).thenReturn(annotatedString)
+        selectable.textToReturn = annotatedString
         selectionManager.selection = Selection(
             start = Selection.AnchorInfo(
                 direction = ResolvedTextDirection.Ltr,
@@ -230,7 +227,7 @@
 
         assertThat(selectionManager.getSelectedText())
             .isEqualTo(annotatedString.subSequence(endOffset, startOffset))
-        verify(selectable, times(1)).getText()
+        assertThat(selectable.getTextCalledTimes).isEqualTo(1)
     }
 
     @Test
@@ -265,7 +262,7 @@
         val result = annotatedString.subSequence(startOffset, annotatedString.length) +
             annotatedString + annotatedString.subSequence(0, endOffset)
         assertThat(selectionManager.getSelectedText()).isEqualTo(result)
-        verify(selectable, times(0)).getText()
+        assertThat(selectable.getTextCalledTimes).isEqualTo(0)
         verify(startSelectable, times(1)).getText()
         verify(middleSelectable, times(1)).getText()
         verify(endSelectable, times(1)).getText()
@@ -304,7 +301,7 @@
         val result = annotatedString.subSequence(endOffset, annotatedString.length) +
             annotatedString + annotatedString.subSequence(0, startOffset)
         assertThat(selectionManager.getSelectedText()).isEqualTo(result)
-        verify(selectable, times(0)).getText()
+        assertThat(selectable.getTextCalledTimes).isEqualTo(0)
         verify(startSelectable, times(1)).getText()
         verify(middleSelectable, times(1)).getText()
         verify(endSelectable, times(1)).getText()
@@ -326,7 +323,7 @@
         val annotatedString = AnnotatedString(text = text)
         val startOffset = text.indexOf('m')
         val endOffset = text.indexOf('x')
-        whenever(selectable.getText()).thenReturn(annotatedString)
+        selectable.textToReturn = annotatedString
         selectionManager.selection = Selection(
             start = Selection.AnchorInfo(
                 direction = ResolvedTextDirection.Ltr,
@@ -357,7 +354,7 @@
         val annotatedString = AnnotatedString(text = text)
         val startOffset = text.indexOf('m')
         val endOffset = text.indexOf('x')
-        whenever(selectable.getText()).thenReturn(annotatedString)
+        selectable.textToReturn = annotatedString
         selectionManager.selection = Selection(
             start = Selection.AnchorInfo(
                 direction = ResolvedTextDirection.Ltr,
@@ -406,14 +403,14 @@
 
         selectionManager.onRelease()
 
-        verify(selectable, times(1))
-            .getSelection(
-                startPosition = Offset(-1f, -1f),
-                endPosition = Offset(-1f, -1f),
-                containerLayoutCoordinates = selectionManager.requireContainerCoordinates(),
-                longPress = false,
-                previousSelection = fakeSelection
-            )
+        assertThat(selectable.getSelectionCalledTimes).isEqualTo(1)
+        assertThat(selectable.lastStartPosition).isEqualTo(Offset(-1f, -1f))
+        assertThat(selectable.lastEndPosition).isEqualTo(Offset(-1f, -1f))
+        assertThat(selectable.lastContainerLayoutCoordinates)
+            .isEqualTo(selectionManager.requireContainerCoordinates())
+        assertThat(selectable.lastLongPress).isEqualTo(false)
+        assertThat(selectable.lastPreviousSelection).isEqualTo(fakeSelection)
+
         assertThat(selection).isNull()
         verify(spyLambda, times(1)).invoke(null)
         verify(
@@ -445,14 +442,14 @@
 
         selectionRegistrar.notifySelectableChange(selectable)
 
-        verify(selectable, times(1))
-            .getSelection(
-                startPosition = Offset(-1f, -1f),
-                endPosition = Offset(-1f, -1f),
-                containerLayoutCoordinates = selectionManager.requireContainerCoordinates(),
-                longPress = false,
-                previousSelection = fakeSelection
-            )
+        assertThat(selectable.getSelectionCalledTimes).isEqualTo(1)
+        assertThat(selectable.lastStartPosition).isEqualTo(Offset(-1f, -1f))
+        assertThat(selectable.lastEndPosition).isEqualTo(Offset(-1f, -1f))
+        assertThat(selectable.lastContainerLayoutCoordinates)
+            .isEqualTo(selectionManager.requireContainerCoordinates())
+        assertThat(selectable.lastLongPress).isEqualTo(false)
+        assertThat(selectable.lastPreviousSelection).isEqualTo(fakeSelection)
+
         assertThat(selection).isNull()
         verify(spyLambda, times(1)).invoke(null)
         verify(
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt
index 65acfda..029cfd7 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt
@@ -40,6 +40,7 @@
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.util.packInts
 import com.google.common.truth.Truth.assertThat
 import com.nhaarman.mockitokotlin2.any
 import com.nhaarman.mockitokotlin2.isNull
@@ -512,5 +513,6 @@
 // This class is a workaround for the bug that mockito can't stub a method returning inline class.
 // (https://github.com/nhaarman/mockito-kotlin/issues/309).
 internal class TextRangeAnswer(private val textRange: TextRange) : Answer<Any> {
-    override fun answer(invocation: InvocationOnMock?): Any = textRange.packedValue
+    override fun answer(invocation: InvocationOnMock?): Any =
+        packInts(textRange.start, textRange.end)
 }
diff --git a/compose/integration-tests/benchmark/src/androidTest/java/androidx/compose/ui/text/input/EditProcessorBenchmark.kt b/compose/integration-tests/benchmark/src/androidTest/java/androidx/compose/ui/text/input/EditProcessorBenchmark.kt
index 196a882..5553f43 100644
--- a/compose/integration-tests/benchmark/src/androidTest/java/androidx/compose/ui/text/input/EditProcessorBenchmark.kt
+++ b/compose/integration-tests/benchmark/src/androidTest/java/androidx/compose/ui/text/input/EditProcessorBenchmark.kt
@@ -18,17 +18,15 @@
 
 import androidx.benchmark.junit4.BenchmarkRule
 import androidx.benchmark.junit4.measureRepeated
+import androidx.compose.ui.text.TextRange
 import androidx.test.filters.LargeTest
 import androidx.ui.integration.test.RandomTextGenerator
 import androidx.ui.integration.test.cartesian
-import androidx.compose.ui.text.InternalTextApi
-import androidx.compose.ui.text.TextRange
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
 
-@OptIn(InternalTextApi::class)
 @LargeTest
 @RunWith(Parameterized::class)
 class EditProcessorBenchmark(val initText: InitialText, val scenario: TestScenario) {
@@ -82,18 +80,17 @@
         benchmarkRule.measureRepeated {
             val ep = runWithTimingDisabled {
                 EditProcessor().apply {
-                    onNewState(
+                    reset(
                         TextFieldValue(
                             text = initText.text,
                             selection = TextRange(5)
                         ),
-                        null, // text input service, not used.
-                        0 // session token, not used
+                        null // text input service, not used.
                     )
                 }
             }
 
-            ep.onEditCommands(scenario.ops)
+            ep.apply(scenario.ops)
         }
     }
 }
\ No newline at end of file
diff --git a/compose/integration-tests/demos/src/androidTest/java/androidx/compose/integration/demos/test/DemoTest.kt b/compose/integration-tests/demos/src/androidTest/java/androidx/compose/integration/demos/test/DemoTest.kt
index 03c45ef..c49f0e8 100644
--- a/compose/integration-tests/demos/src/androidTest/java/androidx/compose/integration/demos/test/DemoTest.kt
+++ b/compose/integration-tests/demos/src/androidTest/java/androidx/compose/integration/demos/test/DemoTest.kt
@@ -39,10 +39,10 @@
 import androidx.compose.ui.test.performScrollTo
 import androidx.test.espresso.Espresso
 import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.FlakyTest
 import androidx.test.filters.LargeTest
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -95,7 +95,7 @@
     }
 
     @Test
-    @FlakyTest(bugId = 179339732)
+    @Ignore("b/179339732")
     fun navigateThroughAllDemos_2() {
         navigateThroughAllDemos(SplitDemoCategories[1])
     }
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/interoperability/Interoperability.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/interoperability/Interoperability.kt
index e203e8d..6be0f0f 100644
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/interoperability/Interoperability.kt
+++ b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/interoperability/Interoperability.kt
@@ -193,7 +193,7 @@
         // Adds view to Compose
         AndroidView(
             modifier = Modifier.fillMaxSize(), // Occupy the max size in the Compose UI tree
-            viewBlock = { context ->
+            factory = { context ->
                 // Creates custom view
                 CustomView(context).apply {
                     // Sets up listeners for View -> Compose communication
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/testing/CheatSheet.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/testing/CheatSheet.kt
new file mode 100644
index 0000000..72b3300
--- /dev/null
+++ b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/testing/CheatSheet.kt
@@ -0,0 +1,413 @@
+/*
+ * 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.
+ */
+
+// Ignore lint warnings in documentation snippets
+@file:Suppress("unused", "UNUSED_PARAMETER", "UNUSED_VARIABLE")
+
+package androidx.compose.integration.docs.testing
+
+import android.os.Build
+import androidx.activity.ComponentActivity
+import androidx.annotation.RequiresApi
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.input.key.KeyEvent
+import androidx.compose.ui.layout.FirstBaseline
+import androidx.compose.ui.semantics.ProgressBarRangeInfo
+import androidx.compose.ui.semantics.SemanticsActions
+import androidx.compose.ui.test.assert
+import androidx.compose.ui.test.assertAll
+import androidx.compose.ui.test.assertAny
+import androidx.compose.ui.test.assertContentDescriptionContains
+import androidx.compose.ui.test.assertContentDescriptionEquals
+import androidx.compose.ui.test.assertCountEquals
+import androidx.compose.ui.test.assertHasClickAction
+import androidx.compose.ui.test.assertHasNoClickAction
+import androidx.compose.ui.test.assertHeightIsAtLeast
+import androidx.compose.ui.test.assertHeightIsEqualTo
+import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.assertIsEnabled
+import androidx.compose.ui.test.assertIsFocused
+import androidx.compose.ui.test.assertIsNotDisplayed
+import androidx.compose.ui.test.assertIsNotEnabled
+import androidx.compose.ui.test.assertIsNotFocused
+import androidx.compose.ui.test.assertIsNotSelected
+import androidx.compose.ui.test.assertIsOff
+import androidx.compose.ui.test.assertIsOn
+import androidx.compose.ui.test.assertIsSelectable
+import androidx.compose.ui.test.assertIsSelected
+import androidx.compose.ui.test.assertIsToggleable
+import androidx.compose.ui.test.assertLeftPositionInRootIsEqualTo
+import androidx.compose.ui.test.assertPositionInRootIsEqualTo
+import androidx.compose.ui.test.assertRangeInfoEquals
+import androidx.compose.ui.test.assertTextContains
+import androidx.compose.ui.test.assertTextEquals
+import androidx.compose.ui.test.assertTopPositionInRootIsEqualTo
+import androidx.compose.ui.test.assertValueEquals
+import androidx.compose.ui.test.assertWidthIsAtLeast
+import androidx.compose.ui.test.assertWidthIsEqualTo
+import androidx.compose.ui.test.bottom
+import androidx.compose.ui.test.bottomCenter
+import androidx.compose.ui.test.bottomLeft
+import androidx.compose.ui.test.bottomRight
+import androidx.compose.ui.test.cancel
+import androidx.compose.ui.test.captureToImage
+import androidx.compose.ui.test.center
+import androidx.compose.ui.test.centerLeft
+import androidx.compose.ui.test.centerRight
+import androidx.compose.ui.test.centerX
+import androidx.compose.ui.test.centerY
+import androidx.compose.ui.test.click
+import androidx.compose.ui.test.doubleClick
+import androidx.compose.ui.test.down
+import androidx.compose.ui.test.filter
+import androidx.compose.ui.test.filterToOne
+import androidx.compose.ui.test.getAlignmentLinePosition
+import androidx.compose.ui.test.getUnclippedBoundsInRoot
+import androidx.compose.ui.test.hasAnyAncestor
+import androidx.compose.ui.test.hasAnyChild
+import androidx.compose.ui.test.hasAnyDescendant
+import androidx.compose.ui.test.hasAnySibling
+import androidx.compose.ui.test.hasClickAction
+import androidx.compose.ui.test.hasContentDescription
+import androidx.compose.ui.test.hasImeAction
+import androidx.compose.ui.test.hasNoClickAction
+import androidx.compose.ui.test.hasNoScrollAction
+import androidx.compose.ui.test.hasParent
+import androidx.compose.ui.test.hasProgressBarRangeInfo
+import androidx.compose.ui.test.hasScrollAction
+import androidx.compose.ui.test.hasSetTextAction
+import androidx.compose.ui.test.hasStateDescription
+import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.hasText
+import androidx.compose.ui.test.height
+import androidx.compose.ui.test.isDialog
+import androidx.compose.ui.test.isEnabled
+import androidx.compose.ui.test.isFocusable
+import androidx.compose.ui.test.isFocused
+import androidx.compose.ui.test.isHeading
+import androidx.compose.ui.test.isNotEnabled
+import androidx.compose.ui.test.isNotFocusable
+import androidx.compose.ui.test.isNotFocused
+import androidx.compose.ui.test.isNotSelected
+import androidx.compose.ui.test.isOff
+import androidx.compose.ui.test.isOn
+import androidx.compose.ui.test.isPopup
+import androidx.compose.ui.test.isRoot
+import androidx.compose.ui.test.isSelectable
+import androidx.compose.ui.test.isSelected
+import androidx.compose.ui.test.isToggleable
+import androidx.compose.ui.test.junit4.createAndroidComposeRule
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.left
+import androidx.compose.ui.test.longClick
+import androidx.compose.ui.test.move
+import androidx.compose.ui.test.moveBy
+import androidx.compose.ui.test.movePointerBy
+import androidx.compose.ui.test.movePointerTo
+import androidx.compose.ui.test.moveTo
+import androidx.compose.ui.test.onAllNodesWithContentDescription
+import androidx.compose.ui.test.onAllNodesWithTag
+import androidx.compose.ui.test.onAllNodesWithText
+import androidx.compose.ui.test.onAncestors
+import androidx.compose.ui.test.onChild
+import androidx.compose.ui.test.onChildAt
+import androidx.compose.ui.test.onChildren
+import androidx.compose.ui.test.onFirst
+import androidx.compose.ui.test.onLast
+import androidx.compose.ui.test.onNodeWithContentDescription
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.test.onParent
+import androidx.compose.ui.test.onRoot
+import androidx.compose.ui.test.onSibling
+import androidx.compose.ui.test.onSiblings
+import androidx.compose.ui.test.percentOffset
+import androidx.compose.ui.test.performClick
+import androidx.compose.ui.test.performGesture
+import androidx.compose.ui.test.performImeAction
+import androidx.compose.ui.test.performKeyPress
+import androidx.compose.ui.test.performScrollTo
+import androidx.compose.ui.test.performSemanticsAction
+import androidx.compose.ui.test.performTextClearance
+import androidx.compose.ui.test.performTextInput
+import androidx.compose.ui.test.performTextReplacement
+import androidx.compose.ui.test.pinch
+import androidx.compose.ui.test.printToLog
+import androidx.compose.ui.test.printToString
+import androidx.compose.ui.test.right
+import androidx.compose.ui.test.swipe
+import androidx.compose.ui.test.swipeDown
+import androidx.compose.ui.test.swipeLeft
+import androidx.compose.ui.test.swipeRight
+import androidx.compose.ui.test.swipeUp
+import androidx.compose.ui.test.swipeWithVelocity
+import androidx.compose.ui.test.top
+import androidx.compose.ui.test.topCenter
+import androidx.compose.ui.test.topLeft
+import androidx.compose.ui.test.topRight
+import androidx.compose.ui.test.up
+import androidx.compose.ui.test.width
+import androidx.compose.ui.text.input.ImeAction
+import androidx.compose.ui.unit.dp
+import android.view.KeyEvent as AndroidKeyEvent
+import android.view.KeyEvent.ACTION_DOWN as ActionDown
+import android.view.KeyEvent.KEYCODE_A as KeyCodeA
+
+/**
+ * This file lets DevRel track changes to snippets present in
+ * https://developer.android.com/jetpack/compose/testing-cheatsheet.html
+ *
+ * No action required if it's modified.
+ */
+
+@Composable
+private fun TestingCheatSheetFinders() {
+    // FINDERS
+    composeTestRule.onNode(matcher)
+    composeTestRule.onAllNodes(matcher)
+    composeTestRule.onNodeWithContentDescription("label")
+    composeTestRule.onAllNodesWithContentDescription("label")
+    composeTestRule.onNodeWithTag("tag")
+    composeTestRule.onAllNodesWithTag("tag")
+    composeTestRule.onNodeWithText("text")
+    composeTestRule.onAllNodesWithText("text")
+    composeTestRule.onRoot()
+
+    // OPTIONS
+    composeTestRule.onNode(matcher, useUnmergedTree = true)
+
+    // SELECTORS
+    composeTestRule.onAllNodes(matcher)
+        .filter(matcher)
+        .filterToOne(matcher)
+    composeTestRule.onNode(matcher)
+        .onAncestors()
+    composeTestRule.onNode(matcher)
+        .onChild()
+        .onChildAt(0)
+        .onChildren()
+        .onFirst()
+    composeTestRule.onAllNodes(matcher)
+        .onLast()
+        .onParent()
+        .onSibling()
+        .onSiblings()
+
+    // HIERARCHICAL
+    composeTestRule.onNode(
+        hasAnyAncestor(matcher) and
+            hasAnyChild(matcher) and
+            hasAnyDescendant(matcher) and
+            hasAnySibling(matcher) and
+            hasParent(matcher)
+    )
+
+    // MATCHERS
+    composeTestRule.onNode(
+        hasClickAction() and
+            hasNoClickAction() and
+            hasContentDescription("label") and
+            hasImeAction(ImeAction.Default) and
+            hasProgressBarRangeInfo(rangeInfo) and
+            hasScrollAction() and
+            hasNoScrollAction() and
+            hasSetTextAction() and
+            hasStateDescription("label") and
+            hasTestTag("tag") and
+            hasText("text") and
+            isDialog() and
+            isEnabled() and
+            isFocusable() and
+            isFocused() and
+            isHeading() and
+            isNotEnabled() and
+            isNotFocusable() and
+            isNotFocused() and
+            isNotSelected() and
+            isOff() and
+            isOn() and
+            isPopup() and
+            isRoot() and
+            isSelectable() and
+            isSelected() and
+            isToggleable()
+    )
+}
+
+@Composable
+private fun TestingCheatSheetActions() {
+    composeTestRule.onRoot()
+        .performClick()
+        .performGesture { longClick() }
+        .performScrollTo()
+        .performSemanticsAction(SemanticsActions.OnLongClick)
+    composeTestRule.onRoot()
+        .performKeyPress(keyEvent2)
+    composeTestRule.onRoot()
+        .performImeAction()
+    composeTestRule.onRoot()
+        .performTextClearance()
+    composeTestRule.onRoot()
+        .performTextInput("text")
+    composeTestRule.onRoot()
+        .performTextReplacement("text")
+
+    // GESTURES
+
+    composeTestRule.onRoot().performGesture {
+        click()
+        longClick()
+        doubleClick()
+        swipe(this.center, offset)
+        pinch(offset, offset, offset, offset)
+        swipeWithVelocity(offset, offset, 1f)
+        swipeUp()
+        swipeDown()
+        swipeLeft()
+        swipeRight()
+
+        // PARTIAL GESTURES
+        down(offset)
+        moveTo(offset)
+        movePointerTo(0, offset)
+        moveBy(offset)
+        movePointerBy(0, offset)
+        move()
+        percentOffset()
+        up()
+        cancel()
+
+        visibleSize
+
+        bottom
+        bottomCenter
+        bottomLeft
+        bottomRight
+        center
+        centerLeft
+        centerRight
+        centerX
+        centerY
+        height
+        left
+        right
+        top
+        topCenter
+        topLeft
+        topRight
+        width
+    }
+}
+
+@Composable
+private fun TestingCheatSheetAssertions() {
+    composeTestRule.onRoot().apply {
+        assert(matcher)
+        assertContentDescriptionContains("label")
+        assertContentDescriptionEquals("label")
+        assertHasClickAction()
+        assertHasNoClickAction()
+        assertIsDisplayed()
+        assertIsEnabled()
+        assertIsFocused()
+        assertIsNotDisplayed()
+        assertIsNotEnabled()
+        assertIsNotFocused()
+        assertIsNotSelected()
+        assertIsOff()
+        assertIsOn()
+        assertIsSelectable()
+        assertIsSelected()
+        assertIsToggleable()
+        assertRangeInfoEquals(rangeInfo)
+        assertTextContains("text")
+        assertTextEquals("text")
+        assertValueEquals("value")
+    }
+
+    composeTestRule.onRoot().apply {
+        assertDoesNotExist()
+        assertExists()
+    }
+
+    // COLLECTIONS
+    composeTestRule.onAllNodes(matcher)
+        .assertAll(matcher)
+        .assertAny(matcher)
+        .assertCountEquals(1)
+
+    // BOUNDS
+    composeTestRule.onRoot()
+        .assertWidthIsEqualTo(1.dp)
+        .assertHeightIsEqualTo(1.dp)
+        .assertWidthIsAtLeast(1.dp)
+        .assertHeightIsAtLeast(1.dp)
+        .assertPositionInRootIsEqualTo(1.dp, 1.dp)
+        .assertTopPositionInRootIsEqualTo(1.dp)
+        .assertLeftPositionInRootIsEqualTo(1.dp)
+
+    composeTestRule.onNodeWithTag("button")
+        .getAlignmentLinePosition(FirstBaseline)
+
+    composeTestRule.onRoot()
+        .getUnclippedBoundsInRoot()
+}
+
+@RequiresApi(Build.VERSION_CODES.O)
+@Composable
+private fun TestingCheatSheetOther() {
+
+    // COMPOSE TEST RULE
+    nonAndroidComposeTestRule.apply {
+        setContent { }
+        density
+        runOnIdle { }
+        runOnUiThread { }
+        waitForIdle()
+        mainClock.apply {
+            autoAdvance
+            currentTime
+            advanceTimeBy(1L)
+            advanceTimeByFrame()
+            advanceTimeUntil { true }
+        }
+    }
+
+    // ANDROID COMPOSE TEST RULE
+    composeTestRule.activity
+    composeTestRule.activityRule
+
+    // Capture and debug
+    composeTestRule.onRoot().apply {
+        printToLog("TAG")
+        printToString()
+        captureToImage()
+    }
+    // MATCHERS
+    matcher.matches(composeTestRule.onRoot().fetchSemanticsNode())
+}
+
+/*
+Fakes needed for snippets to build:
+ */
+private val matcher = isDialog()
+private class FakeActivity : ComponentActivity()
+private val composeTestRule = createAndroidComposeRule<FakeActivity>()
+private val nonAndroidComposeTestRule = createComposeRule()
+private val keyEvent2 = KeyEvent(AndroidKeyEvent(ActionDown, KeyCodeA))
+private val offset = Offset(0f, 0f)
+private val rangeInfo = ProgressBarRangeInfo(0f, 0f..1f)
\ No newline at end of file
diff --git a/compose/material/material-ripple/api/current.txt b/compose/material/material-ripple/api/current.txt
index b1a6a95..3e18f6d 100644
--- a/compose/material/material-ripple/api/current.txt
+++ b/compose/material/material-ripple/api/current.txt
@@ -1,11 +1,16 @@
 // Signature format: 4.0
 package androidx.compose.material.ripple {
 
-  @kotlin.RequiresOptIn(message="This ripple API is experimental and is likely to change or to be removed in" + " the future.") public @interface ExperimentalRippleApi {
-  }
-
-  @androidx.compose.material.ripple.ExperimentalRippleApi public fun interface RippleAlpha {
-    method public float alphaForInteraction(androidx.compose.foundation.Interaction interaction);
+  @androidx.compose.runtime.Immutable public final class RippleAlpha {
+    ctor public RippleAlpha(float draggedAlpha, float focusedAlpha, float hoveredAlpha, float pressedAlpha);
+    method public float getDraggedAlpha();
+    method public float getFocusedAlpha();
+    method public float getHoveredAlpha();
+    method public float getPressedAlpha();
+    property public final float draggedAlpha;
+    property public final float focusedAlpha;
+    property public final float hoveredAlpha;
+    property public final float pressedAlpha;
   }
 
   public final class RippleAnimationKt {
@@ -15,19 +20,19 @@
     method @androidx.compose.runtime.Composable public static androidx.compose.foundation.Indication rememberRipple-aOO63xs(optional boolean bounded, optional float radius, optional long color);
   }
 
-  @androidx.compose.material.ripple.ExperimentalRippleApi public interface RippleTheme {
+  public interface RippleTheme {
     method @androidx.compose.runtime.Composable public long defaultColor-0d7_KjU();
     method @androidx.compose.runtime.Composable public androidx.compose.material.ripple.RippleAlpha rippleAlpha();
     field public static final androidx.compose.material.ripple.RippleTheme.Companion Companion;
   }
 
   public static final class RippleTheme.Companion {
-    method @androidx.compose.material.ripple.ExperimentalRippleApi public androidx.compose.material.ripple.RippleAlpha defaultRippleAlpha-QZCes2I(long contentColor, boolean lightTheme);
-    method @androidx.compose.material.ripple.ExperimentalRippleApi public long defaultRippleColor-QZCes2I(long contentColor, boolean lightTheme);
+    method public androidx.compose.material.ripple.RippleAlpha defaultRippleAlpha-QZCes2I(long contentColor, boolean lightTheme);
+    method public long defaultRippleColor-QZCes2I(long contentColor, boolean lightTheme);
   }
 
   public final class RippleThemeKt {
-    method @androidx.compose.material.ripple.ExperimentalRippleApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ripple.RippleTheme> getLocalRippleTheme();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ripple.RippleTheme> getLocalRippleTheme();
   }
 
 }
diff --git a/compose/material/material-ripple/api/public_plus_experimental_current.txt b/compose/material/material-ripple/api/public_plus_experimental_current.txt
index b1a6a95..3e18f6d 100644
--- a/compose/material/material-ripple/api/public_plus_experimental_current.txt
+++ b/compose/material/material-ripple/api/public_plus_experimental_current.txt
@@ -1,11 +1,16 @@
 // Signature format: 4.0
 package androidx.compose.material.ripple {
 
-  @kotlin.RequiresOptIn(message="This ripple API is experimental and is likely to change or to be removed in" + " the future.") public @interface ExperimentalRippleApi {
-  }
-
-  @androidx.compose.material.ripple.ExperimentalRippleApi public fun interface RippleAlpha {
-    method public float alphaForInteraction(androidx.compose.foundation.Interaction interaction);
+  @androidx.compose.runtime.Immutable public final class RippleAlpha {
+    ctor public RippleAlpha(float draggedAlpha, float focusedAlpha, float hoveredAlpha, float pressedAlpha);
+    method public float getDraggedAlpha();
+    method public float getFocusedAlpha();
+    method public float getHoveredAlpha();
+    method public float getPressedAlpha();
+    property public final float draggedAlpha;
+    property public final float focusedAlpha;
+    property public final float hoveredAlpha;
+    property public final float pressedAlpha;
   }
 
   public final class RippleAnimationKt {
@@ -15,19 +20,19 @@
     method @androidx.compose.runtime.Composable public static androidx.compose.foundation.Indication rememberRipple-aOO63xs(optional boolean bounded, optional float radius, optional long color);
   }
 
-  @androidx.compose.material.ripple.ExperimentalRippleApi public interface RippleTheme {
+  public interface RippleTheme {
     method @androidx.compose.runtime.Composable public long defaultColor-0d7_KjU();
     method @androidx.compose.runtime.Composable public androidx.compose.material.ripple.RippleAlpha rippleAlpha();
     field public static final androidx.compose.material.ripple.RippleTheme.Companion Companion;
   }
 
   public static final class RippleTheme.Companion {
-    method @androidx.compose.material.ripple.ExperimentalRippleApi public androidx.compose.material.ripple.RippleAlpha defaultRippleAlpha-QZCes2I(long contentColor, boolean lightTheme);
-    method @androidx.compose.material.ripple.ExperimentalRippleApi public long defaultRippleColor-QZCes2I(long contentColor, boolean lightTheme);
+    method public androidx.compose.material.ripple.RippleAlpha defaultRippleAlpha-QZCes2I(long contentColor, boolean lightTheme);
+    method public long defaultRippleColor-QZCes2I(long contentColor, boolean lightTheme);
   }
 
   public final class RippleThemeKt {
-    method @androidx.compose.material.ripple.ExperimentalRippleApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ripple.RippleTheme> getLocalRippleTheme();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ripple.RippleTheme> getLocalRippleTheme();
   }
 
 }
diff --git a/compose/material/material-ripple/api/restricted_current.txt b/compose/material/material-ripple/api/restricted_current.txt
index b1a6a95..3e18f6d 100644
--- a/compose/material/material-ripple/api/restricted_current.txt
+++ b/compose/material/material-ripple/api/restricted_current.txt
@@ -1,11 +1,16 @@
 // Signature format: 4.0
 package androidx.compose.material.ripple {
 
-  @kotlin.RequiresOptIn(message="This ripple API is experimental and is likely to change or to be removed in" + " the future.") public @interface ExperimentalRippleApi {
-  }
-
-  @androidx.compose.material.ripple.ExperimentalRippleApi public fun interface RippleAlpha {
-    method public float alphaForInteraction(androidx.compose.foundation.Interaction interaction);
+  @androidx.compose.runtime.Immutable public final class RippleAlpha {
+    ctor public RippleAlpha(float draggedAlpha, float focusedAlpha, float hoveredAlpha, float pressedAlpha);
+    method public float getDraggedAlpha();
+    method public float getFocusedAlpha();
+    method public float getHoveredAlpha();
+    method public float getPressedAlpha();
+    property public final float draggedAlpha;
+    property public final float focusedAlpha;
+    property public final float hoveredAlpha;
+    property public final float pressedAlpha;
   }
 
   public final class RippleAnimationKt {
@@ -15,19 +20,19 @@
     method @androidx.compose.runtime.Composable public static androidx.compose.foundation.Indication rememberRipple-aOO63xs(optional boolean bounded, optional float radius, optional long color);
   }
 
-  @androidx.compose.material.ripple.ExperimentalRippleApi public interface RippleTheme {
+  public interface RippleTheme {
     method @androidx.compose.runtime.Composable public long defaultColor-0d7_KjU();
     method @androidx.compose.runtime.Composable public androidx.compose.material.ripple.RippleAlpha rippleAlpha();
     field public static final androidx.compose.material.ripple.RippleTheme.Companion Companion;
   }
 
   public static final class RippleTheme.Companion {
-    method @androidx.compose.material.ripple.ExperimentalRippleApi public androidx.compose.material.ripple.RippleAlpha defaultRippleAlpha-QZCes2I(long contentColor, boolean lightTheme);
-    method @androidx.compose.material.ripple.ExperimentalRippleApi public long defaultRippleColor-QZCes2I(long contentColor, boolean lightTheme);
+    method public androidx.compose.material.ripple.RippleAlpha defaultRippleAlpha-QZCes2I(long contentColor, boolean lightTheme);
+    method public long defaultRippleColor-QZCes2I(long contentColor, boolean lightTheme);
   }
 
   public final class RippleThemeKt {
-    method @androidx.compose.material.ripple.ExperimentalRippleApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ripple.RippleTheme> getLocalRippleTheme();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ripple.RippleTheme> getLocalRippleTheme();
   }
 
 }
diff --git a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/ExperimentalRippleApi.kt b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/ExperimentalRippleApi.kt
deleted file mode 100644
index a4942eb..0000000
--- a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/ExperimentalRippleApi.kt
+++ /dev/null
@@ -1,23 +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.material.ripple
-
-@RequiresOptIn(
-    "This ripple API is experimental and is likely to change or to be removed in" +
-        " the future."
-)
-public annotation class ExperimentalRippleApi
diff --git a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/Ripple.kt b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/Ripple.kt
index 463909a..09ad441 100644
--- a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/Ripple.kt
+++ b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/Ripple.kt
@@ -20,20 +20,20 @@
 import androidx.compose.animation.core.AnimationSpec
 import androidx.compose.animation.core.LinearEasing
 import androidx.compose.animation.core.TweenSpec
+import androidx.compose.foundation.interaction.DragInteraction
 import androidx.compose.foundation.Indication
 import androidx.compose.foundation.IndicationInstance
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.InteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.RememberObserver
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.State
-import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.mutableStateMapOf
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.rememberUpdatedState
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.drawscope.ContentDrawScope
 import androidx.compose.ui.graphics.drawscope.DrawScope
@@ -41,8 +41,7 @@
 import androidx.compose.ui.graphics.isSpecified
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.isUnspecified
-import androidx.compose.ui.util.fastForEach
-import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.launch
 
 /**
@@ -51,7 +50,7 @@
  * A Ripple is a Material implementation of [Indication] that expresses different [Interaction]s
  * by drawing ripple animations and state layers.
  *
- * A Ripple responds to [Interaction.Pressed] by starting a new [RippleAnimation], and
+ * A Ripple responds to [PressInteraction.Press] by starting a new [RippleAnimation], and
  * responds to other [Interaction]s by showing a fixed [StateLayer] with varying alpha values
  * depending on the [Interaction].
  *
@@ -75,7 +74,6 @@
  * used will be [RippleTheme.defaultColor] instead.
  */
 @Composable
-@OptIn(ExperimentalRippleApi::class)
 public fun rememberRipple(
     bounded: Boolean = true,
     radius: Dp = Dp.Unspecified,
@@ -91,7 +89,7 @@
  * A Ripple is a Material implementation of [Indication] that expresses different [Interaction]s
  * by drawing ripple animations and state layers.
  *
- * A Ripple responds to [Interaction.Pressed] by starting a new [RippleAnimation], and
+ * A Ripple responds to [PressInteraction.Press] by starting a new [RippleAnimation], and
  * responds to other [Interaction]s by showing a fixed [StateLayer] with varying alpha values
  * depending on the [Interaction].
  *
@@ -105,14 +103,13 @@
  * parameters from the default, such as to create an unbounded ripple with a fixed size.
  */
 @Stable
-@ExperimentalRippleApi
 private class Ripple(
     private val bounded: Boolean,
     private val radius: Dp,
     private val color: State<Color>,
 ) : Indication {
     @Composable
-    override fun rememberUpdatedInstance(interactionState: InteractionState): IndicationInstance {
+    override fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance {
         val theme = LocalRippleTheme.current
         val color = rememberUpdatedState(
             if (color.value.isSpecified) {
@@ -121,11 +118,29 @@
                 theme.defaultColor()
             }
         )
-        val rippleAlpha = theme.rippleAlpha()
-        val scope = rememberCoroutineScope()
-        return remember(this, interactionState, rippleAlpha, scope) {
-            RippleIndicationInstance(interactionState, bounded, radius, color, rippleAlpha, scope)
+        val rippleAlpha = rememberUpdatedState(theme.rippleAlpha())
+        val instance = remember(interactionSource, this) {
+            RippleIndicationInstance(bounded, radius, color, rippleAlpha)
         }
+        LaunchedEffect(interactionSource, instance) {
+            interactionSource.interactions.collect { interaction ->
+                when (interaction) {
+                    is PressInteraction.Press -> {
+                        launch {
+                            instance.addRipple(interaction)
+                        }
+                    }
+                    is PressInteraction.Release -> {
+                        instance.removeRipple(interaction.press)
+                    }
+                    is PressInteraction.Cancel -> {
+                        instance.removeRipple(interaction.press)
+                    }
+                    else -> instance.updateStateLayer(interaction)
+                }
+            }
+        }
+        return instance
     }
 
     // to force stability on this indication we need equals and hashcode, there's no value in
@@ -149,70 +164,52 @@
     }
 }
 
-@ExperimentalRippleApi
 private class RippleIndicationInstance constructor(
-    private val interactionState: InteractionState,
     private val bounded: Boolean,
     private val radius: Dp,
     private val color: State<Color>,
-    private val rippleAlpha: RippleAlpha,
-    private val scope: CoroutineScope
+    private val rippleAlpha: State<RippleAlpha>
 ) : RememberObserver, IndicationInstance {
 
-    private val stateLayer = StateLayer(bounded, rippleAlpha, scope)
+    private val stateLayer = StateLayer(bounded, rippleAlpha)
 
-    private val ripples = mutableStateListOf<RippleAnimation>()
-    private var currentPressPosition: Offset? = null
-    private var currentRipple: RippleAnimation? = null
+    private val ripples = mutableStateMapOf<PressInteraction.Press, RippleAnimation>()
 
     override fun ContentDrawScope.drawIndication() {
         val color = color.value
-        val targetRadius = if (radius.isUnspecified) {
-            getRippleEndRadius(bounded, size)
-        } else {
-            radius.toPx()
-        }
         drawContent()
         with(stateLayer) {
-            drawStateLayer(interactionState, targetRadius, color)
-        }
-        val pressPosition = interactionState.interactionPositionFor(Interaction.Pressed)
-        if (pressPosition != null) {
-            if (currentPressPosition != pressPosition) {
-                addRipple(targetRadius, pressPosition)
-            }
-        } else {
-            removeRipple()
+            drawStateLayer(radius, color)
         }
         drawRipples(color)
     }
 
-    private fun ContentDrawScope.addRipple(targetRadius: Float, pressPosition: Offset) {
-        currentRipple?.finish()
-        val pxSize = Size(size.width, size.height)
-        val center = Offset(size.width / 2f, size.height / 2f)
-        val position = if (bounded) pressPosition else center
-        val ripple = RippleAnimation(pxSize, position, targetRadius, scope, bounded) { ripple ->
-            ripples.remove(ripple)
-            if (currentRipple == ripple) {
-                currentRipple = null
-            }
-        }
-        ripples.add(ripple)
-        currentPressPosition = pressPosition
-        currentRipple = ripple
+    suspend fun addRipple(interaction: PressInteraction.Press) {
+        // Finish existing ripples
+        ripples.forEach { (_, ripple) -> ripple.finish() }
+        val origin = if (bounded) interaction.pressPosition else null
+        val rippleAnimation = RippleAnimation(
+            origin = origin,
+            radius = radius,
+            bounded = bounded
+        )
+        ripples[interaction] = rippleAnimation
+        rippleAnimation.animate()
+        ripples.remove(interaction)
     }
 
-    private fun removeRipple() {
-        currentRipple?.finish()
-        currentRipple = null
-        currentPressPosition = null
+    suspend fun updateStateLayer(interaction: Interaction) {
+        stateLayer.handleInteraction(interaction)
+    }
+
+    fun removeRipple(interaction: PressInteraction.Press) {
+        ripples[interaction]?.finish()
     }
 
     private fun DrawScope.drawRipples(color: Color) {
-        ripples.fastForEach {
-            with(it) {
-                val alpha = rippleAlpha.alphaForInteraction(Interaction.Pressed)
+        ripples.forEach { (_, ripple) ->
+            with(ripple) {
+                val alpha = rippleAlpha.value.pressedAlpha
                 if (alpha != 0f) {
                     draw(color.copy(alpha = alpha))
                 }
@@ -220,32 +217,20 @@
         }
     }
 
-    private var timesRememembered = 0
-
-    override fun onRemembered() {
-        timesRememembered++
-    }
+    override fun onRemembered() {}
 
     override fun onForgotten() {
-        timesRememembered--
-        if (timesRememembered == 0) {
-            onDispose()
-        }
+        ripples.clear()
     }
 
     override fun onAbandoned() {
-        onDispose()
-    }
-
-    private fun onDispose() {
         ripples.clear()
-        currentRipple = null
     }
 }
 
 /**
  * Represents the layer underneath the press ripple, that displays an overlay for states such as
- * [Interaction.Dragged].
+ * [DragInteraction.Start].
  *
  * Typically, there should be both an 'incoming' and an 'outgoing' layer, so that when
  * transitioning between two states, the incoming of the new state, and the outgoing of the old
@@ -263,75 +248,62 @@
  * A state -> a different state = incoming transition for the new state
  * A state -> no state = outgoing transition for the old state
  *
- * @see IncomingStateLayerAnimationSpecs
- * @see OutgoingStateLayerAnimationSpecs
+ * @see incomingStateLayerAnimationSpecFor
+ * @see outgoingStateLayerAnimationSpecFor
  */
-@ExperimentalRippleApi
 private class StateLayer(
     private val bounded: Boolean,
-    private val rippleAlpha: RippleAlpha,
-    private val scope: CoroutineScope
+    // TODO: consider dynamically updating the alpha for existing interactions when rippleAlpha
+    // changes
+    private val rippleAlpha: State<RippleAlpha>
 ) {
     private val animatedAlpha = Animatable(0f)
-    private var previousInteractions: Set<Interaction> = emptySet()
-    private var lastDrawnInteraction: Interaction? = null
 
-    fun ContentDrawScope.drawStateLayer(
-        interactionState: InteractionState,
-        targetRadius: Float,
-        color: Color
-    ) {
-        val currentInteractions = interactionState.value
-        var handled = false
+    private val interactions: MutableList<Interaction> = mutableListOf()
+    private var currentInteraction: Interaction? = null
 
-        // Handle a new interaction, starting from the end as we care about the most recent
-        // interaction, not the oldest interaction.
-        for (interaction in currentInteractions.reversed()) {
-            // Stop looping if we have already moved to a new state
-            if (handled) break
-
-            // Pressed state is explicitly handled with a ripple animation, and not a state layer
-            if (interaction is Interaction.Pressed) continue
-
-            // Move to the next interaction if this interaction is not a new interaction
-            if (interaction in previousInteractions) continue
-
-            // Move to the next interaction if this is not an interaction we show a state layer for
-            val targetAlpha = rippleAlpha.alphaForInteraction(interaction)
-            if (targetAlpha == 0f) continue
-
-            // TODO: consider defaults - these will be used for a custom Interaction that we are
-            // not aware of, but has an alpha that should be shown because of a custom RippleTheme.
-            val incomingAnimationSpec = IncomingStateLayerAnimationSpecs[interaction]
-                ?: TweenSpec(durationMillis = 15, easing = LinearEasing)
-
-            scope.launch {
-                animatedAlpha.animateTo(targetAlpha, incomingAnimationSpec)
+    suspend fun handleInteraction(interaction: Interaction) {
+        // TODO: handle hover / focus states
+        when (interaction) {
+            is DragInteraction.Start -> {
+                interactions.add(interaction)
             }
-
-            lastDrawnInteraction = interaction
-            handled = true
+            is DragInteraction.Stop -> {
+                interactions.remove(interaction.start)
+            }
+            is DragInteraction.Cancel -> {
+                interactions.remove(interaction.start)
+            }
+            else -> return
         }
 
-        // Clean up any stale interactions if we have not moved to a new interaction
-        if (!handled) {
-            val previousInteraction = lastDrawnInteraction
-            if (previousInteraction != null && previousInteraction !in currentInteractions) {
-                // TODO: consider defaults - these will be used for a custom Interaction that we are
-                // not aware of, but has an alpha that should be shown because of a custom
-                // RippleTheme.
-                val outgoingAnimationSpec = OutgoingStateLayerAnimationSpecs[previousInteraction]
-                    ?: TweenSpec(durationMillis = 15, easing = LinearEasing)
+        // The most recent interaction is the one we want to show
+        val newInteraction = interactions.lastOrNull()
 
-                scope.launch {
-                    animatedAlpha.animateTo(0f, outgoingAnimationSpec)
+        if (currentInteraction != newInteraction) {
+            if (newInteraction != null) {
+                val targetAlpha = when (interaction) {
+                    is DragInteraction.Start -> rippleAlpha.value.draggedAlpha
+                    else -> 0f
                 }
+                val incomingAnimationSpec = incomingStateLayerAnimationSpecFor(newInteraction)
 
-                lastDrawnInteraction = null
+                animatedAlpha.animateTo(targetAlpha, incomingAnimationSpec)
+            } else {
+                val outgoingAnimationSpec = outgoingStateLayerAnimationSpecFor(currentInteraction)
+
+                animatedAlpha.animateTo(0f, outgoingAnimationSpec)
             }
+            currentInteraction = newInteraction
         }
+    }
 
-        previousInteractions = currentInteractions
+    fun DrawScope.drawStateLayer(radius: Dp, color: Color) {
+        val targetRadius = if (radius.isUnspecified) {
+            getRippleEndRadius(bounded, size)
+        } else {
+            radius.toPx()
+        }
 
         val alpha = animatedAlpha.value
 
@@ -350,26 +322,33 @@
 }
 
 /**
- * [AnimationSpec]s used when transitioning to a new state, either from a previous state, or no
- * state.
+ * @return the [AnimationSpec] used when transitioning to [interaction], either from a previous
+ * state, or no state.
  *
  * TODO: handle hover / focus states
  */
-private val IncomingStateLayerAnimationSpecs: Map<Interaction, AnimationSpec<Float>> = mapOf(
-    Interaction.Dragged to TweenSpec(
-        durationMillis = 45,
-        easing = LinearEasing
-    )
-)
+private fun incomingStateLayerAnimationSpecFor(interaction: Interaction): AnimationSpec<Float> {
+    return if (interaction is DragInteraction.Start) {
+        TweenSpec(durationMillis = 45, easing = LinearEasing)
+    } else {
+        DefaultTweenSpec
+    }
+}
 
 /**
- * [AnimationSpec]s used when transitioning away from a state, to no state.
+ * @return the [AnimationSpec] used when transitioning away from [interaction], to no state.
  *
  * TODO: handle hover / focus states
  */
-private val OutgoingStateLayerAnimationSpecs: Map<Interaction, AnimationSpec<Float>> = mapOf(
-    Interaction.Dragged to TweenSpec(
-        durationMillis = 150,
-        easing = LinearEasing
-    )
-)
+private fun outgoingStateLayerAnimationSpecFor(interaction: Interaction?): AnimationSpec<Float> {
+    return if (interaction is DragInteraction.Start) {
+        TweenSpec(durationMillis = 150, easing = LinearEasing)
+    } else {
+        DefaultTweenSpec
+    }
+}
+
+/**
+ * Default / fallback [AnimationSpec].
+ */
+private val DefaultTweenSpec = TweenSpec<Float>(durationMillis = 15, easing = LinearEasing)
diff --git a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleAnimation.kt b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleAnimation.kt
index 257d152..6005049 100644
--- a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleAnimation.kt
+++ b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleAnimation.kt
@@ -19,7 +19,6 @@
 import androidx.compose.animation.core.Animatable
 import androidx.compose.animation.core.FastOutSlowInEasing
 import androidx.compose.animation.core.LinearEasing
-import androidx.compose.animation.core.VectorConverter
 import androidx.compose.animation.core.tween
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
@@ -30,18 +29,18 @@
 import androidx.compose.ui.graphics.drawscope.DrawScope
 import androidx.compose.ui.graphics.drawscope.clipRect
 import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import kotlinx.coroutines.CoroutineScope
+import androidx.compose.ui.unit.isUnspecified
+import androidx.compose.ui.util.lerp
+import kotlinx.coroutines.CompletableDeferred
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.launch
-import kotlin.coroutines.Continuation
-import kotlin.coroutines.resume
-import kotlin.coroutines.suspendCoroutine
 import kotlin.math.max
 
 /**
  * [RippleAnimation]s are drawn as part of [Ripple] as a visual indicator for an
- * different [androidx.compose.foundation.Interaction]s.
+ * different [androidx.compose.foundation.interaction.Interaction]s.
  *
  * Use [androidx.compose.foundation.clickable] or [androidx.compose.foundation.indication] to add a
  * ripple to your component, which contains a RippleAnimation for pressed states, and
@@ -53,66 +52,54 @@
  * radius expanding from 60% of the final value. The ripple origin animates to the center of its
  * target layout for the bounded version and stays in the center for the unbounded one.
  *
- * @param size The size of the target layout.
- * @param startPosition The position the animation will start from.
+ * @param origin The position the animation will start from. If null the animation will start
+ * from the center of the layout bounds.
  * @param radius Effects grow up to this size.
- * @param clipped If true the effect should be clipped by the target layout bounds.
- * @param scope The coroutine scope used for suspending animations
- * @param onAnimationFinished Call when the effect animation has been finished.
+ * @param bounded If true the effect should be clipped by the target layout bounds.
  */
 internal class RippleAnimation(
-    size: Size,
-    startPosition: Offset,
-    radius: Float,
-    scope: CoroutineScope,
-    private val clipped: Boolean,
-    private val onAnimationFinished: (RippleAnimation) -> Unit
+    private var origin: Offset?,
+    private val radius: Dp,
+    private val bounded: Boolean
 ) {
-    private val startAlpha = 0f
-    private val startRadius = getRippleStartRadius(size)
+    private var startRadius: Float? = null
+    private var targetRadius: Float? = null
 
-    private val targetAlpha = 1f
-    private val targetRadius = radius
-    private val targetCenter = Offset(size.width / 2.0f, size.height / 2.0f)
+    private var targetCenter: Offset? = null
 
-    private val animatedAlpha = Animatable(startAlpha)
-    private val animatedRadius = Animatable(startRadius)
-    private val animatedCenter = Animatable(startPosition, Offset.VectorConverter)
+    private val animatedAlpha = Animatable(0f)
+    private val animatedRadiusPercent = Animatable(0f)
+    private val animatedCenterPercent = Animatable(0f)
 
-    private var finishContinuation: Continuation<Unit>? = null
+    private val finishSignalDeferred = CompletableDeferred<Unit>(null)
+
     private var finishedFadingIn by mutableStateOf(false)
     private var finishRequested by mutableStateOf(false)
 
-    init {
-        scope.launch {
-            fadeIn()
-            finishedFadingIn = true
-            // If we haven't been told to finish, wait until we have been
-            if (!finishRequested) {
-                suspendCoroutine<Unit> { finishContinuation = it }
-            }
-            fadeOut()
-            onAnimationFinished(this@RippleAnimation)
-        }
+    suspend fun animate() {
+        fadeIn()
+        finishedFadingIn = true
+        finishSignalDeferred.await()
+        fadeOut()
     }
 
     private suspend fun fadeIn() {
         coroutineScope {
             launch {
                 animatedAlpha.animateTo(
-                    targetAlpha,
+                    1f,
                     tween(durationMillis = FadeInDuration, easing = LinearEasing)
                 )
             }
             launch {
-                animatedRadius.animateTo(
-                    targetRadius,
+                animatedRadiusPercent.animateTo(
+                    1f,
                     tween(durationMillis = RadiusDuration, easing = FastOutSlowInEasing)
                 )
             }
             launch {
-                animatedCenter.animateTo(
-                    targetCenter,
+                animatedCenterPercent.animateTo(
+                    1f,
                     tween(durationMillis = RadiusDuration, easing = LinearEasing)
                 )
             }
@@ -132,10 +119,27 @@
 
     fun finish() {
         finishRequested = true
-        finishContinuation?.resume(Unit)
+        finishSignalDeferred.complete(Unit)
     }
 
     fun DrawScope.draw(color: Color) {
+        if (startRadius == null) {
+            startRadius = getRippleStartRadius(size)
+        }
+        if (targetRadius == null) {
+            targetRadius = if (radius.isUnspecified) {
+                getRippleEndRadius(bounded, size)
+            } else {
+                radius.toPx()
+            }
+        }
+        if (origin == null) {
+            origin = center
+        }
+        if (targetCenter == null) {
+            targetCenter = Offset(size.width / 2.0f, size.height / 2.0f)
+        }
+
         val alpha = if (finishRequested && !finishedFadingIn) {
             // If we are still fading-in we should immediately switch to the final alpha.
             1f
@@ -143,11 +147,14 @@
             animatedAlpha.value
         }
 
-        val radius = animatedRadius.value
-        val centerOffset = animatedCenter.value
+        val radius = lerp(startRadius!!, targetRadius!!, animatedRadiusPercent.value)
+        val centerOffset = Offset(
+            lerp(origin!!.x, targetCenter!!.x, animatedCenterPercent.value),
+            lerp(origin!!.y, targetCenter!!.y, animatedCenterPercent.value),
+        )
 
         val modulatedColor = color.copy(alpha = color.alpha * alpha)
-        if (clipped) {
+        if (bounded) {
             clipRect {
                 drawCircle(modulatedColor, radius, centerOffset)
             }
diff --git a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleTheme.kt b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleTheme.kt
index 02433b5..b1b1411 100644
--- a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleTheme.kt
+++ b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleTheme.kt
@@ -16,7 +16,9 @@
 
 package androidx.compose.material.ripple
 
-import androidx.compose.foundation.Interaction
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.material.ripple.RippleTheme.Companion.defaultRippleAlpha
+import androidx.compose.material.ripple.RippleTheme.Companion.defaultRippleColor
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.ProvidableCompositionLocal
@@ -31,7 +33,6 @@
  *
  * @see rememberRipple
  */
-@ExperimentalRippleApi
 public interface RippleTheme {
     /**
      * @return the default ripple color at the call site's position in the hierarchy.
@@ -59,7 +60,6 @@
          * contains the ripple.
          * @param lightTheme whether the theme is light or not
          */
-        @ExperimentalRippleApi
         public fun defaultRippleColor(
             contentColor: Color,
             lightTheme: Boolean
@@ -83,7 +83,6 @@
          * contains the ripple.
          * @param lightTheme whether the theme is light or not
          */
-        @ExperimentalRippleApi
         public fun defaultRippleAlpha(contentColor: Color, lightTheme: Boolean): RippleAlpha {
             return when {
                 lightTheme -> {
@@ -102,15 +101,44 @@
 }
 
 /**
- * RippleAlpha defines the alpha of the ripple / state layer for a given [Interaction].
+ * RippleAlpha defines the alpha of the ripple / state layer for different [Interaction]s.
+ *
+ * @property draggedAlpha the alpha used when the ripple is dragged
+ * @property focusedAlpha not currently supported
+ * @property hoveredAlpha not currently supported
+ * @property pressedAlpha the alpha used when the ripple is pressed
  */
-@ExperimentalRippleApi
-public fun interface RippleAlpha {
-    /**
-     * @return the alpha of the ripple for the given [interaction]. Return `0f` if this
-     * particular interaction should not show a corresponding ripple / state layer.
-     */
-    public fun alphaForInteraction(interaction: Interaction): Float
+@Immutable
+public class RippleAlpha(
+    public val draggedAlpha: Float,
+    public val focusedAlpha: Float,
+    public val hoveredAlpha: Float,
+    public val pressedAlpha: Float
+) {
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is RippleAlpha) return false
+
+        if (draggedAlpha != other.draggedAlpha) return false
+        if (focusedAlpha != other.focusedAlpha) return false
+        if (hoveredAlpha != other.hoveredAlpha) return false
+        if (pressedAlpha != other.pressedAlpha) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = draggedAlpha.hashCode()
+        result = 31 * result + focusedAlpha.hashCode()
+        result = 31 * result + hoveredAlpha.hashCode()
+        result = 31 * result + pressedAlpha.hashCode()
+        return result
+    }
+
+    override fun toString(): String {
+        return "RippleAlpha(draggedAlpha=$draggedAlpha, focusedAlpha=$focusedAlpha, " +
+            "hoveredAlpha=$hoveredAlpha, pressedAlpha=$pressedAlpha)"
+    }
 }
 
 /**
@@ -119,26 +147,9 @@
  * See [RippleTheme.defaultRippleColor] and [RippleTheme.defaultRippleAlpha] functions for the
  * default implementations for color and alpha.
  */
-@get:ExperimentalRippleApi
-@ExperimentalRippleApi
 public val LocalRippleTheme: ProvidableCompositionLocal<RippleTheme> =
     staticCompositionLocalOf { DebugRippleTheme }
 
-@Suppress("unused")
-@OptIn(ExperimentalRippleApi::class)
-private sealed class DefaultRippleAlpha(
-    val pressed: Float,
-    val focused: Float,
-    val dragged: Float,
-    val hovered: Float
-) : RippleAlpha {
-    override fun alphaForInteraction(interaction: Interaction): Float = when (interaction) {
-        Interaction.Pressed -> pressed
-        Interaction.Dragged -> dragged
-        else -> 0f
-    }
-}
-
 /**
  * Alpha values for high luminance content in a light theme.
  *
@@ -148,11 +159,11 @@
  * These levels are typically used for text / iconography in primary colored tabs /
  * bottom navigation / etc.
  */
-private object LightThemeHighContrastRippleAlpha : DefaultRippleAlpha(
-    pressed = 0.24f,
-    focused = 0.24f,
-    dragged = 0.16f,
-    hovered = 0.08f
+private val LightThemeHighContrastRippleAlpha = RippleAlpha(
+    pressedAlpha = 0.24f,
+    focusedAlpha = 0.24f,
+    draggedAlpha = 0.16f,
+    hoveredAlpha = 0.08f
 )
 
 /**
@@ -164,21 +175,21 @@
  * These levels are typically used for body text on the main surface (white in light theme, grey
  * in dark theme) and text / iconography in surface colored tabs / bottom navigation / etc.
  */
-private object LightThemeLowContrastRippleAlpha : DefaultRippleAlpha(
-    pressed = 0.12f,
-    focused = 0.12f,
-    dragged = 0.08f,
-    hovered = 0.04f
+private val LightThemeLowContrastRippleAlpha = RippleAlpha(
+    pressedAlpha = 0.12f,
+    focusedAlpha = 0.12f,
+    draggedAlpha = 0.08f,
+    hoveredAlpha = 0.04f
 )
 
 /**
  * Alpha levels for all content in a dark theme.
  */
-private object DarkThemeRippleAlpha : DefaultRippleAlpha(
-    pressed = 0.10f,
-    focused = 0.12f,
-    dragged = 0.08f,
-    hovered = 0.04f
+private val DarkThemeRippleAlpha = RippleAlpha(
+    pressedAlpha = 0.10f,
+    focusedAlpha = 0.12f,
+    draggedAlpha = 0.08f,
+    hoveredAlpha = 0.04f
 )
 
 /**
@@ -186,14 +197,13 @@
  * instead provide your own theme with meaningful values - this exists as an alternative to
  * crashing if no theme is provided.
  */
-@ExperimentalRippleApi
 @Immutable
 private object DebugRippleTheme : RippleTheme {
     @Composable
-    override fun defaultColor() = RippleTheme.defaultRippleColor(Color.Black, lightTheme = true)
+    override fun defaultColor() = defaultRippleColor(Color.Black, lightTheme = true)
 
     @Composable
-    override fun rippleAlpha(): RippleAlpha = RippleTheme.defaultRippleAlpha(
+    override fun rippleAlpha(): RippleAlpha = defaultRippleAlpha(
         Color.Black,
         lightTheme = true
     )
diff --git a/compose/material/material/api/current.txt b/compose/material/material/api/current.txt
index 0a84dce..041d5bf10 100644
--- a/compose/material/material/api/current.txt
+++ b/compose/material/material/api/current.txt
@@ -11,7 +11,7 @@
 
   public final class AndroidMenu_androidKt {
     method @androidx.compose.runtime.Composable public static void DropdownMenu-jyMeD6A(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.InteractionState interactionState, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
   }
 
   public final class AppBarDefaults {
@@ -51,11 +51,11 @@
 
   @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BackdropScaffoldState extends androidx.compose.material.SwipeableState<androidx.compose.material.BackdropValue> {
     ctor public BackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, androidx.compose.material.SnackbarHostState snackbarHostState);
-    method public suspend Object? conceal(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? conceal(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public androidx.compose.material.SnackbarHostState getSnackbarHostState();
     method public boolean isConcealed();
     method public boolean isRevealed();
-    method public suspend Object? reveal(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? reveal(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final boolean isConcealed;
     property public final boolean isRevealed;
     property public final androidx.compose.material.SnackbarHostState snackbarHostState;
@@ -73,12 +73,12 @@
 
   public final class BottomDrawerState extends androidx.compose.material.SwipeableState<androidx.compose.material.BottomDrawerValue> {
     ctor public BottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? close(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
-    method public suspend Object? expand(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public boolean isClosed();
     method public boolean isExpanded();
     method public boolean isOpen();
-    method public suspend Object? open(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? open(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final boolean isClosed;
     property public final boolean isExpanded;
     property public final boolean isOpen;
@@ -103,7 +103,7 @@
 
   public final class BottomNavigationKt {
     method @androidx.compose.runtime.Composable public static void BottomNavigation-ye6PvEY(optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional float elevation, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void BottomNavigationItem-mT8lZtY(androidx.compose.foundation.layout.RowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.foundation.InteractionState interactionState, optional long selectedContentColor, optional long unselectedContentColor);
+    method @androidx.compose.runtime.Composable public static void BottomNavigationItem-g7W06kY(androidx.compose.foundation.layout.RowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional long selectedContentColor, optional long unselectedContentColor);
   }
 
   public final class BottomSheetScaffoldDefaults {
@@ -132,8 +132,8 @@
 
   @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BottomSheetState extends androidx.compose.material.SwipeableState<androidx.compose.material.BottomSheetValue> {
     ctor public BottomSheetState(androidx.compose.material.BottomSheetValue initialValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? collapse(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
-    method public suspend Object? expand(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? collapse(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public boolean isCollapsed();
     method public boolean isExpanded();
     property public final boolean isCollapsed;
@@ -181,13 +181,13 @@
   }
 
   @androidx.compose.runtime.Stable public interface ButtonElevation {
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> elevation(boolean enabled, androidx.compose.foundation.InteractionState interactionState);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> elevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource interactionSource);
   }
 
   public final class ButtonKt {
-    method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static inline void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static inline void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
   }
 
   public final class CardKt {
@@ -206,8 +206,8 @@
   }
 
   public final class CheckboxKt {
-    method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.CheckboxColors colors);
-    method @androidx.compose.runtime.Composable public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.CheckboxColors colors);
+    method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.CheckboxColors colors);
+    method @androidx.compose.runtime.Composable public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.CheckboxColors colors);
   }
 
   @androidx.compose.runtime.Stable public final class Colors {
@@ -273,10 +273,10 @@
 
   @androidx.compose.material.ExperimentalMaterialApi public final class DismissState extends androidx.compose.material.SwipeableState<androidx.compose.material.DismissValue> {
     ctor public DismissState(androidx.compose.material.DismissValue initialValue, kotlin.jvm.functions.Function1<? super androidx.compose.material.DismissValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? dismiss(androidx.compose.material.DismissDirection direction, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? dismiss(androidx.compose.material.DismissDirection direction, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public androidx.compose.material.DismissDirection? getDismissDirection();
     method public boolean isDismissed(androidx.compose.material.DismissDirection direction);
-    method public suspend Object? reset(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? reset(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final androidx.compose.material.DismissDirection? dismissDirection;
     field public static final androidx.compose.material.DismissState.Companion Companion;
   }
@@ -313,10 +313,10 @@
 
   @androidx.compose.runtime.Stable public final class DrawerState extends androidx.compose.material.SwipeableState<androidx.compose.material.DrawerValue> {
     ctor public DrawerState(androidx.compose.material.DrawerValue initialValue, kotlin.jvm.functions.Function1<? super androidx.compose.material.DrawerValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? close(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public boolean isClosed();
     method public boolean isOpen();
-    method public suspend Object? open(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? open(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final boolean isClosed;
     property public final boolean isOpen;
     field public static final androidx.compose.material.DrawerState.Companion Companion;
@@ -362,12 +362,12 @@
   }
 
   @androidx.compose.runtime.Stable public interface FloatingActionButtonElevation {
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> elevation(androidx.compose.foundation.InteractionState interactionState);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> elevation(androidx.compose.foundation.interaction.InteractionSource interactionSource);
   }
 
   public final class FloatingActionButtonKt {
-    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton-i36UMrA(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.material.FloatingActionButtonElevation elevation);
-    method @androidx.compose.runtime.Composable public static void FloatingActionButton-lf3tHAI(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.material.FloatingActionButtonElevation elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton-opHSmBI(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.material.FloatingActionButtonElevation elevation);
+    method @androidx.compose.runtime.Composable public static void FloatingActionButton-n9X6i6U(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.material.FloatingActionButtonElevation elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class FractionalThreshold implements androidx.compose.material.ThresholdConfig {
@@ -377,8 +377,8 @@
   }
 
   public final class IconButtonKt {
-    method @androidx.compose.runtime.Composable public static void IconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void IconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, 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.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   public final class IconKt {
@@ -432,7 +432,7 @@
 
   @androidx.compose.material.ExperimentalMaterialApi public final class ModalBottomSheetState extends androidx.compose.material.SwipeableState<androidx.compose.material.ModalBottomSheetValue> {
     ctor public ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? hide(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? hide(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public boolean isVisible();
     method public suspend Object? show(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final boolean isVisible;
@@ -450,8 +450,8 @@
   }
 
   public final class OutlinedTextFieldKt {
-    method @androidx.compose.runtime.Composable public static void OutlinedTextField-TIQU8E0(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isErrorValue, 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 kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional long activeColor, optional long inactiveColor, optional long errorColor);
-    method @androidx.compose.runtime.Composable public static void OutlinedTextField-uticZRQ(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isErrorValue, 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 kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional long activeColor, optional long inactiveColor, optional long errorColor);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.TextFieldColors colors);
   }
 
   public final class ProgressIndicatorDefaults {
@@ -480,7 +480,7 @@
   }
 
   public final class RadioButtonKt {
-    method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.RadioButtonColors colors);
+    method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.RadioButtonColors colors);
   }
 
   @androidx.compose.runtime.Immutable public final class ResistanceConfig {
@@ -522,14 +522,24 @@
   public final class ShapesKt {
   }
 
+  @androidx.compose.runtime.Stable public interface SliderColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> thumbColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> tickColor(boolean enabled, boolean active);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trackColor(boolean enabled, boolean active);
+  }
+
   public final class SliderDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material.SliderColors colors-kU-unao(optional long thumbColor, optional long disabledThumbColor, optional long activeTrackColor, optional long inactiveTrackColor, optional long disabledActiveTrackColor, optional long disabledInactiveTrackColor, optional long activeTickColor, optional long inactiveTickColor, optional long disabledActiveTickColor, optional long disabledInactiveTickColor);
+    field public static final float DisabledActiveTrackAlpha = 0.32f;
+    field public static final float DisabledInactiveTrackAlpha = 0.12f;
+    field public static final float DisabledTickAlpha = 0.12f;
     field public static final androidx.compose.material.SliderDefaults INSTANCE;
-    field public static final float InactiveTrackColorAlpha = 0.24f;
-    field public static final float TickColorAlpha = 0.54f;
+    field public static final float InactiveTrackAlpha = 0.24f;
+    field public static final float TickAlpha = 0.54f;
   }
 
   public final class SliderKt {
-    method @androidx.compose.runtime.Composable public static void Slider-7LIuTVc(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.foundation.InteractionState interactionState, optional long thumbColor, optional long activeTrackColor, optional long inactiveTrackColor, optional long activeTickColor, optional long inactiveTickColor);
+    method @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.SliderColors colors);
   }
 
   public interface SnackbarData {
@@ -610,12 +620,12 @@
 
   public final class SwipeableKt {
     method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static <T> androidx.compose.material.SwipeableState<T> rememberSwipeableState(T initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
-    method @androidx.compose.material.ExperimentalMaterialApi public static <T> androidx.compose.ui.Modifier swipeable-rEcnmuA(androidx.compose.ui.Modifier, androidx.compose.material.SwipeableState<T> state, java.util.Map<java.lang.Float,? extends T> anchors, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.InteractionState? interactionState, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends androidx.compose.material.ThresholdConfig> thresholds, optional androidx.compose.material.ResistanceConfig? resistance, optional float velocityThreshold);
+    method @androidx.compose.material.ExperimentalMaterialApi public static <T> androidx.compose.ui.Modifier swipeable-827DgyA(androidx.compose.ui.Modifier, androidx.compose.material.SwipeableState<T> state, java.util.Map<java.lang.Float,? extends T> anchors, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends androidx.compose.material.ThresholdConfig> thresholds, optional androidx.compose.material.ResistanceConfig? resistance, optional float velocityThreshold);
   }
 
   @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public class SwipeableState<T> {
     ctor public SwipeableState(T? initialValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
-    method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? animateTo(T? targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? animateTo(T? targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, optional kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public final T! getCurrentValue();
     method public final float getDirection();
     method public final androidx.compose.runtime.State<java.lang.Float> getOffset();
@@ -624,7 +634,7 @@
     method public final T! getTargetValue();
     method public final boolean isAnimationRunning();
     method public final float performDrag(float delta);
-    method public final suspend Object? performFling(float velocity, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public final suspend Object? performFling(float velocity, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? snapTo(T? targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final T! currentValue;
     property public final float direction;
@@ -651,12 +661,12 @@
   }
 
   public final class SwitchKt {
-    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.SwitchColors colors);
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.SwitchColors colors);
   }
 
   public final class TabKt {
-    method @androidx.compose.runtime.Composable public static void Tab-EwjEPwU(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional long selectedContentColor, optional long unselectedContentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void Tab-iV7aoUM(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.foundation.InteractionState interactionState, optional long selectedContentColor, optional long unselectedContentColor);
+    method @androidx.compose.runtime.Composable public static void Tab-TC9MJzw(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional long selectedContentColor, optional long unselectedContentColor);
+    method @androidx.compose.runtime.Composable public static void Tab-wUuQ7UU(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional long selectedContentColor, optional long unselectedContentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
   }
 
   @androidx.compose.runtime.Immutable public final class TabPosition {
@@ -687,13 +697,36 @@
     method @androidx.compose.runtime.Composable public static void TabRow-xUsefZ0(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
   }
 
+  @androidx.compose.runtime.Stable public interface TextFieldColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> backgroundColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> cursorColor(boolean isError);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> indicatorColor(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> labelColor(boolean enabled, boolean error, androidx.compose.foundation.interaction.InteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconColor(boolean enabled, boolean isError);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> placeholderColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trailingIconColor(boolean enabled, boolean isError);
+  }
+
+  public final class TextFieldDefaults {
+    method public float getMinHeight-D9Ej5fM();
+    method public float getMinWidth-D9Ej5fM();
+    method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors outlinedTextFieldColors-LWDMS30(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors textFieldColors-LWDMS30(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    property public final float MinHeight;
+    property public final float MinWidth;
+    field public static final float BackgroundOpacity = 0.12f;
+    field public static final androidx.compose.material.TextFieldDefaults INSTANCE;
+    field public static final float IconOpacity = 0.54f;
+    field public static final float UnfocusedIndicatorLineOpacity = 0.42f;
+  }
+
   public final class TextFieldImplKt {
   }
 
   public final class TextFieldKt {
-    method @androidx.compose.runtime.Composable public static void TextField-Pd9g5P8(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isErrorValue, 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 kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional long activeColor, optional long inactiveColor, optional long errorColor, optional long backgroundColor, optional androidx.compose.ui.graphics.Shape shape);
-    method @androidx.compose.runtime.Composable public static void TextField-TG6cP-s(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isErrorValue, 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 kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional long activeColor, optional long inactiveColor, optional long errorColor, optional long backgroundColor, optional androidx.compose.ui.graphics.Shape shape);
-    field public static final float ContainerAlpha = 0.12f;
+    method @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material.TextFieldColors colors);
   }
 
   public final class TextKt {
diff --git a/compose/material/material/api/public_plus_experimental_current.txt b/compose/material/material/api/public_plus_experimental_current.txt
index 0a84dce..041d5bf10 100644
--- a/compose/material/material/api/public_plus_experimental_current.txt
+++ b/compose/material/material/api/public_plus_experimental_current.txt
@@ -11,7 +11,7 @@
 
   public final class AndroidMenu_androidKt {
     method @androidx.compose.runtime.Composable public static void DropdownMenu-jyMeD6A(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.InteractionState interactionState, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
   }
 
   public final class AppBarDefaults {
@@ -51,11 +51,11 @@
 
   @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BackdropScaffoldState extends androidx.compose.material.SwipeableState<androidx.compose.material.BackdropValue> {
     ctor public BackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, androidx.compose.material.SnackbarHostState snackbarHostState);
-    method public suspend Object? conceal(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? conceal(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public androidx.compose.material.SnackbarHostState getSnackbarHostState();
     method public boolean isConcealed();
     method public boolean isRevealed();
-    method public suspend Object? reveal(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? reveal(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final boolean isConcealed;
     property public final boolean isRevealed;
     property public final androidx.compose.material.SnackbarHostState snackbarHostState;
@@ -73,12 +73,12 @@
 
   public final class BottomDrawerState extends androidx.compose.material.SwipeableState<androidx.compose.material.BottomDrawerValue> {
     ctor public BottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? close(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
-    method public suspend Object? expand(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public boolean isClosed();
     method public boolean isExpanded();
     method public boolean isOpen();
-    method public suspend Object? open(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? open(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final boolean isClosed;
     property public final boolean isExpanded;
     property public final boolean isOpen;
@@ -103,7 +103,7 @@
 
   public final class BottomNavigationKt {
     method @androidx.compose.runtime.Composable public static void BottomNavigation-ye6PvEY(optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional float elevation, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void BottomNavigationItem-mT8lZtY(androidx.compose.foundation.layout.RowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.foundation.InteractionState interactionState, optional long selectedContentColor, optional long unselectedContentColor);
+    method @androidx.compose.runtime.Composable public static void BottomNavigationItem-g7W06kY(androidx.compose.foundation.layout.RowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional long selectedContentColor, optional long unselectedContentColor);
   }
 
   public final class BottomSheetScaffoldDefaults {
@@ -132,8 +132,8 @@
 
   @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BottomSheetState extends androidx.compose.material.SwipeableState<androidx.compose.material.BottomSheetValue> {
     ctor public BottomSheetState(androidx.compose.material.BottomSheetValue initialValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? collapse(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
-    method public suspend Object? expand(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? collapse(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public boolean isCollapsed();
     method public boolean isExpanded();
     property public final boolean isCollapsed;
@@ -181,13 +181,13 @@
   }
 
   @androidx.compose.runtime.Stable public interface ButtonElevation {
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> elevation(boolean enabled, androidx.compose.foundation.InteractionState interactionState);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> elevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource interactionSource);
   }
 
   public final class ButtonKt {
-    method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static inline void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static inline void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
   }
 
   public final class CardKt {
@@ -206,8 +206,8 @@
   }
 
   public final class CheckboxKt {
-    method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.CheckboxColors colors);
-    method @androidx.compose.runtime.Composable public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.CheckboxColors colors);
+    method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.CheckboxColors colors);
+    method @androidx.compose.runtime.Composable public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.CheckboxColors colors);
   }
 
   @androidx.compose.runtime.Stable public final class Colors {
@@ -273,10 +273,10 @@
 
   @androidx.compose.material.ExperimentalMaterialApi public final class DismissState extends androidx.compose.material.SwipeableState<androidx.compose.material.DismissValue> {
     ctor public DismissState(androidx.compose.material.DismissValue initialValue, kotlin.jvm.functions.Function1<? super androidx.compose.material.DismissValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? dismiss(androidx.compose.material.DismissDirection direction, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? dismiss(androidx.compose.material.DismissDirection direction, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public androidx.compose.material.DismissDirection? getDismissDirection();
     method public boolean isDismissed(androidx.compose.material.DismissDirection direction);
-    method public suspend Object? reset(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? reset(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final androidx.compose.material.DismissDirection? dismissDirection;
     field public static final androidx.compose.material.DismissState.Companion Companion;
   }
@@ -313,10 +313,10 @@
 
   @androidx.compose.runtime.Stable public final class DrawerState extends androidx.compose.material.SwipeableState<androidx.compose.material.DrawerValue> {
     ctor public DrawerState(androidx.compose.material.DrawerValue initialValue, kotlin.jvm.functions.Function1<? super androidx.compose.material.DrawerValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? close(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public boolean isClosed();
     method public boolean isOpen();
-    method public suspend Object? open(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? open(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final boolean isClosed;
     property public final boolean isOpen;
     field public static final androidx.compose.material.DrawerState.Companion Companion;
@@ -362,12 +362,12 @@
   }
 
   @androidx.compose.runtime.Stable public interface FloatingActionButtonElevation {
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> elevation(androidx.compose.foundation.InteractionState interactionState);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> elevation(androidx.compose.foundation.interaction.InteractionSource interactionSource);
   }
 
   public final class FloatingActionButtonKt {
-    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton-i36UMrA(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.material.FloatingActionButtonElevation elevation);
-    method @androidx.compose.runtime.Composable public static void FloatingActionButton-lf3tHAI(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.material.FloatingActionButtonElevation elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton-opHSmBI(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.material.FloatingActionButtonElevation elevation);
+    method @androidx.compose.runtime.Composable public static void FloatingActionButton-n9X6i6U(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.material.FloatingActionButtonElevation elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class FractionalThreshold implements androidx.compose.material.ThresholdConfig {
@@ -377,8 +377,8 @@
   }
 
   public final class IconButtonKt {
-    method @androidx.compose.runtime.Composable public static void IconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void IconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, 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.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   public final class IconKt {
@@ -432,7 +432,7 @@
 
   @androidx.compose.material.ExperimentalMaterialApi public final class ModalBottomSheetState extends androidx.compose.material.SwipeableState<androidx.compose.material.ModalBottomSheetValue> {
     ctor public ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? hide(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? hide(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public boolean isVisible();
     method public suspend Object? show(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final boolean isVisible;
@@ -450,8 +450,8 @@
   }
 
   public final class OutlinedTextFieldKt {
-    method @androidx.compose.runtime.Composable public static void OutlinedTextField-TIQU8E0(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isErrorValue, 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 kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional long activeColor, optional long inactiveColor, optional long errorColor);
-    method @androidx.compose.runtime.Composable public static void OutlinedTextField-uticZRQ(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isErrorValue, 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 kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional long activeColor, optional long inactiveColor, optional long errorColor);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.TextFieldColors colors);
   }
 
   public final class ProgressIndicatorDefaults {
@@ -480,7 +480,7 @@
   }
 
   public final class RadioButtonKt {
-    method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.RadioButtonColors colors);
+    method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.RadioButtonColors colors);
   }
 
   @androidx.compose.runtime.Immutable public final class ResistanceConfig {
@@ -522,14 +522,24 @@
   public final class ShapesKt {
   }
 
+  @androidx.compose.runtime.Stable public interface SliderColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> thumbColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> tickColor(boolean enabled, boolean active);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trackColor(boolean enabled, boolean active);
+  }
+
   public final class SliderDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material.SliderColors colors-kU-unao(optional long thumbColor, optional long disabledThumbColor, optional long activeTrackColor, optional long inactiveTrackColor, optional long disabledActiveTrackColor, optional long disabledInactiveTrackColor, optional long activeTickColor, optional long inactiveTickColor, optional long disabledActiveTickColor, optional long disabledInactiveTickColor);
+    field public static final float DisabledActiveTrackAlpha = 0.32f;
+    field public static final float DisabledInactiveTrackAlpha = 0.12f;
+    field public static final float DisabledTickAlpha = 0.12f;
     field public static final androidx.compose.material.SliderDefaults INSTANCE;
-    field public static final float InactiveTrackColorAlpha = 0.24f;
-    field public static final float TickColorAlpha = 0.54f;
+    field public static final float InactiveTrackAlpha = 0.24f;
+    field public static final float TickAlpha = 0.54f;
   }
 
   public final class SliderKt {
-    method @androidx.compose.runtime.Composable public static void Slider-7LIuTVc(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.foundation.InteractionState interactionState, optional long thumbColor, optional long activeTrackColor, optional long inactiveTrackColor, optional long activeTickColor, optional long inactiveTickColor);
+    method @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.SliderColors colors);
   }
 
   public interface SnackbarData {
@@ -610,12 +620,12 @@
 
   public final class SwipeableKt {
     method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static <T> androidx.compose.material.SwipeableState<T> rememberSwipeableState(T initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
-    method @androidx.compose.material.ExperimentalMaterialApi public static <T> androidx.compose.ui.Modifier swipeable-rEcnmuA(androidx.compose.ui.Modifier, androidx.compose.material.SwipeableState<T> state, java.util.Map<java.lang.Float,? extends T> anchors, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.InteractionState? interactionState, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends androidx.compose.material.ThresholdConfig> thresholds, optional androidx.compose.material.ResistanceConfig? resistance, optional float velocityThreshold);
+    method @androidx.compose.material.ExperimentalMaterialApi public static <T> androidx.compose.ui.Modifier swipeable-827DgyA(androidx.compose.ui.Modifier, androidx.compose.material.SwipeableState<T> state, java.util.Map<java.lang.Float,? extends T> anchors, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends androidx.compose.material.ThresholdConfig> thresholds, optional androidx.compose.material.ResistanceConfig? resistance, optional float velocityThreshold);
   }
 
   @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public class SwipeableState<T> {
     ctor public SwipeableState(T? initialValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
-    method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? animateTo(T? targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? animateTo(T? targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, optional kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public final T! getCurrentValue();
     method public final float getDirection();
     method public final androidx.compose.runtime.State<java.lang.Float> getOffset();
@@ -624,7 +634,7 @@
     method public final T! getTargetValue();
     method public final boolean isAnimationRunning();
     method public final float performDrag(float delta);
-    method public final suspend Object? performFling(float velocity, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public final suspend Object? performFling(float velocity, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? snapTo(T? targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final T! currentValue;
     property public final float direction;
@@ -651,12 +661,12 @@
   }
 
   public final class SwitchKt {
-    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.SwitchColors colors);
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.SwitchColors colors);
   }
 
   public final class TabKt {
-    method @androidx.compose.runtime.Composable public static void Tab-EwjEPwU(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional long selectedContentColor, optional long unselectedContentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void Tab-iV7aoUM(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.foundation.InteractionState interactionState, optional long selectedContentColor, optional long unselectedContentColor);
+    method @androidx.compose.runtime.Composable public static void Tab-TC9MJzw(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional long selectedContentColor, optional long unselectedContentColor);
+    method @androidx.compose.runtime.Composable public static void Tab-wUuQ7UU(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional long selectedContentColor, optional long unselectedContentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
   }
 
   @androidx.compose.runtime.Immutable public final class TabPosition {
@@ -687,13 +697,36 @@
     method @androidx.compose.runtime.Composable public static void TabRow-xUsefZ0(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
   }
 
+  @androidx.compose.runtime.Stable public interface TextFieldColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> backgroundColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> cursorColor(boolean isError);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> indicatorColor(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> labelColor(boolean enabled, boolean error, androidx.compose.foundation.interaction.InteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconColor(boolean enabled, boolean isError);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> placeholderColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trailingIconColor(boolean enabled, boolean isError);
+  }
+
+  public final class TextFieldDefaults {
+    method public float getMinHeight-D9Ej5fM();
+    method public float getMinWidth-D9Ej5fM();
+    method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors outlinedTextFieldColors-LWDMS30(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors textFieldColors-LWDMS30(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    property public final float MinHeight;
+    property public final float MinWidth;
+    field public static final float BackgroundOpacity = 0.12f;
+    field public static final androidx.compose.material.TextFieldDefaults INSTANCE;
+    field public static final float IconOpacity = 0.54f;
+    field public static final float UnfocusedIndicatorLineOpacity = 0.42f;
+  }
+
   public final class TextFieldImplKt {
   }
 
   public final class TextFieldKt {
-    method @androidx.compose.runtime.Composable public static void TextField-Pd9g5P8(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isErrorValue, 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 kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional long activeColor, optional long inactiveColor, optional long errorColor, optional long backgroundColor, optional androidx.compose.ui.graphics.Shape shape);
-    method @androidx.compose.runtime.Composable public static void TextField-TG6cP-s(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isErrorValue, 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 kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional long activeColor, optional long inactiveColor, optional long errorColor, optional long backgroundColor, optional androidx.compose.ui.graphics.Shape shape);
-    field public static final float ContainerAlpha = 0.12f;
+    method @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material.TextFieldColors colors);
   }
 
   public final class TextKt {
diff --git a/compose/material/material/api/restricted_current.txt b/compose/material/material/api/restricted_current.txt
index 0a84dce..041d5bf10 100644
--- a/compose/material/material/api/restricted_current.txt
+++ b/compose/material/material/api/restricted_current.txt
@@ -11,7 +11,7 @@
 
   public final class AndroidMenu_androidKt {
     method @androidx.compose.runtime.Composable public static void DropdownMenu-jyMeD6A(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.InteractionState interactionState, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
   }
 
   public final class AppBarDefaults {
@@ -51,11 +51,11 @@
 
   @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BackdropScaffoldState extends androidx.compose.material.SwipeableState<androidx.compose.material.BackdropValue> {
     ctor public BackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, androidx.compose.material.SnackbarHostState snackbarHostState);
-    method public suspend Object? conceal(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? conceal(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public androidx.compose.material.SnackbarHostState getSnackbarHostState();
     method public boolean isConcealed();
     method public boolean isRevealed();
-    method public suspend Object? reveal(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? reveal(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final boolean isConcealed;
     property public final boolean isRevealed;
     property public final androidx.compose.material.SnackbarHostState snackbarHostState;
@@ -73,12 +73,12 @@
 
   public final class BottomDrawerState extends androidx.compose.material.SwipeableState<androidx.compose.material.BottomDrawerValue> {
     ctor public BottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? close(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
-    method public suspend Object? expand(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public boolean isClosed();
     method public boolean isExpanded();
     method public boolean isOpen();
-    method public suspend Object? open(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? open(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final boolean isClosed;
     property public final boolean isExpanded;
     property public final boolean isOpen;
@@ -103,7 +103,7 @@
 
   public final class BottomNavigationKt {
     method @androidx.compose.runtime.Composable public static void BottomNavigation-ye6PvEY(optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional float elevation, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void BottomNavigationItem-mT8lZtY(androidx.compose.foundation.layout.RowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.foundation.InteractionState interactionState, optional long selectedContentColor, optional long unselectedContentColor);
+    method @androidx.compose.runtime.Composable public static void BottomNavigationItem-g7W06kY(androidx.compose.foundation.layout.RowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional long selectedContentColor, optional long unselectedContentColor);
   }
 
   public final class BottomSheetScaffoldDefaults {
@@ -132,8 +132,8 @@
 
   @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BottomSheetState extends androidx.compose.material.SwipeableState<androidx.compose.material.BottomSheetValue> {
     ctor public BottomSheetState(androidx.compose.material.BottomSheetValue initialValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? collapse(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
-    method public suspend Object? expand(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? collapse(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public boolean isCollapsed();
     method public boolean isExpanded();
     property public final boolean isCollapsed;
@@ -181,13 +181,13 @@
   }
 
   @androidx.compose.runtime.Stable public interface ButtonElevation {
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> elevation(boolean enabled, androidx.compose.foundation.InteractionState interactionState);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> elevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource interactionSource);
   }
 
   public final class ButtonKt {
-    method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static inline void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static inline void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
   }
 
   public final class CardKt {
@@ -206,8 +206,8 @@
   }
 
   public final class CheckboxKt {
-    method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.CheckboxColors colors);
-    method @androidx.compose.runtime.Composable public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.CheckboxColors colors);
+    method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.CheckboxColors colors);
+    method @androidx.compose.runtime.Composable public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.CheckboxColors colors);
   }
 
   @androidx.compose.runtime.Stable public final class Colors {
@@ -273,10 +273,10 @@
 
   @androidx.compose.material.ExperimentalMaterialApi public final class DismissState extends androidx.compose.material.SwipeableState<androidx.compose.material.DismissValue> {
     ctor public DismissState(androidx.compose.material.DismissValue initialValue, kotlin.jvm.functions.Function1<? super androidx.compose.material.DismissValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? dismiss(androidx.compose.material.DismissDirection direction, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? dismiss(androidx.compose.material.DismissDirection direction, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public androidx.compose.material.DismissDirection? getDismissDirection();
     method public boolean isDismissed(androidx.compose.material.DismissDirection direction);
-    method public suspend Object? reset(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? reset(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final androidx.compose.material.DismissDirection? dismissDirection;
     field public static final androidx.compose.material.DismissState.Companion Companion;
   }
@@ -313,10 +313,10 @@
 
   @androidx.compose.runtime.Stable public final class DrawerState extends androidx.compose.material.SwipeableState<androidx.compose.material.DrawerValue> {
     ctor public DrawerState(androidx.compose.material.DrawerValue initialValue, kotlin.jvm.functions.Function1<? super androidx.compose.material.DrawerValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? close(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public boolean isClosed();
     method public boolean isOpen();
-    method public suspend Object? open(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? open(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final boolean isClosed;
     property public final boolean isOpen;
     field public static final androidx.compose.material.DrawerState.Companion Companion;
@@ -362,12 +362,12 @@
   }
 
   @androidx.compose.runtime.Stable public interface FloatingActionButtonElevation {
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> elevation(androidx.compose.foundation.InteractionState interactionState);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> elevation(androidx.compose.foundation.interaction.InteractionSource interactionSource);
   }
 
   public final class FloatingActionButtonKt {
-    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton-i36UMrA(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.material.FloatingActionButtonElevation elevation);
-    method @androidx.compose.runtime.Composable public static void FloatingActionButton-lf3tHAI(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.material.FloatingActionButtonElevation elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton-opHSmBI(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.material.FloatingActionButtonElevation elevation);
+    method @androidx.compose.runtime.Composable public static void FloatingActionButton-n9X6i6U(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.material.FloatingActionButtonElevation elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class FractionalThreshold implements androidx.compose.material.ThresholdConfig {
@@ -377,8 +377,8 @@
   }
 
   public final class IconButtonKt {
-    method @androidx.compose.runtime.Composable public static void IconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void IconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, 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.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   public final class IconKt {
@@ -432,7 +432,7 @@
 
   @androidx.compose.material.ExperimentalMaterialApi public final class ModalBottomSheetState extends androidx.compose.material.SwipeableState<androidx.compose.material.ModalBottomSheetValue> {
     ctor public ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? hide(kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public suspend Object? hide(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public boolean isVisible();
     method public suspend Object? show(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final boolean isVisible;
@@ -450,8 +450,8 @@
   }
 
   public final class OutlinedTextFieldKt {
-    method @androidx.compose.runtime.Composable public static void OutlinedTextField-TIQU8E0(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isErrorValue, 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 kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional long activeColor, optional long inactiveColor, optional long errorColor);
-    method @androidx.compose.runtime.Composable public static void OutlinedTextField-uticZRQ(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isErrorValue, 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 kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional long activeColor, optional long inactiveColor, optional long errorColor);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.TextFieldColors colors);
   }
 
   public final class ProgressIndicatorDefaults {
@@ -480,7 +480,7 @@
   }
 
   public final class RadioButtonKt {
-    method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.RadioButtonColors colors);
+    method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.RadioButtonColors colors);
   }
 
   @androidx.compose.runtime.Immutable public final class ResistanceConfig {
@@ -522,14 +522,24 @@
   public final class ShapesKt {
   }
 
+  @androidx.compose.runtime.Stable public interface SliderColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> thumbColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> tickColor(boolean enabled, boolean active);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trackColor(boolean enabled, boolean active);
+  }
+
   public final class SliderDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material.SliderColors colors-kU-unao(optional long thumbColor, optional long disabledThumbColor, optional long activeTrackColor, optional long inactiveTrackColor, optional long disabledActiveTrackColor, optional long disabledInactiveTrackColor, optional long activeTickColor, optional long inactiveTickColor, optional long disabledActiveTickColor, optional long disabledInactiveTickColor);
+    field public static final float DisabledActiveTrackAlpha = 0.32f;
+    field public static final float DisabledInactiveTrackAlpha = 0.12f;
+    field public static final float DisabledTickAlpha = 0.12f;
     field public static final androidx.compose.material.SliderDefaults INSTANCE;
-    field public static final float InactiveTrackColorAlpha = 0.24f;
-    field public static final float TickColorAlpha = 0.54f;
+    field public static final float InactiveTrackAlpha = 0.24f;
+    field public static final float TickAlpha = 0.54f;
   }
 
   public final class SliderKt {
-    method @androidx.compose.runtime.Composable public static void Slider-7LIuTVc(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.foundation.InteractionState interactionState, optional long thumbColor, optional long activeTrackColor, optional long inactiveTrackColor, optional long activeTickColor, optional long inactiveTickColor);
+    method @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.SliderColors colors);
   }
 
   public interface SnackbarData {
@@ -610,12 +620,12 @@
 
   public final class SwipeableKt {
     method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static <T> androidx.compose.material.SwipeableState<T> rememberSwipeableState(T initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
-    method @androidx.compose.material.ExperimentalMaterialApi public static <T> androidx.compose.ui.Modifier swipeable-rEcnmuA(androidx.compose.ui.Modifier, androidx.compose.material.SwipeableState<T> state, java.util.Map<java.lang.Float,? extends T> anchors, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.InteractionState? interactionState, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends androidx.compose.material.ThresholdConfig> thresholds, optional androidx.compose.material.ResistanceConfig? resistance, optional float velocityThreshold);
+    method @androidx.compose.material.ExperimentalMaterialApi public static <T> androidx.compose.ui.Modifier swipeable-827DgyA(androidx.compose.ui.Modifier, androidx.compose.material.SwipeableState<T> state, java.util.Map<java.lang.Float,? extends T> anchors, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends androidx.compose.material.ThresholdConfig> thresholds, optional androidx.compose.material.ResistanceConfig? resistance, optional float velocityThreshold);
   }
 
   @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public class SwipeableState<T> {
     ctor public SwipeableState(T? initialValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
-    method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? animateTo(T? targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? animateTo(T? targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, optional kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public final T! getCurrentValue();
     method public final float getDirection();
     method public final androidx.compose.runtime.State<java.lang.Float> getOffset();
@@ -624,7 +634,7 @@
     method public final T! getTargetValue();
     method public final boolean isAnimationRunning();
     method public final float performDrag(float delta);
-    method public final suspend Object? performFling(float velocity, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationEndReason> p);
+    method public final suspend Object? performFling(float velocity, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? snapTo(T? targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final T! currentValue;
     property public final float direction;
@@ -651,12 +661,12 @@
   }
 
   public final class SwitchKt {
-    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional androidx.compose.material.SwitchColors colors);
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.SwitchColors colors);
   }
 
   public final class TabKt {
-    method @androidx.compose.runtime.Composable public static void Tab-EwjEPwU(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.InteractionState interactionState, optional long selectedContentColor, optional long unselectedContentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void Tab-iV7aoUM(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.foundation.InteractionState interactionState, optional long selectedContentColor, optional long unselectedContentColor);
+    method @androidx.compose.runtime.Composable public static void Tab-TC9MJzw(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional long selectedContentColor, optional long unselectedContentColor);
+    method @androidx.compose.runtime.Composable public static void Tab-wUuQ7UU(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional long selectedContentColor, optional long unselectedContentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
   }
 
   @androidx.compose.runtime.Immutable public final class TabPosition {
@@ -687,13 +697,36 @@
     method @androidx.compose.runtime.Composable public static void TabRow-xUsefZ0(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
   }
 
+  @androidx.compose.runtime.Stable public interface TextFieldColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> backgroundColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> cursorColor(boolean isError);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> indicatorColor(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> labelColor(boolean enabled, boolean error, androidx.compose.foundation.interaction.InteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconColor(boolean enabled, boolean isError);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> placeholderColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trailingIconColor(boolean enabled, boolean isError);
+  }
+
+  public final class TextFieldDefaults {
+    method public float getMinHeight-D9Ej5fM();
+    method public float getMinWidth-D9Ej5fM();
+    method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors outlinedTextFieldColors-LWDMS30(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors textFieldColors-LWDMS30(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    property public final float MinHeight;
+    property public final float MinWidth;
+    field public static final float BackgroundOpacity = 0.12f;
+    field public static final androidx.compose.material.TextFieldDefaults INSTANCE;
+    field public static final float IconOpacity = 0.54f;
+    field public static final float UnfocusedIndicatorLineOpacity = 0.42f;
+  }
+
   public final class TextFieldImplKt {
   }
 
   public final class TextFieldKt {
-    method @androidx.compose.runtime.Composable public static void TextField-Pd9g5P8(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isErrorValue, 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 kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional long activeColor, optional long inactiveColor, optional long errorColor, optional long backgroundColor, optional androidx.compose.ui.graphics.Shape shape);
-    method @androidx.compose.runtime.Composable public static void TextField-TG6cP-s(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isErrorValue, 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 kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.SoftwareKeyboardController,kotlin.Unit> onTextInputStarted, optional androidx.compose.foundation.InteractionState interactionState, optional long activeColor, optional long inactiveColor, optional long errorColor, optional long backgroundColor, optional androidx.compose.ui.graphics.Shape shape);
-    field public static final float ContainerAlpha = 0.12f;
+    method @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material.TextFieldColors colors);
   }
 
   public final class TextKt {
diff --git a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/BottomNavigationDemo.kt b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/BottomNavigationDemo.kt
index 8889140..bddb1e2 100644
--- a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/BottomNavigationDemo.kt
+++ b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/BottomNavigationDemo.kt
@@ -25,6 +25,7 @@
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.requiredWidth
 import androidx.compose.foundation.selection.selectable
+import androidx.compose.foundation.selection.selectableGroup
 import androidx.compose.material.RadioButton
 import androidx.compose.material.Text
 import androidx.compose.material.samples.BottomNavigationSample
@@ -41,7 +42,10 @@
 @Composable
 fun BottomNavigationDemo() {
     var alwaysShowLabels by remember { mutableStateOf(false) }
-    Column(Modifier.fillMaxHeight(), verticalArrangement = Arrangement.Bottom) {
+    Column(
+        modifier = Modifier.fillMaxHeight().selectableGroup(),
+        verticalArrangement = Arrangement.Bottom
+    ) {
         Row(
             modifier = Modifier
                 .fillMaxWidth()
diff --git a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/ColorPickerDemo.kt b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/ColorPickerDemo.kt
index dd73b2e..2fe2f1a 100644
--- a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/ColorPickerDemo.kt
+++ b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/ColorPickerDemo.kt
@@ -24,7 +24,9 @@
 import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
-import androidx.compose.foundation.gestures.detectDragGestures
+import androidx.compose.foundation.gestures.awaitFirstDown
+import androidx.compose.foundation.gestures.drag
+import androidx.compose.foundation.gestures.forEachGesture
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxWithConstraints
 import androidx.compose.foundation.layout.Column
@@ -64,6 +66,7 @@
 import androidx.compose.ui.graphics.isSpecified
 import androidx.compose.ui.graphics.toArgb
 import androidx.compose.ui.graphics.toPixelMap
+import androidx.compose.ui.input.pointer.consumePositionChange
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.text.style.TextAlign
@@ -98,11 +101,9 @@
         var position by remember { mutableStateOf(Offset.Zero) }
         val colorWheel = remember(diameter) { ColorWheel(diameter) }
 
-        var isDragging by remember { mutableStateOf(false) }
-        val inputModifier = Modifier.pointerInput(Unit) {
-            detectDragGestures { change, _ ->
-                isDragging = true
-                val newPosition = change.position
+        var hasInput by remember { mutableStateOf(false) }
+        val inputModifier = Modifier.pointerInput(colorWheel) {
+            fun updateColorWheel(newPosition: Offset) {
                 // Work out if the new position is inside the circle we are drawing, and has a
                 // valid color associated to it. If not, keep the current position
                 val newColor = colorWheel.colorForPosition(newPosition)
@@ -111,13 +112,26 @@
                     onColorChange(newColor)
                 }
             }
+
+            forEachGesture {
+                awaitPointerEventScope {
+                    val down = awaitFirstDown()
+                    hasInput = true
+                    updateColorWheel(down.position)
+                    drag(down.id) { change ->
+                        change.consumePositionChange()
+                        updateColorWheel(change.position)
+                    }
+                    hasInput = false
+                }
+            }
         }
 
         Box(Modifier.fillMaxSize()) {
             Image(modifier = inputModifier, contentDescription = null, bitmap = colorWheel.image)
             val color = colorWheel.colorForPosition(position)
             if (color.isSpecified) {
-                Magnifier(visible = isDragging, position = position, color = color)
+                Magnifier(visible = hasInput, position = position, color = color)
             }
         }
     }
diff --git a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MaterialTextField.kt b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MaterialTextField.kt
index 2440c91..33d7b16 100644
--- a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MaterialTextField.kt
+++ b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MaterialTextField.kt
@@ -180,7 +180,7 @@
                         trailingIcon = {
                             if (trailingChecked) Icon(Icons.Filled.Info, "Info")
                         },
-                        isErrorValue = selectedOption == Option.Error,
+                        isError = selectedOption == Option.Error,
                         modifier = Modifier.requiredWidth(300.dp)
                     )
                 TextFieldType.Outlined ->
@@ -201,7 +201,7 @@
                         trailingIcon = {
                             if (trailingChecked) Icon(Icons.Filled.Info, "Info")
                         },
-                        isErrorValue = selectedOption == Option.Error,
+                        isError = selectedOption == Option.Error,
                         modifier = Modifier.requiredWidth(300.dp)
                     )
             }
diff --git a/compose/material/material/integration-tests/material-studies/src/main/java/androidx/compose/material/studies/rally/TopAppBar.kt b/compose/material/material/integration-tests/material-studies/src/main/java/androidx/compose/material/studies/rally/TopAppBar.kt
index df0166c..27debe0 100644
--- a/compose/material/material/integration-tests/material-studies/src/main/java/androidx/compose/material/studies/rally/TopAppBar.kt
+++ b/compose/material/material/integration-tests/material-studies/src/main/java/androidx/compose/material/studies/rally/TopAppBar.kt
@@ -20,7 +20,7 @@
 import androidx.compose.animation.core.LinearEasing
 import androidx.compose.animation.core.tween
 import androidx.compose.animation.core.updateTransition
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxWidth
@@ -77,7 +77,7 @@
                 .selectable(
                     selected = selected,
                     onClick = onSelected,
-                    interactionState = remember { InteractionState() },
+                    interactionSource = remember { MutableInteractionSource() },
                     indication = rememberRipple(bounded = false)
                 )
         ) {
diff --git a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/ListSamples.kt b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/ListSamples.kt
index f1a1f11..652d8d6 100644
--- a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/ListSamples.kt
+++ b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/ListSamples.kt
@@ -36,7 +36,6 @@
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.semantics.clearAndSetSemantics
 import androidx.compose.ui.unit.dp
 
 @Sampled
@@ -49,13 +48,9 @@
         ListItem(
             text = { Text("Switch ListItem") },
             trailing = {
-                // The [clearAndSetSemantics] causes the switch's redundant
-                // toggleable semantics to be cleared in favor of the [ListItem]
-                // toggleable's, to improve usability with screen-readers.
                 Switch(
-                    modifier = Modifier.clearAndSetSemantics {},
                     checked = switched,
-                    onCheckedChange = onSwitchedChange
+                    onCheckedChange = null // null recommended for accessibility with screenreaders
                 )
             },
             modifier = Modifier.toggleable(
@@ -69,13 +64,9 @@
         ListItem(
             text = { Text("Checkbox ListItem") },
             trailing = {
-                // The [clearAndSetSemantics] causes the checkbox's redundant
-                // toggleable semantics to be cleared in favor of the [ListItem]
-                // toggleable's, to improve usability with screen-readers.
                 Checkbox(
-                    modifier = Modifier.clearAndSetSemantics {},
                     checked = checked,
-                    onCheckedChange = onCheckedChange
+                    onCheckedChange = null // null recommended for accessibility with screenreaders
                 )
             },
             modifier = Modifier.toggleable(
diff --git a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SelectionControlsSamples.kt b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SelectionControlsSamples.kt
index 692020b..6e0dab8 100644
--- a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SelectionControlsSamples.kt
+++ b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SelectionControlsSamples.kt
@@ -23,6 +23,7 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.selection.selectable
+import androidx.compose.foundation.selection.selectableGroup
 import androidx.compose.material.Checkbox
 import androidx.compose.material.CheckboxDefaults
 import androidx.compose.material.MaterialTheme
@@ -37,7 +38,7 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.semantics.clearAndSetSemantics
+import androidx.compose.ui.semantics.Role
 import androidx.compose.ui.state.ToggleableState
 import androidx.compose.ui.unit.dp
 
@@ -101,7 +102,8 @@
 fun RadioButtonSample() {
     // We have two radio buttons and only one can be selected
     var state by remember { mutableStateOf(true) }
-    Row {
+    // Note that Modifier.selectableGroup() is essential to ensure correct accessibility behavior
+    Row(Modifier.selectableGroup()) {
         RadioButton(
             selected = state,
             onClick = { state = true }
@@ -118,7 +120,8 @@
 fun RadioGroupSample() {
     val radioOptions = listOf("Calls", "Missed", "Friends")
     val (selectedOption, onOptionSelected) = remember { mutableStateOf(radioOptions[0]) }
-    Column {
+    // Note that Modifier.selectableGroup() is essential to ensure correct accessibility behavior
+    Column(Modifier.selectableGroup()) {
         radioOptions.forEach { text ->
             Row(
                 Modifier
@@ -126,18 +129,15 @@
                     .height(56.dp)
                     .selectable(
                         selected = (text == selectedOption),
-                        onClick = { onOptionSelected(text) }
+                        onClick = { onOptionSelected(text) },
+                        role = Role.RadioButton
                     )
                     .padding(horizontal = 16.dp),
                 verticalAlignment = Alignment.CenterVertically
             ) {
-                // The [clearAndSetSemantics] causes the button's redundant
-                // selectable semantics to be cleared in favor of the [Row]
-                // selectable's, to improve usability with screen-readers.
                 RadioButton(
-                    modifier = Modifier.clearAndSetSemantics {},
                     selected = (text == selectedOption),
-                    onClick = { onOptionSelected(text) }
+                    onClick = null // null recommended for accessibility with screenreaders
                 )
                 Text(
                     text = text,
diff --git a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SliderSample.kt b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SliderSample.kt
index 7e692cf..98211d5 100644
--- a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SliderSample.kt
+++ b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SliderSample.kt
@@ -19,6 +19,7 @@
 import androidx.annotation.Sampled
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Slider
+import androidx.compose.material.SliderDefaults
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
@@ -48,7 +49,9 @@
             // viewModel.updateSelectedSliderValue(sliderPosition)
         },
         steps = 5,
-        thumbColor = MaterialTheme.colors.secondary,
-        activeTrackColor = MaterialTheme.colors.secondary
+        colors = SliderDefaults.colors(
+            thumbColor = MaterialTheme.colors.secondary,
+            activeTrackColor = MaterialTheme.colors.secondary
+        )
     )
 }
\ No newline at end of file
diff --git a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/TextFieldSamples.kt b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/TextFieldSamples.kt
index 324b6bb..0596f18 100644
--- a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/TextFieldSamples.kt
+++ b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/TextFieldSamples.kt
@@ -36,7 +36,6 @@
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.text.SoftwareKeyboardController
 import androidx.compose.ui.text.TextRange
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.KeyboardType
@@ -109,7 +108,7 @@
             val label = if (isValid) "Email" else "Email*"
             Text(label)
         },
-        isErrorValue = !isValid
+        isError = !isValid
     )
 }
 
@@ -127,7 +126,7 @@
                 val label = if (invalidInput) "Email*" else "Email"
                 Text(label)
             },
-            isErrorValue = invalidInput
+            isError = invalidInput
         )
         val textColor = if (invalidInput) {
             MaterialTheme.colors.error
@@ -186,17 +185,15 @@
 @Sampled
 @Composable
 fun TextFieldWithHideKeyboardOnImeAction() {
+    // TODO(b/1583763): re-add software keyboard controller when replacement API is added
     var text by rememberSaveable { mutableStateOf("") }
-    lateinit var softwareKeyboardController: SoftwareKeyboardController
     TextField(
         value = text,
         onValueChange = { text = it },
         label = { Text("Label") },
-        onTextInputStarted = { softwareKeyboardController = it },
         keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
         keyboardActions = KeyboardActions(
             onDone = {
-                softwareKeyboardController.hideSoftwareKeyboard()
                 // do something here
             }
         )
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BottomNavigationScreenshotTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BottomNavigationScreenshotTest.kt
index c347707..f5801f5 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BottomNavigationScreenshotTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BottomNavigationScreenshotTest.kt
@@ -17,12 +17,14 @@
 package androidx.compose.material
 
 import android.os.Build
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.foundation.layout.Box
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Favorite
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.testutils.assertAgainstGolden
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
@@ -37,6 +39,8 @@
 import androidx.test.filters.LargeTest
 import androidx.test.filters.SdkSuppress
 import androidx.test.screenshot.AndroidXScreenshotTestRule
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -55,18 +59,20 @@
 
     @Test
     fun lightTheme_defaultColors() {
-        val interactionState = InteractionState().apply {
-            addInteraction(Interaction.Pressed)
-        }
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
             MaterialTheme(lightColors()) {
-                DefaultBottomNavigation(interactionState)
+                scope = rememberCoroutineScope()
+                DefaultBottomNavigation(interactionSource)
             }
         }
 
         assertBottomNavigationMatches(
-            interactionState = interactionState,
+            scope = scope!!,
+            interactionSource = interactionSource,
             interaction = null,
             goldenIdentifier = "bottomNavigation_lightTheme_defaultColors"
         )
@@ -74,31 +80,36 @@
 
     @Test
     fun lightTheme_defaultColors_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
             MaterialTheme(lightColors()) {
-                DefaultBottomNavigation(interactionState)
+                scope = rememberCoroutineScope()
+                DefaultBottomNavigation(interactionSource)
             }
         }
 
         assertBottomNavigationMatches(
-            interactionState = interactionState,
-            interaction = Interaction.Pressed,
+            scope = scope!!,
+            interactionSource = interactionSource,
+            interaction = PressInteraction.Press(Offset(10f, 10f)),
             goldenIdentifier = "bottomNavigation_lightTheme_defaultColors_pressed"
         )
     }
 
     @Test
     fun lightTheme_surfaceColors() {
-        val interactionState = InteractionState().apply {
-            addInteraction(Interaction.Pressed)
-        }
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
             MaterialTheme(lightColors()) {
+                scope = rememberCoroutineScope()
                 CustomBottomNavigation(
-                    interactionState,
+                    interactionSource,
                     backgroundColor = MaterialTheme.colors.surface,
                     selectedContentColor = MaterialTheme.colors.primary,
                     unselectedContentColor = MaterialTheme.colors.onSurface
@@ -107,7 +118,8 @@
         }
 
         assertBottomNavigationMatches(
-            interactionState = interactionState,
+            scope = scope!!,
+            interactionSource = interactionSource,
             interaction = null,
             goldenIdentifier = "bottomNavigation_lightTheme_surfaceColors"
         )
@@ -115,12 +127,15 @@
 
     @Test
     fun lightTheme_surfaceColors_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
             MaterialTheme(lightColors()) {
+                scope = rememberCoroutineScope()
                 CustomBottomNavigation(
-                    interactionState,
+                    interactionSource,
                     backgroundColor = MaterialTheme.colors.surface,
                     selectedContentColor = MaterialTheme.colors.primary,
                     unselectedContentColor = MaterialTheme.colors.onSurface
@@ -129,26 +144,29 @@
         }
 
         assertBottomNavigationMatches(
-            interactionState = interactionState,
-            interaction = Interaction.Pressed,
+            scope = scope!!,
+            interactionSource = interactionSource,
+            interaction = PressInteraction.Press(Offset(10f, 10f)),
             goldenIdentifier = "bottomNavigation_lightTheme_surfaceColors_pressed"
         )
     }
 
     @Test
     fun darkTheme_defaultColors() {
-        val interactionState = InteractionState().apply {
-            addInteraction(Interaction.Pressed)
-        }
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
             MaterialTheme(darkColors()) {
-                DefaultBottomNavigation(interactionState)
+                scope = rememberCoroutineScope()
+                DefaultBottomNavigation(interactionSource)
             }
         }
 
         assertBottomNavigationMatches(
-            interactionState = interactionState,
+            scope = scope!!,
+            interactionSource = interactionSource,
             interaction = null,
             goldenIdentifier = "bottomNavigation_darkTheme_defaultColors"
         )
@@ -156,17 +174,21 @@
 
     @Test
     fun darkTheme_defaultColors_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
             MaterialTheme(darkColors()) {
-                DefaultBottomNavigation(interactionState)
+                scope = rememberCoroutineScope()
+                DefaultBottomNavigation(interactionSource)
             }
         }
 
         assertBottomNavigationMatches(
-            interactionState = interactionState,
-            interaction = Interaction.Pressed,
+            scope = scope!!,
+            interactionSource = interactionSource,
+            interaction = PressInteraction.Press(Offset(10f, 10f)),
             goldenIdentifier = "bottomNavigation_darkTheme_defaultColors_pressed"
         )
     }
@@ -176,14 +198,15 @@
     // matches that use case.
     @Test
     fun darkTheme_surfaceColors() {
-        val interactionState = InteractionState().apply {
-            addInteraction(Interaction.Pressed)
-        }
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
             MaterialTheme(darkColors()) {
+                scope = rememberCoroutineScope()
                 CustomBottomNavigation(
-                    interactionState,
+                    interactionSource,
                     backgroundColor = MaterialTheme.colors.surface,
                     selectedContentColor = MaterialTheme.colors.primary,
                     unselectedContentColor = MaterialTheme.colors.onSurface
@@ -192,7 +215,8 @@
         }
 
         assertBottomNavigationMatches(
-            interactionState = interactionState,
+            scope = scope!!,
+            interactionSource = interactionSource,
             interaction = null,
             goldenIdentifier = "bottomNavigation_darkTheme_surfaceColors"
         )
@@ -200,12 +224,15 @@
 
     @Test
     fun darkTheme_surfaceColors_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
             MaterialTheme(darkColors()) {
+                scope = rememberCoroutineScope()
                 CustomBottomNavigation(
-                    interactionState,
+                    interactionSource,
                     backgroundColor = MaterialTheme.colors.surface,
                     selectedContentColor = MaterialTheme.colors.primary,
                     unselectedContentColor = MaterialTheme.colors.onSurface
@@ -214,22 +241,24 @@
         }
 
         assertBottomNavigationMatches(
-            interactionState = interactionState,
-            interaction = Interaction.Pressed,
+            scope = scope!!,
+            interactionSource = interactionSource,
+            interaction = PressInteraction.Press(Offset(10f, 10f)),
             goldenIdentifier = "bottomNavigation_darkTheme_surfaceColors_pressed"
         )
     }
 
     @Test
     fun darkTheme_primaryColors() {
-        val interactionState = InteractionState().apply {
-            addInteraction(Interaction.Pressed)
-        }
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
             MaterialTheme(darkColors()) {
+                scope = rememberCoroutineScope()
                 CustomBottomNavigation(
-                    interactionState,
+                    interactionSource,
                     backgroundColor = MaterialTheme.colors.primary,
                     selectedContentColor = MaterialTheme.colors.onPrimary,
                     unselectedContentColor = MaterialTheme.colors.onPrimary
@@ -238,7 +267,8 @@
         }
 
         assertBottomNavigationMatches(
-            interactionState = interactionState,
+            scope = scope!!,
+            interactionSource = interactionSource,
             interaction = null,
             goldenIdentifier = "bottomNavigation_darkTheme_primaryColors"
         )
@@ -246,12 +276,15 @@
 
     @Test
     fun darkTheme_primaryColors_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
             MaterialTheme(darkColors()) {
+                scope = rememberCoroutineScope()
                 CustomBottomNavigation(
-                    interactionState,
+                    interactionSource,
                     backgroundColor = MaterialTheme.colors.primary,
                     selectedContentColor = MaterialTheme.colors.onPrimary,
                     unselectedContentColor = MaterialTheme.colors.onPrimary
@@ -260,8 +293,9 @@
         }
 
         assertBottomNavigationMatches(
-            interactionState = interactionState,
-            interaction = Interaction.Pressed,
+            scope = scope!!,
+            interactionSource = interactionSource,
+            interaction = PressInteraction.Press(Offset(10f, 10f)),
             goldenIdentifier = "bottomNavigation_darkTheme_primaryColors_pressed"
         )
     }
@@ -269,12 +303,15 @@
     /**
      * Asserts that the BottomNavigation matches the screenshot with identifier [goldenIdentifier].
      *
-     * @param interactionState the [InteractionState] used for the first BottomNavigationItem
+     * @param scope [CoroutineScope] used to interact with [MutableInteractionSource]
+     * @param interactionSource the [MutableInteractionSource] used for the first
+     * BottomNavigationItem
      * @param interaction the [Interaction] to assert for, or `null` if no [Interaction].
      * @param goldenIdentifier the identifier for the corresponding screenshot
      */
     private fun assertBottomNavigationMatches(
-        interactionState: InteractionState,
+        scope: CoroutineScope,
+        interactionSource: MutableInteractionSource,
         interaction: Interaction? = null,
         goldenIdentifier: String
     ) {
@@ -282,12 +319,8 @@
 
         if (interaction != null) {
             // Start ripple
-            composeTestRule.runOnUiThread {
-                if (interaction is Interaction.Pressed) {
-                    interactionState.addInteraction(interaction, Offset(10f, 10f))
-                } else {
-                    interactionState.addInteraction(interaction)
-                }
+            scope.launch {
+                interactionSource.emit(interaction)
             }
 
             // Advance to somewhere in the middle of the animation for the ripple
@@ -306,12 +339,12 @@
  * Default colored [BottomNavigation] with three [BottomNavigationItem]s. The first
  * [BottomNavigationItem] is selected, and the rest are not.
  *
- * @param interactionState the [InteractionState] for the first [BottomNavigationItem], to control
- * its visual state.
+ * @param interactionSource the [MutableInteractionSource] for the first [BottomNavigationItem], to
+ * control its visual state.
  */
 @Composable
 private fun DefaultBottomNavigation(
-    interactionState: InteractionState
+    interactionSource: MutableInteractionSource
 ) {
     Box(Modifier.semantics(mergeDescendants = true) {}.testTag(Tag)) {
         BottomNavigation {
@@ -319,7 +352,7 @@
                 icon = { Icon(Icons.Filled.Favorite, null) },
                 selected = true,
                 onClick = {},
-                interactionState = interactionState
+                interactionSource = interactionSource
             )
             BottomNavigationItem(
                 icon = { Icon(Icons.Filled.Favorite, null) },
@@ -339,8 +372,8 @@
  * Custom colored [BottomNavigation] with three [BottomNavigationItem]s. The first
  * [BottomNavigationItem] is selected, and the rest are not.
  *
- * @param interactionState the [InteractionState] for the first [BottomNavigationItem], to control
- * its visual state.
+ * @param interactionSource the [MutableInteractionSource] for the first [BottomNavigationItem], to
+ * control its visual state.
  * @param backgroundColor the backgroundColor of the [BottomNavigation]
  * @param selectedContentColor the content color for a selected [BottomNavigationItem] (first item)
  * @param unselectedContentColor the content color for an unselected [BottomNavigationItem] (second
@@ -348,7 +381,7 @@
  */
 @Composable
 private fun CustomBottomNavigation(
-    interactionState: InteractionState,
+    interactionSource: MutableInteractionSource,
     backgroundColor: Color,
     selectedContentColor: Color,
     unselectedContentColor: Color
@@ -362,7 +395,7 @@
                 icon = { Icon(Icons.Filled.Favorite, null) },
                 selected = true,
                 onClick = {},
-                interactionState = interactionState,
+                interactionSource = interactionSource,
                 selectedContentColor = selectedContentColor,
                 unselectedContentColor = unselectedContentColor
             )
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BottomNavigationTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BottomNavigationTest.kt
index bbb0198..7af8d54 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BottomNavigationTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BottomNavigationTest.kt
@@ -19,6 +19,7 @@
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Favorite
 import androidx.compose.material.samples.BottomNavigationSample
+import androidx.compose.testutils.assertIsEqualTo
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.layout.LayoutCoordinates
 import androidx.compose.ui.layout.onGloballyPositioned
@@ -32,7 +33,6 @@
 import androidx.compose.ui.test.assertHasClickAction
 import androidx.compose.ui.test.assertHeightIsEqualTo
 import androidx.compose.ui.test.assertIsEnabled
-import androidx.compose.ui.test.assertIsEqualTo
 import androidx.compose.ui.test.assertIsNotDisplayed
 import androidx.compose.ui.test.assertIsNotEnabled
 import androidx.compose.ui.test.assertIsNotSelected
@@ -45,6 +45,7 @@
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.test.onParent
 import androidx.compose.ui.test.performClick
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.height
@@ -88,6 +89,10 @@
             .assertIsSelected()
             .assertIsEnabled()
             .assertHasClickAction()
+
+        rule.onNodeWithTag("item")
+            .onParent()
+            .assert(SemanticsMatcher.keyIsDefined(SemanticsProperties.SelectableGroup))
     }
 
     @Test
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BottomSheetScaffoldTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BottomSheetScaffoldTest.kt
index 06883ab..e4279ca 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BottomSheetScaffoldTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BottomSheetScaffoldTest.kt
@@ -293,7 +293,7 @@
                         Box(
                             Modifier
                                 .onGloballyPositioned { positioned: LayoutCoordinates ->
-                                    drawerChildPosition = positioned.positionInParent
+                                    drawerChildPosition = positioned.positionInParent()
                                 }
                                 .fillMaxWidth()
                                 .height(50.dp)
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/CheckboxUiTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/CheckboxUiTest.kt
index 12767ff..af7baf4 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/CheckboxUiTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/CheckboxUiTest.kt
@@ -15,6 +15,7 @@
  */
 package androidx.compose.material
 
+import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
@@ -22,17 +23,22 @@
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.semantics.SemanticsProperties
 import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.focused
+import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.state.ToggleableState
 import androidx.compose.ui.state.ToggleableState.Indeterminate
 import androidx.compose.ui.state.ToggleableState.Off
 import androidx.compose.ui.state.ToggleableState.On
 import androidx.compose.ui.test.assertHasClickAction
+import androidx.compose.ui.test.assertHasNoClickAction
 import androidx.compose.ui.test.SemanticsMatcher
 import androidx.compose.ui.test.assert
 import androidx.compose.ui.test.assertIsEnabled
 import androidx.compose.ui.test.assertIsOff
 import androidx.compose.ui.test.assertIsOn
 import androidx.compose.ui.test.assertValueEquals
+import androidx.compose.ui.test.isFocusable
+import androidx.compose.ui.test.isNotFocusable
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performClick
@@ -103,15 +109,45 @@
     }
 
     @Test
-    fun checkBoxTest_untoggleable_whenNoLambda() {
+    fun checkBoxTest_untoggleable_whenEmptyLambda() {
+        val parentTag = "parent"
 
         rule.setMaterialContent {
             val (checked, _) = remember { mutableStateOf(false) }
-            Checkbox(checked, {}, enabled = false, modifier = Modifier.testTag(defaultTag))
+            Box(Modifier.semantics(mergeDescendants = true) {}.testTag(parentTag)) {
+                Checkbox(
+                    checked,
+                    {},
+                    enabled = false,
+                    modifier = Modifier.testTag(defaultTag).semantics { focused = true }
+                )
+            }
         }
 
         rule.onNodeWithTag(defaultTag)
             .assertHasClickAction()
+
+        // Check not merged into parent
+        rule.onNodeWithTag(parentTag)
+            .assert(isNotFocusable())
+    }
+
+    @Test
+    fun checkBoxTest_untoggleableAndMergeable_whenNullLambda() {
+        rule.setMaterialContent {
+            val (checked, _) = remember { mutableStateOf(false) }
+            Box(Modifier.semantics(mergeDescendants = true) {}.testTag(defaultTag)) {
+                Checkbox(
+                    checked,
+                    null,
+                    modifier = Modifier.semantics { focused = true }
+                )
+            }
+        }
+
+        rule.onNodeWithTag(defaultTag)
+            .assertHasNoClickAction()
+            .assert(isFocusable()) // Check merged into parent
     }
 
     @Test
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/MaterialRippleThemeTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/MaterialRippleThemeTest.kt
index d9c2ca1..a69e05a 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/MaterialRippleThemeTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/MaterialRippleThemeTest.kt
@@ -17,9 +17,11 @@
 package androidx.compose.material
 
 import android.os.Build
+import androidx.compose.foundation.interaction.DragInteraction
 import androidx.compose.foundation.Indication
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.foundation.indication
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
@@ -27,7 +29,6 @@
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.ripple.ExperimentalRippleApi
 import androidx.compose.material.ripple.LocalRippleTheme
 import androidx.compose.material.ripple.RippleAlpha
 import androidx.compose.material.ripple.RippleTheme
@@ -36,6 +37,7 @@
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
 import androidx.compose.testutils.assertAgainstGolden
 import androidx.compose.ui.Alignment
@@ -46,7 +48,6 @@
 import androidx.compose.ui.graphics.compositeOver
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.semantics.semantics
-import androidx.compose.ui.test.ExperimentalTestApi
 import androidx.compose.ui.test.captureToImage
 import androidx.compose.ui.test.junit4.ComposeContentTestRule
 import androidx.compose.ui.test.junit4.createComposeRule
@@ -57,6 +58,8 @@
 import androidx.test.filters.SdkSuppress
 import androidx.test.screenshot.AndroidXScreenshotTestRule
 import com.google.common.truth.Truth
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -68,7 +71,6 @@
 @LargeTest
 @RunWith(AndroidJUnit4::class)
 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
-@OptIn(ExperimentalMaterialApi::class, ExperimentalTestApi::class, ExperimentalRippleApi::class)
 class MaterialRippleThemeTest {
 
     @get:Rule
@@ -79,20 +81,21 @@
 
     @Test
     fun bounded_lightTheme_highLuminance_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.White
 
-        rule.setRippleContent(
-            interactionState = interactionState,
+        val scope = rule.setRippleContent(
+            interactionSource = interactionSource,
             bounded = true,
             lightTheme = true,
             contentColor = contentColor
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Pressed,
+            scope,
+            interactionSource,
+            PressInteraction.Press(Offset(10f, 10f)),
             "ripple_bounded_light_highluminance_pressed",
             calculateResultingRippleColor(contentColor, rippleOpacity = 0.24f)
         )
@@ -100,20 +103,21 @@
 
     @Test
     fun bounded_lightTheme_highLuminance_dragged() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.White
 
-        rule.setRippleContent(
-            interactionState = interactionState,
+        val scope = rule.setRippleContent(
+            interactionSource = interactionSource,
             bounded = true,
             lightTheme = true,
             contentColor = contentColor
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Dragged,
+            scope,
+            interactionSource,
+            DragInteraction.Start(),
             "ripple_bounded_light_highluminance_dragged",
             calculateResultingRippleColor(contentColor, rippleOpacity = 0.16f)
         )
@@ -121,20 +125,21 @@
 
     @Test
     fun bounded_lightTheme_lowLuminance_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.Black
 
-        rule.setRippleContent(
-            interactionState = interactionState,
+        val scope = rule.setRippleContent(
+            interactionSource = interactionSource,
             bounded = true,
             lightTheme = true,
             contentColor = contentColor
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Pressed,
+            scope,
+            interactionSource,
+            PressInteraction.Press(Offset(10f, 10f)),
             "ripple_bounded_light_lowluminance_pressed",
             calculateResultingRippleColor(contentColor, rippleOpacity = 0.12f)
         )
@@ -142,20 +147,21 @@
 
     @Test
     fun bounded_lightTheme_lowLuminance_dragged() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.Black
 
-        rule.setRippleContent(
-            interactionState = interactionState,
+        val scope = rule.setRippleContent(
+            interactionSource = interactionSource,
             bounded = true,
             lightTheme = true,
             contentColor = contentColor
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Dragged,
+            scope,
+            interactionSource,
+            DragInteraction.Start(),
             "ripple_bounded_light_lowluminance_dragged",
             calculateResultingRippleColor(contentColor, rippleOpacity = 0.08f)
         )
@@ -163,20 +169,21 @@
 
     @Test
     fun bounded_darkTheme_highLuminance_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.White
 
-        rule.setRippleContent(
-            interactionState = interactionState,
+        val scope = rule.setRippleContent(
+            interactionSource = interactionSource,
             bounded = true,
             lightTheme = false,
             contentColor = contentColor
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Pressed,
+            scope,
+            interactionSource,
+            PressInteraction.Press(Offset(10f, 10f)),
             "ripple_bounded_dark_highluminance_pressed",
             calculateResultingRippleColor(contentColor, rippleOpacity = 0.10f)
         )
@@ -184,20 +191,21 @@
 
     @Test
     fun bounded_darkTheme_highLuminance_dragged() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.White
 
-        rule.setRippleContent(
-            interactionState = interactionState,
+        val scope = rule.setRippleContent(
+            interactionSource = interactionSource,
             bounded = true,
             lightTheme = false,
             contentColor = contentColor
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Dragged,
+            scope,
+            interactionSource,
+            DragInteraction.Start(),
             "ripple_bounded_dark_highluminance_dragged",
             calculateResultingRippleColor(contentColor, rippleOpacity = 0.08f)
         )
@@ -205,20 +213,21 @@
 
     @Test
     fun bounded_darkTheme_lowLuminance_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.Black
 
-        rule.setRippleContent(
-            interactionState = interactionState,
+        val scope = rule.setRippleContent(
+            interactionSource = interactionSource,
             bounded = true,
             lightTheme = false,
             contentColor = contentColor
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Pressed,
+            scope,
+            interactionSource,
+            PressInteraction.Press(Offset(10f, 10f)),
             "ripple_bounded_dark_lowluminance_pressed",
             // Low luminance content in dark theme should use a white ripple by default
             calculateResultingRippleColor(Color.White, rippleOpacity = 0.10f)
@@ -227,20 +236,21 @@
 
     @Test
     fun bounded_darkTheme_lowLuminance_dragged() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.Black
 
-        rule.setRippleContent(
-            interactionState = interactionState,
+        val scope = rule.setRippleContent(
+            interactionSource = interactionSource,
             bounded = true,
             lightTheme = false,
             contentColor = contentColor
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Dragged,
+            scope,
+            interactionSource,
+            DragInteraction.Start(),
             "ripple_bounded_dark_lowluminance_dragged",
             // Low luminance content in dark theme should use a white ripple by default
             calculateResultingRippleColor(Color.White, rippleOpacity = 0.08f)
@@ -249,20 +259,21 @@
 
     @Test
     fun unbounded_lightTheme_highLuminance_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.White
 
-        rule.setRippleContent(
-            interactionState = interactionState,
+        val scope = rule.setRippleContent(
+            interactionSource = interactionSource,
             bounded = false,
             lightTheme = true,
             contentColor = contentColor
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Pressed,
+            scope,
+            interactionSource,
+            PressInteraction.Press(Offset(10f, 10f)),
             "ripple_unbounded_light_highluminance_pressed",
             calculateResultingRippleColor(contentColor, rippleOpacity = 0.24f)
         )
@@ -270,20 +281,21 @@
 
     @Test
     fun unbounded_lightTheme_highLuminance_dragged() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.White
 
-        rule.setRippleContent(
-            interactionState = interactionState,
+        val scope = rule.setRippleContent(
+            interactionSource = interactionSource,
             bounded = false,
             lightTheme = true,
             contentColor = contentColor
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Dragged,
+            scope,
+            interactionSource,
+            DragInteraction.Start(),
             "ripple_unbounded_light_highluminance_dragged",
             calculateResultingRippleColor(contentColor, rippleOpacity = 0.16f)
         )
@@ -291,20 +303,21 @@
 
     @Test
     fun unbounded_lightTheme_lowLuminance_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.Black
 
-        rule.setRippleContent(
-            interactionState = interactionState,
+        val scope = rule.setRippleContent(
+            interactionSource = interactionSource,
             bounded = false,
             lightTheme = true,
             contentColor = contentColor
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Pressed,
+            scope,
+            interactionSource,
+            PressInteraction.Press(Offset(10f, 10f)),
             "ripple_unbounded_light_lowluminance_pressed",
             calculateResultingRippleColor(contentColor, rippleOpacity = 0.12f)
         )
@@ -312,20 +325,21 @@
 
     @Test
     fun unbounded_lightTheme_lowLuminance_dragged() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.Black
 
-        rule.setRippleContent(
-            interactionState = interactionState,
+        val scope = rule.setRippleContent(
+            interactionSource = interactionSource,
             bounded = false,
             lightTheme = true,
             contentColor = contentColor
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Dragged,
+            scope,
+            interactionSource,
+            DragInteraction.Start(),
             "ripple_unbounded_light_lowluminance_dragged",
             calculateResultingRippleColor(contentColor, rippleOpacity = 0.08f)
         )
@@ -333,20 +347,21 @@
 
     @Test
     fun unbounded_darkTheme_highLuminance_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.White
 
-        rule.setRippleContent(
-            interactionState = interactionState,
+        val scope = rule.setRippleContent(
+            interactionSource = interactionSource,
             bounded = false,
             lightTheme = false,
             contentColor = contentColor
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Pressed,
+            scope,
+            interactionSource,
+            PressInteraction.Press(Offset(10f, 10f)),
             "ripple_unbounded_dark_highluminance_pressed",
             calculateResultingRippleColor(contentColor, rippleOpacity = 0.10f)
         )
@@ -354,20 +369,21 @@
 
     @Test
     fun unbounded_darkTheme_highLuminance_dragged() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.White
 
-        rule.setRippleContent(
-            interactionState = interactionState,
+        val scope = rule.setRippleContent(
+            interactionSource = interactionSource,
             bounded = false,
             lightTheme = false,
             contentColor = contentColor
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Dragged,
+            scope,
+            interactionSource,
+            DragInteraction.Start(),
             "ripple_unbounded_dark_highluminance_dragged",
             calculateResultingRippleColor(contentColor, rippleOpacity = 0.08f)
         )
@@ -375,20 +391,21 @@
 
     @Test
     fun unbounded_darkTheme_lowLuminance_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.Black
 
-        rule.setRippleContent(
-            interactionState = interactionState,
+        val scope = rule.setRippleContent(
+            interactionSource = interactionSource,
             bounded = false,
             lightTheme = false,
             contentColor = contentColor
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Pressed,
+            scope,
+            interactionSource,
+            PressInteraction.Press(Offset(10f, 10f)),
             "ripple_unbounded_dark_lowluminance_pressed",
             // Low luminance content in dark theme should use a white ripple by default
             calculateResultingRippleColor(Color.White, rippleOpacity = 0.10f)
@@ -397,20 +414,21 @@
 
     @Test
     fun unbounded_darkTheme_lowLuminance_dragged() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.Black
 
-        rule.setRippleContent(
-            interactionState = interactionState,
+        val scope = rule.setRippleContent(
+            interactionSource = interactionSource,
             bounded = false,
             lightTheme = false,
             contentColor = contentColor
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Dragged,
+            scope,
+            interactionSource,
+            DragInteraction.Start(),
             "ripple_unbounded_dark_lowluminance_dragged",
             // Low luminance content in dark theme should use a white ripple by default
             calculateResultingRippleColor(Color.White, rippleOpacity = 0.08f)
@@ -419,13 +437,13 @@
 
     @Test
     fun customRippleTheme_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.Black
 
         val rippleColor = Color.Red
         val expectedAlpha = 0.5f
-        val rippleAlpha = RippleAlpha { expectedAlpha }
+        val rippleAlpha = RippleAlpha(expectedAlpha, expectedAlpha, expectedAlpha, expectedAlpha)
 
         val rippleTheme = object : RippleTheme {
             @Composable
@@ -435,12 +453,15 @@
             override fun rippleAlpha() = rippleAlpha
         }
 
+        var scope: CoroutineScope? = null
+
         rule.setContent {
+            scope = rememberCoroutineScope()
             MaterialTheme {
                 CompositionLocalProvider(LocalRippleTheme provides rippleTheme) {
                     Surface(contentColor = contentColor) {
                         Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
-                            RippleBox(interactionState, rememberRipple())
+                            RippleBox(interactionSource, rememberRipple())
                         }
                     }
                 }
@@ -453,8 +474,9 @@
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Pressed,
+            scope!!,
+            interactionSource,
+            PressInteraction.Press(Offset(10f, 10f)),
             "ripple_customtheme_pressed",
             expectedColor
         )
@@ -462,13 +484,13 @@
 
     @Test
     fun customRippleTheme_dragged() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val contentColor = Color.Black
 
         val rippleColor = Color.Red
         val expectedAlpha = 0.5f
-        val rippleAlpha = RippleAlpha { 0.5f }
+        val rippleAlpha = RippleAlpha(expectedAlpha, expectedAlpha, expectedAlpha, expectedAlpha)
 
         val rippleTheme = object : RippleTheme {
             @Composable
@@ -477,12 +499,15 @@
             override fun rippleAlpha() = rippleAlpha
         }
 
+        var scope: CoroutineScope? = null
+
         rule.setContent {
+            scope = rememberCoroutineScope()
             MaterialTheme {
                 CompositionLocalProvider(LocalRippleTheme provides rippleTheme) {
                     Surface(contentColor = contentColor) {
                         Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
-                            RippleBox(interactionState, rememberRipple())
+                            RippleBox(interactionSource, rememberRipple())
                         }
                     }
                 }
@@ -495,19 +520,20 @@
         )
 
         assertRippleMatches(
-            interactionState,
-            Interaction.Dragged,
+            scope!!,
+            interactionSource,
+            DragInteraction.Start(),
             "ripple_customtheme_dragged",
             expectedColor
         )
     }
 
     @Test
-    fun themeChangeDuringRipple() {
-        val interactionState = InteractionState()
+    fun themeChangeDuringRipple_dragged() {
+        val interactionSource = MutableInteractionSource()
 
         fun createRippleTheme(color: Color, alpha: Float) = object : RippleTheme {
-            val rippleAlpha = RippleAlpha { alpha }
+            val rippleAlpha = RippleAlpha(alpha, alpha, alpha, alpha)
             @Composable
             override fun defaultColor() = color
 
@@ -520,21 +546,100 @@
 
         var rippleTheme by mutableStateOf(createRippleTheme(initialColor, initialAlpha))
 
+        var scope: CoroutineScope? = null
+
         rule.setContent {
+            scope = rememberCoroutineScope()
             MaterialTheme {
                 CompositionLocalProvider(LocalRippleTheme provides rippleTheme) {
                     Surface(contentColor = Color.Black) {
                         Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
-                            RippleBox(interactionState, rememberRipple())
+                            RippleBox(interactionSource, rememberRipple())
                         }
                     }
                 }
             }
         }
 
-        rule.runOnUiThread {
-            interactionState.addInteraction(Interaction.Pressed, Offset(10f, 10f))
+        rule.runOnIdle {
+            scope!!.launch {
+                interactionSource.emit(DragInteraction.Start())
+            }
         }
+        rule.waitForIdle()
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            val expectedColor =
+                calculateResultingRippleColor(initialColor, rippleOpacity = initialAlpha)
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+
+        val newColor = Color.Green
+        // TODO: changing alpha for existing state layers is not currently supported
+        val newAlpha = 0.5f
+
+        rule.runOnUiThread {
+            rippleTheme = createRippleTheme(newColor, newAlpha)
+        }
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            val expectedColor =
+                calculateResultingRippleColor(newColor, rippleOpacity = newAlpha)
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+    }
+
+    @Test
+    fun themeChangeDuringRipple_pressed() {
+        val interactionSource = MutableInteractionSource()
+
+        fun createRippleTheme(color: Color, alpha: Float) = object : RippleTheme {
+            val rippleAlpha = RippleAlpha(alpha, alpha, alpha, alpha)
+            @Composable
+            override fun defaultColor() = color
+
+            @Composable
+            override fun rippleAlpha() = rippleAlpha
+        }
+
+        val initialColor = Color.Red
+        val initialAlpha = 0.5f
+
+        var rippleTheme by mutableStateOf(createRippleTheme(initialColor, initialAlpha))
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            MaterialTheme {
+                CompositionLocalProvider(LocalRippleTheme provides rippleTheme) {
+                    Surface(contentColor = Color.Black) {
+                        Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                            RippleBox(interactionSource, rememberRipple())
+                        }
+                    }
+                }
+            }
+        }
+
+        rule.runOnIdle {
+            scope!!.launch {
+                interactionSource.emit(PressInteraction.Press(Offset.Zero))
+            }
+        }
+        rule.waitForIdle()
 
         with(rule.onNodeWithTag(Tag)) {
             val centerPixel = captureToImage().asAndroidBitmap()
@@ -570,10 +675,10 @@
 
     @Test
     fun contentColorProvidedAfterRememberRipple() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
 
         val alpha = 0.5f
-        val rippleAlpha = RippleAlpha { 0.5f }
+        val rippleAlpha = RippleAlpha(alpha, alpha, alpha, alpha)
         val expectedRippleColor = Color.Red
 
         val theme = object : RippleTheme {
@@ -584,7 +689,10 @@
             override fun rippleAlpha() = rippleAlpha
         }
 
+        var scope: CoroutineScope? = null
+
         rule.setContent {
+            scope = rememberCoroutineScope()
             MaterialTheme {
                 CompositionLocalProvider(LocalRippleTheme provides theme) {
                     Surface(contentColor = Color.Black) {
@@ -594,7 +702,7 @@
                             Surface(contentColor = expectedRippleColor) {
                                 // Ripple is used where contentColor is red, so the instance
                                 // should get the red color when it is created
-                                RippleBox(interactionState, ripple)
+                                RippleBox(interactionSource, ripple)
                             }
                         }
                     }
@@ -603,7 +711,9 @@
         }
 
         rule.runOnUiThread {
-            interactionState.addInteraction(Interaction.Pressed, Offset(10f, 10f))
+            scope!!.launch {
+                interactionSource.emit(PressInteraction.Press(Offset(10f, 10f)))
+            }
         }
 
         with(rule.onNodeWithTag(Tag)) {
@@ -623,14 +733,15 @@
      * Asserts that the ripple matches the screenshot with identifier [goldenIdentifier], and
      * that the resultant color of the ripple on screen matches [expectedCenterPixelColor].
      *
-     * @param interactionState the [InteractionState] driving the ripple
+     * @param interactionSource the [MutableInteractionSource] driving the ripple
      * @param interaction the [Interaction] to assert for
      * @param goldenIdentifier the identifier for the corresponding screenshot
      * @param expectedCenterPixelColor the expected color for the pixel at the center of the
      * [RippleBox]
      */
     private fun assertRippleMatches(
-        interactionState: InteractionState,
+        scope: CoroutineScope,
+        interactionSource: MutableInteractionSource,
         interaction: Interaction,
         goldenIdentifier: String,
         expectedCenterPixelColor: Color
@@ -638,12 +749,8 @@
         rule.mainClock.autoAdvance = false
 
         // Start ripple
-        rule.runOnUiThread {
-            if (interaction is Interaction.Pressed) {
-                interactionState.addInteraction(interaction, Offset(10f, 10f))
-            } else {
-                interactionState.addInteraction(interaction)
-            }
+        scope.launch {
+            interactionSource.emit(interaction)
         }
 
         // Advance to somewhere in the middle of the animation for a ripple, or at the end of a
@@ -675,11 +782,11 @@
  * Generic Button like component that allows injecting an [Indication] and also includes
  * padding around the rippled surface, so screenshots will include some dead space for clarity.
  *
- * @param interactionState the [InteractionState] that is used to drive the ripple state
+ * @param interactionSource the [MutableInteractionSource] that is used to drive the ripple state
  * @param ripple ripple [Indication] placed inside the surface
  */
 @Composable
-private fun RippleBox(interactionState: InteractionState, ripple: Indication) {
+private fun RippleBox(interactionSource: MutableInteractionSource, ripple: Indication) {
     Box(Modifier.semantics(mergeDescendants = true) {}.testTag(Tag)) {
         Surface(
             Modifier.padding(25.dp),
@@ -687,7 +794,7 @@
         ) {
             Box(
                 Modifier.width(80.dp).height(50.dp).indication(
-                    interactionState = interactionState,
+                    interactionSource = interactionSource,
                     indication = ripple
                 )
             )
@@ -698,28 +805,33 @@
 /**
  * Sets the content to a [RippleBox] with a [MaterialTheme] and surrounding [Surface]
  *
- * @param interactionState [InteractionState] used to drive the ripple inside the [RippleBox]
+ * @param interactionSource [MutableInteractionSource] used to drive the ripple inside the [RippleBox]
  * @param bounded whether the ripple inside the [RippleBox] is bounded
  * @param lightTheme whether the theme is light or dark
  * @param contentColor the contentColor that will be used for the ripple color
  */
 private fun ComposeContentTestRule.setRippleContent(
-    interactionState: InteractionState,
+    interactionSource: MutableInteractionSource,
     bounded: Boolean,
     lightTheme: Boolean,
     contentColor: Color
-) {
+): CoroutineScope {
+    var scope: CoroutineScope? = null
+
     setContent {
+        scope = rememberCoroutineScope()
         val colors = if (lightTheme) lightColors() else darkColors()
 
         MaterialTheme(colors) {
             Surface(contentColor = contentColor) {
                 Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
-                    RippleBox(interactionState, rememberRipple(bounded))
+                    RippleBox(interactionSource, rememberRipple(bounded))
                 }
             }
         }
     }
+    waitForIdle()
+    return scope!!
 }
 
 /**
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/MaterialTextSelectionColorsScreenshotTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/MaterialTextSelectionColorsScreenshotTest.kt
index 97d55b4..a1adf38 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/MaterialTextSelectionColorsScreenshotTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/MaterialTextSelectionColorsScreenshotTest.kt
@@ -18,14 +18,14 @@
 
 import android.os.Build
 import androidx.compose.foundation.layout.requiredWidth
+import androidx.compose.foundation.text.selection.SelectionContainer
+import androidx.compose.foundation.text.selection.TextSelectionColors
 import androidx.compose.runtime.Composable
 import androidx.compose.testutils.assertAgainstGolden
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.platform.testTag
-import androidx.compose.foundation.text.selection.SelectionContainer
-import androidx.compose.foundation.text.selection.TextSelectionColors
 import androidx.compose.ui.test.captureToImage
 import androidx.compose.ui.test.click
 import androidx.compose.ui.test.height
@@ -87,6 +87,7 @@
             .isEqualTo(darkPrimary.copy(alpha = 0.375f))
     }
 
+    @FlakyTest(bugId = 179770443)
     @Test
     fun text_lightThemeSelectionColors() {
         rule.setContent {
@@ -105,6 +106,7 @@
             .assertAgainstGolden(screenshotRule, "text_lightThemeSelectionColors")
     }
 
+    @FlakyTest(bugId = 179770443)
     @Test
     fun text_darkThemeSelectionColors() {
         rule.setContent {
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/RadioButtonTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/RadioButtonTest.kt
index 38d3c90..a3d6852 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/RadioButtonTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/RadioButtonTest.kt
@@ -22,12 +22,16 @@
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.semantics.SemanticsProperties
 import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.focused
+import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.test.SemanticsMatcher
 import androidx.compose.ui.test.SemanticsNodeInteraction
 import androidx.compose.ui.test.assert
+import androidx.compose.ui.test.assertHasNoClickAction
 import androidx.compose.ui.test.assertIsNotSelected
 import androidx.compose.ui.test.assertIsSelected
 import androidx.compose.ui.test.assertValueEquals
+import androidx.compose.ui.test.isFocusable
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performClick
@@ -146,6 +150,24 @@
     }
 
     @Test
+    fun radioGroup_untoggleableAndMergeable_whenNullLambda() {
+        val parentTag = "parent"
+        rule.setMaterialContent {
+            Column(Modifier.semantics(mergeDescendants = true) {}.testTag(parentTag)) {
+                RadioButton(
+                    selected = true,
+                    onClick = null,
+                    modifier = Modifier.semantics { focused = true }
+                )
+            }
+        }
+
+        rule.onNodeWithTag(parentTag)
+            .assertHasNoClickAction()
+            .assert(isFocusable()) // Check merged into parent
+    }
+
+    @Test
     @LargeTest
     fun radioGroupTest_clickSelectTwoDifferentItems() {
         val selected = mutableStateOf(itemOne)
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ScaffoldTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ScaffoldTest.kt
index ed44892..fc2e7b46e 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ScaffoldTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ScaffoldTest.kt
@@ -92,11 +92,11 @@
             Scaffold {
                 Text(
                     "One",
-                    Modifier.onGloballyPositioned { child1 = it.positionInParent }
+                    Modifier.onGloballyPositioned { child1 = it.positionInParent() }
                 )
                 Text(
                     "Two",
-                    Modifier.onGloballyPositioned { child2 = it.positionInParent }
+                    Modifier.onGloballyPositioned { child2 = it.positionInParent() }
                 )
             }
         }
@@ -149,7 +149,7 @@
                     Box(
                         Modifier
                             .onGloballyPositioned { positioned: LayoutCoordinates ->
-                                appbarPosition = positioned.positionInParent
+                                appbarPosition = positioned.positionInParent()
                                 appbarSize = positioned.size
                             }
                             .fillMaxWidth()
@@ -161,7 +161,7 @@
                 Box(
                     Modifier
                         .onGloballyPositioned { positioned: LayoutCoordinates ->
-                            contentPosition = positioned.positionInParent
+                            contentPosition = positioned.positionInParent()
                             contentSize = positioned.size
                         }
                         .fillMaxSize()
@@ -187,7 +187,7 @@
                         Box(
                             Modifier
                                 .onGloballyPositioned { positioned: LayoutCoordinates ->
-                                    drawerChildPosition = positioned.positionInParent
+                                    drawerChildPosition = positioned.positionInParent()
                                 }
                                 .fillMaxWidth()
                                 .height(50.dp)
@@ -243,7 +243,7 @@
                         Box(
                             Modifier
                                 .onGloballyPositioned { positioned: LayoutCoordinates ->
-                                    drawerChildPosition = positioned.positionInParent
+                                    drawerChildPosition = positioned.positionInParent()
                                 }
                                 .fillMaxWidth()
                                 .height(50.dp)
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SliderScreenshotTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SliderScreenshotTest.kt
index 2487b7d..a8c0759 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SliderScreenshotTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SliderScreenshotTest.kt
@@ -37,6 +37,7 @@
 import androidx.test.filters.LargeTest
 import androidx.test.filters.SdkSuppress
 import androidx.test.screenshot.AndroidXScreenshotTestRule
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -68,6 +69,18 @@
     }
 
     @Test
+    @Ignore("b/179922733 cannot upload new goldens")
+    fun sliderTest_origin_disabled() {
+        rule.setMaterialContent {
+            Box(wrap.testTag(wrapperTestTag)) {
+                var position by remember { mutableStateOf(0f) }
+                Slider(position, { position = it }, enabled = false)
+            }
+        }
+        assertSliderAgainstGolden("slider_origin_disabled")
+    }
+
+    @Test
     fun sliderTest_middle() {
         rule.setMaterialContent {
             Box(wrap.testTag(wrapperTestTag)) {
@@ -101,6 +114,18 @@
     }
 
     @Test
+    @Ignore("b/179922733 cannot upload new goldens")
+    fun sliderTest_middle_steps_disabled() {
+        rule.setMaterialContent {
+            Box(wrap.testTag(wrapperTestTag)) {
+                var position by remember { mutableStateOf(0.5f) }
+                Slider(position, { position = it }, steps = 5, enabled = false)
+            }
+        }
+        assertSliderAgainstGolden("slider_middle_steps_disabled")
+    }
+
+    @Test
     fun sliderTest_customColors() {
         rule.setMaterialContent {
             Box(wrap.testTag(wrapperTestTag)) {
@@ -109,16 +134,46 @@
                     value = position,
                     onValueChange = { position = it },
                     steps = 5,
-                    thumbColor = Color.Red,
-                    activeTrackColor = Color.Blue,
-                    activeTickColor = Color.Yellow,
-                    inactiveTickColor = Color.Magenta
+                    colors = SliderDefaults.colors(
+                        thumbColor = Color.Red,
+                        activeTrackColor = Color.Blue,
+                        activeTickColor = Color.Yellow,
+                        inactiveTickColor = Color.Magenta
+                    )
+
                 )
             }
         }
         assertSliderAgainstGolden("slider_customColors")
     }
 
+    @Test
+    @Ignore("b/179922733 cannot upload new goldens")
+    fun sliderTest_customColors_disabled() {
+        rule.setMaterialContent {
+            Box(wrap.testTag(wrapperTestTag)) {
+                var position by remember { mutableStateOf(0.5f) }
+                Slider(
+                    value = position,
+                    onValueChange = { position = it },
+                    steps = 5,
+                    enabled = false,
+                    // this is intentionally made to appear as enabled in disabled state for a
+                    // brighter test
+                    colors = SliderDefaults.colors(
+                        disabledThumbColor = Color.Blue,
+                        disabledActiveTrackColor = Color.Red,
+                        disabledInactiveTrackColor = Color.Yellow,
+                        disabledActiveTickColor = Color.Magenta,
+                        disabledInactiveTickColor = Color.Cyan
+                    )
+
+                )
+            }
+        }
+        assertSliderAgainstGolden("slider_customColors_disabled")
+    }
+
     private fun assertSliderAgainstGolden(goldenName: String) {
         rule.onNodeWithTag(wrapperTestTag)
             .captureToImage()
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SliderTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SliderTest.kt
index 03edfbd..6667f7e 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SliderTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SliderTest.kt
@@ -170,6 +170,21 @@
     }
 
     @Test
+    fun slider_semantics_disabled() {
+        rule.setMaterialContent {
+            Slider(
+                value = 0f,
+                onValueChange = {},
+                modifier = Modifier.testTag(tag),
+                enabled = false
+            )
+        }
+
+        rule.onNodeWithTag(tag)
+            .assert(SemanticsMatcher.keyIsDefined(SemanticsProperties.Disabled))
+    }
+
+    @Test
     fun slider_drag() {
         val state = mutableStateOf(0f)
         var slop = 0f
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 84b8fc6..420e85d 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
@@ -19,6 +19,7 @@
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.platform.AccessibilityManager
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithText
 import androidx.compose.ui.test.performClick
@@ -26,13 +27,19 @@
 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 kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.SupervisorJob
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
+import org.junit.Assert.assertEquals
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.AdditionalMatchers.not
 
 @MediumTest
 @RunWith(AndroidJUnit4::class)
@@ -152,4 +159,73 @@
 
         rule.waitUntil { job1.isCompleted && job2.isCompleted }
     }
+
+    @Test
+    fun snackbarDuration_toMillis_nonNullAccessibilityManager() {
+        val mockDurationControl = 10000L
+        val mockDurationNonControl = 5000L
+        val accessibilityManager: AccessibilityManager = mock {
+            on {
+                calculateRecommendedTimeoutMillis(eq(Long.MAX_VALUE), any(), any(), any())
+            } doReturn Long.MAX_VALUE
+            on {
+                calculateRecommendedTimeoutMillis(not(eq(Long.MAX_VALUE)), any(), any(), eq(true))
+            } doReturn mockDurationControl
+            on {
+                calculateRecommendedTimeoutMillis(not(eq(Long.MAX_VALUE)), any(), any(), eq(false))
+            } doReturn mockDurationNonControl
+        }
+        assertEquals(
+            Long.MAX_VALUE,
+            SnackbarDuration.Indefinite.toMillis(true, accessibilityManager)
+        )
+        assertEquals(
+            Long.MAX_VALUE,
+            SnackbarDuration.Indefinite.toMillis(false, accessibilityManager)
+        )
+        assertEquals(
+            mockDurationControl,
+            SnackbarDuration.Long.toMillis(true, accessibilityManager)
+        )
+        assertEquals(
+            mockDurationNonControl,
+            SnackbarDuration.Long.toMillis(false, accessibilityManager)
+        )
+        assertEquals(
+            mockDurationControl,
+            SnackbarDuration.Short.toMillis(true, accessibilityManager)
+        )
+        assertEquals(
+            mockDurationNonControl,
+            SnackbarDuration.Short.toMillis(false, accessibilityManager)
+        )
+    }
+
+    @Test
+    fun snackbarDuration_toMillis_nullAccessibilityManager() {
+        assertEquals(
+            Long.MAX_VALUE,
+            SnackbarDuration.Indefinite.toMillis(true, null)
+        )
+        assertEquals(
+            Long.MAX_VALUE,
+            SnackbarDuration.Indefinite.toMillis(false, null)
+        )
+        assertEquals(
+            10000L,
+            SnackbarDuration.Long.toMillis(true, null)
+        )
+        assertEquals(
+            10000L,
+            SnackbarDuration.Long.toMillis(false, null)
+        )
+        assertEquals(
+            4000L,
+            SnackbarDuration.Short.toMillis(true, null)
+        )
+        assertEquals(
+            4000L,
+            SnackbarDuration.Short.toMillis(false, null)
+        )
+    }
 }
\ No newline at end of file
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SnackbarTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SnackbarTest.kt
index 8324804..8f4e270 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SnackbarTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SnackbarTest.kt
@@ -20,6 +20,8 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.shape.CutCornerShape
 import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.testutils.assertIsEqualTo
+import androidx.compose.testutils.assertIsNotEqualTo
 import androidx.compose.testutils.assertShape
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
@@ -29,8 +31,6 @@
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.test.assertHeightIsEqualTo
-import androidx.compose.ui.test.assertIsEqualTo
-import androidx.compose.ui.test.assertIsNotEqualTo
 import androidx.compose.ui.test.assertTopPositionInRootIsEqualTo
 import androidx.compose.ui.test.assertWidthIsEqualTo
 import androidx.compose.ui.test.captureToImage
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwipeableTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwipeableTest.kt
index 1333e23..a3a0cfb 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwipeableTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwipeableTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.material
 
-import androidx.compose.animation.core.AnimationEndReason
 import androidx.compose.foundation.ScrollState
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.gestures.scrollBy
@@ -58,6 +57,7 @@
 import androidx.test.filters.LargeTest
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CancellationException
 import kotlinx.coroutines.async
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
@@ -1370,9 +1370,15 @@
             )
         }
 
-        val endValue = state.animateTo("B")
+        var result: Boolean?
+        try {
+            state.animateTo("B")
+            result = true
+        } catch (c: CancellationException) {
+            result = false
+        }
         advanceClock()
-        assertThat(endValue).isEqualTo(AnimationEndReason.Finished)
+        assertThat(result).isEqualTo(true)
     }
 
     /**
@@ -1402,8 +1408,7 @@
             up()
         }
         advanceClock()
-        val endReason = job.await()
-        assertThat(endReason).isEqualTo(AnimationEndReason.Interrupted)
+        job.await()
     }
 
     /**
@@ -1553,7 +1558,7 @@
                 "orientation",
                 "enabled",
                 "reverseDirection",
-                "interactionState",
+                "interactionSource",
                 "thresholds",
                 "resistance",
                 "velocityThreshold"
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwitchTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwitchTest.kt
index 4ff71b6..283803e 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwitchTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwitchTest.kt
@@ -27,14 +27,19 @@
 import androidx.compose.ui.test.assertHasClickAction
 import androidx.compose.ui.semantics.SemanticsProperties
 import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.focused
+import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.test.SemanticsMatcher
 import androidx.compose.ui.test.assert
+import androidx.compose.ui.test.assertHasNoClickAction
 import androidx.compose.ui.test.assertHeightIsEqualTo
 import androidx.compose.ui.test.assertIsEnabled
 import androidx.compose.ui.test.assertIsOff
 import androidx.compose.ui.test.assertIsOn
 import androidx.compose.ui.test.assertValueEquals
 import androidx.compose.ui.test.assertWidthIsEqualTo
+import androidx.compose.ui.test.isFocusable
+import androidx.compose.ui.test.isNotFocusable
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performClick
@@ -142,6 +147,48 @@
     }
 
     @Test
+    fun switch_untoggleable_whenEmptyLambda() {
+        val parentTag = "parent"
+
+        rule.setMaterialContent {
+            val (checked, _) = remember { mutableStateOf(false) }
+            Box(Modifier.semantics(mergeDescendants = true) {}.testTag(parentTag)) {
+                Switch(
+                    checked,
+                    {},
+                    enabled = false,
+                    modifier = Modifier.testTag(defaultSwitchTag).semantics { focused = true }
+                )
+            }
+        }
+
+        rule.onNodeWithTag(defaultSwitchTag)
+            .assertHasClickAction()
+
+        // Check not merged into parent
+        rule.onNodeWithTag(parentTag)
+            .assert(isNotFocusable())
+    }
+
+    @Test
+    fun switch_untoggleableAndMergeable_whenNullLambda() {
+        rule.setMaterialContent {
+            val (checked, _) = remember { mutableStateOf(false) }
+            Box(Modifier.semantics(mergeDescendants = true) {}.testTag(defaultSwitchTag)) {
+                Switch(
+                    checked,
+                    null,
+                    modifier = Modifier.semantics { focused = true }
+                )
+            }
+        }
+
+        rule.onNodeWithTag(defaultSwitchTag)
+            .assertHasNoClickAction()
+            .assert(isFocusable()) // Check merged into parent
+    }
+
+    @Test
     fun switch_materialSizes_whenChecked() {
         materialSizesTestForValue(true)
     }
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/TabScreenshotTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/TabScreenshotTest.kt
index 778b0ba..0ac6564 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/TabScreenshotTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/TabScreenshotTest.kt
@@ -17,10 +17,12 @@
 package androidx.compose.material
 
 import android.os.Build
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.foundation.layout.Box
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.testutils.assertAgainstGolden
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
@@ -35,6 +37,8 @@
 import androidx.test.filters.LargeTest
 import androidx.test.filters.SdkSuppress
 import androidx.test.screenshot.AndroidXScreenshotTestRule
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -53,18 +57,20 @@
 
     @Test
     fun lightTheme_defaultColors() {
-        val interactionState = InteractionState().apply {
-            addInteraction(Interaction.Pressed)
-        }
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
+            scope = rememberCoroutineScope()
             MaterialTheme(lightColors()) {
-                DefaultTabs(interactionState)
+                DefaultTabs(interactionSource)
             }
         }
 
         assertTabsMatch(
-            interactionState = interactionState,
+            scope = scope!!,
+            interactionSource = interactionSource,
             interaction = null,
             goldenIdentifier = "tabs_lightTheme_defaultColors"
         )
@@ -72,31 +78,36 @@
 
     @Test
     fun lightTheme_defaultColors_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
+            scope = rememberCoroutineScope()
             MaterialTheme(lightColors()) {
-                DefaultTabs(interactionState)
+                DefaultTabs(interactionSource)
             }
         }
 
         assertTabsMatch(
-            interactionState = interactionState,
-            interaction = Interaction.Pressed,
+            scope = scope!!,
+            interactionSource = interactionSource,
+            interaction = PressInteraction.Press(Offset(10f, 10f)),
             goldenIdentifier = "tabs_lightTheme_defaultColors_pressed"
         )
     }
 
     @Test
     fun lightTheme_surfaceColors() {
-        val interactionState = InteractionState().apply {
-            addInteraction(Interaction.Pressed)
-        }
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
             MaterialTheme(lightColors()) {
+                scope = rememberCoroutineScope()
                 CustomTabs(
-                    interactionState,
+                    interactionSource,
                     backgroundColor = MaterialTheme.colors.surface,
                     selectedContentColor = MaterialTheme.colors.primary,
                     unselectedContentColor = MaterialTheme.colors.onSurface
@@ -105,7 +116,8 @@
         }
 
         assertTabsMatch(
-            interactionState = interactionState,
+            scope = scope!!,
+            interactionSource = interactionSource,
             interaction = null,
             goldenIdentifier = "tabs_lightTheme_surfaceColors"
         )
@@ -113,12 +125,15 @@
 
     @Test
     fun lightTheme_surfaceColors_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
             MaterialTheme(lightColors()) {
+                scope = rememberCoroutineScope()
                 CustomTabs(
-                    interactionState,
+                    interactionSource,
                     backgroundColor = MaterialTheme.colors.surface,
                     selectedContentColor = MaterialTheme.colors.primary,
                     unselectedContentColor = MaterialTheme.colors.onSurface
@@ -127,26 +142,29 @@
         }
 
         assertTabsMatch(
-            interactionState = interactionState,
-            interaction = Interaction.Pressed,
+            scope = scope!!,
+            interactionSource = interactionSource,
+            interaction = PressInteraction.Press(Offset(10f, 10f)),
             goldenIdentifier = "tabs_lightTheme_surfaceColors_pressed"
         )
     }
 
     @Test
     fun darkTheme_defaultColors() {
-        val interactionState = InteractionState().apply {
-            addInteraction(Interaction.Pressed)
-        }
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
+            scope = rememberCoroutineScope()
             MaterialTheme(darkColors()) {
-                DefaultTabs(interactionState)
+                DefaultTabs(interactionSource)
             }
         }
 
         assertTabsMatch(
-            interactionState = interactionState,
+            scope = scope!!,
+            interactionSource = interactionSource,
             interaction = null,
             goldenIdentifier = "tabs_darkTheme_defaultColors"
         )
@@ -154,17 +172,21 @@
 
     @Test
     fun darkTheme_defaultColors_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
+            scope = rememberCoroutineScope()
             MaterialTheme(darkColors()) {
-                DefaultTabs(interactionState)
+                DefaultTabs(interactionSource)
             }
         }
 
         assertTabsMatch(
-            interactionState = interactionState,
-            interaction = Interaction.Pressed,
+            scope = scope!!,
+            interactionSource = interactionSource,
+            interaction = PressInteraction.Press(Offset(10f, 10f)),
             goldenIdentifier = "tabs_darkTheme_defaultColors_pressed"
         )
     }
@@ -174,14 +196,15 @@
     // matches that use case.
     @Test
     fun darkTheme_surfaceColors() {
-        val interactionState = InteractionState().apply {
-            addInteraction(Interaction.Pressed)
-        }
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
             MaterialTheme(darkColors()) {
+                scope = rememberCoroutineScope()
                 CustomTabs(
-                    interactionState,
+                    interactionSource,
                     backgroundColor = MaterialTheme.colors.surface,
                     selectedContentColor = MaterialTheme.colors.primary,
                     unselectedContentColor = MaterialTheme.colors.onSurface
@@ -190,7 +213,8 @@
         }
 
         assertTabsMatch(
-            interactionState = interactionState,
+            scope = scope!!,
+            interactionSource = interactionSource,
             interaction = null,
             goldenIdentifier = "tabs_darkTheme_surfaceColors"
         )
@@ -198,12 +222,15 @@
 
     @Test
     fun darkTheme_surfaceColors_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
             MaterialTheme(darkColors()) {
+                scope = rememberCoroutineScope()
                 CustomTabs(
-                    interactionState,
+                    interactionSource,
                     backgroundColor = MaterialTheme.colors.surface,
                     selectedContentColor = MaterialTheme.colors.primary,
                     unselectedContentColor = MaterialTheme.colors.onSurface
@@ -212,22 +239,24 @@
         }
 
         assertTabsMatch(
-            interactionState = interactionState,
-            interaction = Interaction.Pressed,
+            scope = scope!!,
+            interactionSource = interactionSource,
+            interaction = PressInteraction.Press(Offset(10f, 10f)),
             goldenIdentifier = "tabs_darkTheme_surfaceColors_pressed"
         )
     }
 
     @Test
     fun darkTheme_primaryColors() {
-        val interactionState = InteractionState().apply {
-            addInteraction(Interaction.Pressed)
-        }
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
             MaterialTheme(darkColors()) {
+                scope = rememberCoroutineScope()
                 CustomTabs(
-                    interactionState,
+                    interactionSource,
                     backgroundColor = MaterialTheme.colors.primary,
                     selectedContentColor = MaterialTheme.colors.onPrimary,
                     unselectedContentColor = MaterialTheme.colors.onPrimary
@@ -236,7 +265,8 @@
         }
 
         assertTabsMatch(
-            interactionState = interactionState,
+            scope = scope!!,
+            interactionSource = interactionSource,
             interaction = null,
             goldenIdentifier = "tabs_darkTheme_primaryColors"
         )
@@ -244,12 +274,15 @@
 
     @Test
     fun darkTheme_primaryColors_pressed() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         composeTestRule.setContent {
             MaterialTheme(darkColors()) {
+                scope = rememberCoroutineScope()
                 CustomTabs(
-                    interactionState,
+                    interactionSource,
                     backgroundColor = MaterialTheme.colors.primary,
                     selectedContentColor = MaterialTheme.colors.onPrimary,
                     unselectedContentColor = MaterialTheme.colors.onPrimary
@@ -258,8 +291,9 @@
         }
 
         assertTabsMatch(
-            interactionState = interactionState,
-            interaction = Interaction.Pressed,
+            scope = scope!!,
+            interactionSource = interactionSource,
+            interaction = PressInteraction.Press(Offset(10f, 10f)),
             goldenIdentifier = "tabs_darkTheme_primaryColors_pressed"
         )
     }
@@ -267,12 +301,13 @@
     /**
      * Asserts that the tabs match the screenshot with identifier [goldenIdentifier].
      *
-     * @param interactionState the [InteractionState] used for the first Tab
+     * @param interactionSource the [MutableInteractionSource] used for the first Tab
      * @param interaction the [Interaction] to assert for, or `null` if no [Interaction].
      * @param goldenIdentifier the identifier for the corresponding screenshot
      */
     private fun assertTabsMatch(
-        interactionState: InteractionState,
+        scope: CoroutineScope,
+        interactionSource: MutableInteractionSource,
         interaction: Interaction? = null,
         goldenIdentifier: String
     ) {
@@ -280,12 +315,8 @@
 
         if (interaction != null) {
             // Start ripple
-            composeTestRule.runOnUiThread {
-                if (interaction is Interaction.Pressed) {
-                    interactionState.addInteraction(interaction, Offset(10f, 10f))
-                } else {
-                    interactionState.addInteraction(interaction)
-                }
+            scope.launch {
+                interactionSource.emit(interaction)
             }
 
             // Advance to somewhere in the middle of the animation for the ripple
@@ -303,18 +334,19 @@
 /**
  * Default colored [TabRow] with three [Tab]s. The first [Tab] is selected, and the rest are not.
  *
- * @param interactionState the [InteractionState] for the first [Tab], to control its visual state.
+ * @param interactionSource the [MutableInteractionSource] for the first [Tab], to control its
+ * visual state.
  */
 @Composable
 private fun DefaultTabs(
-    interactionState: InteractionState
+    interactionSource: MutableInteractionSource
 ) {
     Box(Modifier.semantics(mergeDescendants = true) {}.testTag(Tag)) {
         TabRow(selectedTabIndex = 0) {
             Tab(
                 text = { Text("TAB") },
                 selected = true,
-                interactionState = interactionState,
+                interactionSource = interactionSource,
                 onClick = {}
             )
             Tab(
@@ -334,14 +366,15 @@
 /**
  * Custom colored [TabRow] with three [Tab]s. The first [Tab] is selected, and the rest are not.
  *
- * @param interactionState the [InteractionState] for the first [Tab], to control its visual state.
+ * @param interactionSource the [MutableInteractionSource] for the first [Tab], to control its
+ * visual state.
  * @param backgroundColor the backgroundColor of the [TabRow]
  * @param selectedContentColor the content color for a selected [Tab] (first tab)
  * @param unselectedContentColor the content color for an unselected [Tab] (second and third tabs)
  */
 @Composable
 private fun CustomTabs(
-    interactionState: InteractionState,
+    interactionSource: MutableInteractionSource,
     backgroundColor: Color,
     selectedContentColor: Color,
     unselectedContentColor: Color
@@ -354,7 +387,7 @@
             Tab(
                 text = { Text("TAB") },
                 selected = true,
-                interactionState = interactionState,
+                interactionSource = interactionSource,
                 selectedContentColor = selectedContentColor,
                 unselectedContentColor = unselectedContentColor,
                 onClick = {}
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/TabTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/TabTest.kt
index 725f4d6..afc4989 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/TabTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/TabTest.kt
@@ -29,6 +29,7 @@
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
+import androidx.compose.testutils.assertIsEqualTo
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.platform.InspectableValue
@@ -42,7 +43,6 @@
 import androidx.compose.ui.test.assertHasClickAction
 import androidx.compose.ui.test.assertHeightIsEqualTo
 import androidx.compose.ui.test.assertIsEnabled
-import androidx.compose.ui.test.assertIsEqualTo
 import androidx.compose.ui.test.assertIsNotEnabled
 import androidx.compose.ui.test.assertIsNotSelected
 import androidx.compose.ui.test.assertIsSelected
@@ -51,6 +51,7 @@
 import androidx.compose.ui.test.isSelectable
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.onParent
 import androidx.compose.ui.test.performClick
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.height
@@ -89,7 +90,7 @@
     @Test
     fun defaultSemantics() {
         rule.setMaterialContent {
-            Box {
+            TabRow(0) {
                 Tab(
                     text = { Text("Text") },
                     modifier = Modifier.testTag("tab"),
@@ -104,6 +105,10 @@
             .assertIsSelected()
             .assertIsEnabled()
             .assertHasClickAction()
+
+        rule.onNodeWithTag("tab")
+            .onParent()
+            .assert(SemanticsMatcher.keyIsDefined(SemanticsProperties.SelectableGroup))
     }
 
     @Test
@@ -198,7 +203,7 @@
 
         val tabRowBounds = rule.onNodeWithTag("tabRow").getUnclippedBoundsInRoot()
 
-        rule.onNodeWithTag("indicator")
+        rule.onNodeWithTag("indicator", true)
             .assertPositionInRootIsEqualTo(
                 expectedLeft = 0.dp,
                 expectedTop = tabRowBounds.height - indicatorHeight
@@ -209,7 +214,7 @@
 
         // Indicator should now be placed in the bottom left of the second tab, so its x coordinate
         // should be in the middle of the TabRow
-        rule.onNodeWithTag("indicator")
+        rule.onNodeWithTag("indicator", true)
             .assertPositionInRootIsEqualTo(
                 expectedLeft = (tabRowBounds.width / 2),
                 expectedTop = tabRowBounds.height - indicatorHeight
@@ -375,7 +380,7 @@
         val tabRowBounds = rule.onNodeWithTag("tabRow").getUnclippedBoundsInRoot()
 
         // Indicator should be placed in the bottom left of the first tab
-        rule.onNodeWithTag("indicator")
+        rule.onNodeWithTag("indicator", true)
             .assertPositionInRootIsEqualTo(
                 // Tabs in a scrollable tab row are offset 52.dp from each end
                 expectedLeft = TabRowDefaults.ScrollableTabRowPadding,
@@ -387,7 +392,7 @@
 
         // Indicator should now be placed in the bottom left of the second tab, so its x coordinate
         // should be in the middle of the TabRow
-        rule.onNodeWithTag("indicator")
+        rule.onNodeWithTag("indicator", true)
             .assertPositionInRootIsEqualTo(
                 expectedLeft = TabRowDefaults.ScrollableTabRowPadding + minimumTabWidth,
                 expectedTop = tabRowBounds.height - indicatorHeight
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/OutlinedTextFieldScreenshotTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/OutlinedTextFieldScreenshotTest.kt
index 9618e72..b88ce1f 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/OutlinedTextFieldScreenshotTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/OutlinedTextFieldScreenshotTest.kt
@@ -155,7 +155,7 @@
                     value = "Input",
                     onValueChange = {},
                     label = { Text("Label") },
-                    isErrorValue = true,
+                    isError = true,
                     modifier = Modifier.requiredWidth(280.dp)
                 )
             }
@@ -174,7 +174,7 @@
                     value = "",
                     onValueChange = {},
                     label = { Text("Label") },
-                    isErrorValue = true,
+                    isError = true,
                     modifier = Modifier.requiredWidth(280.dp)
                 )
             }
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 4c2d8ec..a207db8 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
@@ -58,11 +58,11 @@
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performClick
 import androidx.compose.ui.test.performGesture
-import androidx.compose.ui.text.SoftwareKeyboardController
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.ImeOptions
 import androidx.compose.ui.text.input.KeyboardType
 import androidx.compose.ui.text.input.PasswordVisualTransformation
+import androidx.compose.ui.text.input.PlatformTextInputService
 import androidx.compose.ui.text.input.TextInputService
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.dp
@@ -606,7 +606,7 @@
                 value = "",
                 onValueChange = {},
                 label = {},
-                isErrorValue = false,
+                isError = false,
                 leadingIcon = {
                     assertThat(LocalContentColor.current)
                         .isEqualTo(
@@ -634,7 +634,7 @@
                 value = "",
                 onValueChange = {},
                 label = {},
-                isErrorValue = true,
+                isError = true,
                 leadingIcon = {
                     assertThat(LocalContentColor.current)
                         .isEqualTo(
@@ -652,7 +652,8 @@
 
     @Test
     fun testOutlinedTextField_imeActionAndKeyboardTypePropagatedDownstream() {
-        val textInputService = mock<TextInputService>()
+        val platformTextInputService = mock<PlatformTextInputService>()
+        val textInputService = TextInputService(platformTextInputService)
         rule.setContent {
             CompositionLocalProvider(
                 LocalTextInputService provides textInputService
@@ -674,7 +675,7 @@
         rule.onNodeWithTag(TextfieldTag).performClick()
 
         rule.runOnIdle {
-            verify(textInputService, atLeastOnce()).startInput(
+            verify(platformTextInputService, atLeastOnce()).startInput(
                 value = any(),
                 imeOptions = eq(
                     ImeOptions(
@@ -715,29 +716,4 @@
                 shapeOverlapPixelCount = with(rule.density) { 3.dp.toPx() }
             )
     }
-
-    @Test
-    fun testOutlinedTextField_onTextInputStartedCallback() {
-        var controller: SoftwareKeyboardController? = null
-
-        rule.setMaterialContent {
-            OutlinedTextField(
-                modifier = Modifier.testTag(TextfieldTag),
-                value = "",
-                onValueChange = {},
-                label = {},
-                onTextInputStarted = {
-                    controller = it
-                }
-            )
-        }
-        assertThat(controller).isNull()
-
-        rule.onNodeWithTag(TextfieldTag)
-            .performClick()
-
-        rule.runOnIdle {
-            assertThat(controller).isNotNull()
-        }
-    }
 }
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/TextFieldScreenshotTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/TextFieldScreenshotTest.kt
index 1f87e48..478be85 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/TextFieldScreenshotTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/TextFieldScreenshotTest.kt
@@ -150,7 +150,7 @@
                 value = "Input",
                 onValueChange = {},
                 label = { Text("Label") },
-                isErrorValue = true,
+                isError = true,
                 modifier = Modifier.requiredWidth(280.dp).testTag(TextFieldTag)
             )
         }
@@ -167,7 +167,7 @@
                 value = "",
                 onValueChange = {},
                 label = { Text("Label") },
-                isErrorValue = true,
+                isError = true,
                 modifier = Modifier.requiredWidth(280.dp).testTag(TextFieldTag)
             )
         }
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 7ea7709..0cdf030 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
@@ -20,8 +20,9 @@
 import android.os.Build
 import android.view.View
 import android.view.inputmethod.InputMethodManager
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.FocusInteraction
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
@@ -30,19 +31,25 @@
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.requiredWidth
 import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.material.Icon
 import androidx.compose.material.LocalContentAlpha
 import androidx.compose.material.LocalContentColor
 import androidx.compose.material.LocalTextStyle
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Text
 import androidx.compose.material.TextField
+import androidx.compose.material.TextFieldDefaults
 import androidx.compose.material.TextFieldPadding
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Favorite
 import androidx.compose.material.runOnIdleWithDensity
 import androidx.compose.material.setMaterialContent
 import androidx.compose.material.setMaterialContentForSizeAssertions
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.testutils.assertPixels
 import androidx.compose.testutils.assertShape
 import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
@@ -59,7 +66,9 @@
 import androidx.compose.ui.platform.LocalTextInputService
 import androidx.compose.ui.platform.LocalView
 import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.semantics.SemanticsProperties
 import androidx.compose.ui.test.ExperimentalTestApi
+import androidx.compose.ui.test.SemanticsMatcher
 import androidx.compose.ui.test.assertHeightIsEqualTo
 import androidx.compose.ui.test.assertWidthIsEqualTo
 import androidx.compose.ui.test.captureToImage
@@ -68,12 +77,17 @@
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performClick
 import androidx.compose.ui.test.performGesture
-import androidx.compose.ui.text.SoftwareKeyboardController
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.buildAnnotatedString
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.ImeOptions
 import androidx.compose.ui.text.input.KeyboardType
+import androidx.compose.ui.text.input.OffsetMapping
 import androidx.compose.ui.text.input.PasswordVisualTransformation
+import androidx.compose.ui.text.input.PlatformTextInputService
 import androidx.compose.ui.text.input.TextInputService
+import androidx.compose.ui.text.input.TransformedText
+import androidx.compose.ui.text.input.VisualTransformation
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
@@ -87,6 +101,9 @@
 import com.nhaarman.mockitokotlin2.eq
 import com.nhaarman.mockitokotlin2.mock
 import com.nhaarman.mockitokotlin2.verify
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -151,63 +168,99 @@
     fun testTextFields_singleFocus() {
         val textField1Tag = "TextField1"
         val textField2Tag = "TextField2"
-        val interactionState1 = InteractionState()
-        val interactionState2 = InteractionState()
+        val interactionSource1 = MutableInteractionSource()
+        val interactionSource2 = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
 
         rule.setMaterialContent {
+            scope = rememberCoroutineScope()
             Column {
                 TextField(
                     modifier = Modifier.testTag(textField1Tag),
                     value = "input1",
                     onValueChange = {},
                     label = {},
-                    interactionState = interactionState1
+                    interactionSource = interactionSource1
                 )
                 TextField(
                     modifier = Modifier.testTag(textField2Tag),
                     value = "input2",
                     onValueChange = {},
                     label = {},
-                    interactionState = interactionState2
+                    interactionSource = interactionSource2
                 )
             }
         }
 
+        val interactions1 = mutableListOf<Interaction>()
+        val interactions2 = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource1.interactions.collect { interactions1.add(it) }
+        }
+        scope!!.launch {
+            interactionSource2.interactions.collect { interactions2.add(it) }
+        }
+
+        rule.runOnIdle {
+            assertThat(interactions1).isEmpty()
+            assertThat(interactions2).isEmpty()
+        }
+
         rule.onNodeWithTag(textField1Tag).performClick()
 
         rule.runOnIdle {
-            assertThat(interactionState1.contains(Interaction.Focused)).isTrue()
-            assertThat(interactionState2.contains(Interaction.Focused)).isFalse()
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions1.filterIsInstance<FocusInteraction.Focus>()).hasSize(1)
+            assertThat(interactions2).isEmpty()
         }
 
         rule.onNodeWithTag(textField2Tag).performClick()
 
         rule.runOnIdle {
-            assertThat(interactionState1.contains(Interaction.Focused)).isFalse()
-            assertThat(interactionState2.contains(Interaction.Focused)).isTrue()
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions1.filterIsInstance<FocusInteraction.Focus>()).hasSize(1)
+            assertThat(interactions1.filterIsInstance<FocusInteraction.Unfocus>()).hasSize(1)
+            assertThat(interactions2.filterIsInstance<FocusInteraction.Focus>()).hasSize(1)
+            assertThat(interactions2.filterIsInstance<FocusInteraction.Unfocus>()).isEmpty()
         }
     }
 
     @Test
     fun testTextField_getFocus_whenClickedOnSurfaceArea() {
-        val interactionState = InteractionState()
+        val interactionSource = MutableInteractionSource()
+        var scope: CoroutineScope? = null
+
         rule.setMaterialContent {
+            scope = rememberCoroutineScope()
             TextField(
                 modifier = Modifier.testTag(TextfieldTag),
                 value = "input",
                 onValueChange = {},
                 label = {},
-                interactionState = interactionState
+                interactionSource = interactionSource
             )
         }
 
+        val interactions = mutableListOf<Interaction>()
+
+        scope!!.launch {
+            interactionSource.interactions.collect { interactions.add(it) }
+        }
+
+        rule.runOnIdle {
+            assertThat(interactions).isEmpty()
+        }
+
         // Click on (2, 2) which is Surface area and outside input area
         rule.onNodeWithTag(TextfieldTag).performGesture {
             click(Offset(2f, 2f))
         }
 
-        rule.runOnIdleWithDensity {
-            assertThat(interactionState.contains(Interaction.Focused)).isTrue()
+        rule.runOnIdle {
+            // Not asserting total size as we have other interactions here too
+            assertThat(interactions.filterIsInstance<FocusInteraction.Focus>()).hasSize(1)
         }
     }
 
@@ -241,40 +294,7 @@
         rule.runOnIdle { assertThat(hostView.isSoftwareKeyboardShown).isFalse() }
     }
 
-    @ExperimentalComposeUiApi
-    @Test
-    fun testTextField_clickingOnTextAfterDismissingKeyboard_showsKeyboard() {
-        val (focusRequester, parentFocusRequester) = FocusRequester.createRefs()
-        lateinit var softwareKeyboardController: SoftwareKeyboardController
-        lateinit var hostView: View
-        rule.setMaterialContent {
-            hostView = LocalView.current
-            Box {
-                TextField(
-                    modifier = Modifier
-                        .focusRequester(parentFocusRequester)
-                        .focusModifier()
-                        .focusRequester(focusRequester)
-                        .testTag(TextfieldTag),
-                    value = "input",
-                    onValueChange = {},
-                    onTextInputStarted = { softwareKeyboardController = it },
-                    label = {}
-                )
-            }
-        }
-
-        // Shows keyboard when the text field is focused.
-        rule.runOnIdle { focusRequester.requestFocus() }
-        rule.runOnIdle { assertThat(hostView.isSoftwareKeyboardShown).isTrue() }
-
-        // Hide keyboard.
-        rule.runOnIdle { softwareKeyboardController.hideSoftwareKeyboard() }
-
-        // Clicking on the text field shows the keyboard.
-        rule.onNodeWithTag(TextfieldTag).performClick()
-        rule.runOnIdle { assertThat(hostView.isSoftwareKeyboardShown).isTrue() }
-    }
+    // TODO(b/1583763): re-add keyboard hide/show test when replacement API is added
 
     @Test
     fun testTextField_labelPosition_initial_singleLine() {
@@ -760,7 +780,7 @@
                 value = "",
                 onValueChange = {},
                 label = {},
-                isErrorValue = false,
+                isError = false,
                 leadingIcon = {
                     assertThat(LocalContentColor.current)
                         .isEqualTo(
@@ -788,7 +808,7 @@
                 value = "",
                 onValueChange = {},
                 label = {},
-                isErrorValue = true,
+                isError = true,
                 leadingIcon = {
                     assertThat(LocalContentColor.current)
                         .isEqualTo(
@@ -806,7 +826,8 @@
 
     @Test
     fun testTextField_imeActionAndKeyboardTypePropagatedDownstream() {
-        val textInputService = mock<TextInputService>()
+        val platformTextInputService = mock<PlatformTextInputService>()
+        val textInputService = TextInputService(platformTextInputService)
         rule.setContent {
             CompositionLocalProvider(
                 LocalTextInputService provides textInputService
@@ -828,7 +849,7 @@
         rule.onNodeWithTag(TextfieldTag).performClick()
 
         rule.runOnIdle {
-            verify(textInputService, atLeastOnce()).startInput(
+            verify(platformTextInputService, atLeastOnce()).startInput(
                 value = any(),
                 imeOptions = eq(
                     ImeOptions(
@@ -851,10 +872,9 @@
                 modifier = Modifier.testTag(TextfieldTag),
                 value = "qwerty",
                 onValueChange = {},
-                label = {},
                 visualTransformation = PasswordVisualTransformation('\u0020'),
-                backgroundColor = Color.White,
-                shape = RectangleShape
+                shape = RectangleShape,
+                colors = TextFieldDefaults.textFieldColors(backgroundColor = Color.White)
             )
         }
 
@@ -874,20 +894,30 @@
     @LargeTest
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     fun testTextField_alphaNotApplied_toCustomBackgroundColorAndTransparentColors() {
-        val interactionState = InteractionState()
 
         rule.setMaterialContent {
             Box(Modifier.background(color = Color.White)) {
                 TextField(
                     modifier = Modifier.testTag(TextfieldTag),
-                    value = "",
+                    value = "test",
                     onValueChange = {},
-                    label = {},
+                    label = { Text("label") },
                     shape = RectangleShape,
-                    backgroundColor = Color.Blue,
-                    activeColor = Color.Transparent,
-                    inactiveColor = Color.Transparent,
-                    interactionState = interactionState
+                    leadingIcon = {
+                        Icon(Icons.Default.Favorite, null, tint = Color.Transparent)
+                    },
+                    trailingIcon = {
+                        Icon(Icons.Default.Favorite, null, tint = Color.Transparent)
+                    },
+                    colors = TextFieldDefaults.textFieldColors(
+                        backgroundColor = Color.Blue,
+                        focusedIndicatorColor = Color.Transparent,
+                        unfocusedIndicatorColor = Color.Transparent,
+                        textColor = Color.Transparent,
+                        cursorColor = Color.Transparent,
+                        focusedLabelColor = Color.Transparent,
+                        unfocusedLabelColor = Color.Transparent
+                    )
                 )
             }
         }
@@ -904,9 +934,6 @@
             )
 
         rule.onNodeWithTag(TextfieldTag).performClick()
-        rule.runOnIdle {
-            assertThat(interactionState.contains(Interaction.Focused)).isTrue()
-        }
 
         rule.onNodeWithTag(TextfieldTag)
             .captureToImage()
@@ -921,28 +948,83 @@
     }
 
     @Test
-    fun testTextField_onTextInputStartedCallback() {
-        var controller: SoftwareKeyboardController? = null
+    @LargeTest
+    fun testTransformedTextIsUsed_toDefineLabelPosition() {
+        // if non-transformed value were used to check if the text input is empty, the label
+        // wouldn't be aligned to the top, as a result it would be obscured by text
+        val prefixTransformation = VisualTransformation { text ->
+            val prefix = "prefix"
+            val transformed = buildAnnotatedString {
+                append(prefix)
+                append(text)
+            }
+            val mapping = object : OffsetMapping {
+                override fun originalToTransformed(offset: Int) = offset + prefix.length
+                override fun transformedToOriginal(offset: Int) =
+                    (offset - prefix.length).coerceAtLeast(0)
+            }
+            TransformedText(transformed, mapping)
+        }
+        rule.setMaterialContent {
+            TextField(
+                value = "",
+                onValueChange = {},
+                visualTransformation = prefixTransformation,
+                label = {
+                    Text("label", color = Color.Red, modifier = Modifier.background(Color.Red))
+                },
+                textStyle = TextStyle(color = Color.Blue),
+                colors = TextFieldDefaults.textFieldColors(backgroundColor = Color.White)
+            )
+        }
+        rule.onNode(SemanticsMatcher.keyIsDefined(SemanticsProperties.Text), true)
+            .captureToImage()
+            .assertPixels { Color.Red }
+    }
 
+    @Test
+    @LargeTest
+    fun testTransformedTextIsUsed_toDefineIfPlaceholderNeeded() {
+        // if original value were used to check if the text input is empty, the placeholder would be
+        // displayed on top of the text
+        val prefixTransformation = VisualTransformation { text ->
+            val prefix = "prefix"
+            val transformed = buildAnnotatedString {
+                append(prefix)
+                append(text)
+            }
+            val mapping = object : OffsetMapping {
+                override fun originalToTransformed(offset: Int) = offset + prefix.length
+                override fun transformedToOriginal(offset: Int) =
+                    (offset - prefix.length).coerceAtLeast(0)
+            }
+            TransformedText(transformed, mapping)
+        }
         rule.setMaterialContent {
             TextField(
                 modifier = Modifier.testTag(TextfieldTag),
                 value = "",
                 onValueChange = {},
-                label = {},
-                onTextInputStarted = {
-                    controller = it
-                }
+                visualTransformation = prefixTransformation,
+                placeholder = {
+                    Text(
+                        text = "placeholder",
+                        color = Color.Red,
+                        modifier = Modifier.background(Color.Red)
+                    )
+                },
+                textStyle = TextStyle(color = Color.White),
+                colors = TextFieldDefaults.textFieldColors(
+                    backgroundColor = Color.White,
+                    unfocusedIndicatorColor = Color.Transparent
+                )
             )
         }
-        assertThat(controller).isNull()
-
         rule.onNodeWithTag(TextfieldTag)
-            .performClick()
-
-        rule.runOnIdle {
-            assertThat(controller).isNotNull()
-        }
+            .captureToImage()
+            .assertPixels {
+                Color.White
+            }
     }
 
     private val View.isSoftwareKeyboardShown: Boolean
diff --git a/compose/material/material/src/androidMain/kotlin/androidx/compose/material/AndroidMenu.android.kt b/compose/material/material/src/androidMain/kotlin/androidx/compose/material/AndroidMenu.android.kt
index 8622f56..546a3b91 100644
--- a/compose/material/material/src/androidMain/kotlin/androidx/compose/material/AndroidMenu.android.kt
+++ b/compose/material/material/src/androidMain/kotlin/androidx/compose/material/AndroidMenu.android.kt
@@ -17,12 +17,12 @@
 package androidx.compose.material
 
 import androidx.compose.animation.core.MutableTransitionState
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.ColumnScope
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.RowScope
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
@@ -113,10 +113,10 @@
  * @param enabled Controls the enabled state of the menu item - when `false`, the menu item
  * will not be clickable and [onClick] will not be invoked
  * @param contentPadding the padding applied to the content of this menu item
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this DropdownMenuItem. You can create and pass in your own remembered
- * [InteractionState] if you want to read the [InteractionState] and customize the appearance /
- * behavior of this DropdownMenuItem in different [Interaction]s.
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this DropdownMenuItem. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this DropdownMenuItem in different [Interaction]s.
  */
 @Composable
 fun DropdownMenuItem(
@@ -124,7 +124,7 @@
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
     contentPadding: PaddingValues = MenuDefaults.DropdownMenuItemContentPadding,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     content: @Composable RowScope.() -> Unit
 ) {
     DropdownMenuItemContent(
@@ -132,7 +132,7 @@
         modifier = modifier,
         enabled = enabled,
         contentPadding = contentPadding,
-        interactionState = interactionState,
+        interactionSource = interactionSource,
         content = content
     )
 }
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt
index f72dd9e..3a5248b 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt
@@ -16,11 +16,11 @@
 
 package androidx.compose.material
 
-import androidx.compose.animation.core.AnimationEndReason
 import androidx.compose.animation.core.AnimationSpec
 import androidx.compose.animation.core.TweenSpec
 import androidx.compose.animation.core.animateFloatAsState
 import androidx.compose.foundation.Canvas
+import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.gestures.detectTapGestures
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
@@ -39,11 +39,10 @@
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.input.nestedscroll.nestedScroll
-import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.input.nestedscroll.nestedScroll
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.layout.SubcomposeLayout
 import androidx.compose.ui.platform.LocalDensity
@@ -58,6 +57,7 @@
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.util.fastMap
 import androidx.compose.ui.zIndex
+import kotlinx.coroutines.CancellationException
 import kotlinx.coroutines.launch
 import kotlin.math.max
 import kotlin.math.min
@@ -113,19 +113,21 @@
 
     /**
      * Reveal the back layer with animation and suspend until it if fully revealed or animation
-     * has been cancelled.
+     * has been cancelled.  This method will throw [CancellationException] if the animation is
+     * interrupted
      *
      * @return the reason the reveal animation ended
      */
-    suspend fun reveal(): AnimationEndReason = animateTo(targetValue = Revealed)
+    suspend fun reveal() = animateTo(targetValue = Revealed)
 
     /**
      * Conceal the back layer with animation and suspend until it if fully concealed or animation
-     * has been cancelled.
+     * has been cancelled. This method will throw [CancellationException] if the animation is
+     * interrupted
      *
      * @return the reason the conceal animation ended
      */
-    suspend fun conceal(): AnimationEndReason = animateTo(targetValue = Concealed)
+    suspend fun conceal() = animateTo(targetValue = Concealed)
 
     internal val nestedScrollConnection = this.PreUpPostDownNestedScrollConnection
 
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt
index 58d9c28..eb184b3 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt
@@ -20,8 +20,8 @@
 import androidx.compose.animation.core.TweenSpec
 import androidx.compose.animation.core.VectorizedAnimationSpec
 import androidx.compose.animation.core.animateFloatAsState
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Row
@@ -30,6 +30,7 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.selection.selectable
+import androidx.compose.foundation.selection.selectableGroup
 import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
@@ -97,7 +98,10 @@
         modifier = modifier
     ) {
         Row(
-            Modifier.fillMaxWidth().height(BottomNavigationHeight),
+            Modifier
+                .fillMaxWidth()
+                .height(BottomNavigationHeight)
+                .selectableGroup(),
             horizontalArrangement = Arrangement.SpaceBetween,
             content = content
         )
@@ -128,10 +132,10 @@
  * @param label optional text label for this item
  * @param alwaysShowLabel whether to always show the label for this item. If false, the label will
  * only be shown when this item is selected.
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this BottomNavigationItem. You can create and pass in your own remembered
- * [InteractionState] if you want to read the [InteractionState] and customize the appearance /
- * behavior of this BottomNavigationItem in different [Interaction]s.
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this BottomNavigationItem. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this BottomNavigationItem in different [Interaction]s.
  * @param selectedContentColor the color of the text label and icon when this item is selected,
  * and the color of the ripple.
  * @param unselectedContentColor the color of the text label and icon when this item is not selected
@@ -145,7 +149,7 @@
     enabled: Boolean = true,
     label: @Composable (() -> Unit)? = null,
     alwaysShowLabel: Boolean = true,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     selectedContentColor: Color = LocalContentColor.current,
     unselectedContentColor: Color = selectedContentColor.copy(alpha = ContentAlpha.medium)
 ) {
@@ -167,7 +171,7 @@
                 onClick = onClick,
                 enabled = enabled,
                 role = Role.Tab,
-                interactionState = interactionState,
+                interactionSource = interactionSource,
                 indication = ripple
             )
             .weight(1f),
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
index b096a61..e5bded3 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.material
 
-import androidx.compose.animation.core.AnimationEndReason
 import androidx.compose.animation.core.AnimationSpec
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.layout.Box
@@ -49,6 +48,7 @@
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
+import kotlinx.coroutines.CancellationException
 import kotlinx.coroutines.launch
 import kotlin.math.roundToInt
 
@@ -100,19 +100,21 @@
 
     /**
      * Expand the bottom sheet with animation and suspend until it if fully expanded or animation
-     * has been cancelled.
+     * has been cancelled. This method will throw [CancellationException] if the animation is
+     * interrupted
      *
      * @return the reason the expand animation ended
      */
-    suspend fun expand(): AnimationEndReason = animateTo(BottomSheetValue.Expanded)
+    suspend fun expand() = animateTo(BottomSheetValue.Expanded)
 
     /**
      * Collapse the bottom sheet with animation and suspend until it if fully collapsed or animation
-     * has been cancelled.
+     * has been cancelled. This method will throw [CancellationException] if the animation is
+     * interrupted
      *
      * @return the reason the collapse animation ended
      */
-    suspend fun collapse(): AnimationEndReason = animateTo(BottomSheetValue.Collapsed)
+    suspend fun collapse() = animateTo(BottomSheetValue.Collapsed)
 
     companion object {
         /**
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Button.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Button.kt
index d684b53..13c198f 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Button.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Button.kt
@@ -14,17 +14,17 @@
  * limitations under the License.
  */
 
-@file:Suppress("NOTHING_TO_INLINE")
-
 package androidx.compose.material
 
 import androidx.compose.animation.core.Animatable
 import androidx.compose.animation.core.VectorConverter
 import androidx.compose.foundation.BorderStroke
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.indication
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.InteractionSource
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.Row
@@ -33,22 +33,25 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.State
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateListOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberUpdatedState
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.compositeOver
 import androidx.compose.ui.semantics.Role
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
+import kotlinx.coroutines.flow.collect
 
 /**
  * Material Design implementation of a
@@ -76,11 +79,10 @@
  * @param modifier Modifier to be applied to the button
  * @param enabled Controls the enabled state of the button. When `false`, this button will not
  * be clickable
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this Button. You can create and pass in your own remembered [InteractionState] if
- * you want to read the [InteractionState] and customize the appearance / behavior of this Button
- * in different [Interaction]s, such as customizing how the [elevation] of this Button changes when
- * it is [Interaction.Pressed].
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this Button. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this Button in different [Interaction]s.
  * @param elevation [ButtonElevation] used to resolve the elevation for this button in different
  * states. This controls the size of the shadow below the button. Pass `null` here to disable
  * elevation for this button. See [ButtonDefaults.elevation].
@@ -95,7 +97,7 @@
     onClick: () -> Unit,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     elevation: ButtonElevation? = ButtonDefaults.elevation(),
     shape: Shape = MaterialTheme.shapes.small,
     border: BorderStroke? = null,
@@ -113,12 +115,12 @@
         color = colors.backgroundColor(enabled).value,
         contentColor = contentColor.copy(alpha = 1f),
         border = border,
-        elevation = elevation?.elevation(enabled, interactionState)?.value ?: 0.dp,
+        elevation = elevation?.elevation(enabled, interactionSource)?.value ?: 0.dp,
         modifier = modifier.clickable(
             onClick = onClick,
             enabled = enabled,
             role = Role.Button,
-            interactionState = interactionState,
+            interactionSource = interactionSource,
             indication = null
         )
     ) {
@@ -132,7 +134,7 @@
                             minWidth = ButtonDefaults.MinWidth,
                             minHeight = ButtonDefaults.MinHeight
                         )
-                        .indication(interactionState, rememberRipple())
+                        .indication(interactionSource, rememberRipple())
                         .padding(contentPadding),
                     horizontalArrangement = Arrangement.Center,
                     verticalAlignment = Alignment.CenterVertically,
@@ -167,11 +169,10 @@
  * @param modifier Modifier to be applied to the button
  * @param enabled Controls the enabled state of the button. When `false`, this button will not
  * be clickable
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this Button. You can create and pass in your own remembered [InteractionState] if
- * you want to read the [InteractionState] and customize the appearance / behavior of this Button
- * in different [Interaction]s, such as customizing how the [elevation] of this Button changes when
- * it is [Interaction.Pressed].
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this Button. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this Button in different [Interaction]s.
  * @param elevation [ButtonElevation] used to resolve the elevation for this button in different
  * states. An OutlinedButton typically has no elevation, see [Button] for a button with elevation.
  * @param shape Defines the button's shape as well as its shadow
@@ -181,22 +182,22 @@
  * @param contentPadding The spacing values to apply internally between the container and the content
  */
 @Composable
-inline fun OutlinedButton(
-    noinline onClick: () -> Unit,
+fun OutlinedButton(
+    onClick: () -> Unit,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     elevation: ButtonElevation? = null,
     shape: Shape = MaterialTheme.shapes.small,
     border: BorderStroke? = ButtonDefaults.outlinedBorder,
     colors: ButtonColors = ButtonDefaults.outlinedButtonColors(),
     contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
-    noinline content: @Composable RowScope.() -> Unit
+    content: @Composable RowScope.() -> Unit
 ) = Button(
     onClick = onClick,
     modifier = modifier,
     enabled = enabled,
-    interactionState = interactionState,
+    interactionSource = interactionSource,
     elevation = elevation,
     shape = shape,
     border = border,
@@ -226,11 +227,10 @@
  * @param modifier Modifier to be applied to the button
  * @param enabled Controls the enabled state of the button. When `false`, this button will not
  * be clickable
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this Button. You can create and pass in your own remembered [InteractionState] if
- * you want to read the [InteractionState] and customize the appearance / behavior of this Button
- * in different [Interaction]s, such as customizing how the [elevation] of this Button changes when
- * it is [Interaction.Pressed].
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this Button. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this Button in different [Interaction]s.
  * @param elevation [ButtonElevation] used to resolve the elevation for this button in different
  * states. A TextButton typically has no elevation, see [Button] for a button with elevation.
  * @param shape Defines the button's shape as well as its shadow
@@ -240,22 +240,22 @@
  * @param contentPadding The spacing values to apply internally between the container and the content
  */
 @Composable
-inline fun TextButton(
-    noinline onClick: () -> Unit,
+fun TextButton(
+    onClick: () -> Unit,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     elevation: ButtonElevation? = null,
     shape: Shape = MaterialTheme.shapes.small,
     border: BorderStroke? = null,
     colors: ButtonColors = ButtonDefaults.textButtonColors(),
     contentPadding: PaddingValues = ButtonDefaults.TextButtonContentPadding,
-    noinline content: @Composable RowScope.() -> Unit
+    content: @Composable RowScope.() -> Unit
 ) = Button(
     onClick = onClick,
     modifier = modifier,
     enabled = enabled,
-    interactionState = interactionState,
+    interactionSource = interactionSource,
     elevation = elevation,
     shape = shape,
     border = border,
@@ -272,13 +272,14 @@
 @Stable
 interface ButtonElevation {
     /**
-     * Represents the elevation used in a button, depending on [enabled] and [interactionState].
+     * Represents the elevation used in a button, depending on [enabled] and
+     * [interactionSource].
      *
      * @param enabled whether the button is enabled
-     * @param interactionState the [InteractionState] for this button
+     * @param interactionSource the [InteractionSource] for this button
      */
     @Composable
-    fun elevation(enabled: Boolean, interactionState: InteractionState): State<Dp>
+    fun elevation(enabled: Boolean, interactionSource: InteractionSource): State<Dp>
 }
 
 /**
@@ -359,7 +360,7 @@
      * @param defaultElevation the elevation to use when the [Button] is enabled, and has no
      * other [Interaction]s.
      * @param pressedElevation the elevation to use when the [Button] is enabled and
-     * is [Interaction.Pressed].
+     * is pressed.
      * @param disabledElevation the elevation to use when the [Button] is not enabled.
      */
     @Composable
@@ -487,16 +488,31 @@
     private val disabledElevation: Dp,
 ) : ButtonElevation {
     @Composable
-    override fun elevation(enabled: Boolean, interactionState: InteractionState): State<Dp> {
-        val interaction = interactionState.value.lastOrNull {
-            it is Interaction.Pressed
+    override fun elevation(enabled: Boolean, interactionSource: InteractionSource): State<Dp> {
+        val interactions = remember { mutableStateListOf<Interaction>() }
+        LaunchedEffect(interactionSource) {
+            interactionSource.interactions.collect { interaction ->
+                when (interaction) {
+                    is PressInteraction.Press -> {
+                        interactions.add(interaction)
+                    }
+                    is PressInteraction.Release -> {
+                        interactions.remove(interaction.press)
+                    }
+                    is PressInteraction.Cancel -> {
+                        interactions.remove(interaction.press)
+                    }
+                }
+            }
         }
 
+        val interaction = interactions.lastOrNull()
+
         val target = if (!enabled) {
             disabledElevation
         } else {
             when (interaction) {
-                Interaction.Pressed -> pressedElevation
+                is PressInteraction.Press -> pressedElevation
                 else -> defaultElevation
             }
         }
@@ -511,7 +527,7 @@
         } else {
             LaunchedEffect(target) {
                 val lastInteraction = when (animatable.targetValue) {
-                    pressedElevation -> Interaction.Pressed
+                    pressedElevation -> PressInteraction.Press(Offset.Zero)
                     else -> null
                 }
                 animatable.animateElevation(
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Checkbox.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Checkbox.kt
index fe4f57e..8229fc6 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Checkbox.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Checkbox.kt
@@ -23,8 +23,8 @@
 import androidx.compose.animation.core.tween
 import androidx.compose.animation.core.updateTransition
 import androidx.compose.foundation.Canvas
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.foundation.layout.wrapContentSize
@@ -65,30 +65,30 @@
  *
  * @param checked whether Checkbox is checked or unchecked
  * @param onCheckedChange callback to be invoked when checkbox is being clicked,
- * therefore the change of checked state in requested.
+ * therefore the change of checked state in requested.  If null, then this is passive
+ * and relies entirely on a higher-level component to control the "checked" state.
  * @param modifier Modifier to be applied to the layout of the checkbox
- * @param enabled enabled whether or not this [Checkbox] will handle input events and appear
- * enabled for semantics purposes
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this Checkbox. You can create and pass in your own remembered
- * [InteractionState] if you want to read the [InteractionState] and customize the appearance /
- * behavior of this Checkbox in different [Interaction]s.
+ * @param enabled whether the component is enabled or grayed out
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this Checkbox. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this Checkbox in different [Interaction]s.
  * @param colors [CheckboxColors] that will be used to determine the color of the checkmark / box
  * / border in different states. See [CheckboxDefaults.colors].
  */
 @Composable
 fun Checkbox(
     checked: Boolean,
-    onCheckedChange: (Boolean) -> Unit,
+    onCheckedChange: ((Boolean) -> Unit)?,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     colors: CheckboxColors = CheckboxDefaults.colors()
 ) {
     TriStateCheckbox(
         state = ToggleableState(checked),
-        onClick = { onCheckedChange(!checked) },
-        interactionState = interactionState,
+        onClick = if (onCheckedChange != null) { { onCheckedChange(!checked) } } else null,
+        interactionSource = interactionSource,
         enabled = enabled,
         colors = colors,
         modifier = modifier
@@ -108,41 +108,47 @@
  *
  * @param state whether TriStateCheckbox is checked, unchecked or in indeterminate state
  * @param onClick callback to be invoked when checkbox is being clicked,
- * therefore the change of ToggleableState state is requested.
+ * therefore the change of ToggleableState state is requested.  If null, then this is passive
+ * and relies entirely on a higher-level component to control the state.
  * @param modifier Modifier to be applied to the layout of the checkbox
- * @param enabled whether or not this [TriStateCheckbox] will handle input events and
- * appear enabled for semantics purposes
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this TriStateCheckbox. You can create and pass in your own remembered
- * [InteractionState] if you want to read the [InteractionState] and customize the appearance /
- * behavior of this TriStateCheckbox in different [Interaction]s.
+ * @param enabled whether the component is enabled or grayed out
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this TriStateCheckbox. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this TriStateCheckbox in different [Interaction]s.
  * @param colors [CheckboxColors] that will be used to determine the color of the checkmark / box
  * / border in different states. See [CheckboxDefaults.colors].
  */
 @Composable
 fun TriStateCheckbox(
     state: ToggleableState,
-    onClick: () -> Unit,
+    onClick: (() -> Unit)?,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     colors: CheckboxColors = CheckboxDefaults.colors()
 ) {
-    CheckboxImpl(
-        enabled = enabled,
-        value = state,
-        modifier = modifier
-            .triStateToggleable(
+    val toggleableModifier =
+        if (onClick != null) {
+            Modifier.triStateToggleable(
                 state = state,
                 onClick = onClick,
                 enabled = enabled,
                 role = Role.Checkbox,
-                interactionState = interactionState,
+                interactionSource = interactionSource,
                 indication = rememberRipple(
                     bounded = false,
                     radius = CheckboxRippleRadius
                 )
             )
+        } else {
+            Modifier
+        }
+    CheckboxImpl(
+        enabled = enabled,
+        value = state,
+        modifier = modifier
+            .then(toggleableModifier)
             .padding(CheckboxDefaultPadding),
         colors = colors
     )
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
index 1e6ac33..6383e28 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.material
 
-import androidx.compose.animation.core.AnimationEndReason
 import androidx.compose.animation.core.TweenSpec
 import androidx.compose.foundation.Canvas
 import androidx.compose.foundation.gestures.Orientation
@@ -50,6 +49,7 @@
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.util.lerp
+import kotlinx.coroutines.CancellationException
 import kotlinx.coroutines.launch
 import kotlin.math.roundToInt
 
@@ -119,19 +119,21 @@
 
     /**
      * Open the drawer with animation and suspend until it if fully opened or animation has been
-     * cancelled.
+     * cancelled. This method will throw [CancellationException] if the animation is
+     * interrupted
      *
      * @return the reason the open animation ended
      */
-    suspend fun open(): AnimationEndReason = animateTo(DrawerValue.Open)
+    suspend fun open() = animateTo(DrawerValue.Open)
 
     /**
      * Close the drawer with animation and suspend until it if fully closed or animation has been
-     * cancelled.
+     * cancelled. This method will throw [CancellationException] if the animation is
+     * interrupted
      *
      * @return the reason the close animation ended
      */
-    suspend fun close(): AnimationEndReason = animateTo(DrawerValue.Closed)
+    suspend fun close() = animateTo(DrawerValue.Closed)
 
     companion object {
         /**
@@ -181,15 +183,17 @@
 
     /**
      * Open the drawer with animation and suspend until it if fully opened or animation has been
-     * cancelled.
+     * cancelled. This method will throw [CancellationException] if the animation is
+     * interrupted
      *
      * @return the reason the open animation ended
      */
-    suspend fun open(): AnimationEndReason = animateTo(BottomDrawerValue.Open)
+    suspend fun open() = animateTo(BottomDrawerValue.Open)
 
     /**
      * Close the drawer with animation and suspend until it if fully closed or animation has been
-     * cancelled.
+     * cancelled. This method will throw [CancellationException] if the animation is
+     * interrupted
      *
      * @return the reason the close animation ended
      */
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Elevation.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Elevation.kt
index 8928ce2..1a8d1e1 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Elevation.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Elevation.kt
@@ -21,7 +21,9 @@
 import androidx.compose.animation.core.CubicBezierEasing
 import androidx.compose.animation.core.FastOutSlowInEasing
 import androidx.compose.animation.core.TweenSpec
-import androidx.compose.foundation.Interaction
+import androidx.compose.foundation.interaction.DragInteraction
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.ui.unit.Dp
 
 /**
@@ -34,7 +36,7 @@
  * desired for the [to] state.
  * @param from the previous [Interaction] that was used to calculate elevation. `null` if there
  * was no previous [Interaction], such as when the component is in its default state.
- * @param to the [Interaction] that this component is moving to, such as [Interaction.Pressed]
+ * @param to the [Interaction] that this component is moving to, such as [PressInteraction.Press]
  * when this component is being pressed. `null` if this component is moving back to its default
  * state.
  */
@@ -75,8 +77,8 @@
      */
     fun incomingAnimationSpecForInteraction(interaction: Interaction): AnimationSpec<Dp>? {
         return when (interaction) {
-            is Interaction.Pressed -> DefaultIncomingSpec
-            is Interaction.Dragged -> DefaultIncomingSpec
+            is PressInteraction.Press -> DefaultIncomingSpec
+            is DragInteraction.Start -> DefaultIncomingSpec
             else -> null
         }
     }
@@ -89,8 +91,8 @@
      */
     fun outgoingAnimationSpecForInteraction(interaction: Interaction): AnimationSpec<Dp>? {
         return when (interaction) {
-            is Interaction.Pressed -> DefaultOutgoingSpec
-            is Interaction.Dragged -> DefaultOutgoingSpec
+            is PressInteraction.Press -> DefaultOutgoingSpec
+            is DragInteraction.Start -> DefaultOutgoingSpec
             // TODO: use [HoveredOutgoingSpec] when hovered
             else -> null
         }
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/FloatingActionButton.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/FloatingActionButton.kt
index 98fd3dd..5420d3c3 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/FloatingActionButton.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/FloatingActionButton.kt
@@ -18,8 +18,10 @@
 
 import androidx.compose.animation.core.Animatable
 import androidx.compose.animation.core.VectorConverter
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.InteractionSource
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.indication
 import androidx.compose.foundation.layout.Box
@@ -32,18 +34,21 @@
 import androidx.compose.foundation.shape.CornerSize
 import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.State
+import androidx.compose.runtime.mutableStateListOf
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.semantics.Role
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
+import kotlinx.coroutines.flow.collect
 
 /**
  * A floating action button (FAB) is a button that represents the primary action of a screen.
@@ -57,11 +62,10 @@
  * @param onClick will be called when user clicked on this FAB. The FAB will be disabled
  * when it is null.
  * @param modifier [Modifier] to be applied to this FAB.
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this FAB. You can create and pass in your own remembered [InteractionState] if
- * you want to read the [InteractionState] and customize the appearance / behavior of this FAB
- * in different [Interaction]s, such as customizing how the [elevation] of this FAB changes when
- * it is [Interaction.Pressed].
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this FAB. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this FAB in different [Interaction]s.
  * @param shape The [Shape] of this FAB
  * @param backgroundColor The background color. Use [Color.Transparent] to have no color
  * @param contentColor The preferred content color for content inside this FAB
@@ -73,7 +77,7 @@
 fun FloatingActionButton(
     onClick: () -> Unit,
     modifier: Modifier = Modifier,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     shape: Shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)),
     backgroundColor: Color = MaterialTheme.colors.secondary,
     contentColor: Color = contentColorFor(backgroundColor),
@@ -87,20 +91,20 @@
         modifier = modifier.clickable(
             onClick = onClick,
             role = Role.Button,
-            interactionState = interactionState,
+            interactionSource = interactionSource,
             indication = null
         ),
         shape = shape,
         color = backgroundColor,
         contentColor = contentColor,
-        elevation = elevation.elevation(interactionState).value
+        elevation = elevation.elevation(interactionSource).value
     ) {
         CompositionLocalProvider(LocalContentAlpha provides contentColor.alpha) {
             ProvideTextStyle(MaterialTheme.typography.button) {
                 Box(
                     modifier = Modifier
                         .defaultMinSize(minWidth = FabSize, minHeight = FabSize)
-                        .indication(interactionState, rememberRipple()),
+                        .indication(interactionSource, rememberRipple()),
                     contentAlignment = Alignment.Center
                 ) { content() }
             }
@@ -128,11 +132,10 @@
  * @param modifier [Modifier] to be applied to this FAB
  * @param icon Optional icon for this FAB, typically this will be a
  * [Icon].
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this FAB. You can create and pass in your own remembered [InteractionState] if
- * you want to read the [InteractionState] and customize the appearance / behavior of this FAB
- * in different [Interaction]s, such as customizing how the [elevation] of this FAB changes when
- * it is [Interaction.Pressed].
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this FAB. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this FAB in different [Interaction]s.
  * @param shape The [Shape] of this FAB
  * @param backgroundColor The background color. Use [Color.Transparent] to have no color
  * @param contentColor The preferred content color. Will be used by text and iconography
@@ -145,7 +148,7 @@
     onClick: () -> Unit,
     modifier: Modifier = Modifier,
     icon: @Composable (() -> Unit)? = null,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     shape: Shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)),
     backgroundColor: Color = MaterialTheme.colors.secondary,
     contentColor: Color = contentColorFor(backgroundColor),
@@ -157,7 +160,7 @@
             minHeight = ExtendedFabSize
         ),
         onClick = onClick,
-        interactionState = interactionState,
+        interactionSource = interactionSource,
         shape = shape,
         backgroundColor = backgroundColor,
         contentColor = contentColor,
@@ -192,12 +195,13 @@
 @Stable
 interface FloatingActionButtonElevation {
     /**
-     * Represents the elevation used in a floating action button, depending on [interactionState].
+     * Represents the elevation used in a floating action button, depending on
+     * [interactionSource].
      *
-     * @param interactionState the [InteractionState] for this floating action button
+     * @param interactionSource the [InteractionSource] for this floating action button
      */
     @Composable
-    fun elevation(interactionState: InteractionState): State<Dp>
+    fun elevation(interactionSource: InteractionSource): State<Dp>
 }
 
 /**
@@ -212,7 +216,7 @@
      * @param defaultElevation the elevation to use when the [FloatingActionButton] has no
      * [Interaction]s
      * @param pressedElevation the elevation to use when the [FloatingActionButton] is
-     * [Interaction.Pressed].
+     * pressed.
      */
     @Composable
     fun elevation(
@@ -239,13 +243,28 @@
     private val pressedElevation: Dp,
 ) : FloatingActionButtonElevation {
     @Composable
-    override fun elevation(interactionState: InteractionState): State<Dp> {
-        val interaction = interactionState.value.lastOrNull {
-            it is Interaction.Pressed
+    override fun elevation(interactionSource: InteractionSource): State<Dp> {
+        val interactions = remember { mutableStateListOf<Interaction>() }
+        LaunchedEffect(interactionSource) {
+            interactionSource.interactions.collect { interaction ->
+                when (interaction) {
+                    is PressInteraction.Press -> {
+                        interactions.add(interaction)
+                    }
+                    is PressInteraction.Release -> {
+                        interactions.remove(interaction.press)
+                    }
+                    is PressInteraction.Cancel -> {
+                        interactions.remove(interaction.press)
+                    }
+                }
+            }
         }
 
+        val interaction = interactions.lastOrNull()
+
         val target = when (interaction) {
-            Interaction.Pressed -> pressedElevation
+            is PressInteraction.Press -> pressedElevation
             else -> defaultElevation
         }
 
@@ -253,7 +272,7 @@
 
         LaunchedEffect(target) {
             val lastInteraction = when (animatable.targetValue) {
-                pressedElevation -> Interaction.Pressed
+                pressedElevation -> PressInteraction.Press(Offset.Zero)
                 else -> null
             }
             animatable.animateElevation(
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/IconButton.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/IconButton.kt
index 56b7f40..7abb824 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/IconButton.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/IconButton.kt
@@ -16,8 +16,8 @@
 
 package androidx.compose.material
 
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.size
@@ -48,10 +48,10 @@
  * @param modifier optional [Modifier] for this IconButton
  * @param enabled whether or not this IconButton will handle input events and appear enabled for
  * semantics purposes
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this IconButton. You can create and pass in your own remembered
- * [InteractionState] if you want to read the [InteractionState] and customize the appearance /
- * behavior of this IconButton in different [Interaction]s.
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this IconButton. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this IconButton in different [Interaction]s.
  * @param content the content (icon) to be drawn inside the IconButton. This is typically an
  * [Icon].
  */
@@ -60,7 +60,7 @@
     onClick: () -> Unit,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     content: @Composable () -> Unit
 ) {
     Box(
@@ -69,7 +69,7 @@
                 onClick = onClick,
                 enabled = enabled,
                 role = Role.Button,
-                interactionState = interactionState,
+                interactionSource = interactionSource,
                 indication = rememberRipple(bounded = false, radius = RippleRadius)
             )
             .then(IconButtonSizeModifier),
@@ -88,10 +88,10 @@
  * @param modifier optional [Modifier] for this IconToggleButton
  * @param enabled enabled whether or not this [IconToggleButton] will handle input events and appear
  * enabled for semantics purposes
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this IconToggleButton. You can create and pass in your own remembered
- * [InteractionState] if you want to read the [InteractionState] and customize the appearance /
- * behavior of this IconToggleButton in different [Interaction]s.
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this IconToggleButton. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this IconToggleButton in different [Interaction]s.
  * @param content the content (icon) to be drawn inside the IconToggleButton. This is typically an
  * [Icon].
  */
@@ -101,7 +101,7 @@
     onCheckedChange: (Boolean) -> Unit,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     content: @Composable () -> Unit
 ) {
     Box(
@@ -110,7 +110,7 @@
             onValueChange = onCheckedChange,
             enabled = enabled,
             role = Role.Checkbox,
-            interactionState = interactionState,
+            interactionSource = interactionSource,
             indication = rememberRipple(bounded = false, radius = RippleRadius)
         ).then(IconButtonSizeModifier),
         contentAlignment = Alignment.Center
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/MaterialTheme.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/MaterialTheme.kt
index a336319..e41a07e 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/MaterialTheme.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/MaterialTheme.kt
@@ -17,7 +17,6 @@
 package androidx.compose.material
 
 import androidx.compose.foundation.LocalIndication
-import androidx.compose.material.ripple.ExperimentalRippleApi
 import androidx.compose.material.ripple.LocalRippleTheme
 import androidx.compose.material.ripple.RippleTheme
 import androidx.compose.material.ripple.rememberRipple
@@ -53,7 +52,6 @@
  * @param typography A set of text styles to be used as this hierarchy's typography system
  * @param shapes A set of shapes to be used by the components in this hierarchy
  */
-@OptIn(ExperimentalRippleApi::class)
 @Composable
 fun MaterialTheme(
     colors: Colors = MaterialTheme.colors,
@@ -115,7 +113,6 @@
         get() = LocalShapes.current
 }
 
-@OptIn(ExperimentalRippleApi::class)
 @Immutable
 private object MaterialRippleTheme : RippleTheme {
     @Composable
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Menu.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Menu.kt
index b4c0338..c0b77f1 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Menu.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Menu.kt
@@ -21,11 +21,10 @@
 import androidx.compose.animation.core.animateFloat
 import androidx.compose.animation.core.tween
 import androidx.compose.animation.core.updateTransition
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.ColumnScope
-import androidx.compose.foundation.layout.ExperimentalLayout
 import androidx.compose.foundation.layout.IntrinsicSize
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.Row
@@ -38,8 +37,8 @@
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.remember
@@ -49,8 +48,8 @@
 import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.DpOffset
-import androidx.compose.ui.unit.IntRect
 import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.IntRect
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
@@ -123,7 +122,6 @@
         },
         elevation = MenuElevation
     ) {
-        @OptIn(ExperimentalLayout::class)
         Column(
             modifier = modifier
                 .padding(vertical = DropdownMenuVerticalPadding)
@@ -140,7 +138,7 @@
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
     contentPadding: PaddingValues = MenuDefaults.DropdownMenuItemContentPadding,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     content: @Composable RowScope.() -> Unit
 ) {
     // TODO(popam, b/156911853): investigate replacing this Row with ListItem
@@ -149,7 +147,7 @@
             .clickable(
                 enabled = enabled,
                 onClick = onClick,
-                interactionState = interactionState,
+                interactionSource = interactionSource,
                 indication = rememberRipple(true)
             )
             .fillMaxWidth()
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt
index 1391894..6002125 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt
@@ -16,11 +16,11 @@
 
 package androidx.compose.material
 
-import androidx.compose.animation.core.AnimationEndReason
 import androidx.compose.animation.core.AnimationSpec
 import androidx.compose.animation.core.TweenSpec
 import androidx.compose.animation.core.animateFloatAsState
 import androidx.compose.foundation.Canvas
+import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.gestures.detectTapGestures
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
@@ -35,10 +35,9 @@
 import androidx.compose.runtime.saveable.Saver
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.input.nestedscroll.nestedScroll
-import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.input.nestedscroll.nestedScroll
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.layout.SubcomposeLayout
 import androidx.compose.ui.semantics.collapse
@@ -49,6 +48,7 @@
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.dp
+import kotlinx.coroutines.CancellationException
 import kotlinx.coroutines.launch
 import kotlin.math.max
 import kotlin.math.roundToInt
@@ -127,19 +127,21 @@
 
     /**
      * Fully expand the bottom sheet with animation and suspend until it if fully expanded or
-     * animation has been cancelled.
+     * animation has been cancelled. This method will throw [CancellationException] if the
+     * animation is interrupted
      *
      * @return the reason the expand animation ended
      */
-    internal suspend fun expand(): AnimationEndReason = animateTo(ModalBottomSheetValue.Expanded)
+    internal suspend fun expand() = animateTo(ModalBottomSheetValue.Expanded)
 
     /**
      * Hide the bottom sheet with animation and suspend until it if fully hidden or animation has
-     * been cancelled.
+     * been cancelled. This method will throw [CancellationException] if the animation is
+     * interrupted
      *
      * @return the reason the hide animation ended
      */
-    suspend fun hide(): AnimationEndReason = animateTo(ModalBottomSheetValue.Hidden)
+    suspend fun hide() = animateTo(ModalBottomSheetValue.Hidden)
 
     internal val nestedScrollConnection = this.PreUpPostDownNestedScrollConnection
 
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/OutlinedTextField.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/OutlinedTextField.kt
index 520f7e9..5e38b4b 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/OutlinedTextField.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/OutlinedTextField.kt
@@ -16,14 +16,16 @@
 
 package androidx.compose.material
 
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.defaultMinSize
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.text.BasicTextField
 import androidx.compose.foundation.text.KeyboardActions
 import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.material.TextFieldDefaults.MinHeight
+import androidx.compose.material.TextFieldDefaults.MinWidth
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.getValue
@@ -41,7 +43,6 @@
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.layout.Placeable
 import androidx.compose.ui.layout.layoutId
-import androidx.compose.ui.text.SoftwareKeyboardController
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.KeyboardType
@@ -87,39 +88,31 @@
  * container
  * @param trailingIcon the optional trailing icon to be displayed at the end of the text field
  * container
- * @param isErrorValue indicates if the text field's current value is in error. If set to true, the
- * label, bottom indicator and trailing icon will be displayed in [errorColor] color
- * @param visualTransformation transforms the visual representation of the input [value].
+ * @param isError indicates if the text field's current value is in error. If set to true, the
+ * label, bottom indicator and trailing icon by default will be displayed in error color
+ * @param visualTransformation transforms the visual representation of the input [value]
  * For example, you can use [androidx.compose.ui.text.input.PasswordVisualTransformation] to create a password
  * text field. By default no visual transformation is applied
  * @param keyboardOptions software keyboard options that contains configuration such as
- * [KeyboardType] and [ImeAction].
+ * [KeyboardType] and [ImeAction]
  * @param keyboardActions when the input service emits an IME action, the corresponding callback
  * is called. Note that this IME action may be different from what you specified in
- * [KeyboardOptions.imeAction].
+ * [KeyboardOptions.imeAction]
  * @param singleLine when set to true, this text field becomes a single horizontally scrolling
  * text field instead of wrapping onto multiple lines. The keyboard will be informed to not show
  * the return key as the [ImeAction]. Note that [maxLines] parameter will be ignored as the
- * maxLines attribute will be automatically set to 1.
+ * maxLines attribute will be automatically set to 1
  * @param maxLines the maximum height in terms of maximum number of visible lines. Should be
  * equal or greater than 1. Note that this parameter will be ignored and instead maxLines will be
- * set to 1 if [singleLine] is set to true.
- * [KeyboardOptions.imeAction] field. The callback also exposes a [SoftwareKeyboardController]
- * instance as a parameter that can be used to request to hide the software keyboard
- * @param onTextInputStarted a callback to be invoked when the connection with the platform's text
- * input service (e.g. software keyboard on Android) has been established. Called with the
- * [SoftwareKeyboardController] instance that can be used to request to show or hide the software
- * keyboard
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this OutlinedTextField. You can create and pass in your own remembered
- * [InteractionState] if you want to read the [InteractionState] and customize the appearance /
- * behavior of this OutlinedTextField in different [Interaction]s.
- * @param activeColor the color of the label, bottom indicator and the cursor when the text field is
- * in focus
- * @param inactiveColor the color of either the input text or placeholder when the text field is in
- * focus, and the color of the label and bottom indicator when the text field is not in focus
- * @param errorColor the alternative color of the label, bottom indicator, cursor and trailing icon
- * used when [isErrorValue] is set to true
+ * set to 1 if [singleLine] is set to true
+ * [KeyboardOptions.imeAction] field.
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this OutlinedTextField. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this OutlinedTextField in different [Interaction]s.
+ * @param colors [TextFieldColors] that will be used to resolve color of the text and content
+ * (including label, placeholder, leading and trailing icons, border) for this text field in
+ * different states. See [TextFieldDefaults.outlinedTextFieldColors]
  */
 @Composable
 fun OutlinedTextField(
@@ -133,23 +126,19 @@
     placeholder: @Composable (() -> Unit)? = null,
     leadingIcon: @Composable (() -> Unit)? = null,
     trailingIcon: @Composable (() -> Unit)? = null,
-    isErrorValue: Boolean = false,
+    isError: Boolean = false,
     visualTransformation: VisualTransformation = VisualTransformation.None,
     keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
     keyboardActions: KeyboardActions = KeyboardActions.Default,
     singleLine: Boolean = false,
     maxLines: Int = Int.MAX_VALUE,
-    onTextInputStarted: (SoftwareKeyboardController) -> Unit = {},
-    interactionState: InteractionState = remember { InteractionState() },
-    activeColor: Color = MaterialTheme.colors.primary,
-    inactiveColor: Color = MaterialTheme.colors.onSurface,
-    errorColor: Color = MaterialTheme.colors.error
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    colors: TextFieldColors = TextFieldDefaults.outlinedTextFieldColors()
 ) {
     var textFieldValueState by remember { mutableStateOf(TextFieldValue(text = value)) }
     val textFieldValue = textFieldValueState.copy(text = value)
 
-    TextFieldImpl(
-        type = TextFieldType.Outlined,
+    OutlinedTextField(
         enabled = enabled,
         readOnly = readOnly,
         value = textFieldValue,
@@ -164,20 +153,15 @@
         textStyle = textStyle,
         label = label,
         placeholder = placeholder,
-        leading = leadingIcon,
-        trailing = trailingIcon,
-        isErrorValue = isErrorValue,
+        leadingIcon = leadingIcon,
+        trailingIcon = trailingIcon,
+        isError = isError,
         visualTransformation = visualTransformation,
         keyboardOptions = keyboardOptions,
         keyboardActions = keyboardActions,
         maxLines = maxLines,
-        onTextInputStarted = onTextInputStarted,
-        interactionState = interactionState,
-        activeColor = activeColor,
-        inactiveColor = inactiveColor,
-        errorColor = errorColor,
-        backgroundColor = Color.Unspecified,
-        shape = RectangleShape
+        interactionSource = interactionSource,
+        colors = colors
     )
 }
 
@@ -213,39 +197,30 @@
  * container
  * @param trailingIcon the optional trailing icon to be displayed at the end of the text field
  * container
- * @param isErrorValue indicates if the text field's current value is in error state. If set to
- * true, the label, bottom indicator and trailing icon will be displayed in [errorColor] color
- * @param visualTransformation transforms the visual representation of the input [value].
+ * @param isError indicates if the text field's current value is in error state. If set to
+ * true, the label, bottom indicator and trailing icon by default will be displayed in error color
+ * @param visualTransformation transforms the visual representation of the input [value]
  * For example, you can use [androidx.compose.ui.text.input.PasswordVisualTransformation] to create a password
  * text field. By default no visual transformation is applied
  * @param keyboardOptions software keyboard options that contains configuration such as
- * [KeyboardType] and [ImeAction].
+ * [KeyboardType] and [ImeAction]
  * @param keyboardActions when the input service emits an IME action, the corresponding callback
  * is called. Note that this IME action may be different from what you specified in
- * [KeyboardOptions.imeAction].
+ * [KeyboardOptions.imeAction]
  * @param singleLine when set to true, this text field becomes a single horizontally scrolling
  * text field instead of wrapping onto multiple lines. The keyboard will be informed to not show
  * the return key as the [ImeAction]. Note that [maxLines] parameter will be ignored as the
- * maxLines attribute will be automatically set to 1.
+ * maxLines attribute will be automatically set to 1
  * @param maxLines the maximum height in terms of maximum number of visible lines. Should be
  * equal or greater than 1. Note that this parameter will be ignored and instead maxLines will be
- * set to 1 if [singleLine] is set to true.
- * [KeyboardOptions.imeAction] field. The callback also exposes a [SoftwareKeyboardController]
- * instance as a parameter that can be used to request to hide the software keyboard.
- * @param onTextInputStarted a callback to be invoked when the connection with the platform's text
- * input service (e.g. software keyboard on Android) has been established. Called with the
- * [SoftwareKeyboardController] instance that can be used to request to show or hide the software
- * keyboard
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this OutlinedTextField. You can create and pass in your own remembered
- * [InteractionState] if you want to read the [InteractionState] and customize the appearance /
- * behavior of this OutlinedTextField in different [Interaction]s.
- * @param activeColor the color of the label, bottom indicator and the cursor when the text field is
- * in focus
- * @param inactiveColor the color of either the input text or placeholder when the text field is in
- * focus, and the color of the label and bottom indicator when the text field is not in focus
- * @param errorColor the alternative color of the label, bottom indicator, cursor and trailing icon
- * used when [isErrorValue] is set to true
+ * set to 1 if [singleLine] is set to true
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this OutlinedTextField. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this OutlinedTextField in different [Interaction]s.
+ * @param colors [TextFieldColors] that will be used to resolve color of the text and content
+ * (including label, placeholder, leading and trailing icons, border) for this text field in
+ * different states. See [TextFieldDefaults.outlinedTextFieldColors]
  */
 @Composable
 fun OutlinedTextField(
@@ -259,17 +234,14 @@
     placeholder: @Composable (() -> Unit)? = null,
     leadingIcon: @Composable (() -> Unit)? = null,
     trailingIcon: @Composable (() -> Unit)? = null,
-    isErrorValue: Boolean = false,
+    isError: Boolean = false,
     visualTransformation: VisualTransformation = VisualTransformation.None,
     keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
     keyboardActions: KeyboardActions = KeyboardActions(),
     singleLine: Boolean = false,
     maxLines: Int = Int.MAX_VALUE,
-    onTextInputStarted: (SoftwareKeyboardController) -> Unit = {},
-    interactionState: InteractionState = remember { InteractionState() },
-    activeColor: Color = MaterialTheme.colors.primary,
-    inactiveColor: Color = MaterialTheme.colors.onSurface,
-    errorColor: Color = MaterialTheme.colors.error
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    colors: TextFieldColors = TextFieldDefaults.outlinedTextFieldColors()
 ) {
     TextFieldImpl(
         type = TextFieldType.Outlined,
@@ -284,18 +256,14 @@
         placeholder = placeholder,
         leading = leadingIcon,
         trailing = trailingIcon,
-        isErrorValue = isErrorValue,
+        isError = isError,
         visualTransformation = visualTransformation,
         keyboardOptions = keyboardOptions,
         keyboardActions = keyboardActions,
         maxLines = maxLines,
-        onTextInputStarted = onTextInputStarted,
-        interactionState = interactionState,
-        activeColor = activeColor,
-        inactiveColor = inactiveColor,
-        errorColor = errorColor,
-        backgroundColor = Color.Unspecified,
-        shape = RectangleShape
+        interactionSource = interactionSource,
+        shape = RectangleShape,
+        colors = colors
     )
 }
 
@@ -312,8 +280,7 @@
     singleLine: Boolean,
     maxLines: Int = Int.MAX_VALUE,
     visualTransformation: VisualTransformation,
-    onTextInputStarted: (SoftwareKeyboardController) -> Unit,
-    interactionState: InteractionState,
+    interactionSource: MutableInteractionSource,
     decoratedPlaceholder: @Composable ((Modifier) -> Unit)?,
     decoratedLabel: @Composable (() -> Unit)?,
     leading: @Composable (() -> Unit)?,
@@ -342,8 +309,8 @@
         value = value,
         modifier = modifier
             .defaultMinSize(
-                minWidth = TextFieldMinWidth,
-                minHeight = TextFieldMinHeight + OutlinedTextFieldTopPadding,
+                minWidth = MinWidth,
+                minHeight = MinHeight + OutlinedTextFieldTopPadding,
             )
             .padding(top = OutlinedTextFieldTopPadding)
             .drawOutlinedBorder(outlinedBorderParams),
@@ -355,8 +322,7 @@
         visualTransformation = visualTransformation,
         keyboardOptions = keyboardOptions,
         keyboardActions = keyboardActions,
-        interactionState = interactionState,
-        onTextInputStarted = onTextInputStarted,
+        interactionSource = interactionSource,
         singleLine = singleLine,
         maxLines = maxLines,
         decorationBox = @Composable { coreTextField ->
@@ -719,6 +685,7 @@
 // TODO(b/158077409) support shape in OutlinedTextField
 private val OutlinedTextFieldCornerRadius = 4.dp
 private val OutlinedTextFieldInnerPadding = 4.dp
+
 /*
 This padding is used to allow label not overlap with the content above it. This 8.dp will work
 for default cases when developers do not override the label's font size. If they do, they will
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/RadioButton.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/RadioButton.kt
index bdb73d6..9e6817b 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/RadioButton.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/RadioButton.kt
@@ -20,8 +20,8 @@
 import androidx.compose.animation.core.animateDpAsState
 import androidx.compose.animation.core.tween
 import androidx.compose.foundation.Canvas
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.padding
@@ -56,24 +56,25 @@
  * @sample androidx.compose.material.samples.RadioGroupSample
  *
  * @param selected boolean state for this button: either it is selected or not
- * @param onClick callback to be invoked when the RadioButton is being clicked
+ * @param onClick callback to be invoked when the RadioButton is being clicked.  If null,
+ * then this is passive and relies entirely on a higher-level component to control the state.
  * @param modifier Modifier to be applied to the radio button
  * @param enabled Controls the enabled state of the [RadioButton]. When `false`, this button will
  * not be selectable and appears in the disabled ui state
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this RadioButton. You can create and pass in your own remembered
- * [InteractionState] if you want to read the [InteractionState] and customize the appearance /
- * behavior of this RadioButton in different [Interaction]s.
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this RadioButton. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this RadioButton in different [Interaction]s.
  * @param colors [RadioButtonColors] that will be used to resolve the color used for this
  * RadioButton in different states. See [RadioButtonDefaults.colors].
  */
 @Composable
 fun RadioButton(
     selected: Boolean,
-    onClick: () -> Unit,
+    onClick: (() -> Unit)?,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     colors: RadioButtonColors = RadioButtonDefaults.colors()
 ) {
     val dotRadius by animateDpAsState(
@@ -81,19 +82,25 @@
         animationSpec = tween(durationMillis = RadioAnimationDuration)
     )
     val radioColor by colors.radioColor(enabled, selected)
-    Canvas(
-        modifier
-            .selectable(
+    val selectableModifier =
+        if (onClick != null) {
+            Modifier.selectable(
                 selected = selected,
                 onClick = onClick,
                 enabled = enabled,
                 role = Role.RadioButton,
-                interactionState = interactionState,
+                interactionSource = interactionSource,
                 indication = rememberRipple(
                     bounded = false,
                     radius = RadioButtonRippleRadius
                 )
             )
+        } else {
+            Modifier
+        }
+    Canvas(
+        modifier
+            .then(selectableModifier)
             .wrapContentSize(Alignment.Center)
             .padding(RadioButtonPadding)
             .requiredSize(RadioButtonSize)
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Slider.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Slider.kt
index 0d31a0f..1d3a691 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Slider.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Slider.kt
@@ -19,30 +19,36 @@
 import androidx.compose.animation.core.Animatable
 import androidx.compose.animation.core.TweenSpec
 import androidx.compose.foundation.Canvas
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.foundation.focusable
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.gestures.detectTapGestures
 import androidx.compose.foundation.gestures.draggable
 import androidx.compose.foundation.gestures.rememberDraggableState
 import androidx.compose.foundation.indication
+import androidx.compose.foundation.interaction.collectIsDraggedAsState
+import androidx.compose.foundation.interaction.collectIsPressedAsState
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxWithConstraints
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.heightIn
+import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.widthIn
 import androidx.compose.foundation.progressSemantics
 import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.material.SliderDefaults.InactiveTrackColorAlpha
-import androidx.compose.material.SliderDefaults.TickColorAlpha
 import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
+import androidx.compose.runtime.Stable
+import androidx.compose.runtime.State
+import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.rememberUpdatedState
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
@@ -50,15 +56,18 @@
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.PointMode
 import androidx.compose.ui.graphics.StrokeCap
+import androidx.compose.ui.graphics.compositeOver
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.LocalLayoutDirection
+import androidx.compose.ui.semantics.disabled
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.semantics.setProgress
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.util.lerp
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.launch
 import kotlin.math.abs
 
@@ -82,6 +91,7 @@
  * coerced to this range.
  * @param onValueChange lambda in which value should be updated
  * @param modifier modifiers for the Slider layout
+ * @param enabled whether or not component is enabled and can we interacted with or not
  * @param valueRange range of values that Slider value can take. Passed [value] will be coerced to
  * this range
  * @param steps if greater than 0, specifies the amounts of discrete values, evenly distributed
@@ -90,35 +100,25 @@
  * @param onValueChangeFinished lambda to be invoked when value change has ended. This callback
  * shouldn't be used to update the slider value (use [onValueChange] for that), but rather to
  * know when the user has completed selecting a new value by ending a drag or a click.
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this Slider. You can create and pass in your own remembered
- * [InteractionState] if you want to read the [InteractionState] and customize the appearance /
- * behavior of this Slider in different [Interaction]s.
- * @param thumbColor color of thumb of the slider
- * @param activeTrackColor color of the track in the part that is "active", meaning that the
- * thumb is ahead of it
- * @param inactiveTrackColor color of the track in the part that is "inactive", meaning that the
- * thumb is before it
- * @param activeTickColor colors to be used to draw tick marks on the active track, if [steps]
- * is specified
- * @param inactiveTickColor colors to be used to draw tick marks on the inactive track, if
- * [steps] is specified
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this Slider. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this Slider in different [Interaction]s.
+ * @param colors [SliderColors] that will be used to determine the color of the Slider parts in
+ * different state. See [SliderDefaults.colors] to customize.
  */
 @Composable
 fun Slider(
     value: Float,
     onValueChange: (Float) -> Unit,
     modifier: Modifier = Modifier,
+    enabled: Boolean = true,
     valueRange: ClosedFloatingPointRange<Float> = 0f..1f,
     /*@IntRange(from = 0)*/
     steps: Int = 0,
     onValueChangeFinished: (() -> Unit)? = null,
-    interactionState: InteractionState = remember { InteractionState() },
-    thumbColor: Color = MaterialTheme.colors.primary,
-    activeTrackColor: Color = MaterialTheme.colors.primary,
-    inactiveTrackColor: Color = activeTrackColor.copy(alpha = InactiveTrackColorAlpha),
-    activeTickColor: Color = MaterialTheme.colors.onPrimary.copy(alpha = TickColorAlpha),
-    inactiveTickColor: Color = activeTrackColor.copy(alpha = TickColorAlpha)
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    colors: SliderColors = SliderDefaults.colors()
 ) {
     val scope = rememberCoroutineScope()
     val position = remember(valueRange, steps, scope) {
@@ -127,7 +127,7 @@
     position.onValueChange = onValueChange
     position.scaledValue = value
     BoxWithConstraints(
-        modifier.sliderSemantics(value, position, onValueChange, valueRange, steps)
+        modifier.sliderSemantics(value, position, enabled, onValueChange, valueRange, steps)
     ) {
         val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
         val maxPx = constraints.maxWidth.toFloat()
@@ -150,22 +150,36 @@
             }
         }
 
-        val press = Modifier.pointerInput(Unit) {
-            detectTapGestures(
-                onPress = { pos ->
-                    position.snapTo(if (isRtl) maxPx - pos.x else pos.x)
-                    interactionState.addInteraction(Interaction.Pressed, pos)
-                    val success = tryAwaitRelease()
-                    if (success) gestureEndAction(0f)
-                    interactionState.removeInteraction(Interaction.Pressed)
-                }
-            )
+        val press = if (enabled) {
+            Modifier.pointerInput(Unit) {
+                detectTapGestures(
+                    onPress = { pos ->
+                        position.snapTo(if (isRtl) maxPx - pos.x else pos.x)
+                        val interaction = PressInteraction.Press(pos)
+                        coroutineScope {
+                            launch {
+                                interactionSource.emit(interaction)
+                            }
+                        }
+                        val success = tryAwaitRelease()
+                        if (success) gestureEndAction(0f)
+                        coroutineScope {
+                            launch {
+                                interactionSource.emit(PressInteraction.Release(interaction))
+                            }
+                        }
+                    }
+                )
+            }
+        } else {
+            Modifier
         }
 
         val drag = Modifier.draggable(
             orientation = Orientation.Horizontal,
             reverseDirection = isRtl,
-            interactionState = interactionState,
+            enabled = enabled,
+            interactionSource = interactionSource,
             onDragStopped = { velocity -> gestureEndAction(velocity) },
             startDragImmediately = position.holder.isRunning,
             state = rememberDraggableState {
@@ -175,15 +189,12 @@
         val coerced = value.coerceIn(position.startValue, position.endValue)
         val fraction = calcFraction(position.startValue, position.endValue, coerced)
         SliderImpl(
+            enabled,
             fraction,
             position.tickFractions,
-            thumbColor,
-            activeTrackColor,
-            inactiveTrackColor,
-            activeTickColor,
-            inactiveTickColor,
+            colors,
             maxPx,
-            interactionState,
+            interactionSource,
             modifier = press.then(drag)
         )
     }
@@ -193,28 +204,142 @@
  * Object to hold defaults used by [Slider]
  */
 object SliderDefaults {
+
+    /**
+     * Creates a [SliderColors] that represents the different colors used in parts of the
+     * [Slider] in different states.
+     *
+     * For the name references below the words "active" and "inactive" are used. Active part of
+     * the slider is filled with progress, so if slider's progress is 30% out of 100%, left (or
+     * right in RTL) 30% of the track will be active, the rest is not active.
+     *
+     * @param thumbColor thumb color when enabled
+     * @param disabledThumbColor thumb colors when disabled
+     * @param activeTrackColor color of the track in the part that is "active", meaning that the
+     * thumb is ahead of it
+     * @param inactiveTrackColor color of the track in the part that is "inactive", meaning that the
+     * thumb is before it
+     * @param disabledActiveTrackColor color of the track in the "active" part when the Slider is
+     * disabled
+     * @param disabledInactiveTrackColor color of the track in the "inactive" part when the
+     * Slider is disabled
+     * @param activeTickColor colors to be used to draw tick marks on the active track, if `steps`
+     * is specified
+     * @param inactiveTickColor colors to be used to draw tick marks on the inactive track, if
+     * `steps` are specified on the Slider is specified
+     * @param disabledActiveTickColor colors to be used to draw tick marks on the active track
+     * when Slider is disabled and when `steps` are specified on it
+     * @param disabledInactiveTickColor colors to be used to draw tick marks on the inactive part
+     * of the track when Slider is disabled and when `steps` are specified on it
+     */
+    @Composable
+    fun colors(
+        thumbColor: Color = MaterialTheme.colors.primary,
+        disabledThumbColor: Color = MaterialTheme.colors.onSurface
+            .copy(alpha = ContentAlpha.disabled)
+            .compositeOver(MaterialTheme.colors.surface),
+        activeTrackColor: Color = MaterialTheme.colors.primary,
+        inactiveTrackColor: Color = activeTrackColor.copy(alpha = InactiveTrackAlpha),
+        disabledActiveTrackColor: Color =
+            MaterialTheme.colors.onSurface.copy(alpha = DisabledActiveTrackAlpha),
+        disabledInactiveTrackColor: Color =
+            disabledActiveTrackColor.copy(alpha = DisabledInactiveTrackAlpha),
+        activeTickColor: Color = contentColorFor(activeTrackColor).copy(alpha = TickAlpha),
+        inactiveTickColor: Color = activeTrackColor.copy(alpha = TickAlpha),
+        disabledActiveTickColor: Color = activeTickColor.copy(alpha = DisabledTickAlpha),
+        disabledInactiveTickColor: Color = disabledInactiveTrackColor
+            .copy(alpha = DisabledTickAlpha)
+    ): SliderColors = DefaultSliderColors(
+        thumbColor = thumbColor,
+        disabledThumbColor = disabledThumbColor,
+        activeTrackColor = activeTrackColor,
+        inactiveTrackColor = inactiveTrackColor,
+        disabledActiveTrackColor = disabledActiveTrackColor,
+        disabledInactiveTrackColor = disabledInactiveTrackColor,
+        activeTickColor = activeTickColor,
+        inactiveTickColor = inactiveTickColor,
+        disabledActiveTickColor = disabledActiveTickColor,
+        disabledInactiveTickColor = disabledInactiveTickColor
+    )
+
     /**
      * Default alpha of the inactive part of the track
      */
-    const val InactiveTrackColorAlpha = 0.24f
+    const val InactiveTrackAlpha = 0.24f
+
+    /**
+     * Default alpha for the track when it is disabled but active
+     */
+    const val DisabledInactiveTrackAlpha = 0.12f
+
+    /**
+     * Default alpha for the track when it is disabled and inactive
+     */
+    const val DisabledActiveTrackAlpha = 0.32f
 
     /**
      * Default alpha of the ticks that are drawn on top of the track
      */
-    const val TickColorAlpha = 0.54f
+    const val TickAlpha = 0.54f
+
+    /**
+     * Default alpha for tick marks when they are disabled
+     */
+    const val DisabledTickAlpha = 0.12f
+}
+
+/**
+ * Represents the colors used by a [Slider] and its parts in different states
+ *
+ * See [SliderDefaults.colors] for the default implementation that follows Material
+ * specifications.
+ */
+@Stable
+interface SliderColors {
+
+    /**
+     * Represents the color used for the sliders's thumb, depending on [enabled].
+     *
+     * @param enabled whether the [Slider] is enabled or not
+     */
+    @Composable
+    fun thumbColor(enabled: Boolean): State<Color>
+
+    /**
+     * Represents the color used for the sliders's track, depending on [enabled] and [active].
+     *
+     * Active part is filled with progress, so if sliders progress is 30% out of 100%, left (or
+     * right in RTL) 30% of the track will be active, the rest is not active.
+     *
+     * @param enabled whether the [Slider] is enabled or not
+     * @param active whether the part of the track is active of not
+     */
+    @Composable
+    fun trackColor(enabled: Boolean, active: Boolean): State<Color>
+
+    /**
+     * Represents the color used for the sliders's tick which is the dot separating steps, if
+     * they are set on the slider, depending on [enabled] and [active].
+     *
+     * Active tick is the tick that is in the part of the track filled with progress, so if
+     * sliders progress is 30% out of 100%, left (or right in RTL) 30% of the track and the ticks
+     * in this 30% will be active, the rest is not active.
+     *
+     * @param enabled whether the [Slider] is enabled or not
+     * @param active whether the part of the track this tick is in is active of not
+     */
+    @Composable
+    fun tickColor(enabled: Boolean, active: Boolean): State<Color>
 }
 
 @Composable
 private fun SliderImpl(
+    enabled: Boolean,
     positionFraction: Float,
     tickFractions: List<Float>,
-    thumbColor: Color,
-    trackColor: Color,
-    inactiveTrackColor: Color,
-    activeTickColor: Color,
-    inactiveTickColor: Color,
+    colors: SliderColors,
     width: Float,
-    interactionState: InteractionState,
+    interactionSource: MutableInteractionSource,
     modifier: Modifier
 ) {
     val widthDp = with(LocalDensity.current) {
@@ -233,31 +358,30 @@
         }
         Track(
             center.fillMaxSize(),
-            trackColor,
-            inactiveTrackColor,
-            activeTickColor,
-            inactiveTickColor,
+            colors,
+            enabled,
             positionFraction,
             tickFractions,
             thumbPx,
             trackStrokeWidth
         )
         Box(center.padding(start = offset)) {
-            val elevation = if (
-                Interaction.Pressed in interactionState || Interaction.Dragged in interactionState
-            ) {
+            val isPressed by interactionSource.collectIsPressedAsState()
+            val isDragged by interactionSource.collectIsDraggedAsState()
+            val hasInteraction = isPressed || isDragged
+            val elevation = if (hasInteraction) {
                 ThumbPressedElevation
             } else {
                 ThumbDefaultElevation
             }
             Surface(
                 shape = CircleShape,
-                color = thumbColor,
-                elevation = elevation,
+                color = colors.thumbColor(enabled).value,
+                elevation = if (enabled) elevation else 0.dp,
                 modifier = Modifier
-                    .focusable(interactionState = interactionState)
+                    .focusable(interactionSource = interactionSource)
                     .indication(
-                        interactionState = interactionState,
+                        interactionSource = interactionSource,
                         indication = rememberRipple(
                             bounded = false,
                             radius = ThumbRippleRadius
@@ -273,15 +397,17 @@
 @Composable
 private fun Track(
     modifier: Modifier,
-    color: Color,
-    inactiveColor: Color,
-    activeTickColor: Color,
-    inactiveTickColor: Color,
+    colors: SliderColors,
+    enabled: Boolean,
     positionFraction: Float,
     tickFractions: List<Float>,
     thumbPx: Float,
     trackStrokeWidth: Float
 ) {
+    val inactiveTrackColor = colors.trackColor(enabled, active = false)
+    val activeTrackColor = colors.trackColor(enabled, active = true)
+    val inactiveTickColor = colors.tickColor(enabled, active = false)
+    val activeTickColor = colors.tickColor(enabled, active = true)
     Canvas(modifier) {
         val isRtl = layoutDirection == LayoutDirection.Rtl
         val sliderLeft = Offset(thumbPx, center.y)
@@ -289,7 +415,7 @@
         val sliderStart = if (isRtl) sliderRight else sliderLeft
         val sliderEnd = if (isRtl) sliderLeft else sliderRight
         drawLine(
-            inactiveColor,
+            inactiveTrackColor.value,
             sliderStart,
             sliderEnd,
             trackStrokeWidth,
@@ -300,14 +426,20 @@
             center.y
         )
 
-        drawLine(color, sliderStart, sliderValue, trackStrokeWidth, StrokeCap.Round)
+        drawLine(
+            activeTrackColor.value,
+            sliderStart,
+            sliderValue,
+            trackStrokeWidth,
+            StrokeCap.Round
+        )
         tickFractions.groupBy { it > positionFraction }.forEach { (afterFraction, list) ->
             drawPoints(
                 list.map {
                     Offset(lerp(sliderStart, sliderEnd, it).x, center.y)
                 },
                 PointMode.Points,
-                if (afterFraction) inactiveTickColor else activeTickColor,
+                (if (afterFraction) inactiveTickColor else activeTickColor).value,
                 trackStrokeWidth,
                 StrokeCap.Round
             )
@@ -326,12 +458,14 @@
 private fun Modifier.sliderSemantics(
     value: Float,
     position: SliderPosition,
+    enabled: Boolean,
     onValueChange: (Float) -> Unit,
     valueRange: ClosedFloatingPointRange<Float> = 0f..1f,
     steps: Int = 0
 ): Modifier {
     val coerced = value.coerceIn(position.startValue, position.endValue)
     return semantics(mergeDescendants = true) {
+        if (!enabled) disabled()
         setProgress(
             action = { targetValue ->
                 val newValue = targetValue.coerceIn(position.startValue, position.endValue)
@@ -430,6 +564,82 @@
     }
 }
 
+@Immutable
+private class DefaultSliderColors(
+    private val thumbColor: Color,
+    private val disabledThumbColor: Color,
+    private val activeTrackColor: Color,
+    private val inactiveTrackColor: Color,
+    private val disabledActiveTrackColor: Color,
+    private val disabledInactiveTrackColor: Color,
+    private val activeTickColor: Color,
+    private val inactiveTickColor: Color,
+    private val disabledActiveTickColor: Color,
+    private val disabledInactiveTickColor: Color
+) : SliderColors {
+
+    @Composable
+    override fun thumbColor(enabled: Boolean): State<Color> {
+        return rememberUpdatedState(if (enabled) thumbColor else disabledThumbColor)
+    }
+
+    @Composable
+    override fun trackColor(enabled: Boolean, active: Boolean): State<Color> {
+        return rememberUpdatedState(
+            if (enabled) {
+                if (active) activeTrackColor else inactiveTrackColor
+            } else {
+                if (active) disabledActiveTrackColor else disabledInactiveTrackColor
+            }
+        )
+    }
+
+    @Composable
+    override fun tickColor(enabled: Boolean, active: Boolean): State<Color> {
+        return rememberUpdatedState(
+            if (enabled) {
+                if (active) activeTickColor else inactiveTickColor
+            } else {
+                if (active) disabledActiveTickColor else disabledInactiveTickColor
+            }
+        )
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other == null || this::class != other::class) return false
+
+        other as DefaultSliderColors
+
+        if (thumbColor != other.thumbColor) return false
+        if (disabledThumbColor != other.disabledThumbColor) return false
+        if (activeTrackColor != other.activeTrackColor) return false
+        if (inactiveTrackColor != other.inactiveTrackColor) return false
+        if (disabledActiveTrackColor != other.disabledActiveTrackColor) return false
+        if (disabledInactiveTrackColor != other.disabledInactiveTrackColor) return false
+        if (activeTickColor != other.activeTickColor) return false
+        if (inactiveTickColor != other.inactiveTickColor) return false
+        if (disabledActiveTickColor != other.disabledActiveTickColor) return false
+        if (disabledInactiveTickColor != other.disabledInactiveTickColor) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = thumbColor.hashCode()
+        result = 31 * result + disabledThumbColor.hashCode()
+        result = 31 * result + activeTrackColor.hashCode()
+        result = 31 * result + inactiveTrackColor.hashCode()
+        result = 31 * result + disabledActiveTrackColor.hashCode()
+        result = 31 * result + disabledInactiveTrackColor.hashCode()
+        result = 31 * result + activeTickColor.hashCode()
+        result = 31 * result + inactiveTickColor.hashCode()
+        result = 31 * result + disabledActiveTickColor.hashCode()
+        result = 31 * result + disabledInactiveTickColor.hashCode()
+        return result
+    }
+}
+
 // Internal to be referred to in tests
 internal val ThumbRadius = 10.dp
 private val ThumbRippleRadius = 24.dp
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SnackbarHost.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SnackbarHost.kt
index 4143d74..d760e94 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SnackbarHost.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SnackbarHost.kt
@@ -35,6 +35,8 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.platform.AccessibilityManager
+import androidx.compose.ui.platform.LocalAccessibilityManager
 import androidx.compose.ui.util.fastForEach
 import kotlinx.coroutines.CancellableContinuation
 import kotlinx.coroutines.delay
@@ -148,9 +150,14 @@
     snackbar: @Composable (SnackbarData) -> Unit = { Snackbar(it) }
 ) {
     val currentSnackbarData = hostState.currentSnackbarData
+    val accessibilityManager = LocalAccessibilityManager.current
     LaunchedEffect(currentSnackbarData) {
         if (currentSnackbarData != null) {
-            delay(currentSnackbarData.duration.toMillis())
+            val duration = currentSnackbarData.duration.toMillis(
+                currentSnackbarData.actionLabel != null,
+                accessibilityManager
+            )
+            delay(duration)
             currentSnackbarData.dismiss()
         }
     }
@@ -219,11 +226,25 @@
     Indefinite
 }
 
-// TODO: a11y and magic numbers adjustment
-private fun SnackbarDuration.toMillis() = when (this) {
-    SnackbarDuration.Indefinite -> Long.MAX_VALUE
-    SnackbarDuration.Long -> 10000L
-    SnackbarDuration.Short -> 4000L
+// TODO: magic numbers adjustment
+internal fun SnackbarDuration.toMillis(
+    hasAction: Boolean,
+    accessibilityManager: AccessibilityManager?
+): Long {
+    val original = when (this) {
+        SnackbarDuration.Indefinite -> Long.MAX_VALUE
+        SnackbarDuration.Long -> 10000L
+        SnackbarDuration.Short -> 4000L
+    }
+    if (accessibilityManager == null) {
+        return original
+    }
+    return accessibilityManager.calculateRecommendedTimeoutMillis(
+        original,
+        containsIcons = true,
+        containsText = true,
+        containsControls = hasAction
+    )
 }
 
 // TODO: to be replaced with the public customizable implementation
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeToDismiss.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeToDismiss.kt
index e45d7a7..31c09ad 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeToDismiss.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeToDismiss.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.material
 
-import androidx.compose.animation.core.AnimationEndReason
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxWithConstraints
@@ -38,6 +37,7 @@
 import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.LayoutDirection
+import kotlinx.coroutines.CancellationException
 import kotlin.math.roundToInt
 
 /**
@@ -106,20 +106,22 @@
 
     /**
      * Reset the component to the default position with animation and suspend until it if fully
-     * reset or animation has been cancelled.
+     * reset or animation has been cancelled. This method will throw [CancellationException] if
+     * the animation is interrupted
      *
      * @return the reason the reset animation ended
      */
-    suspend fun reset(): AnimationEndReason = animateTo(targetValue = Default)
+    suspend fun reset() = animateTo(targetValue = Default)
 
     /**
-     * Dismiss the component in the given [direction], with an animation and suspend .
+     * Dismiss the component in the given [direction], with an animation and suspend. This method
+     * will throw [CancellationException] if the animation is interrupted
      *
      * @param direction The dismiss direction.
      */
-    suspend fun dismiss(direction: DismissDirection): AnimationEndReason {
+    suspend fun dismiss(direction: DismissDirection) {
         val targetValue = if (direction == StartToEnd) DismissedToEnd else DismissedToStart
-        return animateTo(targetValue = targetValue)
+        animateTo(targetValue = targetValue)
     }
 
     companion object {
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt
index 8e8c924..8cbec9a 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt
@@ -17,11 +17,10 @@
 package androidx.compose.material
 
 import androidx.compose.animation.core.Animatable
-import androidx.compose.animation.core.AnimationEndReason
 import androidx.compose.animation.core.AnimationSpec
 import androidx.compose.animation.core.SpringSpec
-import androidx.compose.foundation.InteractionState
 import androidx.compose.foundation.gestures.DraggableState
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.gestures.draggable
 import androidx.compose.material.SwipeableDefaults.AnimationSpec
@@ -159,14 +158,15 @@
             maxBound = Float.POSITIVE_INFINITY
             val targetOffset = newAnchors.getOffset(currentValue)
                 ?: newAnchors.keys.minByOrNull { abs(it - offset.value) }!!
-            val result = animateInternalToOffset(targetOffset, animationSpec)
+            try {
+                animateInternalToOffset(targetOffset, animationSpec)
+            } catch (c: CancellationException) {
+                // If the animation was interrupted for any reason, snap as a last resort.
+                snapInternalToOffset(targetOffset)
+            }
             currentValue = newAnchors.getValue(targetOffset)
             minBound = newAnchors.keys.minOrNull()!!
             maxBound = newAnchors.keys.maxOrNull()!!
-            // If the animation was interrupted for any reason, snap as a last resort.
-            if (result == AnimationEndReason.Interrupted) {
-                snapInternalToOffset(targetOffset)
-            }
         }
     }
 
@@ -192,28 +192,21 @@
         }
     }
 
-    private suspend fun animateInternalToOffset(
-        target: Float,
-        spec: AnimationSpec<Float>
-    ): AnimationEndReason {
-        var result: AnimationEndReason = AnimationEndReason.Interrupted
+    private suspend fun animateInternalToOffset(target: Float, spec: AnimationSpec<Float>) {
         draggableState.drag {
             var prevValue = absoluteOffset.value
             animationTarget.value = target
             isAnimationRunning = true
             try {
-                result = Animatable(prevValue).animateTo(target, spec) {
+                Animatable(prevValue).animateTo(target, spec) {
                     dragBy(this.value - prevValue)
                     prevValue = this.value
-                }.endReason
-            } catch (c: CancellationException) {
-                result = AnimationEndReason.Interrupted
+                }
             } finally {
                 animationTarget.value = null
                 isAnimationRunning = false
             }
         }
-        return result
     }
 
     /**
@@ -310,14 +303,9 @@
      *
      * @param targetValue The new value to animate to.
      * @param anim The animation that will be used to animate to the new value.
-     *
-     * @return animation end reason
      */
     @ExperimentalMaterialApi
-    suspend fun animateTo(
-        targetValue: T,
-        anim: AnimationSpec<Float> = animationSpec
-    ): AnimationEndReason {
+    suspend fun animateTo(targetValue: T, anim: AnimationSpec<Float> = animationSpec) {
         try {
             val targetOffset = anchors.getOffset(targetValue)
             require(anchors.isNotEmpty()) {
@@ -351,7 +339,7 @@
      *
      * @return the reason fling ended
      */
-    suspend fun performFling(velocity: Float): AnimationEndReason {
+    suspend fun performFling(velocity: Float) {
         val lastAnchor = anchors.getOffset(currentValue)!!
         val targetValue = computeTarget(
             offset = offset.value,
@@ -362,12 +350,9 @@
             velocityThreshold = velocityThreshold
         )
         val targetState = anchors[targetValue]
-        return if (targetState != null && confirmStateChange(targetState)) {
-            animateTo(targetState)
-        } else {
-            // If the user vetoed the state change, rollback to the previous state.
-            animateInternalToOffset(lastAnchor, animationSpec)
-        }
+        if (targetState != null && confirmStateChange(targetState)) animateTo(targetState)
+        // If the user vetoed the state change, rollback to the previous state.
+        else animateInternalToOffset(lastAnchor, animationSpec)
     }
 
     /**
@@ -545,7 +530,8 @@
  * @param enabled Whether this [swipeable] is enabled and should react to the user's input.
  * @param reverseDirection Whether to reverse the direction of the swipe, so a top to bottom
  * swipe will behave like bottom to top, and a left to right swipe will behave like right to left.
- * @param interactionState Optional [InteractionState] that will passed on to [Modifier.draggable].
+ * @param interactionSource Optional [MutableInteractionSource] that will passed on to
+ * the internal [Modifier.draggable].
  * @param resistance Controls how much resistance will be applied when swiping past the bounds.
  * @param velocityThreshold The threshold (in dp per second) that the end velocity has to exceed
  * in order to animate to the next state, even if the positional [thresholds] have not been reached.
@@ -558,7 +544,7 @@
     orientation: Orientation,
     enabled: Boolean = true,
     reverseDirection: Boolean = false,
-    interactionState: InteractionState? = null,
+    interactionSource: MutableInteractionSource? = null,
     thresholds: (from: T, to: T) -> ThresholdConfig = { _, _ -> FixedThreshold(56.dp) },
     resistance: ResistanceConfig? = resistanceConfig(anchors.keys),
     velocityThreshold: Dp = VelocityThreshold
@@ -570,7 +556,7 @@
         properties["orientation"] = orientation
         properties["enabled"] = enabled
         properties["reverseDirection"] = reverseDirection
-        properties["interactionState"] = interactionState
+        properties["interactionSource"] = interactionSource
         properties["thresholds"] = thresholds
         properties["resistance"] = resistance
         properties["velocityThreshold"] = velocityThreshold
@@ -605,7 +591,7 @@
         orientation = orientation,
         enabled = enabled,
         reverseDirection = reverseDirection,
-        interactionState = interactionState,
+        interactionSource = interactionSource,
         startDragImmediately = state.isAnimationRunning,
         onDragStopped = { velocity -> launch { state.performFling(velocity) } },
         state = state.draggableState
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Switch.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Switch.kt
index cbd704a..fa20647 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Switch.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Switch.kt
@@ -18,10 +18,13 @@
 
 import androidx.compose.animation.core.TweenSpec
 import androidx.compose.foundation.Canvas
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.InteractionSource
 import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.indication
+import androidx.compose.foundation.interaction.collectIsDraggedAsState
+import androidx.compose.foundation.interaction.collectIsPressedAsState
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxScope
 import androidx.compose.foundation.layout.fillMaxSize
@@ -59,15 +62,16 @@
  *
  * @sample androidx.compose.material.samples.SwitchSample
  *
- * @param checked whether or not this components is checked
+ * @param checked whether or not this component is checked
  * @param onCheckedChange callback to be invoked when Switch is being clicked,
- * therefore the change of checked state is requested.
+ * therefore the change of checked state is requested.  If null, then this is passive
+ * and relies entirely on a higher-level component to control the "checked" state.
  * @param modifier Modifier to be applied to the switch layout
- * @param enabled whether or not components is enabled and can be clicked to request state change
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this Switch. You can create and pass in your own remembered
- * [InteractionState] if you want to read the [InteractionState] and customize the appearance /
- * behavior of this Switch in different [Interaction]s.
+ * @param enabled whether the component is enabled or grayed out
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this Switch. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this Switch in different [Interaction]s.
  * @param colors [SwitchColors] that will be used to determine the color of the thumb and track
  * in different states. See [SwitchDefaults.colors].
  */
@@ -75,34 +79,41 @@
 @OptIn(ExperimentalMaterialApi::class)
 fun Switch(
     checked: Boolean,
-    onCheckedChange: (Boolean) -> Unit,
+    onCheckedChange: ((Boolean) -> Unit)?,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     colors: SwitchColors = SwitchDefaults.colors()
 ) {
     val minBound = 0f
     val maxBound = with(LocalDensity.current) { ThumbPathLength.toPx() }
-    val swipeableState = rememberSwipeableStateFor(checked, onCheckedChange, AnimationSpec)
+    val swipeableState = rememberSwipeableStateFor(checked, onCheckedChange ?: {}, AnimationSpec)
     val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
-    Box(
-        modifier
-            .toggleable(
+    val toggleableModifier =
+        if (onCheckedChange != null) {
+            Modifier.toggleable(
                 value = checked,
                 onValueChange = onCheckedChange,
                 enabled = enabled,
                 role = Role.Switch,
-                interactionState = interactionState,
+                interactionSource = interactionSource,
                 indication = null
             )
+        } else {
+            Modifier
+        }
+
+    Box(
+        modifier
+            .then(toggleableModifier)
             .swipeable(
                 state = swipeableState,
                 anchors = mapOf(minBound to false, maxBound to true),
                 thresholds = { _, _ -> FractionalThreshold(0.5f) },
                 orientation = Orientation.Horizontal,
-                enabled = enabled,
+                enabled = enabled && onCheckedChange != null,
                 reverseDirection = isRtl,
-                interactionState = interactionState,
+                interactionSource = interactionSource,
                 resistance = null
             )
             .wrapContentSize(Alignment.Center)
@@ -114,7 +125,7 @@
             enabled = enabled,
             colors = colors,
             thumbValue = swipeableState.offset,
-            interactionState = interactionState
+            interactionSource = interactionSource
         )
     }
 }
@@ -153,10 +164,11 @@
     enabled: Boolean,
     colors: SwitchColors,
     thumbValue: State<Float>,
-    interactionState: InteractionState
+    interactionSource: InteractionSource
 ) {
-    val hasInteraction =
-        Interaction.Pressed in interactionState || Interaction.Dragged in interactionState
+    val isPressed by interactionSource.collectIsPressedAsState()
+    val isDragged by interactionSource.collectIsDraggedAsState()
+    val hasInteraction = isPressed || isDragged
     val elevation = if (hasInteraction) {
         ThumbPressedElevation
     } else {
@@ -175,7 +187,7 @@
             .align(Alignment.CenterStart)
             .offset { IntOffset(thumbValue.value.roundToInt(), 0) }
             .indication(
-                interactionState = interactionState,
+                interactionSource = interactionSource,
                 indication = rememberRipple(bounded = false, radius = ThumbRippleRadius)
             )
             .requiredSize(ThumbDiameter),
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Tab.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Tab.kt
index abe0b41..0d107e4 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Tab.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Tab.kt
@@ -20,8 +20,8 @@
 import androidx.compose.animation.core.LinearEasing
 import androidx.compose.animation.core.tween
 import androidx.compose.animation.core.updateTransition
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
@@ -66,10 +66,10 @@
  * be clickable and will appear disabled to accessibility services.
  * @param text the text label displayed in this tab
  * @param icon the icon displayed in this tab
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this Tab. You can create and pass in your own remembered [InteractionState] if
- * you want to read the [InteractionState] and customize the appearance / behavior of this Tab
- * in different [Interaction]s.
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this Tab. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this Tab in different [Interaction]s.
  * @param selectedContentColor the color for the content of this tab when selected, and the color
  * of the ripple.
  * @param unselectedContentColor the color for the content of this tab when not selected
@@ -82,7 +82,7 @@
     enabled: Boolean = true,
     text: @Composable (() -> Unit)? = null,
     icon: @Composable (() -> Unit)? = null,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     selectedContentColor: Color = LocalContentColor.current,
     unselectedContentColor: Color = selectedContentColor.copy(alpha = ContentAlpha.medium)
 ) {
@@ -97,7 +97,7 @@
         onClick,
         modifier,
         enabled,
-        interactionState,
+        interactionSource,
         selectedContentColor,
         unselectedContentColor
     ) {
@@ -119,10 +119,10 @@
  * @param modifier optional [Modifier] for this tab
  * @param enabled controls the enabled state of this tab. When `false`, this tab will not
  * be clickable and will appear disabled to accessibility services.
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this Tab. You can create and pass in your own remembered [InteractionState] if
- * you want to read the [InteractionState] and customize the appearance / behavior of this Tab
- * in different [Interaction]s.
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this Tab. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this Tab in different [Interaction]s.
  * @param selectedContentColor the color for the content of this tab when selected, and the color
  * of the ripple.
  * @param unselectedContentColor the color for the content of this tab when not selected
@@ -134,7 +134,7 @@
     onClick: () -> Unit,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     selectedContentColor: Color = LocalContentColor.current,
     unselectedContentColor: Color = selectedContentColor.copy(alpha = ContentAlpha.medium),
     content: @Composable ColumnScope.() -> Unit
@@ -152,7 +152,7 @@
                     onClick = onClick,
                     enabled = enabled,
                     role = Role.Tab,
-                    interactionState = interactionState,
+                    interactionSource = interactionSource,
                     indication = ripple
                 )
                 .fillMaxWidth(),
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TabRow.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TabRow.kt
index 6831077..c44c731 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TabRow.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TabRow.kt
@@ -30,6 +30,7 @@
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.selection.selectableGroup
 import androidx.compose.material.TabRowDefaults.tabIndicatorOffset
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
@@ -134,7 +135,11 @@
     },
     tabs: @Composable () -> Unit
 ) {
-    Surface(modifier = modifier, color = backgroundColor, contentColor = contentColor) {
+    Surface(
+        modifier = modifier.selectableGroup(),
+        color = backgroundColor,
+        contentColor = contentColor
+    ) {
         SubcomposeLayout(Modifier.fillMaxWidth()) { constraints ->
             val tabRowWidth = constraints.maxWidth
             val tabMeasurables = subcompose(TabSlots.Tabs, tabs)
@@ -215,7 +220,11 @@
     },
     tabs: @Composable () -> Unit
 ) {
-    Surface(modifier = modifier, color = backgroundColor, contentColor = contentColor) {
+    Surface(
+        modifier = modifier.selectableGroup(),
+        color = backgroundColor,
+        contentColor = contentColor
+    ) {
         val scrollState = rememberScrollState()
         val coroutineScope = rememberCoroutineScope()
         val scrollableTabData = remember(scrollState) {
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextField.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextField.kt
index d59e79b..41b57ba 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextField.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextField.kt
@@ -16,8 +16,8 @@
 
 package androidx.compose.material
 
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.defaultMinSize
@@ -26,6 +26,8 @@
 import androidx.compose.foundation.text.BasicTextField
 import androidx.compose.foundation.text.KeyboardActions
 import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.material.TextFieldDefaults.MinHeight
+import androidx.compose.material.TextFieldDefaults.MinWidth
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
@@ -43,7 +45,6 @@
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.layout.Placeable
 import androidx.compose.ui.layout.layoutId
-import androidx.compose.ui.text.SoftwareKeyboardController
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.KeyboardType
@@ -74,7 +75,7 @@
  *
  * @sample androidx.compose.material.samples.TextFieldWithIcons
  *
- * To handle the error input state, use [isErrorValue] parameter:
+ * To handle the error input state, use [isError] parameter:
  *
  * @sample androidx.compose.material.samples.TextFieldWithErrorState
  *
@@ -114,9 +115,9 @@
  * container
  * @param trailingIcon the optional trailing icon to be displayed at the end of the text field
  * container
- * @param isErrorValue indicates if the text field's current value is in error. If set to true, the
- * label, bottom indicator and trailing icon will be displayed in [errorColor] color
- * @param visualTransformation transforms the visual representation of the input [value].
+ * @param isError indicates if the text field's current value is in error. If set to true, the
+ * label, bottom indicator and trailing icon by default will be displayed in error color
+ * @param visualTransformation transforms the visual representation of the input [value]
  * For example, you can use [androidx.compose.ui.text.input.PasswordVisualTransformation] to create a password
  * text field. By default no visual transformation is applied
  * @param keyboardOptions software keyboard options that contains configuration such as
@@ -131,24 +132,14 @@
  * @param maxLines the maximum height in terms of maximum number of visible lines. Should be
  * equal or greater than 1. Note that this parameter will be ignored and instead maxLines will be
  * set to 1 if [singleLine] is set to true.
- * [KeyboardOptions.imeAction] field. The callback also exposes a [SoftwareKeyboardController]
- * instance as a parameter that can be used to request to hide the software keyboard
- * @param onTextInputStarted a callback to be invoked when the connection with the platform's text
- * input service (e.g. software keyboard on Android) has been established. Called with the
- * [SoftwareKeyboardController] instance that can be used to request to show or hide the software
- * keyboard
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this TextField. You can create and pass in your own remembered
- * [InteractionState] if you want to read the [InteractionState] and customize the appearance /
- * behavior of this TextField in different [Interaction]s.
- * @param activeColor the color of the label, bottom indicator and the cursor when the text field is
- * in focus
- * @param inactiveColor the color of either the input text or placeholder when the text field is in
- * focus, and the color of the label and bottom indicator when the text field is not in focus
- * @param errorColor the alternative color of the label, bottom indicator, cursor and trailing icon
- * used when [isErrorValue] is set to true
- * @param backgroundColor the background color of the text field's container
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this TextField. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this TextField in different [Interaction]s.
  * @param shape the shape of the text field's container
+ * @param colors [TextFieldColors] that will be used to resolve color of the text, content
+ * (including label, placeholder, leading and trailing icons, indicator line) and background for
+ * this text field in different states. See [TextFieldDefaults.textFieldColors]
  */
 @Composable
 fun TextField(
@@ -162,26 +153,21 @@
     placeholder: @Composable (() -> Unit)? = null,
     leadingIcon: @Composable (() -> Unit)? = null,
     trailingIcon: @Composable (() -> Unit)? = null,
-    isErrorValue: Boolean = false,
+    isError: Boolean = false,
     visualTransformation: VisualTransformation = VisualTransformation.None,
     keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
     keyboardActions: KeyboardActions = KeyboardActions(),
     singleLine: Boolean = false,
     maxLines: Int = Int.MAX_VALUE,
-    onTextInputStarted: (SoftwareKeyboardController) -> Unit = {},
-    interactionState: InteractionState = remember { InteractionState() },
-    activeColor: Color = MaterialTheme.colors.primary,
-    inactiveColor: Color = MaterialTheme.colors.onSurface,
-    errorColor: Color = MaterialTheme.colors.error,
-    backgroundColor: Color = MaterialTheme.colors.onSurface.copy(alpha = ContainerAlpha),
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     shape: Shape =
-        MaterialTheme.shapes.small.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize)
+        MaterialTheme.shapes.small.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize),
+    colors: TextFieldColors = TextFieldDefaults.textFieldColors()
 ) {
     var textFieldValueState by remember { mutableStateOf(TextFieldValue(text = value)) }
     val textFieldValue = textFieldValueState.copy(text = value)
 
-    TextFieldImpl(
-        type = TextFieldType.Filled,
+    TextField(
         enabled = enabled,
         readOnly = readOnly,
         value = textFieldValue,
@@ -196,20 +182,16 @@
         textStyle = textStyle,
         label = label,
         placeholder = placeholder,
-        leading = leadingIcon,
-        trailing = trailingIcon,
-        isErrorValue = isErrorValue,
+        leadingIcon = leadingIcon,
+        trailingIcon = trailingIcon,
+        isError = isError,
         visualTransformation = visualTransformation,
         keyboardOptions = keyboardOptions,
         keyboardActions = keyboardActions,
         maxLines = maxLines,
-        onTextInputStarted = onTextInputStarted,
-        interactionState = interactionState,
-        activeColor = activeColor,
-        inactiveColor = inactiveColor,
-        errorColor = errorColor,
-        backgroundColor = backgroundColor,
-        shape = shape
+        interactionSource = interactionSource,
+        shape = shape,
+        colors = colors
     )
 }
 
@@ -247,8 +229,8 @@
  * container
  * @param trailingIcon the optional trailing icon to be displayed at the end of the text field
  * container
- * @param isErrorValue indicates if the text field's current value is in error state. If set to
- * true, the label, bottom indicator and trailing icon will be displayed in [errorColor] color
+ * @param isError indicates if the text field's current value is in error state. If set to
+ * true, the label, bottom indicator and trailing icon by default will be displayed in error color
  * @param visualTransformation transforms the visual representation of the input [value].
  * For example, you can use [androidx.compose.ui.text.input.PasswordVisualTransformation] to create a password
  * text field. By default no visual transformation is applied
@@ -264,24 +246,14 @@
  * @param maxLines the maximum height in terms of maximum number of visible lines. Should be
  * equal or greater than 1. Note that this parameter will be ignored and instead maxLines will be
  * set to 1 if [singleLine] is set to true.
- * [KeyboardOptions.imeAction] field. The callback also exposes a [SoftwareKeyboardController]
- * instance as a parameter that can be used to request to hide the software keyboard
- * @param onTextInputStarted a callback to be invoked when the connection with the platform's text
- * input service (e.g. software keyboard on Android) has been established. Called with the
- * [SoftwareKeyboardController] instance that can be used to request to show or hide the software
- * keyboard
- * @param interactionState the [InteractionState] representing the different [Interaction]s
- * present on this TextField. You can create and pass in your own remembered
- * [InteractionState] if you want to read the [InteractionState] and customize the appearance /
- * behavior of this TextField in different [Interaction]s.
- * @param activeColor the color of the label, bottom indicator and the cursor when the text field is
- * in focus
- * @param inactiveColor the color of either the input text or placeholder when the text field is in
- * focus, and the color of the label and bottom indicator when the text field is not in focus
- * @param errorColor the alternative color of the label, bottom indicator, cursor and trailing icon
- * used when [isErrorValue] is set to true
- * @param backgroundColor the background color of the text field's container
+ * @param interactionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this TextField. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this TextField in different [Interaction]s.
  * @param shape the shape of the text field's container
+ * @param colors [TextFieldColors] that will be used to resolve color of the text, content
+ * (including label, placeholder, leading and trailing icons, indicator line) and background for
+ * this text field in different states. See [TextFieldDefaults.textFieldColors]
  */
 @Composable
 fun TextField(
@@ -295,20 +267,16 @@
     placeholder: @Composable (() -> Unit)? = null,
     leadingIcon: @Composable (() -> Unit)? = null,
     trailingIcon: @Composable (() -> Unit)? = null,
-    isErrorValue: Boolean = false,
+    isError: Boolean = false,
     visualTransformation: VisualTransformation = VisualTransformation.None,
     keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
     keyboardActions: KeyboardActions = KeyboardActions(),
     singleLine: Boolean = false,
     maxLines: Int = Int.MAX_VALUE,
-    onTextInputStarted: (SoftwareKeyboardController) -> Unit = {},
-    interactionState: InteractionState = remember { InteractionState() },
-    activeColor: Color = MaterialTheme.colors.primary,
-    inactiveColor: Color = MaterialTheme.colors.onSurface,
-    errorColor: Color = MaterialTheme.colors.error,
-    backgroundColor: Color = MaterialTheme.colors.onSurface.copy(alpha = ContainerAlpha),
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     shape: Shape =
-        MaterialTheme.shapes.small.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize)
+        MaterialTheme.shapes.small.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize),
+    colors: TextFieldColors = TextFieldDefaults.textFieldColors()
 ) {
     TextFieldImpl(
         type = TextFieldType.Filled,
@@ -323,18 +291,14 @@
         placeholder = placeholder,
         leading = leadingIcon,
         trailing = trailingIcon,
-        isErrorValue = isErrorValue,
+        isError = isError,
         visualTransformation = visualTransformation,
         keyboardOptions = keyboardOptions,
         keyboardActions = keyboardActions,
         maxLines = maxLines,
-        onTextInputStarted = onTextInputStarted,
-        interactionState = interactionState,
-        activeColor = activeColor,
-        inactiveColor = inactiveColor,
-        errorColor = errorColor,
-        backgroundColor = backgroundColor,
-        shape = shape
+        interactionSource = interactionSource,
+        shape = shape,
+        colors = colors
     )
 }
 
@@ -351,8 +315,7 @@
     singleLine: Boolean,
     maxLines: Int = Int.MAX_VALUE,
     visualTransformation: VisualTransformation,
-    onTextInputStarted: (SoftwareKeyboardController) -> Unit,
-    interactionState: InteractionState,
+    interactionSource: MutableInteractionSource,
     decoratedPlaceholder: @Composable ((Modifier) -> Unit)?,
     decoratedLabel: @Composable (() -> Unit)?,
     leading: @Composable (() -> Unit)?,
@@ -366,12 +329,13 @@
     cursorColor: Color,
     shape: Shape
 ) {
+
     BasicTextField(
         value = value,
         modifier = modifier
             .defaultMinSize(
-                minWidth = TextFieldMinWidth,
-                minHeight = TextFieldMinHeight
+                minWidth = MinWidth,
+                minHeight = MinHeight
             )
             .background(color = backgroundColor, shape = shape)
             .drawIndicatorLine(lineWidth = indicatorWidth, color = indicatorColor),
@@ -383,8 +347,7 @@
         visualTransformation = visualTransformation,
         keyboardOptions = keyboardOptions,
         keyboardActions = keyboardActions,
-        interactionState = interactionState,
-        onTextInputStarted = onTextInputStarted,
+        interactionSource = interactionSource,
         singleLine = singleLine,
         maxLines = maxLines,
         decorationBox = @Composable { coreTextField ->
@@ -726,5 +689,4 @@
 
 private val FirstBaselineOffset = 20.dp
 private val LastBaselineOffset = 10.dp
-private val TextFieldTopPadding = 4.dp
-const val ContainerAlpha = 0.12f
\ No newline at end of file
+private val TextFieldTopPadding = 4.dp
\ No newline at end of file
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldDefaults.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldDefaults.kt
new file mode 100644
index 0000000..3432747
--- /dev/null
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldDefaults.kt
@@ -0,0 +1,467 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.material
+
+import androidx.compose.animation.animateColorAsState
+import androidx.compose.animation.core.tween
+import androidx.compose.foundation.interaction.FocusInteraction
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.InteractionSource
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.Stable
+import androidx.compose.runtime.State
+import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberUpdatedState
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.unit.dp
+import kotlinx.coroutines.flow.collect
+
+/**
+ * Represents the colors of the input text, background and content (including label, placeholder,
+ * leading and trailing icons) used in a text field in different states.
+ *
+ * See [TextFieldDefaults.textFieldColors] for the default colors used in [TextField].
+ * See [TextFieldDefaults.outlinedTextFieldColors] for the default colors used in
+ * [OutlinedTextField].
+ */
+@Stable
+interface TextFieldColors {
+    /**
+     * Represents the color used for the input text of this text field.
+     *
+     * @param enabled whether the text field is enabled
+     */
+    @Composable
+    fun textColor(enabled: Boolean): State<Color>
+
+    /**
+     * Represents the background color for this text field.
+     *
+     * @param enabled whether the text field is enabled
+     */
+    @Composable
+    fun backgroundColor(enabled: Boolean): State<Color>
+
+    /**
+     * Represents the color used for the placeholder of this text field.
+     *
+     * @param enabled whether the text field is enabled
+     */
+    @Composable
+    fun placeholderColor(enabled: Boolean): State<Color>
+
+    /**
+     * Represents the color used for the label of this text field.
+     *
+     * @param enabled whether the text field is enabled
+     * @param error whether the text field's current value is in error
+     * @param interactionSource the [InteractionSource] of this text field. Helps to determine if
+     * the text field is in focus or not
+     */
+    @Composable
+    fun labelColor(
+        enabled: Boolean,
+        error: Boolean,
+        interactionSource: InteractionSource
+    ): State<Color>
+
+    /**
+     * Represents the color used for the leading icon of this text field.
+     *
+     * @param enabled whether the text field is enabled
+     * @param isError whether the text field's current value is in error
+     */
+    @Composable
+    fun leadingIconColor(enabled: Boolean, isError: Boolean): State<Color>
+
+    /**
+     * Represents the color used for the trailing icon of this text field.
+     *
+     * @param enabled whether the text field is enabled
+     * @param isError whether the text field's current value is in error
+     */
+    @Composable
+    fun trailingIconColor(enabled: Boolean, isError: Boolean): State<Color>
+
+    /**
+     * Represents the color used for the border indicator of this text field.
+     *
+     * @param enabled whether the text field is enabled
+     * @param isError whether the text field's current value is in error
+     * @param interactionSource the [InteractionSource] of this text field. Helps to determine if
+     * the text field is in focus or not
+     */
+    @Composable
+    fun indicatorColor(
+        enabled: Boolean,
+        isError: Boolean,
+        interactionSource: InteractionSource
+    ): State<Color>
+
+    /**
+     * Represents the color used for the cursor of this text field.
+     *
+     * @param isError whether the text field's current value is in error
+     */
+    @Composable
+    fun cursorColor(isError: Boolean): State<Color>
+}
+
+/**
+ * Contains the default values used by [TextField] and [OutlinedTextField].
+ */
+object TextFieldDefaults {
+    /**
+     * The default min width applied for a [TextField] and [OutlinedTextField].
+     * Note that you can override it by applying Modifier.heightIn directly on a text field.
+     */
+    val MinHeight = 56.dp
+
+    /**
+     * The default min width applied for a [TextField] and [OutlinedTextField].
+     * Note that you can override it by applying Modifier.widthIn directly on a text field.
+     */
+    val MinWidth = 280.dp
+
+    /**
+     * The default opacity used for a [TextField]'s and [OutlinedTextField]'s leading and
+     * trailing icons color.
+     */
+    const val IconOpacity = 0.54f
+
+    /**
+     * The default opacity used for a [TextField]'s background color.
+     */
+    const val BackgroundOpacity = 0.12f
+
+    // Filled text field uses 42% opacity to meet the contrast requirements for accessibility reasons
+    /**
+     * The default opacity used for a [TextField]'s indicator line color when text field is
+     * not focused.
+     */
+    const val UnfocusedIndicatorLineOpacity = 0.42f
+
+    /**
+     * Creates a [TextFieldColors] that represents the default input text, background and content
+     * (including label, placeholder, leading and trailing icons) colors used in a [TextField].
+     */
+    @Composable
+    fun textFieldColors(
+        textColor: Color = LocalContentColor.current.copy(LocalContentAlpha.current),
+        disabledTextColor: Color = textColor.copy(ContentAlpha.disabled),
+        backgroundColor: Color = MaterialTheme.colors.onSurface.copy(alpha = BackgroundOpacity),
+        cursorColor: Color = MaterialTheme.colors.primary,
+        errorCursorColor: Color = MaterialTheme.colors.error,
+        focusedIndicatorColor: Color =
+            MaterialTheme.colors.primary.copy(alpha = ContentAlpha.high),
+        unfocusedIndicatorColor: Color =
+            MaterialTheme.colors.onSurface.copy(alpha = UnfocusedIndicatorLineOpacity),
+        disabledIndicatorColor: Color = unfocusedIndicatorColor.copy(alpha = ContentAlpha.disabled),
+        errorIndicatorColor: Color = MaterialTheme.colors.error,
+        leadingIconColor: Color =
+            MaterialTheme.colors.onSurface.copy(alpha = IconOpacity),
+        disabledLeadingIconColor: Color = leadingIconColor.copy(alpha = ContentAlpha.disabled),
+        errorLeadingIconColor: Color = leadingIconColor,
+        trailingIconColor: Color =
+            MaterialTheme.colors.onSurface.copy(alpha = IconOpacity),
+        disabledTrailingIconColor: Color = trailingIconColor.copy(alpha = ContentAlpha.disabled),
+        errorTrailingIconColor: Color = MaterialTheme.colors.error,
+        focusedLabelColor: Color =
+            MaterialTheme.colors.primary.copy(alpha = ContentAlpha.high),
+        unfocusedLabelColor: Color = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium),
+        disabledLabelColor: Color = unfocusedLabelColor.copy(ContentAlpha.disabled),
+        errorLabelColor: Color = MaterialTheme.colors.error,
+        placeholderColor: Color = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium),
+        disabledPlaceholderColor: Color = placeholderColor.copy(ContentAlpha.disabled)
+    ): TextFieldColors =
+        DefaultTextFieldColors(
+            textColor = textColor,
+            disabledTextColor = disabledTextColor,
+            cursorColor = cursorColor,
+            errorCursorColor = errorCursorColor,
+            focusedIndicatorColor = focusedIndicatorColor,
+            unfocusedIndicatorColor = unfocusedIndicatorColor,
+            errorIndicatorColor = errorIndicatorColor,
+            disabledIndicatorColor = disabledIndicatorColor,
+            leadingIconColor = leadingIconColor,
+            disabledLeadingIconColor = disabledLeadingIconColor,
+            errorLeadingIconColor = errorLeadingIconColor,
+            trailingIconColor = trailingIconColor,
+            disabledTrailingIconColor = disabledTrailingIconColor,
+            errorTrailingIconColor = errorTrailingIconColor,
+            backgroundColor = backgroundColor,
+            focusedLabelColor = focusedLabelColor,
+            unfocusedLabelColor = unfocusedLabelColor,
+            disabledLabelColor = disabledLabelColor,
+            errorLabelColor = errorLabelColor,
+            placeholderColor = placeholderColor,
+            disabledPlaceholderColor = disabledPlaceholderColor
+        )
+
+    /**
+     * Creates a [TextFieldColors] that represents the default input text, background and content
+     * (including label, placeholder, leading and trailing icons) colors used in an
+     * [OutlinedTextField].
+     */
+    @Composable
+    fun outlinedTextFieldColors(
+        textColor: Color = LocalContentColor.current.copy(LocalContentAlpha.current),
+        disabledTextColor: Color = textColor.copy(ContentAlpha.disabled),
+        backgroundColor: Color = Color.Transparent,
+        cursorColor: Color = MaterialTheme.colors.primary,
+        errorCursorColor: Color = MaterialTheme.colors.error,
+        focusedBorderColor: Color =
+            MaterialTheme.colors.primary.copy(alpha = ContentAlpha.high),
+        unfocusedBorderColor: Color =
+            MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled),
+        disabledBorderColor: Color = unfocusedBorderColor.copy(alpha = ContentAlpha.disabled),
+        errorBorderColor: Color = MaterialTheme.colors.error,
+        leadingIconColor: Color =
+            MaterialTheme.colors.onSurface.copy(alpha = IconOpacity),
+        disabledLeadingIconColor: Color = leadingIconColor.copy(alpha = ContentAlpha.disabled),
+        errorLeadingIconColor: Color = leadingIconColor,
+        trailingIconColor: Color =
+            MaterialTheme.colors.onSurface.copy(alpha = IconOpacity),
+        disabledTrailingIconColor: Color = trailingIconColor.copy(alpha = ContentAlpha.disabled),
+        errorTrailingIconColor: Color = MaterialTheme.colors.error,
+        focusedLabelColor: Color =
+            MaterialTheme.colors.primary.copy(alpha = ContentAlpha.high),
+        unfocusedLabelColor: Color = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium),
+        disabledLabelColor: Color = unfocusedLabelColor.copy(ContentAlpha.disabled),
+        errorLabelColor: Color = MaterialTheme.colors.error,
+        placeholderColor: Color = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium),
+        disabledPlaceholderColor: Color = placeholderColor.copy(ContentAlpha.disabled)
+    ): TextFieldColors =
+        DefaultTextFieldColors(
+            textColor = textColor,
+            disabledTextColor = disabledTextColor,
+            cursorColor = cursorColor,
+            errorCursorColor = errorCursorColor,
+            focusedIndicatorColor = focusedBorderColor,
+            unfocusedIndicatorColor = unfocusedBorderColor,
+            errorIndicatorColor = errorBorderColor,
+            disabledIndicatorColor = disabledBorderColor,
+            leadingIconColor = leadingIconColor,
+            disabledLeadingIconColor = disabledLeadingIconColor,
+            errorLeadingIconColor = errorLeadingIconColor,
+            trailingIconColor = trailingIconColor,
+            disabledTrailingIconColor = disabledTrailingIconColor,
+            errorTrailingIconColor = errorTrailingIconColor,
+            backgroundColor = backgroundColor,
+            focusedLabelColor = focusedLabelColor,
+            unfocusedLabelColor = unfocusedLabelColor,
+            disabledLabelColor = disabledLabelColor,
+            errorLabelColor = errorLabelColor,
+            placeholderColor = placeholderColor,
+            disabledPlaceholderColor = disabledPlaceholderColor
+        )
+}
+
+@Immutable
+private class DefaultTextFieldColors(
+    private val textColor: Color,
+    private val disabledTextColor: Color,
+    private val cursorColor: Color,
+    private val errorCursorColor: Color,
+    private val focusedIndicatorColor: Color,
+    private val unfocusedIndicatorColor: Color,
+    private val errorIndicatorColor: Color,
+    private val disabledIndicatorColor: Color,
+    private val leadingIconColor: Color,
+    private val disabledLeadingIconColor: Color,
+    private val errorLeadingIconColor: Color,
+    private val trailingIconColor: Color,
+    private val disabledTrailingIconColor: Color,
+    private val errorTrailingIconColor: Color,
+    private val backgroundColor: Color,
+    private val focusedLabelColor: Color,
+    private val unfocusedLabelColor: Color,
+    private val disabledLabelColor: Color,
+    private val errorLabelColor: Color,
+    private val placeholderColor: Color,
+    private val disabledPlaceholderColor: Color
+) : TextFieldColors {
+
+    @Composable
+    override fun leadingIconColor(enabled: Boolean, isError: Boolean): State<Color> {
+        return rememberUpdatedState(
+            when {
+                !enabled -> disabledLeadingIconColor
+                isError -> errorLeadingIconColor
+                else -> leadingIconColor
+            }
+        )
+    }
+
+    @Composable
+    override fun trailingIconColor(enabled: Boolean, isError: Boolean): State<Color> {
+        return rememberUpdatedState(
+            when {
+                !enabled -> disabledTrailingIconColor
+                isError -> errorTrailingIconColor
+                else -> trailingIconColor
+            }
+        )
+    }
+
+    @Composable
+    override fun indicatorColor(
+        enabled: Boolean,
+        isError: Boolean,
+        interactionSource: InteractionSource
+    ): State<Color> {
+        val interactions = remember { mutableStateListOf<Interaction>() }
+        LaunchedEffect(interactionSource) {
+            interactionSource.interactions.collect { interaction ->
+                when (interaction) {
+                    is FocusInteraction.Focus -> {
+                        interactions.add(interaction)
+                    }
+                    is FocusInteraction.Unfocus -> {
+                        interactions.remove(interaction.focus)
+                    }
+                }
+            }
+        }
+        val interaction = interactions.lastOrNull()
+
+        val targetValue = when {
+            !enabled -> disabledIndicatorColor
+            isError -> errorIndicatorColor
+            interaction is FocusInteraction.Focus -> focusedIndicatorColor
+            else -> unfocusedIndicatorColor
+        }
+        return if (enabled) {
+            animateColorAsState(targetValue, tween(durationMillis = AnimationDuration))
+        } else {
+            rememberUpdatedState(targetValue)
+        }
+    }
+
+    @Composable
+    override fun backgroundColor(enabled: Boolean): State<Color> {
+        return rememberUpdatedState(backgroundColor)
+    }
+
+    @Composable
+    override fun placeholderColor(enabled: Boolean): State<Color> {
+        return rememberUpdatedState(if (enabled) placeholderColor else disabledPlaceholderColor)
+    }
+
+    @Composable
+    override fun labelColor(
+        enabled: Boolean,
+        error: Boolean,
+        interactionSource: InteractionSource
+    ): State<Color> {
+        val interactions = remember { mutableStateListOf<Interaction>() }
+        LaunchedEffect(interactionSource) {
+            interactionSource.interactions.collect { interaction ->
+                when (interaction) {
+                    is FocusInteraction.Focus -> {
+                        interactions.add(interaction)
+                    }
+                    is FocusInteraction.Unfocus -> {
+                        interactions.remove(interaction.focus)
+                    }
+                }
+            }
+        }
+        val interaction = interactions.lastOrNull()
+
+        val targetValue = when {
+            !enabled -> disabledLabelColor
+            error -> errorLabelColor
+            interaction is FocusInteraction.Focus -> focusedLabelColor
+            else -> unfocusedLabelColor
+        }
+        return if (enabled) {
+            animateColorAsState(targetValue, tween(durationMillis = AnimationDuration))
+        } else {
+            rememberUpdatedState(targetValue)
+        }
+    }
+
+    @Composable
+    override fun textColor(enabled: Boolean): State<Color> {
+        return rememberUpdatedState(if (enabled) textColor else disabledTextColor)
+    }
+
+    @Composable
+    override fun cursorColor(isError: Boolean): State<Color> {
+        return rememberUpdatedState(if (isError) errorCursorColor else cursorColor)
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other == null || this::class != other::class) return false
+
+        other as DefaultTextFieldColors
+
+        if (textColor != other.textColor) return false
+        if (disabledTextColor != other.disabledTextColor) return false
+        if (cursorColor != other.cursorColor) return false
+        if (errorCursorColor != other.errorCursorColor) return false
+        if (focusedIndicatorColor != other.focusedIndicatorColor) return false
+        if (unfocusedIndicatorColor != other.unfocusedIndicatorColor) return false
+        if (errorIndicatorColor != other.errorIndicatorColor) return false
+        if (disabledIndicatorColor != other.disabledIndicatorColor) return false
+        if (leadingIconColor != other.leadingIconColor) return false
+        if (disabledLeadingIconColor != other.disabledLeadingIconColor) return false
+        if (errorLeadingIconColor != other.errorLeadingIconColor) return false
+        if (trailingIconColor != other.trailingIconColor) return false
+        if (disabledTrailingIconColor != other.disabledTrailingIconColor) return false
+        if (errorTrailingIconColor != other.errorTrailingIconColor) return false
+        if (backgroundColor != other.backgroundColor) return false
+        if (focusedLabelColor != other.focusedLabelColor) return false
+        if (unfocusedLabelColor != other.unfocusedLabelColor) return false
+        if (disabledLabelColor != other.disabledLabelColor) return false
+        if (errorLabelColor != other.errorLabelColor) return false
+        if (placeholderColor != other.placeholderColor) return false
+        if (disabledPlaceholderColor != other.disabledPlaceholderColor) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = textColor.hashCode()
+        result = 31 * result + disabledTextColor.hashCode()
+        result = 31 * result + cursorColor.hashCode()
+        result = 31 * result + errorCursorColor.hashCode()
+        result = 31 * result + focusedIndicatorColor.hashCode()
+        result = 31 * result + unfocusedIndicatorColor.hashCode()
+        result = 31 * result + errorIndicatorColor.hashCode()
+        result = 31 * result + disabledIndicatorColor.hashCode()
+        result = 31 * result + leadingIconColor.hashCode()
+        result = 31 * result + disabledLeadingIconColor.hashCode()
+        result = 31 * result + errorLeadingIconColor.hashCode()
+        result = 31 * result + trailingIconColor.hashCode()
+        result = 31 * result + disabledTrailingIconColor.hashCode()
+        result = 31 * result + errorTrailingIconColor.hashCode()
+        result = 31 * result + backgroundColor.hashCode()
+        result = 31 * result + focusedLabelColor.hashCode()
+        result = 31 * result + unfocusedLabelColor.hashCode()
+        result = 31 * result + disabledLabelColor.hashCode()
+        result = 31 * result + errorLabelColor.hashCode()
+        result = 31 * result + placeholderColor.hashCode()
+        result = 31 * result + disabledPlaceholderColor.hashCode()
+        return result
+    }
+}
\ No newline at end of file
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldImpl.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldImpl.kt
index a70c8bab..d7009e8 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldImpl.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldImpl.kt
@@ -16,16 +16,14 @@
 
 package androidx.compose.material
 
-import androidx.compose.animation.animateColor
 import androidx.compose.animation.core.LinearEasing
 import androidx.compose.animation.core.animateDp
 import androidx.compose.animation.core.animateFloat
 import androidx.compose.animation.core.spring
 import androidx.compose.animation.core.tween
 import androidx.compose.animation.core.updateTransition
-import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.Interaction
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.collectIsFocusedAsState
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.text.KeyboardActions
 import androidx.compose.foundation.text.KeyboardOptions
@@ -43,10 +41,8 @@
 import androidx.compose.ui.layout.MeasureResult
 import androidx.compose.ui.layout.MeasureScope
 import androidx.compose.ui.layout.Placeable
-import androidx.compose.ui.node.Ref
 import androidx.compose.ui.platform.InspectorValueInfo
 import androidx.compose.ui.platform.debugInspectorInfo
-import androidx.compose.ui.text.SoftwareKeyboardController
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.input.TextFieldValue
 import androidx.compose.ui.text.input.VisualTransformation
@@ -65,7 +61,6 @@
  * Implementation of the [TextField] and [OutlinedTextField]
  */
 @Composable
-@OptIn(ExperimentalFoundationApi::class)
 internal fun TextFieldImpl(
     type: TextFieldType,
     enabled: Boolean,
@@ -79,60 +74,34 @@
     placeholder: @Composable (() -> Unit)?,
     leading: @Composable (() -> Unit)?,
     trailing: @Composable (() -> Unit)?,
-    isErrorValue: Boolean,
+    isError: Boolean,
     visualTransformation: VisualTransformation,
     keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
     keyboardActions: KeyboardActions,
     maxLines: Int = Int.MAX_VALUE,
-    onTextInputStarted: (SoftwareKeyboardController) -> Unit,
-    interactionState: InteractionState,
-    activeColor: Color,
-    inactiveColor: Color,
-    errorColor: Color,
-    backgroundColor: Color,
-    shape: Shape
+    interactionSource: MutableInteractionSource,
+    shape: Shape,
+    colors: TextFieldColors
 ) {
-    // TODO(soboleva): b/171305338 provide colors object and apply alpha there instead
     // If color is not provided via the text style, use content color as a default
     val textColor = textStyle.color.takeOrElse {
-        LocalContentColor.current
-    }.copy(alpha = if (enabled) LocalContentAlpha.current else ContentAlpha.disabled)
+        colors.textColor(enabled).value
+    }
     val mergedTextStyle = textStyle.merge(TextStyle(color = textColor))
 
-    val keyboardController: Ref<SoftwareKeyboardController> = remember { Ref() }
-
-    val isFocused = interactionState.contains(Interaction.Focused)
+    val isFocused = interactionSource.collectIsFocusedAsState().value
+    val transformedText = remember(value.annotatedString, visualTransformation) {
+        visualTransformation.filter(value.annotatedString)
+    }.text
     val inputState = when {
         isFocused -> InputPhase.Focused
-        value.text.isEmpty() -> InputPhase.UnfocusedEmpty
+        transformedText.isEmpty() -> InputPhase.UnfocusedEmpty
         else -> InputPhase.UnfocusedNotEmpty
     }
 
     TextFieldTransitionScope.Transition(
-        inputState = inputState,
-        showLabel = label != null,
-        activeColor = if (isErrorValue) {
-            errorColor
-        } else {
-            activeColor.applyAlpha(alpha = ContentAlpha.high)
-        },
-        labelInactiveColor = if (isErrorValue) {
-            errorColor
-        } else {
-            inactiveColor.applyAlpha(if (enabled) ContentAlpha.medium else ContentAlpha.disabled)
-        },
-        indicatorInactiveColor = when {
-            isErrorValue -> errorColor
-            type == TextFieldType.Filled -> inactiveColor.applyAlpha(
-                if (enabled) IndicatorInactiveAlpha else ContentAlpha.disabled
-            )
-            else -> inactiveColor.applyAlpha(alpha = ContentAlpha.disabled)
-        }
-
-    ) { labelProgress, animatedLabelColor, indicatorWidth, indicatorColor, placeholderAlpha ->
-
-        val leadingColor = inactiveColor.applyAlpha(alpha = TrailingLeadingAlpha)
-        val trailingColor = if (isErrorValue) errorColor else leadingColor
+        inputState = inputState, showLabel = label != null
+    ) { labelProgress, indicatorWidth, placeholderAlphaProgress ->
 
         val decoratedLabel: @Composable (() -> Unit)? =
             if (label != null) {
@@ -143,7 +112,7 @@
                         labelProgress
                     )
                     Decoration(
-                        contentColor = animatedLabelColor,
+                        contentColor = colors.labelColor(enabled, isError, interactionSource).value,
                         typography = labelAnimatedStyle,
                         content = label
                     )
@@ -151,25 +120,18 @@
             } else null
 
         val decoratedPlaceholder: @Composable ((Modifier) -> Unit)? =
-            if (placeholder != null && value.text.isEmpty()) {
+            if (placeholder != null && transformedText.isEmpty()) {
                 @Composable { modifier ->
-                    Box(modifier.alpha(placeholderAlpha)) {
+                    Box(modifier.alpha(placeholderAlphaProgress)) {
                         Decoration(
-                            contentColor = inactiveColor,
+                            contentColor = colors.placeholderColor(enabled).value,
                             typography = MaterialTheme.typography.subtitle1,
-                            contentAlpha =
-                                if (enabled) ContentAlpha.medium else ContentAlpha.disabled,
                             content = placeholder
                         )
                     }
                 }
             } else null
 
-        val cursorColor = if (isErrorValue) errorColor else activeColor
-        val onTextInputStartedAction: (SoftwareKeyboardController) -> Unit = {
-            keyboardController.value = it
-            onTextInputStarted(it)
-        }
         when (type) {
             TextFieldType.Filled -> {
                 TextFieldLayout(
@@ -184,19 +146,19 @@
                     singleLine = singleLine,
                     maxLines = maxLines,
                     visualTransformation = visualTransformation,
-                    onTextInputStarted = onTextInputStartedAction,
-                    interactionState = interactionState,
+                    interactionSource = interactionSource,
                     decoratedPlaceholder = decoratedPlaceholder,
                     decoratedLabel = decoratedLabel,
                     leading = leading,
                     trailing = trailing,
-                    leadingColor = leadingColor,
-                    trailingColor = trailingColor,
+                    leadingColor = colors.leadingIconColor(enabled, isError).value,
+                    trailingColor = colors.trailingIconColor(enabled, isError).value,
                     labelProgress = labelProgress,
                     indicatorWidth = indicatorWidth,
-                    indicatorColor = indicatorColor,
-                    backgroundColor = backgroundColor,
-                    cursorColor = cursorColor,
+                    indicatorColor =
+                        colors.indicatorColor(enabled, isError, interactionSource).value,
+                    backgroundColor = colors.backgroundColor(enabled).value,
+                    cursorColor = colors.cursorColor(isError).value,
                     shape = shape
                 )
             }
@@ -213,18 +175,18 @@
                     singleLine = singleLine,
                     maxLines = maxLines,
                     visualTransformation = visualTransformation,
-                    onTextInputStarted = onTextInputStartedAction,
-                    interactionState = interactionState,
+                    interactionSource = interactionSource,
                     decoratedPlaceholder = decoratedPlaceholder,
                     decoratedLabel = decoratedLabel,
                     leading = leading,
                     trailing = trailing,
-                    leadingColor = leadingColor,
-                    trailingColor = trailingColor,
+                    leadingColor = colors.leadingIconColor(enabled, isError).value,
+                    trailingColor = colors.trailingIconColor(enabled, isError).value,
                     labelProgress = labelProgress,
                     indicatorWidth = indicatorWidth,
-                    indicatorColor = indicatorColor,
-                    cursorColor = cursorColor
+                    indicatorColor =
+                        colors.indicatorColor(enabled, isError, interactionSource).value,
+                    cursorColor = colors.cursorColor(isError).value
                 )
             }
         }
@@ -232,13 +194,6 @@
 }
 
 /**
- * Set alpha if the color is not translucent
- */
-internal fun Color.applyAlpha(alpha: Float): Color {
-    return if (this.alpha != 1f) this else this.copy(alpha = alpha)
-}
-
-/**
  * Set content color, typography and emphasis for [content] composable
  */
 @Composable
@@ -248,7 +203,7 @@
     contentAlpha: Float? = null,
     content: @Composable () -> Unit
 ) {
-    val colorAndEmphasis = @Composable {
+    val colorAndEmphasis: @Composable () -> Unit = @Composable {
         CompositionLocalProvider(LocalContentColor provides contentColor) {
             if (contentAlpha != null) {
                 CompositionLocalProvider(
@@ -275,6 +230,7 @@
  */
 internal fun Modifier.iconPadding(start: Dp = 0.dp, end: Dp = 0.dp) =
     this.then(
+        @Suppress("ModifierInspectorInfo")
         object : LayoutModifier, InspectorValueInfo(
             debugInspectorInfo {
                 name = "iconPadding"
@@ -305,14 +261,9 @@
     fun Transition(
         inputState: InputPhase,
         showLabel: Boolean,
-        activeColor: Color,
-        labelInactiveColor: Color,
-        indicatorInactiveColor: Color,
         content: @Composable (
             labelProgress: Float,
-            labelColor: Color,
             indicatorWidth: Dp,
-            indicatorColor: Color,
             placeholderOpacity: Float
         ) -> Unit
     ) {
@@ -320,24 +271,6 @@
         // UnfocusedEmpty <-> UnfocusedNotEmpty are needed when a single state is used to control
         // multiple text fields.
         val transition = updateTransition(inputState)
-        val labelColor by transition.animateColor(
-            transitionSpec = { tween(durationMillis = AnimationDuration) }
-        ) {
-            when (it) {
-                InputPhase.Focused -> activeColor
-                InputPhase.UnfocusedEmpty -> labelInactiveColor
-                InputPhase.UnfocusedNotEmpty -> labelInactiveColor
-            }
-        }
-        val indicatorColor by transition.animateColor(
-            transitionSpec = { tween(durationMillis = AnimationDuration) }
-        ) {
-            when (it) {
-                InputPhase.Focused -> activeColor
-                InputPhase.UnfocusedEmpty -> indicatorInactiveColor
-                InputPhase.UnfocusedNotEmpty -> indicatorInactiveColor
-            }
-        }
 
         val labelProgress by transition.animateFloat(
             transitionSpec = { tween(durationMillis = AnimationDuration) }
@@ -388,9 +321,7 @@
 
         content(
             labelProgress,
-            labelColor,
             indicatorWidth,
-            indicatorColor,
             placeholderOpacity
         )
     }
@@ -414,17 +345,11 @@
 internal const val PlaceholderId = "Hint"
 internal const val LabelId = "Label"
 
-private const val AnimationDuration = 150
+internal const val AnimationDuration = 150
 private const val PlaceholderAnimationDuration = 83
 private const val PlaceholderAnimationDelayOrDuration = 67
 
 private val IndicatorUnfocusedWidth = 1.dp
 private val IndicatorFocusedWidth = 2.dp
-private const val TrailingLeadingAlpha = 0.54f
-internal val TextFieldMinHeight = 56.dp
-internal val TextFieldMinWidth = 280.dp
 internal val TextFieldPadding = 16.dp
 internal val HorizontalIconPadding = 12.dp
-
-// Filled text field uses 42% opacity to meet the contrast requirements for accessibility reasons
-private const val IndicatorInactiveAlpha = 0.42f
diff --git a/compose/material/material/src/desktopMain/kotlin/androidx/compose/material/DesktopMenu.desktop.kt b/compose/material/material/src/desktopMain/kotlin/androidx/compose/material/DesktopMenu.desktop.kt
index a5ae05a..8142487 100644
--- a/compose/material/material/src/desktopMain/kotlin/androidx/compose/material/DesktopMenu.desktop.kt
+++ b/compose/material/material/src/desktopMain/kotlin/androidx/compose/material/DesktopMenu.desktop.kt
@@ -17,7 +17,7 @@
 package androidx.compose.material
 
 import androidx.compose.animation.core.MutableTransitionState
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.ColumnScope
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.RowScope
@@ -110,10 +110,10 @@
  * @param enabled Controls the enabled state of the menu item - when `false`, the menu item
  * will not be clickable and [onClick] will not be invoked
  * @param contentPadding the padding applied to the content of this menu item
- * @param interactionState the [InteractionState] representing the different [Interaction]s
+ * @param interactionSource the [MutableInteractionSource] representing the different [Interaction]s
  * present on this DropdownMenuItem. You can create and pass in your own remembered
- * [InteractionState] if you want to read the [InteractionState] and customize the appearance /
- * behavior of this DropdownMenuItem in different [Interaction]s.
+ * [MutableInteractionSource] if you want to read the [MutableInteractionSource] and customize
+ * the appearance / behavior of this DropdownMenuItem in different [Interaction]s.
  */
 @Composable
 fun DropdownMenuItem(
@@ -121,7 +121,7 @@
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
     contentPadding: PaddingValues = MenuDefaults.DropdownMenuItemContentPadding,
-    interactionState: InteractionState = remember { InteractionState() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     content: @Composable RowScope.() -> Unit
 ) {
     DropdownMenuItemContent(
@@ -129,7 +129,7 @@
         modifier = modifier,
         enabled = enabled,
         contentPadding = contentPadding,
-        interactionState = interactionState,
+        interactionSource = interactionSource,
         content = content
     )
 }
diff --git a/compose/runtime/runtime-saveable/build.gradle b/compose/runtime/runtime-saveable/build.gradle
index 16a9d4c..0161977 100644
--- a/compose/runtime/runtime-saveable/build.gradle
+++ b/compose/runtime/runtime-saveable/build.gradle
@@ -48,7 +48,7 @@
 
         androidTestImplementation project(':compose:ui:ui')
         androidTestImplementation project(":compose:ui:ui-test-junit4")
-        androidTestImplementation "androidx.fragment:fragment:1.3.0-rc02"
+        androidTestImplementation "androidx.fragment:fragment:1.3.0"
         androidTestImplementation project(":activity:activity-compose")
         androidTestImplementation(ANDROIDX_TEST_UIAUTOMATOR)
         androidTestImplementation(ANDROIDX_TEST_CORE)
@@ -96,7 +96,7 @@
             androidAndroidTest.dependencies {
                 implementation project(':compose:ui:ui')
                 implementation project(":compose:ui:ui-test-junit4")
-                implementation "androidx.fragment:fragment:1.3.0-rc02"
+                implementation "androidx.fragment:fragment:1.3.0"
                 implementation project(":activity:activity-compose")
                 implementation(ANDROIDX_TEST_UIAUTOMATOR)
                 implementation(ANDROIDX_TEST_CORE)
diff --git a/compose/runtime/runtime/api/current.txt b/compose/runtime/runtime/api/current.txt
index 21f499c..e94fadb 100644
--- a/compose/runtime/runtime/api/current.txt
+++ b/compose/runtime/runtime/api/current.txt
@@ -159,7 +159,10 @@
 
   public final class CompositionKt {
     method public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent);
+    method @androidx.compose.runtime.ExperimentalComposeApi public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
     method @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent);
+    method @androidx.compose.runtime.ExperimentalComposeApi @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
+    method @androidx.compose.runtime.ExperimentalComposeApi public static kotlin.coroutines.CoroutineContext getRecomposeCoroutineContext(androidx.compose.runtime.ControlledComposition);
   }
 
   @androidx.compose.runtime.Stable public abstract sealed class CompositionLocal<T> {
@@ -304,6 +307,7 @@
     method public kotlinx.coroutines.flow.Flow<androidx.compose.runtime.Recomposer.State> getState();
     method public suspend Object? join(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public suspend Object? runRecomposeAndApplyChanges(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method @androidx.compose.runtime.ExperimentalComposeApi public suspend Object? runRecomposeConcurrentlyAndApplyChanges(kotlin.coroutines.CoroutineContext recomposeCoroutineContext, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final long changeCount;
     property public final boolean hasPendingWork;
     property public final kotlinx.coroutines.flow.Flow<androidx.compose.runtime.Recomposer.State> state;
diff --git a/compose/runtime/runtime/api/public_plus_experimental_current.txt b/compose/runtime/runtime/api/public_plus_experimental_current.txt
index 21f499c..e94fadb 100644
--- a/compose/runtime/runtime/api/public_plus_experimental_current.txt
+++ b/compose/runtime/runtime/api/public_plus_experimental_current.txt
@@ -159,7 +159,10 @@
 
   public final class CompositionKt {
     method public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent);
+    method @androidx.compose.runtime.ExperimentalComposeApi public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
     method @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent);
+    method @androidx.compose.runtime.ExperimentalComposeApi @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
+    method @androidx.compose.runtime.ExperimentalComposeApi public static kotlin.coroutines.CoroutineContext getRecomposeCoroutineContext(androidx.compose.runtime.ControlledComposition);
   }
 
   @androidx.compose.runtime.Stable public abstract sealed class CompositionLocal<T> {
@@ -304,6 +307,7 @@
     method public kotlinx.coroutines.flow.Flow<androidx.compose.runtime.Recomposer.State> getState();
     method public suspend Object? join(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public suspend Object? runRecomposeAndApplyChanges(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method @androidx.compose.runtime.ExperimentalComposeApi public suspend Object? runRecomposeConcurrentlyAndApplyChanges(kotlin.coroutines.CoroutineContext recomposeCoroutineContext, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final long changeCount;
     property public final boolean hasPendingWork;
     property public final kotlinx.coroutines.flow.Flow<androidx.compose.runtime.Recomposer.State> state;
diff --git a/compose/runtime/runtime/api/restricted_current.txt b/compose/runtime/runtime/api/restricted_current.txt
index 185e340..fd0e03e 100644
--- a/compose/runtime/runtime/api/restricted_current.txt
+++ b/compose/runtime/runtime/api/restricted_current.txt
@@ -173,7 +173,10 @@
 
   public final class CompositionKt {
     method public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent);
+    method @androidx.compose.runtime.ExperimentalComposeApi public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
     method @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent);
+    method @androidx.compose.runtime.ExperimentalComposeApi @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
+    method @androidx.compose.runtime.ExperimentalComposeApi public static kotlin.coroutines.CoroutineContext getRecomposeCoroutineContext(androidx.compose.runtime.ControlledComposition);
   }
 
   @androidx.compose.runtime.Stable public abstract sealed class CompositionLocal<T> {
@@ -329,6 +332,7 @@
     method public kotlinx.coroutines.flow.Flow<androidx.compose.runtime.Recomposer.State> getState();
     method public suspend Object? join(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public suspend Object? runRecomposeAndApplyChanges(kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method @androidx.compose.runtime.ExperimentalComposeApi public suspend Object? runRecomposeConcurrentlyAndApplyChanges(kotlin.coroutines.CoroutineContext recomposeCoroutineContext, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     property public final long changeCount;
     property public final boolean hasPendingWork;
     property public final kotlinx.coroutines.flow.Flow<androidx.compose.runtime.Recomposer.State> state;
diff --git a/compose/runtime/runtime/build.gradle b/compose/runtime/runtime/build.gradle
index b0c936b..ec98bf4 100644
--- a/compose/runtime/runtime/build.gradle
+++ b/compose/runtime/runtime/build.gradle
@@ -41,7 +41,7 @@
         api(KOTLIN_COROUTINES_ANDROID)
 
         implementation "androidx.annotation:annotation:1.1.0"
-        implementation "org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3"
+        implementation "org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.3"
         implementation(KOTLIN_STDLIB)
 
         testImplementation KOTLIN_TEST_JUNIT
@@ -74,7 +74,7 @@
             commonMain.dependencies {
                 implementation(KOTLIN_STDLIB_COMMON)
                 implementation(KOTLIN_COROUTINES_CORE)
-                implementation "org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3"
+                implementation "org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.3"
             }
             jvmMain.dependencies {
                 implementation(KOTLIN_STDLIB)
diff --git a/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/EmittableComposer.kt b/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/EmittableComposer.kt
index 9dde852..f34d918 100644
--- a/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/EmittableComposer.kt
+++ b/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/EmittableComposer.kt
@@ -28,7 +28,7 @@
     text: String = "",
     onClickListener: View.OnClickListener? = null
 ) {
-    AndroidView(viewBlock = { TextView(it) }) { view ->
+    AndroidView(factory = { TextView(it) }) { view ->
         view.id = id
         view.text = text
         if (onClickListener != null)
@@ -43,7 +43,7 @@
     text: String = "",
     onClickListener: View.OnClickListener? = null
 ) {
-    AndroidView(viewBlock = { Button(it) }) { view ->
+    AndroidView(factory = { Button(it) }) { view ->
         view.id = id
         view.text = text
         if (onClickListener != null)
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
index b466656..f886ebb 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
@@ -1161,7 +1161,6 @@
         groupNodeCountStack.clear()
         entersStack.clear()
         providersInvalidStack.clear()
-        invalidateStack.clear()
         reader.close()
         compoundKeyHash = 0
         childrenComposing = 0
@@ -1373,7 +1372,6 @@
      */
     internal fun applyChanges() {
         trace("Compose:applyChanges") {
-            invalidateStack.clear()
             val invalidationAnchors = slotTable.read { reader ->
                 invalidations.map { reader.anchor(it.location) to it }
             }
@@ -2903,6 +2901,7 @@
         nodeExpected = false
         startedGroup = false
         startedGroups.clear()
+        invalidateStack.clear()
         clearUpdatedNodeCounts()
     }
 
@@ -3014,6 +3013,10 @@
         override val effectCoroutineContext: CoroutineContext
             get() = parentContext.effectCoroutineContext
 
+        @OptIn(ExperimentalComposeApi::class)
+        override val recomposeCoroutineContext: CoroutineContext
+            get() = composition.recomposeCoroutineContext
+
         override fun composeInitial(
             composition: ControlledComposition,
             content: @Composable () -> Unit
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composition.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composition.kt
index 3a5cc70..eb471ec 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composition.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composition.kt
@@ -17,6 +17,9 @@
 @file:OptIn(InternalComposeApi::class)
 package androidx.compose.runtime
 
+import kotlin.coroutines.CoroutineContext
+import kotlin.coroutines.EmptyCoroutineContext
+
 /**
  * A composition object is usually constructed for you, and returned from an API that
  * is used to initially compose a UI. For instance, [setContent] returns a Composition.
@@ -144,6 +147,20 @@
 }
 
 /**
+ * The [CoroutineContext] that should be used to perform concurrent recompositions of this
+ * [ControlledComposition] when used in an environment supporting concurrent composition.
+ *
+ * See [Recomposer.runRecomposeConcurrentlyAndApplyChanges] as an example of configuring
+ * such an environment.
+ */
+// Implementation note: as/if this method graduates it should become a real method of
+// ControlledComposition with a default implementation.
+@ExperimentalComposeApi
+val ControlledComposition.recomposeCoroutineContext: CoroutineContext
+    @ExperimentalComposeApi
+    get() = (this as? CompositionImpl)?.recomposeContext ?: EmptyCoroutineContext
+
+/**
  * This method is the way to initiate a composition. Optionally, a [parent]
  * [CompositionContext] can be provided to make the composition behave as a sub-composition of
  * the parent or a [Recomposer] can be provided.
@@ -200,6 +217,38 @@
     )
 
 /**
+ * Create a [Composition] using [applier] to manage the composition, as a child of [parent].
+ *
+ * When used in a configuration that supports concurrent recomposition, hint to the environment
+ * that [recomposeCoroutineContext] should be used to perform recomposition. Recompositions will
+ * be launched into the
+ */
+@ExperimentalComposeApi
+fun Composition(
+    applier: Applier<*>,
+    parent: CompositionContext,
+    recomposeCoroutineContext: CoroutineContext
+): Composition = CompositionImpl(
+    parent,
+    applier,
+    recomposeContext = recomposeCoroutineContext
+)
+
+@TestOnly
+@ExperimentalComposeApi
+fun ControlledComposition(
+    applier: Applier<*>,
+    parent: CompositionContext,
+    recomposeCoroutineContext: CoroutineContext
+): ControlledComposition = CompositionImpl(
+    parent,
+    applier,
+    recomposeContext = recomposeCoroutineContext
+)
+
+private val PendingApplyNoModifications = Any()
+
+/**
  * @param parent An optional reference to the parent composition.
  * @param applier The applier to use to manage the tree built by the composer.
  * @param onDispose A callback to be triggered when [dispose] is called.
@@ -207,12 +256,31 @@
 internal class CompositionImpl(
     private val parent: CompositionContext,
     applier: Applier<*>,
-    private val onDispose: (() -> Unit)? = null
+    private val onDispose: (() -> Unit)? = null,
+    recomposeContext: CoroutineContext? = null
 ) : ControlledComposition {
+
+    /**
+     * `null` if a composition isn't pending to apply.
+     * `Set<Any>` or `Array<Set<Any>>` if there are modifications to record
+     * [PendingApplyNoModifications] if a composition is pending to apply, no modifications.
+     * any set contents will be sent to [ComposerImpl.recordModificationsOf] after applying changes
+     * before releasing [lock]
+     */
+    private val pendingModifications = AtomicReference<Any?>(null)
+
+    // Held when making changes to self or composer
+    private val lock = Any()
+
     private val composer: ComposerImpl = ComposerImpl(applier, parent, this).also {
         parent.registerComposer(it)
     }
 
+    private val _recomposeContext: CoroutineContext? = recomposeContext
+
+    val recomposeContext: CoroutineContext
+        get() = _recomposeContext ?: parent.recomposeCoroutineContext
+
     /**
      * Return true if this is a root (non-sub-) composition.
      */
@@ -228,7 +296,7 @@
     override val isDisposed: Boolean = disposed
 
     override val hasPendingChanges: Boolean
-        get() = composer.hasPendingChanges
+        get() = synchronized(lock) { composer.hasPendingChanges }
 
     override fun setContent(content: @Composable () -> Unit) {
         check(!disposed) { "The composition is disposed" }
@@ -236,46 +304,128 @@
         parent.composeInitial(this, composable)
     }
 
-    override fun composeContent(content: @Composable () -> Unit) {
-        composer.composeContent(content)
-    }
-
-    override fun dispose() {
-        if (!disposed) {
-            disposed = true
-            composable = {}
-            composer.dispose()
-            parent.unregisterComposition(this)
-            onDispose?.invoke()
+    @Suppress("UNCHECKED_CAST")
+    private fun drainPendingModificationsForCompositionLocked() {
+        // Recording modifications may race for lock. If there are pending modifications
+        // and we won the lock race, drain them before composing.
+        when (val toRecord = pendingModifications.getAndSet(PendingApplyNoModifications)) {
+            null -> {
+                // Do nothing, just start composing.
+            }
+            PendingApplyNoModifications -> error("pending composition has not been applied")
+            is Set<*> -> composer.recordModificationsOf(toRecord as Set<Any>)
+            is Array<*> -> for (changed in toRecord as Array<Set<Any>>) {
+                composer.recordModificationsOf(changed)
+            }
+            else -> error("corrupt pendingModifications drain: $pendingModifications")
         }
     }
 
-    override val hasInvalidations get() = composer.hasInvalidations
+    @Suppress("UNCHECKED_CAST")
+    private fun drainPendingModificationsLocked() {
+        when (val toRecord = pendingModifications.getAndSet(null)) {
+            PendingApplyNoModifications -> {
+                // No work to do
+            }
+            is Set<*> -> composer.recordModificationsOf(toRecord as Set<Any>)
+            is Array<*> -> for (changed in toRecord as Array<Set<Any>>) {
+                composer.recordModificationsOf(changed)
+            }
+            null -> error(
+                "calling recordModificationsOf and applyChanges concurrently is not supported"
+            )
+            else -> error(
+                "corrupt pendingModifications drain: $pendingModifications"
+            )
+        }
+    }
 
+    override fun composeContent(content: @Composable () -> Unit) {
+        // TODO: This should raise a signal to any currently running recompose calls
+        // to halt and return
+        synchronized(lock) {
+            drainPendingModificationsForCompositionLocked()
+            composer.composeContent(content)
+        }
+    }
+
+    override fun dispose() {
+        synchronized(lock) {
+            if (!disposed) {
+                disposed = true
+                composable = {}
+                composer.dispose()
+                parent.unregisterComposition(this)
+                onDispose?.invoke()
+            }
+        }
+    }
+
+    override val hasInvalidations get() = synchronized(lock) { composer.hasInvalidations }
+
+    /**
+     * To bootstrap multithreading handling, recording modifications is now deferred between
+     * recomposition with changes to apply and the application of those changes.
+     * [pendingModifications] will contain a queue of changes to apply once all current changes
+     * have been successfully processed. Draining this queue is the responsibility of [recompose]
+     * if it would return `false` (changes do not need to be applied) or [applyChanges].
+     */
+    @Suppress("UNCHECKED_CAST")
     override fun recordModificationsOf(values: Set<Any>) {
-        composer.recordModificationsOf(values)
+        while (true) {
+            val old = pendingModifications.get()
+            val new: Any = when (old) {
+                null, PendingApplyNoModifications -> values
+                is Set<*> -> arrayOf(old, values)
+                is Array<*> -> (old as Array<Set<Any>>) + values
+                else -> error("corrupt pendingModifications: $pendingModifications")
+            }
+            if (pendingModifications.compareAndSet(old, new)) {
+                if (old == null) {
+                    synchronized(lock) {
+                        drainPendingModificationsLocked()
+                    }
+                }
+                break
+            }
+        }
     }
 
     override fun recordReadOf(value: Any) {
+        // Not acquiring lock since this happens during composition with it already held
         composer.recordReadOf(value)
     }
 
     override fun recordWriteOf(value: Any) {
+        // Not acquiring lock since this happens during composition with it already held
         composer.recordWriteOf(value)
     }
 
-    override fun recompose(): Boolean = composer.recompose()
+    override fun recompose(): Boolean = synchronized(lock) {
+        drainPendingModificationsForCompositionLocked()
+        composer.recompose().also { shouldDrain ->
+            // Apply would normally do this for us; do it now if apply shouldn't happen.
+            if (!shouldDrain) drainPendingModificationsLocked()
+        }
+    }
 
     override fun applyChanges() {
-        composer.applyChanges()
+        synchronized(lock) {
+            composer.applyChanges()
+            drainPendingModificationsLocked()
+        }
     }
 
     override fun invalidateAll() {
-        composer.invalidateAll()
+        synchronized(lock) {
+            composer.invalidateAll()
+        }
     }
 
     override fun verifyConsistent() {
-        composer.verifyConsistent()
+        synchronized(lock) {
+            composer.verifyConsistent()
+        }
     }
 }
 
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/CompositionContext.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/CompositionContext.kt
index e904404..5a65e8a 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/CompositionContext.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/CompositionContext.kt
@@ -38,6 +38,7 @@
     internal abstract val compoundHashKey: Int
     internal abstract val collectingParameterInformation: Boolean
     internal abstract val effectCoroutineContext: CoroutineContext
+    internal abstract val recomposeCoroutineContext: CoroutineContext
     internal abstract fun composeInitial(
         composition: ControlledComposition,
         content: @Composable () -> Unit
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Effects.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Effects.kt
index e592a4e..2308db7 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Effects.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Effects.kt
@@ -101,6 +101,14 @@
         "the LaunchedEffect and determine when its previous effect coroutine should be cancelled " +
         "and a new effect launched for the new key."
 
+/**
+ * A side effect of composition that must be reversed or cleaned up if the [DisposableEffect]
+ * leaves the composition.
+ *
+ * It is an error to call [DisposableEffect] without at least one `key` parameter.
+ */
+// This deprecated-error function shadows the varargs overload so that the varargs version
+// is not used without key parameters.
 @Composable
 @NonRestartableComposable
 @Suppress("DeprecatedCallableAddReplaceWith", "UNUSED_PARAMETER")
@@ -298,6 +306,8 @@
  *
  * It is an error to call [LaunchedEffect] without at least one `key` parameter.
  */
+// This deprecated-error function shadows the varargs overload so that the varargs version
+// is not used without key parameters.
 @Deprecated(LaunchedEffectNoParamError, level = DeprecationLevel.ERROR)
 @Suppress("DeprecatedCallableAddReplaceWith", "UNUSED_PARAMETER")
 @Composable
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
index e54b2a4..f20d532 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
@@ -27,6 +27,8 @@
 import kotlinx.coroutines.CancellationException
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Job
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.cancelAndJoin
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -38,7 +40,9 @@
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.suspendCancellableCoroutine
 import kotlinx.coroutines.withContext
+import kotlin.coroutines.Continuation
 import kotlin.coroutines.CoroutineContext
+import kotlin.coroutines.EmptyCoroutineContext
 import kotlin.coroutines.coroutineContext
 import kotlin.coroutines.resume
 
@@ -138,10 +142,10 @@
                     if (!isClosed) {
                         // This is the job hosting frameContinuation; no need to resume it otherwise
                         runnerJob.cancel(cancellation)
-                    } else if (frameContinuation != null) {
-                        continuationToResume = frameContinuation
+                    } else if (workContinuation != null) {
+                        continuationToResume = workContinuation
                     }
-                    frameContinuation = null
+                    workContinuation = null
                     runnerJob.invokeOnCompletion { runnerJobCause ->
                         synchronized(stateLock) {
                             closeCause = throwable?.apply {
@@ -167,6 +171,9 @@
     internal override val effectCoroutineContext: CoroutineContext =
         effectCoroutineContext + broadcastFrameClock + effectJob
 
+    internal override val recomposeCoroutineContext: CoroutineContext
+        get() = EmptyCoroutineContext
+
     /**
      * Valid operational states of a [Recomposer].
      */
@@ -223,7 +230,9 @@
     private val knownCompositions = mutableListOf<ControlledComposition>()
     private val snapshotInvalidations = mutableListOf<Set<Any>>()
     private val compositionInvalidations = mutableListOf<ControlledComposition>()
-    private var frameContinuation: CancellableContinuation<Unit>? = null
+    private val compositionsAwaitingApply = mutableListOf<ControlledComposition>()
+    private var workContinuation: CancellableContinuation<Unit>? = null
+    private var concurrentCompositionsOutstanding = 0
     private var isClosed: Boolean = false
     // End properties guarded by stateLock
 
@@ -238,8 +247,9 @@
             knownCompositions.clear()
             snapshotInvalidations.clear()
             compositionInvalidations.clear()
-            frameContinuation?.cancel()
-            frameContinuation = null
+            compositionsAwaitingApply.clear()
+            workContinuation?.cancel()
+            workContinuation = null
             return null
         }
 
@@ -249,15 +259,18 @@
                 compositionInvalidations.clear()
                 if (broadcastFrameClock.hasAwaiters) State.InactivePendingWork else State.Inactive
             }
-            compositionInvalidations.isNotEmpty() || snapshotInvalidations.isNotEmpty() ||
+            compositionInvalidations.isNotEmpty() ||
+                snapshotInvalidations.isNotEmpty() ||
+                compositionsAwaitingApply.isNotEmpty() ||
+                concurrentCompositionsOutstanding > 0 ||
                 broadcastFrameClock.hasAwaiters -> State.PendingWork
             else -> State.Idle
         }
 
         _state.value = newState
         return if (newState == State.PendingWork) {
-            frameContinuation.also {
-                frameContinuation = null
+            workContinuation.also {
+                workContinuation = null
             }
         } else null
     }
@@ -334,6 +347,24 @@
         }
     }
 
+    private inline fun recordComposerModificationsLocked(
+        onEachInvalidComposition: (ControlledComposition) -> Unit
+    ) {
+        if (snapshotInvalidations.isNotEmpty()) {
+            snapshotInvalidations.fastForEach { changes ->
+                knownCompositions.fastForEach { composition ->
+                    composition.recordModificationsOf(changes)
+                }
+            }
+            snapshotInvalidations.clear()
+        }
+        compositionInvalidations.fastForEach(onEachInvalidComposition)
+        compositionInvalidations.clear()
+        if (deriveStateLocked() != null) {
+            error("called outside of runRecomposeAndApplyChanges")
+        }
+    }
+
     private fun registerRunnerJob(callingJob: Job) {
         synchronized(stateLock) {
             closeCause?.let { throw it }
@@ -355,7 +386,227 @@
      * compositions complete.
      * Unhandled failure exceptions from child coroutines will be thrown by this method.
      */
-    suspend fun runRecomposeAndApplyChanges() {
+    suspend fun runRecomposeAndApplyChanges() = recompositionRunner { parentFrameClock ->
+        val toRecompose = mutableListOf<ControlledComposition>()
+        val toApply = mutableListOf<ControlledComposition>()
+        while (shouldKeepRecomposing) {
+            awaitWorkAvailable()
+
+            // Don't await a new frame if we don't have frame-scoped work
+            if (
+                synchronized(stateLock) {
+                    if (!hasFrameWorkLocked) {
+                        recordComposerModificationsLocked()
+                        !hasFrameWorkLocked
+                    } else false
+                }
+            ) continue
+
+            // Align work with the next frame to coalesce changes.
+            // Note: it is possible to resume from the above with no recompositions pending,
+            // instead someone might be awaiting our frame clock dispatch below.
+            // We use the cached frame clock from above not just so that we don't locate it
+            // each time, but because we've installed the broadcastFrameClock as the scope
+            // clock above for user code to locate.
+            parentFrameClock.withFrameNanos { frameTime ->
+                trace("recomposeFrame") {
+                    // Dispatch MonotonicFrameClock frames first; this may produce new
+                    // composer invalidations that we must handle during the same frame.
+                    if (broadcastFrameClock.hasAwaiters) {
+                        // Propagate the frame time to anyone who is awaiting from the
+                        // recomposer clock.
+                        broadcastFrameClock.sendFrame(frameTime)
+
+                        // Ensure any global changes are observed
+                        Snapshot.sendApplyNotifications()
+                    }
+
+                    // Drain any composer invalidations from snapshot changes and record
+                    // composers to work on
+                    synchronized(stateLock) {
+                        recordComposerModificationsLocked()
+
+                        compositionInvalidations.fastForEach { toRecompose += it }
+                        compositionInvalidations.clear()
+                    }
+
+                    // Perform recomposition for any invalidated composers
+                    val modifiedValues = IdentityArraySet<Any>()
+                    try {
+                        toRecompose.fastForEach { composer ->
+                            performRecompose(composer, modifiedValues)?.let {
+                                toApply += it
+                            }
+                        }
+                        if (toApply.isNotEmpty()) changeCount++
+                    } finally {
+                        toRecompose.clear()
+                    }
+
+                    // Perform apply changes
+                    try {
+                        toApply.fastForEach { composition ->
+                            composition.applyChanges()
+                        }
+                    } finally {
+                        toApply.clear()
+                    }
+
+                    synchronized(stateLock) {
+                        deriveStateLocked()
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Await the invalidation of any associated [Composer]s, recompose them, and apply their
+     * changes to their associated [Composition]s if recomposition is successful.
+     *
+     * While [runRecomposeConcurrentlyAndApplyChanges] is running, [awaitIdle] will suspend until
+     * there are no more invalid composers awaiting recomposition.
+     *
+     * Recomposition of invalidated composers will occur in [recomposeCoroutineContext].
+     * [recomposeCoroutineContext] must not contain a [Job].
+     *
+     * This method will not return unless the [Recomposer] is [close]d and all effects in managed
+     * compositions complete.
+     * Unhandled failure exceptions from child coroutines will be thrown by this method.
+     */
+    @ExperimentalComposeApi
+    suspend fun runRecomposeConcurrentlyAndApplyChanges(
+        recomposeCoroutineContext: CoroutineContext
+    ) = recompositionRunner { parentFrameClock ->
+        require(recomposeCoroutineContext[Job] == null) {
+            "recomposeCoroutineContext may not contain a Job; found " +
+                recomposeCoroutineContext[Job]
+        }
+        val recomposeCoroutineScope = CoroutineScope(
+            coroutineContext + recomposeCoroutineContext + Job(coroutineContext.job)
+        )
+        val frameSignal = ProduceFrameSignal()
+        val frameLoop = launch { runFrameLoop(parentFrameClock, frameSignal) }
+        while (shouldKeepRecomposing) {
+            awaitWorkAvailable()
+
+            // Don't await a new frame if we don't have frame-scoped work
+            synchronized(stateLock) {
+                recordComposerModificationsLocked { composition ->
+                    concurrentCompositionsOutstanding++
+                    recomposeCoroutineScope.launch(composition.recomposeCoroutineContext) {
+                        val changedComposition = performRecompose(composition, null)
+                        synchronized(stateLock) {
+                            changedComposition?.let { compositionsAwaitingApply += it }
+                            concurrentCompositionsOutstanding--
+                            deriveStateLocked()
+                        }?.resume(Unit)
+                    }
+                }
+                if (hasConcurrentFrameWorkLocked) {
+                    frameSignal.requestFrameLocked()
+                } else null
+            }?.resume(Unit)
+        }
+        recomposeCoroutineScope.coroutineContext.job.cancelAndJoin()
+        frameLoop.cancelAndJoin()
+    }
+
+    private suspend fun runFrameLoop(
+        parentFrameClock: MonotonicFrameClock,
+        frameSignal: ProduceFrameSignal
+    ) {
+        val toRecompose = mutableListOf<ControlledComposition>()
+        val toApply = mutableListOf<ControlledComposition>()
+        while (true) {
+            frameSignal.awaitFrameRequest(stateLock)
+            // Align applying changes to the frame.
+            // Note: it is possible to resume from the above with no recompositions pending,
+            // instead someone might be awaiting our frame clock dispatch below.
+            // We use the cached frame clock from above not just so that we don't locate it
+            // each time, but because we've installed the broadcastFrameClock as the scope
+            // clock above for user code to locate.
+            parentFrameClock.withFrameNanos { frameTime ->
+                trace("recomposeFrame") {
+                    // Dispatch MonotonicFrameClock frames first; this may produce new
+                    // composer invalidations that we must handle during the same frame.
+                    if (broadcastFrameClock.hasAwaiters) {
+                        // Propagate the frame time to anyone who is awaiting from the
+                        // recomposer clock.
+                        broadcastFrameClock.sendFrame(frameTime)
+
+                        // Ensure any global changes are observed
+                        Snapshot.sendApplyNotifications()
+                    }
+
+                    // Drain any composer invalidations from snapshot changes and record
+                    // composers to work on.
+                    // We'll do these synchronously to make the current frame.
+                    synchronized(stateLock) {
+                        recordComposerModificationsLocked()
+
+                        compositionsAwaitingApply.fastForEach { toApply += it }
+                        compositionsAwaitingApply.clear()
+                        compositionInvalidations.fastForEach { toRecompose += it }
+                        compositionInvalidations.clear()
+                        frameSignal.takeFrameRequestLocked()
+                    }
+
+                    // Perform recomposition for any invalidated composers
+                    val modifiedValues = IdentityArraySet<Any>()
+                    try {
+                        toRecompose.fastForEach { composer ->
+                            performRecompose(composer, modifiedValues)?.let {
+                                toApply += it
+                            }
+                        }
+                    } finally {
+                        toRecompose.clear()
+                    }
+
+                    if (toApply.isNotEmpty()) changeCount++
+
+                    // Perform apply changes
+                    try {
+                        toApply.fastForEach { composition ->
+                            composition.applyChanges()
+                        }
+                    } finally {
+                        toApply.clear()
+                    }
+
+                    synchronized(stateLock) {
+                        deriveStateLocked()
+                    }
+                }
+            }
+        }
+    }
+
+    private val hasSchedulingWork: Boolean
+        get() = synchronized(stateLock) {
+            snapshotInvalidations.isNotEmpty() ||
+                compositionInvalidations.isNotEmpty() ||
+                broadcastFrameClock.hasAwaiters
+        }
+
+    private suspend fun awaitWorkAvailable() {
+        if (!hasSchedulingWork) {
+            suspendCancellableCoroutine<Unit> { co ->
+                synchronized(stateLock) {
+                    if (hasSchedulingWork) {
+                        co.resume(Unit)
+                    } else {
+                        workContinuation = co
+                    }
+                }
+            }
+        }
+    }
+
+    private suspend fun recompositionRunner(
+        block: suspend CoroutineScope.(parentFrameClock: MonotonicFrameClock) -> Unit
+    ) {
         val parentFrameClock = coroutineContext[MonotonicFrameClock] ?: DefaultMonotonicFrameClock
         withContext(broadcastFrameClock) {
             // Enforce mutual exclusion of callers; register self as current runner
@@ -384,90 +635,8 @@
                     // Don't need to deriveStateLocked here; invalidate will do it if needed.
                 }
 
-                val toRecompose = mutableListOf<ControlledComposition>()
-                val toApply = mutableListOf<ControlledComposition>()
-                while (shouldKeepRecomposing) {
-                    // Await something to do
-                    if (_state.value < State.PendingWork) {
-                        suspendCancellableCoroutine<Unit> { co ->
-                            synchronized(stateLock) {
-                                val currentState = _state.value
-                                if (currentState == State.PendingWork ||
-                                    currentState <= State.ShuttingDown
-                                ) {
-                                    co.resume(Unit)
-                                } else {
-                                    frameContinuation = co
-                                }
-                            }
-                        }
-                    }
-
-                    // Don't await a new frame if we don't have frame-scoped work
-                    if (
-                        synchronized(stateLock) {
-                            if (!hasFrameWorkLocked) {
-                                recordComposerModificationsLocked()
-                                !hasFrameWorkLocked
-                            } else false
-                        }
-                    ) continue
-
-                    // Align work with the next frame to coalesce changes.
-                    // Note: it is possible to resume from the above with no recompositions pending,
-                    // instead someone might be awaiting our frame clock dispatch below.
-                    // We use the cached frame clock from above not just so that we don't locate it
-                    // each time, but because we've installed the broadcastFrameClock as the scope
-                    // clock above for user code to locate.
-                    parentFrameClock.withFrameNanos { frameTime ->
-                        trace("recomposeFrame") {
-                            // Dispatch MonotonicFrameClock frames first; this may produce new
-                            // composer invalidations that we must handle during the same frame.
-                            if (broadcastFrameClock.hasAwaiters) {
-                                // Propagate the frame time to anyone who is awaiting from the
-                                // recomposer clock.
-                                broadcastFrameClock.sendFrame(frameTime)
-
-                                // Ensure any global changes are observed
-                                Snapshot.sendApplyNotifications()
-                            }
-
-                            // Drain any composer invalidations from snapshot changes and record
-                            // composers to work on
-                            synchronized(stateLock) {
-                                recordComposerModificationsLocked()
-
-                                compositionInvalidations.fastForEach { toRecompose += it }
-                                compositionInvalidations.clear()
-                            }
-
-                            // Perform recomposition for any invalidated composers
-                            val modifiedValues = IdentityArraySet<Any>()
-                            try {
-                                toRecompose.fastForEach { composer ->
-                                    performRecompose(composer, modifiedValues)?.let {
-                                        toApply += it
-                                    }
-                                }
-                                if (toApply.isNotEmpty()) changeCount++
-                            } finally {
-                                toRecompose.clear()
-                            }
-
-                            // Perform apply changes
-                            try {
-                                toApply.fastForEach { composition ->
-                                    composition.applyChanges()
-                                }
-                            } finally {
-                                toApply.clear()
-                            }
-
-                            synchronized(stateLock) {
-                                deriveStateLocked()
-                            }
-                        }
-                    }
+                coroutineScope {
+                    block(parentFrameClock)
                 }
             } finally {
                 unregisterApplyObserver.dispose()
@@ -546,12 +715,12 @@
 
     private fun performRecompose(
         composition: ControlledComposition,
-        modifiedValues: IdentityArraySet<Any>
+        modifiedValues: IdentityArraySet<Any>?
     ): ControlledComposition? {
         if (composition.isComposing || composition.isDisposed) return null
         return if (
             composing(composition, modifiedValues) {
-                modifiedValues.forEach { composition.recordWriteOf(it) }
+                modifiedValues?.forEach { composition.recordWriteOf(it) }
                 composition.recompose()
             }
         ) composition else null
@@ -603,12 +772,19 @@
      */
     val hasPendingWork: Boolean
         get() = synchronized(stateLock) {
-            snapshotInvalidations.isNotEmpty() || hasFrameWorkLocked
+            snapshotInvalidations.isNotEmpty() ||
+                compositionInvalidations.isNotEmpty() ||
+                concurrentCompositionsOutstanding > 0 ||
+                compositionsAwaitingApply.isNotEmpty() ||
+                broadcastFrameClock.hasAwaiters
         }
 
     private val hasFrameWorkLocked: Boolean
         get() = compositionInvalidations.isNotEmpty() || broadcastFrameClock.hasAwaiters
 
+    private val hasConcurrentFrameWorkLocked: Boolean
+        get() = compositionsAwaitingApply.isNotEmpty() || broadcastFrameClock.hasAwaiters
+
     /**
      * Suspends until the currently pending recomposition frame is complete.
      * Any recomposition for this recomposer triggered by actions before this call begins
@@ -697,3 +873,66 @@
         }
     }
 }
+
+/**
+ * Sentinel used by [ProduceFrameSignal]
+ */
+private val ProduceAnotherFrame = Any()
+private val FramePending = Any()
+
+/**
+ * Multiple producer, single consumer conflated signal that tells concurrent composition when it
+ * should try to produce another frame. This class is intended to be used along with a lock shared
+ * between producers and consumer.
+ */
+private class ProduceFrameSignal {
+    private var pendingFrameContinuation: Any? = null
+
+    /**
+     * Suspend until a frame is requested. After this method returns the signal is in a
+     * [FramePending] state which must be acknowledged by a call to [takeFrameRequestLocked]
+     * once all data that will be used to produce the frame has been claimed.
+     */
+    suspend fun awaitFrameRequest(lock: Any) {
+        synchronized(lock) {
+            if (pendingFrameContinuation === ProduceAnotherFrame) {
+                pendingFrameContinuation = FramePending
+                return
+            }
+        }
+        suspendCancellableCoroutine<Unit> { co ->
+            synchronized(lock) {
+                if (pendingFrameContinuation === ProduceAnotherFrame) {
+                    pendingFrameContinuation = FramePending
+                    co
+                } else {
+                    pendingFrameContinuation = co
+                    null
+                }
+            }?.resume(Unit)
+        }
+    }
+
+    /**
+     * Signal from the frame request consumer that the frame is beginning with data that was
+     * available up until this point. (Synchronizing access to that data is up to the caller.)
+     */
+    fun takeFrameRequestLocked() {
+        check(pendingFrameContinuation === FramePending) { "frame not pending" }
+        pendingFrameContinuation = null
+    }
+
+    fun requestFrameLocked(): Continuation<Unit>? = when (val co = pendingFrameContinuation) {
+        is Continuation<*> -> {
+            pendingFrameContinuation = FramePending
+            @Suppress("UNCHECKED_CAST")
+            co as Continuation<Unit>
+        }
+        ProduceAnotherFrame, FramePending -> null
+        null -> {
+            pendingFrameContinuation = ProduceAnotherFrame
+            null
+        }
+        else -> error("invalid pendingFrameContinuation $co")
+    }
+}
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt
index 5f1b780..d62a9bc 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt
@@ -164,9 +164,9 @@
     /**
      * Notify the snapshot that all objects created in this snapshot to this point should be
      * considered initialized. If any state object is are modified passed this point it will
-     * appear as modified in the snapshot and any applicable [SnapshotWriteObserver] will be
+     * appear as modified in the snapshot and any applicable snapshot write observer will be
      * called for the object and the object will be part of the a set of mutated objects sent to
-     * any applicable [SnapshotApplyObserver].
+     * any applicable snapshot apply observer.
      *
      * Unless [notifyObjectsInitialized] is called, state objects created in a snapshot are not
      * considered modified by the snapshot even if they are modified after construction.
@@ -199,7 +199,7 @@
          * [Snapshot.dispose] is called on the result.
          *
          * The [readObserver] parameter can be used to track when all state objects are read when in
-         * [Snapshot.enter]. A [SnapshotApplyObserver] can be registered using
+         * [Snapshot.enter]. A snapshot apply observer can be registered using
          * [Snapshot.registerApplyObserver] to observe modification of state objects.
          *
          * An active snapshot (after it is created but before [Snapshot.dispose] is called) requires
@@ -223,7 +223,6 @@
          *
          * @see Snapshot
          * @see Snapshot.registerApplyObserver
-         * @see SnapshotApplyObserver
          */
         fun takeSnapshot(
             readObserver: ((Any) -> Unit)? = null
@@ -327,7 +326,8 @@
          * Prior to returning, any changes made to snapshot state (e.g. state holders returned by
          * [androidx.compose.runtime.mutableStateOf] are not visible to other threads. When
          * [withMutableSnapshot] returns successfully those changes will be made visible to other
-         * threads  and any snapshot observers (e.g. [snapshotFlow]) will be notified of changes.
+         * threads  and any snapshot observers (e.g. [androidx.compose.runtime.snapshotFlow]) will
+         * be notified of changes.
          *
          * [block] must not suspend if [withMutableSnapshot] is called from a suspend function.
          */
@@ -431,9 +431,9 @@
         /**
          * Notify the snapshot that all objects created in this snapshot to this point should be
          * considered initialized. If any state object is are modified passed this point it will
-         * appear as modified in the snapshot and any applicable [SnapshotWriteObserver] will be
+         * appear as modified in the snapshot and any applicable snapshot write observer will be
          * called for the object and the object will be part of the a set of mutated objects sent to
-         * any applicable [SnapshotApplyObserver].
+         * any applicable snapshot apply observer.
          *
          * Unless [notifyObjectsInitialized] is called, state objects created in a snapshot are not
          * considered modified by the snapshot even if they are modified after construction.
@@ -495,7 +495,7 @@
  * Snapshots can be nested by calling [takeNestedSnapshot] or
  * [MutableSnapshot.takeNestedMutableSnapshot].
  *
- * @see takeMutableSnapshot
+ * @see Snapshot.takeMutableSnapshot
  * @see androidx.compose.runtime.mutableStateOf
  * @see androidx.compose.runtime.mutableStateListOf
  * @see androidx.compose.runtime.mutableStateMapOf
diff --git a/compose/runtime/runtime/src/jvmMain/kotlin/androidx/compose/runtime/ActualJvm.jvm.kt b/compose/runtime/runtime/src/jvmMain/kotlin/androidx/compose/runtime/ActualJvm.jvm.kt
index 63a02e2..7aa0d96 100644
--- a/compose/runtime/runtime/src/jvmMain/kotlin/androidx/compose/runtime/ActualJvm.jvm.kt
+++ b/compose/runtime/runtime/src/jvmMain/kotlin/androidx/compose/runtime/ActualJvm.jvm.kt
@@ -16,7 +16,7 @@
 
 package androidx.compose.runtime
 
-actual typealias AtomicReference<V> = java.util.concurrent.atomic.AtomicReference<V>
+internal actual typealias AtomicReference<V> = java.util.concurrent.atomic.AtomicReference<V>
 
 internal actual open class ThreadLocal<T> actual constructor(
     private val initialValue: () -> T
diff --git a/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/CompositionTests.kt b/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/CompositionTests.kt
index 54cbbbaa..7fa0307 100644
--- a/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/CompositionTests.kt
+++ b/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/CompositionTests.kt
@@ -19,25 +19,25 @@
 
 import androidx.compose.runtime.mock.Contact
 import androidx.compose.runtime.mock.ContactModel
-import androidx.compose.runtime.mock.MockViewValidator
-import androidx.compose.runtime.mock.Point
-import androidx.compose.runtime.mock.Report
-import androidx.compose.runtime.mock.TestMonotonicFrameClock
-import androidx.compose.runtime.mock.ViewApplier
-import androidx.compose.runtime.mock.contact
 import androidx.compose.runtime.mock.Edit
 import androidx.compose.runtime.mock.Linear
+import androidx.compose.runtime.mock.MockViewValidator
+import androidx.compose.runtime.mock.Point
 import androidx.compose.runtime.mock.Points
 import androidx.compose.runtime.mock.Repeated
+import androidx.compose.runtime.mock.Report
 import androidx.compose.runtime.mock.ReportsReport
 import androidx.compose.runtime.mock.ReportsTo
 import androidx.compose.runtime.mock.SelectContact
-import androidx.compose.runtime.mock.compositionTest
-import androidx.compose.runtime.mock.skip
+import androidx.compose.runtime.mock.TestMonotonicFrameClock
 import androidx.compose.runtime.mock.Text
 import androidx.compose.runtime.mock.View
+import androidx.compose.runtime.mock.ViewApplier
+import androidx.compose.runtime.mock.compositionTest
+import androidx.compose.runtime.mock.contact
 import androidx.compose.runtime.mock.expectChanges
 import androidx.compose.runtime.mock.expectNoChanges
+import androidx.compose.runtime.mock.skip
 import androidx.compose.runtime.mock.validate
 import androidx.compose.runtime.snapshots.Snapshot
 import kotlinx.coroutines.CoroutineScope
@@ -2644,19 +2644,18 @@
     @Test
     fun testComposableLambdaSubcompositionInvalidation() = runBlockingTest {
         localRecomposerTest { recomposer ->
-            val composition = ControlledComposition(EmptyApplier(), recomposer)
+            val composition = Composition(EmptyApplier(), recomposer)
             try {
                 var rootState by mutableStateOf(false)
                 val composedResults = mutableListOf<Boolean>()
                 Snapshot.notifyObjectsInitialized()
-                recomposer.composeInitial(composition) {
+                composition.setContent {
                     // Read into local variable, local will be captured below
                     val capturedValue = rootState
                     TestSubcomposition {
                         composedResults.add(capturedValue)
                     }
                 }
-                composition.applyChanges()
                 assertEquals(listOf(false), composedResults)
                 rootState = true
                 Snapshot.sendApplyNotifications()
@@ -2811,17 +2810,24 @@
     val parentRef = rememberCompositionContext()
     val currentContent by rememberUpdatedState(content)
     DisposableEffect(parentRef) {
-        val subcomposition = ControlledComposition(EmptyApplier(), parentRef)
-        parentRef.composeInitial(subcomposition) {
+        val subcomposition = Composition(EmptyApplier(), parentRef)
+        // TODO: work around for b/179701728
+        callSetContent(subcomposition) {
+            // Note: This is in a lambda invocation to keep the currentContent state read
+            // in the subcomposition's content composable. Changing this to be
+            // subcomposition.setContent(currentContent) would snapshot read only on initial set.
             currentContent()
         }
-        subcomposition.applyChanges()
         onDispose {
             subcomposition.dispose()
         }
     }
 }
 
+private fun callSetContent(composition: Composition, content: @Composable () -> Unit) {
+    composition.setContent(content)
+}
+
 class Ref<T : Any> {
     lateinit var value: T
 }
diff --git a/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/RecomposerTests.kt b/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/RecomposerTests.kt
index 2f6f820..0dc4e9e 100644
--- a/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/RecomposerTests.kt
+++ b/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/RecomposerTests.kt
@@ -22,15 +22,28 @@
 import androidx.compose.runtime.mock.compositionTest
 import androidx.compose.runtime.mock.expectNoChanges
 import androidx.compose.runtime.snapshots.Snapshot
+import kotlinx.coroutines.CoroutineName
+import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
+import kotlinx.coroutines.ObsoleteCoroutinesApi
+import kotlinx.coroutines.channels.Channel
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.newSingleThreadContext
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.TestCoroutineDispatcher
 import kotlinx.coroutines.test.runBlockingTest
 import kotlinx.coroutines.withContext
 import kotlinx.coroutines.withTimeoutOrNull
 import org.junit.Test
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.atomic.AtomicInteger
+import java.util.concurrent.atomic.AtomicLong
+import kotlin.coroutines.EmptyCoroutineContext
 import kotlin.test.assertEquals
+import kotlin.test.assertNotEquals
 import kotlin.test.assertNotNull
 import kotlin.test.assertTrue
 
@@ -214,18 +227,23 @@
         var state1 by mutableStateOf(1)
         var state2 by mutableStateOf(1)
 
-        @Composable fun validate(a: A?) {
+        @Composable
+        fun validate(a: A?) {
             assertNotNull(a)
         }
 
-        @Composable fun use(@Suppress("UNUSED_PARAMETER") i: Int) { }
+        @Composable
+        fun use(@Suppress("UNUSED_PARAMETER") i: Int) {
+        }
 
-        @Composable fun useA(a: A = A()) {
+        @Composable
+        fun useA(a: A = A()) {
             validate(a)
             use(state2)
         }
 
-        @Composable fun test() {
+        @Composable
+        fun test() {
             use(state1)
             useA()
         }
@@ -242,6 +260,140 @@
         advance()
         advance()
     }
+
+    @Test
+    @OptIn(ExperimentalComposeApi::class)
+    fun concurrentRecompositionOffMainThread() = runBlocking<Unit> {
+        val dispatcher = TestCoroutineDispatcher()
+        withContext(dispatcher) {
+            val clock = TestMonotonicFrameClock(this)
+            withContext(clock) {
+                val recomposer = Recomposer(coroutineContext)
+                launch {
+                    recomposer.runRecomposeConcurrentlyAndApplyChanges(Dispatchers.Default)
+                }
+
+                val composition = Composition(UnitApplier(), recomposer)
+                val threadLog = Channel<Thread>(Channel.BUFFERED)
+                lateinit var recomposeScope: RecomposeScope
+                composition.setContent {
+                    threadLog.offer(Thread.currentThread())
+                    val scope = currentRecomposeScope
+                    SideEffect {
+                        recomposeScope = scope
+                    }
+                }
+
+                val firstCompositionThread = threadLog.receive()
+
+                recomposeScope.invalidate()
+                dispatcher.advanceUntilIdle()
+
+                val secondCompositionThread = threadLog.receive()
+                assertNotEquals(firstCompositionThread, secondCompositionThread)
+
+                recomposer.close()
+                dispatcher.advanceUntilIdle()
+            }
+        }
+    }
+
+    @Test
+    @OptIn(ExperimentalComposeApi::class)
+    fun concurrentRecompositionInvalidationDuringComposition() = runBlocking {
+        val dispatcher = TestCoroutineDispatcher()
+        val clock = AutoTestFrameClock()
+        withContext(dispatcher + clock) {
+            val recomposer = Recomposer(coroutineContext)
+            launch {
+                recomposer.runRecomposeConcurrentlyAndApplyChanges(Dispatchers.Default)
+            }
+
+            val composition = Composition(UnitApplier(), recomposer)
+            var longRecomposition by mutableStateOf(false)
+            val longRecompositionLatch = CountDownLatch(1)
+            val applyCount = AtomicInteger(0)
+            val recomposeLatch = CountDownLatch(2)
+            composition.setContent {
+                recomposeLatch.countDown()
+                if (longRecomposition) {
+                    longRecompositionLatch.await()
+                }
+                SideEffect {
+                    applyCount.incrementAndGet()
+                }
+            }
+
+            assertEquals(1, applyCount.get(), "applyCount after initial composition")
+
+            Snapshot.withMutableSnapshot {
+                longRecomposition = true
+            }
+
+            assertTrue(recomposeLatch.await(5, TimeUnit.SECONDS), "recomposeLatch await timed out")
+            assertEquals(1, applyCount.get(), "applyCount after starting long recomposition")
+
+            longRecompositionLatch.countDown()
+            recomposer.awaitIdle()
+
+            assertEquals(2, applyCount.get(), "applyCount after long recomposition")
+
+            recomposer.close()
+        }
+    }
+
+    @Test
+    @OptIn(ExperimentalComposeApi::class, ObsoleteCoroutinesApi::class)
+    fun concurrentRecompositionOnCompositionSpecificContext() = runBlocking(AutoTestFrameClock()) {
+        val recomposer = Recomposer(coroutineContext)
+        launch {
+            recomposer.runRecomposeConcurrentlyAndApplyChanges(Dispatchers.Default)
+        }
+
+        newSingleThreadContext("specialThreadPool").use { pool ->
+            val composition = Composition(UnitApplier(), recomposer, pool)
+            var recomposition by mutableStateOf(false)
+            val recompositionThread = Channel<Thread>(1)
+            composition.setContent {
+                if (recomposition) {
+                    recompositionThread.offer(Thread.currentThread())
+                }
+            }
+
+            Snapshot.withMutableSnapshot {
+                recomposition = true
+            }
+
+            assertTrue(
+                withTimeoutOrNull(3_000) {
+                    recompositionThread.receive()
+                }?.name?.contains("specialThreadPool") == true,
+                "recomposition did not occur on expected thread"
+            )
+
+            recomposer.close()
+        }
+    }
+
+    @Test
+    @OptIn(ExperimentalComposeApi::class)
+    fun compositionRecomposeContextDelegation() {
+        val recomposer = Recomposer(EmptyCoroutineContext)
+        val parent = Composition(UnitApplier(), recomposer, CoroutineName("testParent"))
+        lateinit var child: ControlledComposition
+        parent.setContent {
+            val parentContext = rememberCompositionContext()
+            SideEffect {
+                child = ControlledComposition(UnitApplier(), parentContext)
+            }
+        }
+
+        assertEquals(
+            "testParent",
+            child.recomposeCoroutineContext[CoroutineName]?.name,
+            "child did not inherit parent recomposeCoroutineContext"
+        )
+    }
 }
 
 private class UnitApplier : Applier<Unit> {
@@ -312,3 +464,11 @@
 private fun Wrapper(content: @Composable () -> Unit) {
     content()
 }
+
+private class AutoTestFrameClock : MonotonicFrameClock {
+    private val time = AtomicLong(0)
+
+    override suspend fun <R> withFrameNanos(onFrame: (frameTimeNanos: Long) -> R): R {
+        return onFrame(time.getAndAdd(16_000_000))
+    }
+}
diff --git a/compose/test-utils/src/androidAndroidTest/kotlin/androidx/compose/testutils/DpAssertionsTest.kt b/compose/test-utils/src/androidAndroidTest/kotlin/androidx/compose/testutils/DpAssertionsTest.kt
new file mode 100644
index 0000000..c39f944
--- /dev/null
+++ b/compose/test-utils/src/androidAndroidTest/kotlin/androidx/compose/testutils/DpAssertionsTest.kt
@@ -0,0 +1,55 @@
+/*
+ * 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.testutils
+
+import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class DpAssertionsTest {
+
+    @Test
+    fun dp_assertEquals() {
+        5.dp.assertIsEqualTo(5.dp)
+        5.dp.assertIsEqualTo(4.6.dp)
+        5.dp.assertIsEqualTo(5.4.dp)
+    }
+
+    @Test
+    fun dp_assertNotEquals() {
+        5.dp.assertIsNotEqualTo(6.dp)
+    }
+
+    @Test
+    fun dp_assertEquals_fail() {
+        expectError<AssertionError> {
+            5.dp.assertIsEqualTo(6.dp)
+        }
+    }
+
+    @Test
+    fun dp_assertNotEquals_fail() {
+        expectError<AssertionError> {
+            5.dp.assertIsNotEqualTo(5.dp)
+            5.dp.assertIsNotEqualTo(5.4.dp)
+        }
+    }
+}
\ No newline at end of file
diff --git a/compose/test-utils/src/commonMain/kotlin/androidx/compose/testutils/DpAssertions.kt b/compose/test-utils/src/commonMain/kotlin/androidx/compose/testutils/DpAssertions.kt
new file mode 100644
index 0000000..035441c
--- /dev/null
+++ b/compose/test-utils/src/commonMain/kotlin/androidx/compose/testutils/DpAssertions.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.testutils
+
+import androidx.compose.ui.unit.Dp
+import kotlin.math.absoluteValue
+
+/**
+ * Asserts that this value is equal to the given [expected] value.
+ *
+ * Performs the comparison with the given [tolerance] or the default one if none is provided. It is
+ * recommended to use tolerance when comparing positions and size coming from the framework as there
+ * can be rounding operation performed by individual layouts so the values can be slightly off from
+ * the expected ones.
+ *
+ * @param expected The expected value to which this one should be equal to.
+ * @param subject Used in the error message to identify which item this assertion failed on.
+ * @param tolerance The tolerance within which the values should be treated as equal.
+ *
+ * @throws AssertionError if comparison fails.
+ */
+fun Dp.assertIsEqualTo(expected: Dp, subject: String = "", tolerance: Dp = Dp(.5f)) {
+    val diff = (this - expected).value.absoluteValue
+    if (diff > tolerance.value) {
+        // Comparison failed, report the error in DPs
+        throw AssertionError(
+            "Actual $subject is $this, expected $expected (tolerance: $tolerance)"
+        )
+    }
+}
+
+/**
+ * Asserts that this value is not equal to the given [unexpected] value.
+ *
+ * Performs the comparison with the given [tolerance] or the default one if none is provided. It is
+ * recommended to use tolerance when comparing positions and size coming from the framework as there
+ * can be rounding operation performed by individual layouts so the values can be slightly off from
+ * the expected ones.
+ *
+ * @param unexpected The value to which this one should not be equal to.
+ * @param subject Used in the error message to identify which item this assertion failed on.
+ * @param tolerance The tolerance that is expected to be greater than the difference between the
+ * given values to treat them as non-equal.
+ *
+ * @throws AssertionError if comparison fails.
+ */
+fun Dp.assertIsNotEqualTo(unexpected: Dp, subject: String = "", tolerance: Dp = Dp(.5f)) {
+    val diff = (this - unexpected).value.absoluteValue
+    if (diff <= tolerance.value) {
+        // Comparison failed, report the error in DPs
+        throw AssertionError(
+            "Actual $subject is $this, not expected to be equal to $unexpected within a " +
+                "tolerance of $tolerance"
+        )
+    }
+}
\ No newline at end of file
diff --git a/compose/ui/ui-geometry/api/current.txt b/compose/ui/ui-geometry/api/current.txt
index f93441e..60e5f28 100644
--- a/compose/ui/ui-geometry/api/current.txt
+++ b/compose/ui/ui-geometry/api/current.txt
@@ -5,7 +5,6 @@
     ctor public CornerRadius();
     method @androidx.compose.runtime.Stable public static inline operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static inline operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-kKHJgLs(long $this, optional float x, optional float y);
     method @androidx.compose.runtime.Stable public static operator long div-kKHJgLs(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
@@ -27,7 +26,7 @@
   }
 
   public final class CornerRadiusKt {
-    method @androidx.compose.runtime.Stable public static inline long CornerRadius(float x, optional float y);
+    method @androidx.compose.runtime.Stable public static long CornerRadius(float x, optional float y);
     method @androidx.compose.runtime.Stable public static long lerp-LCIZJP8(long start, long stop, float fraction);
   }
 
@@ -69,14 +68,12 @@
     ctor public Offset();
     method @androidx.compose.runtime.Stable public static operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-F1C5BW0(long $this, optional float x, optional float y);
     method @androidx.compose.runtime.Stable public static operator long div-F1C5BW0(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
     method @androidx.compose.runtime.Stable public static float getDistance-impl(long $this);
     method @androidx.compose.runtime.Stable public static float getDistanceSquared-impl(long $this);
-    method public long getPackedValue();
     method public static float getX-impl(long $this);
     method public static float getY-impl(long $this);
     method @androidx.compose.runtime.Immutable public static inline int hashCode-impl(long p);
@@ -87,7 +84,6 @@
     method @androidx.compose.runtime.Stable public static operator long times-F1C5BW0(long $this, float operand);
     method public static String toString-impl(long $this);
     method @androidx.compose.runtime.Stable public static operator long unaryMinus-F1C5BW0(long $this);
-    property public final long packedValue;
     field public static final androidx.compose.ui.geometry.Offset.Companion Companion;
   }
 
@@ -101,10 +97,10 @@
   }
 
   public final class OffsetKt {
-    method @androidx.compose.runtime.Stable public static inline long Offset(float x, float y);
+    method @androidx.compose.runtime.Stable public static long Offset(float x, float y);
     method public static boolean isFinite-k-4lQ0M(long);
     method public static boolean isSpecified-k-4lQ0M(long);
-    method public static inline boolean isUnspecified-k-4lQ0M(long);
+    method public static boolean isUnspecified-k-4lQ0M(long);
     method @androidx.compose.runtime.Stable public static long lerp-tX6QBWo(long start, long stop, float fraction);
     method public static inline long takeOrElse-Yy5JL0A(long, kotlin.jvm.functions.Function0<androidx.compose.ui.geometry.Offset> block);
   }
@@ -245,7 +241,6 @@
     ctor public Size();
     method @androidx.compose.runtime.Stable public static inline operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static inline operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-NH-jbRc(long $this, optional float width, optional float height);
     method @androidx.compose.runtime.Stable public static operator long div-NH-jbRc(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
diff --git a/compose/ui/ui-geometry/api/public_plus_experimental_current.txt b/compose/ui/ui-geometry/api/public_plus_experimental_current.txt
index f93441e..60e5f28 100644
--- a/compose/ui/ui-geometry/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-geometry/api/public_plus_experimental_current.txt
@@ -5,7 +5,6 @@
     ctor public CornerRadius();
     method @androidx.compose.runtime.Stable public static inline operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static inline operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-kKHJgLs(long $this, optional float x, optional float y);
     method @androidx.compose.runtime.Stable public static operator long div-kKHJgLs(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
@@ -27,7 +26,7 @@
   }
 
   public final class CornerRadiusKt {
-    method @androidx.compose.runtime.Stable public static inline long CornerRadius(float x, optional float y);
+    method @androidx.compose.runtime.Stable public static long CornerRadius(float x, optional float y);
     method @androidx.compose.runtime.Stable public static long lerp-LCIZJP8(long start, long stop, float fraction);
   }
 
@@ -69,14 +68,12 @@
     ctor public Offset();
     method @androidx.compose.runtime.Stable public static operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-F1C5BW0(long $this, optional float x, optional float y);
     method @androidx.compose.runtime.Stable public static operator long div-F1C5BW0(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
     method @androidx.compose.runtime.Stable public static float getDistance-impl(long $this);
     method @androidx.compose.runtime.Stable public static float getDistanceSquared-impl(long $this);
-    method public long getPackedValue();
     method public static float getX-impl(long $this);
     method public static float getY-impl(long $this);
     method @androidx.compose.runtime.Immutable public static inline int hashCode-impl(long p);
@@ -87,7 +84,6 @@
     method @androidx.compose.runtime.Stable public static operator long times-F1C5BW0(long $this, float operand);
     method public static String toString-impl(long $this);
     method @androidx.compose.runtime.Stable public static operator long unaryMinus-F1C5BW0(long $this);
-    property public final long packedValue;
     field public static final androidx.compose.ui.geometry.Offset.Companion Companion;
   }
 
@@ -101,10 +97,10 @@
   }
 
   public final class OffsetKt {
-    method @androidx.compose.runtime.Stable public static inline long Offset(float x, float y);
+    method @androidx.compose.runtime.Stable public static long Offset(float x, float y);
     method public static boolean isFinite-k-4lQ0M(long);
     method public static boolean isSpecified-k-4lQ0M(long);
-    method public static inline boolean isUnspecified-k-4lQ0M(long);
+    method public static boolean isUnspecified-k-4lQ0M(long);
     method @androidx.compose.runtime.Stable public static long lerp-tX6QBWo(long start, long stop, float fraction);
     method public static inline long takeOrElse-Yy5JL0A(long, kotlin.jvm.functions.Function0<androidx.compose.ui.geometry.Offset> block);
   }
@@ -245,7 +241,6 @@
     ctor public Size();
     method @androidx.compose.runtime.Stable public static inline operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static inline operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-NH-jbRc(long $this, optional float width, optional float height);
     method @androidx.compose.runtime.Stable public static operator long div-NH-jbRc(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
diff --git a/compose/ui/ui-geometry/api/restricted_current.txt b/compose/ui/ui-geometry/api/restricted_current.txt
index f93441e..60e5f28 100644
--- a/compose/ui/ui-geometry/api/restricted_current.txt
+++ b/compose/ui/ui-geometry/api/restricted_current.txt
@@ -5,7 +5,6 @@
     ctor public CornerRadius();
     method @androidx.compose.runtime.Stable public static inline operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static inline operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-kKHJgLs(long $this, optional float x, optional float y);
     method @androidx.compose.runtime.Stable public static operator long div-kKHJgLs(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
@@ -27,7 +26,7 @@
   }
 
   public final class CornerRadiusKt {
-    method @androidx.compose.runtime.Stable public static inline long CornerRadius(float x, optional float y);
+    method @androidx.compose.runtime.Stable public static long CornerRadius(float x, optional float y);
     method @androidx.compose.runtime.Stable public static long lerp-LCIZJP8(long start, long stop, float fraction);
   }
 
@@ -69,14 +68,12 @@
     ctor public Offset();
     method @androidx.compose.runtime.Stable public static operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-F1C5BW0(long $this, optional float x, optional float y);
     method @androidx.compose.runtime.Stable public static operator long div-F1C5BW0(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
     method @androidx.compose.runtime.Stable public static float getDistance-impl(long $this);
     method @androidx.compose.runtime.Stable public static float getDistanceSquared-impl(long $this);
-    method public long getPackedValue();
     method public static float getX-impl(long $this);
     method public static float getY-impl(long $this);
     method @androidx.compose.runtime.Immutable public static inline int hashCode-impl(long p);
@@ -87,7 +84,6 @@
     method @androidx.compose.runtime.Stable public static operator long times-F1C5BW0(long $this, float operand);
     method public static String toString-impl(long $this);
     method @androidx.compose.runtime.Stable public static operator long unaryMinus-F1C5BW0(long $this);
-    property public final long packedValue;
     field public static final androidx.compose.ui.geometry.Offset.Companion Companion;
   }
 
@@ -101,10 +97,10 @@
   }
 
   public final class OffsetKt {
-    method @androidx.compose.runtime.Stable public static inline long Offset(float x, float y);
+    method @androidx.compose.runtime.Stable public static long Offset(float x, float y);
     method public static boolean isFinite-k-4lQ0M(long);
     method public static boolean isSpecified-k-4lQ0M(long);
-    method public static inline boolean isUnspecified-k-4lQ0M(long);
+    method public static boolean isUnspecified-k-4lQ0M(long);
     method @androidx.compose.runtime.Stable public static long lerp-tX6QBWo(long start, long stop, float fraction);
     method public static inline long takeOrElse-Yy5JL0A(long, kotlin.jvm.functions.Function0<androidx.compose.ui.geometry.Offset> block);
   }
@@ -245,7 +241,6 @@
     ctor public Size();
     method @androidx.compose.runtime.Stable public static inline operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static inline operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-NH-jbRc(long $this, optional float width, optional float height);
     method @androidx.compose.runtime.Stable public static operator long div-NH-jbRc(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
diff --git a/compose/ui/ui-geometry/src/commonMain/kotlin/androidx/compose/ui/geometry/CornerRadius.kt b/compose/ui/ui-geometry/src/commonMain/kotlin/androidx/compose/ui/geometry/CornerRadius.kt
index ef44e85..d0f5466e 100644
--- a/compose/ui/ui-geometry/src/commonMain/kotlin/androidx/compose/ui/geometry/CornerRadius.kt
+++ b/compose/ui/ui-geometry/src/commonMain/kotlin/androidx/compose/ui/geometry/CornerRadius.kt
@@ -29,9 +29,8 @@
  * the radius along the Y axis matches that of the given x-axis
  * unless otherwise specified. Negative radii values are clamped to 0.
  */
-@Suppress("NOTHING_TO_INLINE")
 @Stable
-inline fun CornerRadius(x: Float, y: Float = x) = CornerRadius(packFloats(x, y))
+fun CornerRadius(x: Float, y: Float = x) = CornerRadius(packFloats(x, y))
 
 /**
  * A radius for either circular or elliptical (oval) shapes.
@@ -42,7 +41,7 @@
  **/
 @Suppress("EXPERIMENTAL_FEATURE_WARNING")
 @Immutable
-inline class CornerRadius(@PublishedApi internal val packedValue: Long) {
+inline class CornerRadius internal constructor(@PublishedApi internal val packedValue: Long) {
 
     /** The radius value on the horizontal axis. */
     @Stable
diff --git a/compose/ui/ui-geometry/src/commonMain/kotlin/androidx/compose/ui/geometry/Offset.kt b/compose/ui/ui-geometry/src/commonMain/kotlin/androidx/compose/ui/geometry/Offset.kt
index bef6a9f..4e048fa 100644
--- a/compose/ui/ui-geometry/src/commonMain/kotlin/androidx/compose/ui/geometry/Offset.kt
+++ b/compose/ui/ui-geometry/src/commonMain/kotlin/androidx/compose/ui/geometry/Offset.kt
@@ -27,9 +27,8 @@
 /**
  * Constructs an Offset from the given relative x and y offsets
  */
-@Suppress("NOTHING_TO_INLINE")
 @Stable
-inline fun Offset(x: Float, y: Float) = Offset(packFloats(x, y))
+fun Offset(x: Float, y: Float) = Offset(packFloats(x, y))
 
 /**
  * An immutable 2D floating-point offset.
@@ -59,7 +58,7 @@
  */
 @Suppress("EXPERIMENTAL_FEATURE_WARNING")
 @Immutable
-inline class Offset(val packedValue: Long) {
+inline class Offset internal constructor(internal val packedValue: Long) {
 
     @Stable
     val x: Float
@@ -250,7 +249,7 @@
  * `true` when this is [Offset.Unspecified].
  */
 @Stable
-inline val Offset.isUnspecified: Boolean get() = packedValue == Offset.Unspecified.packedValue
+val Offset.isUnspecified: Boolean get() = packedValue == Offset.Unspecified.packedValue
 
 /**
  * If this [Offset] [isSpecified] then this is returned, otherwise [block] is executed
diff --git a/compose/ui/ui-geometry/src/commonMain/kotlin/androidx/compose/ui/geometry/Size.kt b/compose/ui/ui-geometry/src/commonMain/kotlin/androidx/compose/ui/geometry/Size.kt
index 6f43c28..3ce5619 100644
--- a/compose/ui/ui-geometry/src/commonMain/kotlin/androidx/compose/ui/geometry/Size.kt
+++ b/compose/ui/ui-geometry/src/commonMain/kotlin/androidx/compose/ui/geometry/Size.kt
@@ -39,7 +39,7 @@
  */
 @Suppress("EXPERIMENTAL_FEATURE_WARNING")
 @Immutable
-inline class Size(@PublishedApi internal val packedValue: Long) {
+inline class Size internal constructor(@PublishedApi internal val packedValue: Long) {
 
     @Stable
     val width: Float
diff --git a/compose/ui/ui-graphics/api/current.txt b/compose/ui/ui-graphics/api/current.txt
index 88cc214..49af2a6 100644
--- a/compose/ui/ui-graphics/api/current.txt
+++ b/compose/ui/ui-graphics/api/current.txt
@@ -1083,9 +1083,6 @@
     property public long intrinsicSize;
   }
 
-  public final class BitmapPainterKt {
-  }
-
   public final class ColorPainter extends androidx.compose.ui.graphics.painter.Painter {
     method public long getColor-0d7_KjU();
     method public long getIntrinsicSize-NH-jbRc();
diff --git a/compose/ui/ui-graphics/api/public_plus_experimental_current.txt b/compose/ui/ui-graphics/api/public_plus_experimental_current.txt
index 88cc214..49af2a6 100644
--- a/compose/ui/ui-graphics/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-graphics/api/public_plus_experimental_current.txt
@@ -1083,9 +1083,6 @@
     property public long intrinsicSize;
   }
 
-  public final class BitmapPainterKt {
-  }
-
   public final class ColorPainter extends androidx.compose.ui.graphics.painter.Painter {
     method public long getColor-0d7_KjU();
     method public long getIntrinsicSize-NH-jbRc();
diff --git a/compose/ui/ui-graphics/api/restricted_current.txt b/compose/ui/ui-graphics/api/restricted_current.txt
index df03ea3..ec4a395 100644
--- a/compose/ui/ui-graphics/api/restricted_current.txt
+++ b/compose/ui/ui-graphics/api/restricted_current.txt
@@ -1139,9 +1139,6 @@
     property public long intrinsicSize;
   }
 
-  public final class BitmapPainterKt {
-  }
-
   public final class ColorPainter extends androidx.compose.ui.graphics.painter.Painter {
     method public long getColor-0d7_KjU();
     method public long getIntrinsicSize-NH-jbRc();
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Brush.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Brush.kt
index adcbba8..61b4ae8 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Brush.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Brush.kt
@@ -34,7 +34,8 @@
 
         /**
          * Creates a linear gradient with the provided colors along the given start and end
-         * coordinates. The colors are dispersed at the provided offset defined in the [ColorStop]
+         * coordinates. The colors are dispersed at the provided offset defined in the
+         * colorstop pair.
          *
          * ```
          *  Brush.linearGradient(
@@ -58,7 +59,7 @@
          */
         @Stable
         fun linearGradient(
-            vararg colorStops: ColorStop,
+            vararg colorStops: Pair<Float, Color>,
             start: Offset = Offset.Zero,
             end: Offset = Offset.Infinite,
             tileMode: TileMode = TileMode.Clamp
@@ -139,7 +140,7 @@
 
         /**
          * Creates a horizontal gradient with the given colors dispersed at the provided offset
-         * defined in the [ColorStop]
+         * defined in the colorstop pair.
          *
          * Ex:
          * ```
@@ -166,7 +167,7 @@
          */
         @Stable
         fun horizontalGradient(
-            vararg colorStops: ColorStop,
+            vararg colorStops: Pair<Float, Color>,
             startX: Float = 0.0f,
             endX: Float = Float.POSITIVE_INFINITY,
             tileMode: TileMode = TileMode.Clamp
@@ -210,7 +211,7 @@
 
         /**
          * Creates a vertical gradient with the given colors at the provided offset defined
-         * in the [ColorStop]
+         * in the [Pair<Float, Color>]
          *
          * Ex:
          * ```
@@ -237,7 +238,7 @@
          */
         @Stable
         fun verticalGradient(
-            vararg colorStops: ColorStop,
+            vararg colorStops: Pair<Float, Color>,
             startY: Float = 0f,
             endY: Float = Float.POSITIVE_INFINITY,
             tileMode: TileMode = TileMode.Clamp
@@ -250,7 +251,7 @@
 
         /**
          * Creates a radial gradient with the given colors at the provided offset
-         * defined in the [ColorStop]
+         * defined in the colorstop pair.
          * ```
          * Brush.radialGradient(
          *      0.0f to Color.Red,
@@ -277,7 +278,7 @@
          */
         @Stable
         fun radialGradient(
-            vararg colorStops: ColorStop,
+            vararg colorStops: Pair<Float, Color>,
             center: Offset = Offset.Unspecified,
             radius: Float = Float.POSITIVE_INFINITY,
             tileMode: TileMode = TileMode.Clamp
@@ -329,7 +330,7 @@
 
         /**
          * Creates a sweep gradient with the given colors dispersed around the center with
-         * offsets defined in each [ColorStop]. The sweep begins relative to 3 o'clock and continues
+         * offsets defined in each colorstop pair. The sweep begins relative to 3 o'clock and continues
          * clockwise until it reaches the starting position again.
          *
          * Ex:
@@ -352,7 +353,7 @@
          */
         @Stable
         fun sweepGradient(
-            vararg colorStops: ColorStop,
+            vararg colorStops: Pair<Float, Color>,
             center: Offset = Offset.Unspecified
         ): Brush = SweepGradient(
             colors = List<Color>(colorStops.size) { i -> colorStops[i].second },
@@ -421,8 +422,6 @@
     }
 }
 
-typealias ColorStop = Pair<Float, Color>
-
 /**
  * Brush implementation used to apply a linear gradient on a given [Paint]
  */
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/painter/BitmapPainter.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/painter/BitmapPainter.kt
index 17a867e..40877ee 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/painter/BitmapPainter.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/painter/BitmapPainter.kt
@@ -25,15 +25,6 @@
 import androidx.compose.ui.unit.toSize
 import kotlin.math.roundToInt
 
-@Deprecated(
-    "Use BitmapPainter instead",
-    ReplaceWith(
-        "BitmapPainter",
-        "androidx.compose.ui.graphics.painter.BitmapPainter"
-    )
-)
-typealias ImagePainter = BitmapPainter
-
 /**
  * [Painter] implementation used to draw an [ImageBitmap] into the provided canvas
  * This implementation can handle applying alpha and [ColorFilter] to it's drawn result
diff --git a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTreeTest.kt b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTreeTest.kt
index 363f58c..e6f6c73 100644
--- a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTreeTest.kt
+++ b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTreeTest.kt
@@ -220,7 +220,7 @@
                 name = "MaterialTheme",
                 hasTransformations = true,
                 fileName = "LayoutInspectorTreeTest.kt",
-                left = 68.0.dp, top = 49.7.dp, width = 88.5.dp, height = 21.7.dp,
+                left = 65.8.dp, top = 49.7.dp, width = 86.2.dp, height = 21.7.dp,
                 children = listOf("Text")
             )
             node(
@@ -228,7 +228,7 @@
                 isRenderNode = true,
                 hasTransformations = true,
                 fileName = "LayoutInspectorTreeTest.kt",
-                left = 68.0.dp, top = 49.7.dp, width = 88.5.dp, height = 21.7.dp,
+                left = 65.8.dp, top = 49.7.dp, width = 86.2.dp, height = 21.7.dp,
             )
         }
     }
@@ -443,9 +443,9 @@
                 assertWithMessage(message).that(node.id).isLessThan(0L)
             }
             if (hasTransformations) {
-                assertWithMessage(message).that(node.bounds).isNotEmpty()
+                assertWithMessage(message).that(node.bounds).isNotNull()
             } else {
-                assertWithMessage(message).that(node.bounds).isEmpty()
+                assertWithMessage(message).that(node.bounds).isNull()
             }
             if (left != Dp.Unspecified) {
                 with(density) {
diff --git a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/ParameterFactoryTest.kt b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/ParameterFactoryTest.kt
index ccc359c..57f9325 100644
--- a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/ParameterFactoryTest.kt
+++ b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/ParameterFactoryTest.kt
@@ -70,7 +70,7 @@
 import androidx.compose.ui.unit.em
 import androidx.compose.ui.unit.sp
 import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.LargeTest
+import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
 import kotlinx.coroutines.runBlocking
@@ -84,7 +84,7 @@
 private fun topLevelFunction() {
 }
 
-@LargeTest
+@MediumTest
 @RunWith(AndroidJUnit4::class)
 class ParameterFactoryTest {
     private val factory = ParameterFactory(InlineClassConverter())
@@ -558,6 +558,14 @@
     }
 
     @Test
+    fun testDoNotRecurseIntoAndroidAndJavaPackages() {
+        runBlocking {
+            assertThat(factory.create(node, "v1", java.net.URL("http://domain.com"))).isNull()
+            assertThat(factory.create(node, "v1", android.app.Notification())).isNull()
+        }
+    }
+
+    @Test
     fun testShadow() {
         assertThat(lookup(Shadow.None)).isEqualTo(ParameterType.String to "None")
         validate(factory.create(node, "shadow", Shadow(Color.Cyan, Offset.Zero, 2.5f))!!) {
diff --git a/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/InspectorNode.kt b/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/InspectorNode.kt
index 75ceb15..ab2a554 100644
--- a/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/InspectorNode.kt
+++ b/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/InspectorNode.kt
@@ -18,8 +18,6 @@
 
 import androidx.compose.ui.layout.LayoutInfo
 
-private val EmptyIntArray = IntArray(0)
-
 /**
  * Node representing a Composable for the Layout Inspector.
  */
@@ -88,12 +86,9 @@
     val height: Int,
 
     /**
-     * The 4 corners of the node after modifier transformations.
-     * If there are no coordinate transforms the array will be empty.
-     * Otherwise the content will be 8 integers representing 4 (x,y) corners
-     * in clockwise order of the original, untransformed coordinates.
+     * The 4 corners of the polygon after transformations of the original rectangle.
      */
-    val bounds: IntArray,
+    val bounds: QuadBounds? = null,
 
     /**
      * The parameters of this Composable.
@@ -106,6 +101,17 @@
     val children: List<InspectorNode>
 )
 
+data class QuadBounds(
+    val x0: Int,
+    val y0: Int,
+    val x1: Int,
+    val y1: Int,
+    val x2: Int,
+    val y2: Int,
+    val x3: Int,
+    val y3: Int,
+)
+
 /**
  * Parameter definition with a raw value reference.
  */
@@ -127,7 +133,7 @@
     var top = 0
     var width = 0
     var height = 0
-    var bounds = EmptyIntArray
+    var bounds: QuadBounds? = null
     val parameters = mutableListOf<RawParameter>()
     val children = mutableListOf<InspectorNode>()
 
@@ -139,7 +145,7 @@
         width = 0
         height = 0
         layoutNodes.clear()
-        bounds = EmptyIntArray
+        bounds = null
         children.clear()
     }
 
diff --git a/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTree.kt b/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTree.kt
index 519f2e3..815ec9c 100644
--- a/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTree.kt
+++ b/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTree.kt
@@ -308,7 +308,7 @@
                 node.layoutNodes.forEach { claimedNodes.getOrPut(it) { resultNode } }
                 parentNode.children.add(resultNode)
             }
-            if (node.bounds.isNotEmpty() && sameBoundingRectangle(parentNode, node)) {
+            if (node.bounds != null && sameBoundingRectangle(parentNode, node)) {
                 parentNode.bounds = node.bounds
             }
             parentNode.layoutNodes.addAll(node.layoutNodes)
@@ -366,11 +366,11 @@
         ) {
             return
         }
-        node.bounds = intArrayOf(
+        node.bounds = QuadBounds(
             topLeft.x, topLeft.y,
             topRight.x, topRight.y,
             bottomRight.x, bottomRight.y,
-            bottomLeft.x, bottomLeft.y
+            bottomLeft.x, bottomLeft.y,
         )
     }
 
diff --git a/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/ParameterFactory.kt b/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/ParameterFactory.kt
index 412e7c0..749087d 100644
--- a/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/ParameterFactory.kt
+++ b/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/ParameterFactory.kt
@@ -86,9 +86,9 @@
     private var creatorCache: ParameterCreator? = null
 
     /**
-     * Do not decompose instances from these package prefixes.
+     * Do not decompose instances or lookup constants from these package prefixes
      */
-    private val ignoredPackagePrefixes = listOf("android.graphics.")
+    private val ignoredPackagePrefixes = listOf("android.", "java.", "javax.")
 
     var density = Density(1.0f)
 
@@ -127,7 +127,9 @@
     }
 
     private fun loadConstantsFrom(javaClass: Class<*>) {
-        if (valuesLoaded.contains(javaClass)) {
+        if (valuesLoaded.contains(javaClass) ||
+            ignoredPackagePrefixes.any { javaClass.name.startsWith(it) }
+        ) {
             return
         }
         val related = generateSequence(javaClass) { it.superclass }.plus(javaClass.interfaces)
diff --git a/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/proto/ComposeExtensions.kt b/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/proto/ComposeExtensions.kt
index b1e6b8f..7fd7202 100644
--- a/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/proto/ComposeExtensions.kt
+++ b/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/proto/ComposeExtensions.kt
@@ -50,18 +50,16 @@
                 w = inspectorNode.width
                 h = inspectorNode.height
             }.build()
-            if (inspectorNode.bounds.size == 8) {
-                // Note: Inspector bounds are clockwise order (TL, TR, BR, BL) but Studio expects
-                // (TL, TR, BL, BR)
+            if (inspectorNode.bounds != null) {
                 render = Quad.newBuilder().apply {
-                    x0 = inspectorNode.bounds[0]
-                    y0 = inspectorNode.bounds[1]
-                    x1 = inspectorNode.bounds[2]
-                    y1 = inspectorNode.bounds[3]
-                    x2 = inspectorNode.bounds[6]
-                    y2 = inspectorNode.bounds[7]
-                    x3 = inspectorNode.bounds[4]
-                    y3 = inspectorNode.bounds[5]
+                    x0 = inspectorNode.bounds.x0
+                    y0 = inspectorNode.bounds.y0
+                    x1 = inspectorNode.bounds.x1
+                    y1 = inspectorNode.bounds.y1
+                    x2 = inspectorNode.bounds.x2
+                    y2 = inspectorNode.bounds.y2
+                    x3 = inspectorNode.bounds.x3
+                    y3 = inspectorNode.bounds.y3
                 }.build()
             }
         }.build()
diff --git a/compose/ui/ui-inspection/src/main/proto/compose_layout_inspection.proto b/compose/ui/ui-inspection/src/main/proto/compose_layout_inspection.proto
index a07d1e9..373809d 100644
--- a/compose/ui/ui-inspection/src/main/proto/compose_layout_inspection.proto
+++ b/compose/ui/ui-inspection/src/main/proto/compose_layout_inspection.proto
@@ -40,10 +40,8 @@
     int32 h = 4;
 }
 
-// A Quad will be the result of a Rect after applying some affine or perspective transformations.
-// While the transformed points can be skewed in a complex manner, the untransformed Rect source of
-// the coordinates will always be consistent:
-// 0 = top left, 1 = top right, 2 = bot left, 3 = bot right
+// A Quad holds the 4 corners of a polygon in drawing order, that represent the transformed shape
+// of a Rect after applying some affine or perspective transformations.
 message Quad {
     sint32 x0 = 1;
     sint32 y0 = 2;
diff --git a/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/FirstDrawTest.kt b/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/FirstDrawTest.kt
index 5f8f714..86ba57d 100644
--- a/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/FirstDrawTest.kt
+++ b/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/FirstDrawTest.kt
@@ -24,6 +24,7 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.platform.ComposeView
+import androidx.test.filters.LargeTest
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
 import org.junit.Rule
@@ -39,6 +40,7 @@
      * Tests that the compose tree has been drawn at least once when
      * [ComposeContentTestRule.setContent] finishes.
      */
+    @LargeTest
     @Test
     fun waitsForFirstDraw_withoutOnIdle() {
         var drawn = false
diff --git a/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/UncaughtExceptionsInCoroutinesTest.kt b/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/UncaughtExceptionsInCoroutinesTest.kt
new file mode 100644
index 0000000..0c5823c
--- /dev/null
+++ b/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/UncaughtExceptionsInCoroutinesTest.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.ui.test.junit4
+
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.withFrameNanos
+import androidx.compose.testutils.expectError
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.RuleChain
+import org.junit.rules.TestRule
+import org.junit.runner.RunWith
+import org.junit.runners.model.Statement
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+class UncaughtExceptionsInCoroutinesTest {
+
+    private class TestException : Exception()
+
+    // Need to expect the error in a test rule around the AndroidComposeTestRule, because the
+    // exception can surface after the test is completed, when the AndroidComposeTestRule cleans
+    // up test scoped variables.
+    private val testExceptionRule = TestRule { base, _ ->
+        object : Statement() {
+            override fun evaluate() {
+                expectError<TestException> {
+                    base.evaluate()
+                }
+            }
+        }
+    }
+
+    private val rule = createComposeRule()
+
+    @get:Rule
+    val testRule: TestRule = RuleChain.outerRule(testExceptionRule).around(rule)
+
+    // Run the test twice so we can verify if a failed test took down the test suite:
+    // - Results have 1 failed test:
+    //   exception handler isn't installed correctly
+    // - Results have 2 failed tests:
+    //   exception handler is installed correctly, but verifying thrown error is wrong
+
+    @Test
+    fun test1() {
+        throwInLaunchedEffect()
+    }
+
+    @Test
+    fun test2() {
+        throwInLaunchedEffect()
+    }
+
+    private fun throwInLaunchedEffect() {
+        rule.setContent {
+            LaunchedEffect(Unit) {
+                withFrameNanos {}
+                throw TestException()
+            }
+        }
+    }
+}
diff --git a/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/WaitingForOnCommitCallbackTest.kt b/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/WaitingForOnCommitCallbackTest.kt
index d6d2c96..887c852 100644
--- a/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/WaitingForOnCommitCallbackTest.kt
+++ b/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/WaitingForOnCommitCallbackTest.kt
@@ -21,6 +21,7 @@
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.Dispatchers
@@ -63,6 +64,7 @@
         assertThat(atomicBoolean.get()).isFalse()
     }
 
+    @LargeTest
     @Test
     fun cascadingOnCommits() {
         // Collect unique values (markers) at each step during the process and
diff --git a/compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule.android.kt b/compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule.android.kt
index f16542a..95c6158 100644
--- a/compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule.android.kt
+++ b/compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule.android.kt
@@ -61,6 +61,7 @@
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.TestCoroutineDispatcher
+import kotlinx.coroutines.test.TestCoroutineExceptionHandler
 import kotlinx.coroutines.withContext
 import org.junit.rules.RuleChain
 import org.junit.rules.TestRule
@@ -75,15 +76,15 @@
  * activity class type [A].
  *
  * This method is useful for tests that require a custom Activity. This is usually the case for
- * app tests. Make sure that you add the provided activity into your app's manifest file (usually
- * in main/AndroidManifest.xml).
+ * tests where the compose content is set by that Activity, instead of via the test rule's
+ * [setContent][ComposeContentTestRule.setContent]. Make sure that you add the provided activity
+ * into your app's manifest file (usually in main/AndroidManifest.xml).
  *
  * This creates a test rule that is using [ActivityScenarioRule] as the activity launcher. If you
  * would like to use a different one you can create [AndroidComposeTestRule] directly and supply
  * it with your own launcher.
  *
- * If you don't care about specific activity and just want to test composables in general, see
- * [createComposeRule].
+ * If your test doesn't require a specific Activity, use [createComposeRule] instead.
  */
 inline fun <reified A : ComponentActivity> createAndroidComposeRule():
     AndroidComposeTestRule<ActivityScenarioRule<A>, A> {
@@ -99,15 +100,15 @@
  * [activityClass].
  *
  * This method is useful for tests that require a custom Activity. This is usually the case for
- * app tests. Make sure that you add the provided activity into your app's manifest file (usually
- * in main/AndroidManifest.xml).
+ * tests where the compose content is set by that Activity, instead of via the test rule's
+ * [setContent][ComposeContentTestRule.setContent]. Make sure that you add the provided activity
+ * into your app's manifest file (usually in main/AndroidManifest.xml).
  *
  * This creates a test rule that is using [ActivityScenarioRule] as the activity launcher. If you
  * would like to use a different one you can create [AndroidComposeTestRule] directly and supply
  * it with your own launcher.
  *
- * If you don't care about specific activity and just want to test composables in general, see
- * [createComposeRule].
+ * If your test doesn't require a specific Activity, use [createComposeRule] instead.
  */
 fun <A : ComponentActivity> createAndroidComposeRule(
     activityClass: Class<A>
@@ -117,10 +118,16 @@
 )
 
 /**
- * Factory method to provide an implementation of [ComposeTestRule] that doesn't create a host
- * for you in which you can set content. Use this if you don't want the test rule to launch an
- * activity for you, which is typically the case when you launch your activity during the test
- * instead of before the test.
+ * Factory method to provide an implementation of [ComposeTestRule] that doesn't create a compose
+ * host for you in which you can set content.
+ *
+ * This method is useful for tests that need to create their own compose host during the test.
+ * The returned test rule will not create a host, and consequently does not provide a
+ * `setContent` method. To set content in tests using this rule, use the appropriate `setContent`
+ * methods from your compose host.
+ *
+ * A typical use case on Android is when the test needs to launch an Activity (the compose host)
+ * after one or more dependencies have been injected.
  */
 fun createEmptyComposeRule(): ComposeTestRule =
     AndroidComposeTestRule<TestRule, ComponentActivity>(
@@ -134,15 +141,22 @@
     )
 
 /**
- * Android specific implementation of [ComposeContentTestRule].
+ * Android specific implementation of [ComposeContentTestRule], where compose content is hosted
+ * by an Activity.
  *
- * This rule wraps around the given [activityRule], which is responsible for launching the activity.
- * The [activityProvider] should return the launched activity instance when the [activityRule] is
- * passed to it. In this way, you can provide any test rule that can launch an activity
+ * The Activity is normally launched by the given [activityRule] before the test starts, but it
+ * is possible to pass a test rule that chooses to launch an Activity on a later time. The
+ * Activity is retrieved from the [activityRule] by means of the [activityProvider], which can be
+ * thought of as a getter for the Activity on the [activityRule]. If you use an [activityRule]
+ * that launches an Activity on a later time, you should make sure that the Activity is launched
+ * by the time or while the [activityProvider] is called.
  *
- * @param activityRule Test rule to use to launch the activity.
- * @param activityProvider To resolve the activity from the given test rule. Must be a blocking
- * function.
+ * The [AndroidComposeTestRule] wraps around the given [activityRule] to make sure the Activity
+ * is launched _after_ the [AndroidComposeTestRule] has completed all necessary steps to control
+ * and monitor the compose content.
+ *
+ * @param activityRule Test rule to use to launch the Activity.
+ * @param activityProvider Function to retrieve the Activity from the given [activityRule].
  */
 @OptIn(InternalTestApi::class)
 class AndroidComposeTestRule<R : TestRule, A : ComponentActivity>(
@@ -172,6 +186,8 @@
     private val testCoroutineDispatcher: TestCoroutineDispatcher
     private val recomposerApplyCoroutineScope: CoroutineScope
     private val frameCoroutineScope: CoroutineScope
+    @OptIn(ExperimentalCoroutinesApi::class)
+    private val coroutineExceptionHandler: TestCoroutineExceptionHandler
 
     override val mainClock: MainTestClock
         get() = mainClockImpl
@@ -192,8 +208,11 @@
             }
         }
         @OptIn(ExperimentalCoroutinesApi::class)
+        coroutineExceptionHandler = TestCoroutineExceptionHandler()
+        @OptIn(ExperimentalCoroutinesApi::class)
         recomposerApplyCoroutineScope = CoroutineScope(
-            testCoroutineDispatcher + frameClock + infiniteAnimationPolicy + Job()
+            testCoroutineDispatcher + frameClock + infiniteAnimationPolicy +
+                coroutineExceptionHandler + Job()
         )
         recomposer = Recomposer(recomposerApplyCoroutineScope.coroutineContext)
             .also { recomposerApplyCoroutineScope.launch { it.runRecomposeAndApplyChanges() } }
@@ -269,6 +288,7 @@
             // Then await composition(s)
             runEspressoOnIdle()
         }
+        checkUncaughtCoroutineExceptions()
     }
 
     override fun <T> runOnUiThread(action: () -> T): T {
@@ -307,6 +327,18 @@
         idlingResourceRegistry.unregisterIdlingResource(idlingResource)
     }
 
+    /**
+     * Checks if the [coroutineExceptionHandler] has caught uncaught exceptions. If so, will
+     * rethrow the first to fail the test. Rather than only calling this only at the end of the
+     * test, as recommended by [cleanupTestCoroutines][kotlinx.coroutines.test
+     * .UncaughtExceptionCaptor.cleanupTestCoroutines], try calling this at a few strategic
+     * points to fail the test asap after the exception was caught.
+     */
+    private fun checkUncaughtCoroutineExceptions() {
+        @OptIn(ExperimentalCoroutinesApi::class)
+        coroutineExceptionHandler.cleanupTestCoroutines()
+    }
+
     inner class AndroidComposeStatement(
         private val base: Statement
     ) : Statement() {
@@ -332,6 +364,7 @@
                 // throwing errors on active coroutines
                 recomposerApplyCoroutineScope.cancel()
                 frameCoroutineScope.cancel()
+                checkUncaughtCoroutineExceptions()
                 @OptIn(ExperimentalCoroutinesApi::class)
                 testCoroutineDispatcher.cleanupTestCoroutines()
                 textInputServiceFactory = oldTextInputFactory
@@ -423,6 +456,8 @@
             //  That means that ComposeRootRegistry.getComposeRoots() may still return an empty list
             //  between now and when the new Activity has created its compose root, even though
             //  waitForComposeRoots() suggests that we are now guaranteed one.
+
+            checkUncaughtCoroutineExceptions()
         }
 
         override fun getRoots(atLeastOneRootExpected: Boolean): Set<RootForTest> {
diff --git a/compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/MainTestClockImpl.android.kt b/compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/MainTestClockImpl.android.kt
index 6c36f26..674fecd 100644
--- a/compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/MainTestClockImpl.android.kt
+++ b/compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/MainTestClockImpl.android.kt
@@ -41,10 +41,14 @@
         advanceDispatcher(frameClock.frameDelayMillis)
     }
 
-    override fun advanceTimeBy(milliseconds: Long) {
-        val actualDelay = ceil(
-            milliseconds.toDouble() / frameClock.frameDelayMillis
-        ).toLong() * frameClock.frameDelayMillis
+    override fun advanceTimeBy(milliseconds: Long, ignoreFrameDuration: Boolean) {
+        val actualDelay = if (ignoreFrameDuration) {
+            milliseconds
+        } else {
+            ceil(
+                milliseconds.toDouble() / frameClock.frameDelayMillis
+            ).toLong() * frameClock.frameDelayMillis
+        }
         advanceDispatcher(actualDelay)
     }
 
diff --git a/compose/ui/ui-test-junit4/src/commonMain/kotlin/androidx/compose/ui/test/junit4/TextInputServiceForTests.kt b/compose/ui/ui-test-junit4/src/commonMain/kotlin/androidx/compose/ui/test/junit4/TextInputServiceForTests.kt
index 85c6c59..fcd3ca1 100644
--- a/compose/ui/ui-test-junit4/src/commonMain/kotlin/androidx/compose/ui/test/junit4/TextInputServiceForTests.kt
+++ b/compose/ui/ui-test-junit4/src/commonMain/kotlin/androidx/compose/ui/test/junit4/TextInputServiceForTests.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,11 +18,11 @@
 
 import androidx.compose.ui.text.input.EditCommand
 import androidx.compose.ui.text.input.ImeAction
-import androidx.compose.ui.text.input.InputSessionToken
 import androidx.compose.ui.text.input.ImeOptions
 import androidx.compose.ui.text.input.PlatformTextInputService
 import androidx.compose.ui.text.input.TextFieldValue
 import androidx.compose.ui.text.input.TextInputService
+import androidx.compose.ui.text.input.TextInputSession
 
 /**
  * Extra layer that serves as an observer between the text input service and text fields.
@@ -43,7 +43,7 @@
         imeOptions: ImeOptions,
         onEditCommand: (List<EditCommand>) -> Unit,
         onImeActionPerformed: (ImeAction) -> Unit
-    ): InputSessionToken {
+    ): TextInputSession {
         this.onEditCommand = onEditCommand
         this.onImeActionPerformed = onImeActionPerformed
         return super.startInput(
@@ -54,9 +54,9 @@
         )
     }
 
-    override fun stopInput(token: InputSessionToken) {
+    override fun stopInput(session: TextInputSession) {
         this.onEditCommand = null
         this.onImeActionPerformed = null
-        super.stopInput(token)
+        super.stopInput(session)
     }
 }
\ No newline at end of file
diff --git a/compose/ui/ui-test-junit4/src/jvmMain/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule.jvm.kt b/compose/ui/ui-test-junit4/src/jvmMain/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule.jvm.kt
index bdd29b4..301c44b 100644
--- a/compose/ui/ui-test-junit4/src/jvmMain/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule.jvm.kt
+++ b/compose/ui/ui-test-junit4/src/jvmMain/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule.jvm.kt
@@ -165,11 +165,14 @@
 /**
  * Factory method to provide an implementation of [ComposeContentTestRule].
  *
- * This method is useful for tests in compose libraries where no custom Activity is usually
- * needed. For app tests or launching custom activities, see [createAndroidComposeRule].
+ * This method is useful for tests in compose libraries where it is irrelevant where the compose
+ * content is hosted (e.g. an Activity on Android). Such tests typically set compose content
+ * themselves via [setContent][ComposeContentTestRule.setContent] and only instrument and assert
+ * that content.
  *
  * For Android this will use the default Activity (android.app.Activity). You need to add a
  * reference to this activity into the manifest file of the corresponding tests (usually in
- * androidTest/AndroidManifest.xml).
+ * androidTest/AndroidManifest.xml). If your Android test requires a specific Activity to be
+ * launched, see [createAndroidComposeRule].
  */
 expect fun createComposeRule(): ComposeContentTestRule
diff --git a/compose/ui/ui-test/api/current.txt b/compose/ui/ui-test/api/current.txt
index aad04da..ec06fc7 100644
--- a/compose/ui/ui-test/api/current.txt
+++ b/compose/ui/ui-test/api/current.txt
@@ -52,14 +52,12 @@
   public final class BoundsAssertionsKt {
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertHeightIsAtLeast-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedMinHeight);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertHeightIsEqualTo-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedHeight);
-    method public static void assertIsEqualTo-nR2IGDg(float, float expected, optional String subject, optional float tolerance);
-    method public static void assertIsNotEqualTo-nR2IGDg(float, float unexpected, optional String subject, optional float tolerance);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertLeftPositionInRootIsEqualTo-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedLeft);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertPositionInRootIsEqualTo-aELHoiQ(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedLeft, float expectedTop);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertTopPositionInRootIsEqualTo-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedTop);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertWidthIsAtLeast-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedMinWidth);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertWidthIsEqualTo-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedWidth);
-    method public static float getAlignmentLinePosition(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.layout.AlignmentLine line);
+    method public static float getAlignmentLinePosition(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.layout.AlignmentLine alignmentLine);
     method public static androidx.compose.ui.unit.DpRect getUnclippedBoundsInRoot(androidx.compose.ui.test.SemanticsNodeInteraction);
   }
 
@@ -180,7 +178,7 @@
   }
 
   public interface MainTestClock {
-    method public void advanceTimeBy(long milliseconds);
+    method public void advanceTimeBy(long milliseconds, optional boolean ignoreFrameDuration);
     method public void advanceTimeByFrame();
     method public void advanceTimeUntil(optional long timeoutMillis, kotlin.jvm.functions.Function0<java.lang.Boolean> condition);
     method public boolean getAutoAdvance();
diff --git a/compose/ui/ui-test/api/public_plus_experimental_current.txt b/compose/ui/ui-test/api/public_plus_experimental_current.txt
index aad04da..ec06fc7 100644
--- a/compose/ui/ui-test/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-test/api/public_plus_experimental_current.txt
@@ -52,14 +52,12 @@
   public final class BoundsAssertionsKt {
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertHeightIsAtLeast-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedMinHeight);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertHeightIsEqualTo-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedHeight);
-    method public static void assertIsEqualTo-nR2IGDg(float, float expected, optional String subject, optional float tolerance);
-    method public static void assertIsNotEqualTo-nR2IGDg(float, float unexpected, optional String subject, optional float tolerance);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertLeftPositionInRootIsEqualTo-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedLeft);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertPositionInRootIsEqualTo-aELHoiQ(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedLeft, float expectedTop);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertTopPositionInRootIsEqualTo-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedTop);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertWidthIsAtLeast-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedMinWidth);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertWidthIsEqualTo-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedWidth);
-    method public static float getAlignmentLinePosition(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.layout.AlignmentLine line);
+    method public static float getAlignmentLinePosition(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.layout.AlignmentLine alignmentLine);
     method public static androidx.compose.ui.unit.DpRect getUnclippedBoundsInRoot(androidx.compose.ui.test.SemanticsNodeInteraction);
   }
 
@@ -180,7 +178,7 @@
   }
 
   public interface MainTestClock {
-    method public void advanceTimeBy(long milliseconds);
+    method public void advanceTimeBy(long milliseconds, optional boolean ignoreFrameDuration);
     method public void advanceTimeByFrame();
     method public void advanceTimeUntil(optional long timeoutMillis, kotlin.jvm.functions.Function0<java.lang.Boolean> condition);
     method public boolean getAutoAdvance();
diff --git a/compose/ui/ui-test/api/restricted_current.txt b/compose/ui/ui-test/api/restricted_current.txt
index aad04da..ec06fc7 100644
--- a/compose/ui/ui-test/api/restricted_current.txt
+++ b/compose/ui/ui-test/api/restricted_current.txt
@@ -52,14 +52,12 @@
   public final class BoundsAssertionsKt {
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertHeightIsAtLeast-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedMinHeight);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertHeightIsEqualTo-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedHeight);
-    method public static void assertIsEqualTo-nR2IGDg(float, float expected, optional String subject, optional float tolerance);
-    method public static void assertIsNotEqualTo-nR2IGDg(float, float unexpected, optional String subject, optional float tolerance);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertLeftPositionInRootIsEqualTo-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedLeft);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertPositionInRootIsEqualTo-aELHoiQ(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedLeft, float expectedTop);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertTopPositionInRootIsEqualTo-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedTop);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertWidthIsAtLeast-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedMinWidth);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction assertWidthIsEqualTo-3AN6ZEs(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedWidth);
-    method public static float getAlignmentLinePosition(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.layout.AlignmentLine line);
+    method public static float getAlignmentLinePosition(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.layout.AlignmentLine alignmentLine);
     method public static androidx.compose.ui.unit.DpRect getUnclippedBoundsInRoot(androidx.compose.ui.test.SemanticsNodeInteraction);
   }
 
@@ -180,7 +178,7 @@
   }
 
   public interface MainTestClock {
-    method public void advanceTimeBy(long milliseconds);
+    method public void advanceTimeBy(long milliseconds, optional boolean ignoreFrameDuration);
     method public void advanceTimeByFrame();
     method public void advanceTimeUntil(optional long timeoutMillis, kotlin.jvm.functions.Function0<java.lang.Boolean> condition);
     method public boolean getAutoAdvance();
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/ScrollToTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/ScrollToTest.kt
index d87b77f..bfcd39a 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/ScrollToTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/ScrollToTest.kt
@@ -19,10 +19,10 @@
 import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.layout.Layout
-import androidx.compose.ui.layout.MeasureBlock
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.MeasurePolicy
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.semantics.scrollBy
 import androidx.compose.ui.semantics.semantics
@@ -48,8 +48,8 @@
 
     private val recorder = mutableListOf<Offset>()
 
-    private fun horizontalLayout(offset: Int, columnWidth: Int): MeasureBlock {
-        return { measurables, constraints ->
+    private fun horizontalLayout(offset: Int, columnWidth: Int): MeasurePolicy {
+        return MeasurePolicy { measurables, constraints ->
             val childConstraints = constraints.copy(minWidth = 0, maxWidth = Constraints.Infinity)
             val placeables = measurables.map { it.measure(childConstraints) }
             layout(columnWidth, crossAxisSize) {
@@ -62,8 +62,8 @@
         }
     }
 
-    private fun verticalLayout(offset: Int, columnHeight: Int): MeasureBlock {
-        return { measurables, constraints ->
+    private fun verticalLayout(offset: Int, columnHeight: Int): MeasurePolicy {
+        return MeasurePolicy { measurables, constraints ->
             val childConstraints = constraints.copy(minHeight = 0, maxHeight = Constraints.Infinity)
             val placeables = measurables.map { it.measure(childConstraints) }
             layout(crossAxisSize, columnHeight) {
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/BoundsAssertionsTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/BoundsAssertionsTest.kt
index 0a0129f..87afff9 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/BoundsAssertionsTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/BoundsAssertionsTest.kt
@@ -32,8 +32,6 @@
 import androidx.test.filters.MediumTest
 import androidx.compose.ui.test.assertHeightIsAtLeast
 import androidx.compose.ui.test.assertHeightIsEqualTo
-import androidx.compose.ui.test.assertIsEqualTo
-import androidx.compose.ui.test.assertIsNotEqualTo
 import androidx.compose.ui.test.assertLeftPositionInRootIsEqualTo
 import androidx.compose.ui.test.assertPositionInRootIsEqualTo
 import androidx.compose.ui.test.assertTopPositionInRootIsEqualTo
@@ -76,33 +74,6 @@
     }
 
     @Test
-    fun dp_assertEquals() {
-        5.dp.assertIsEqualTo(5.dp)
-        5.dp.assertIsEqualTo(4.6.dp)
-        5.dp.assertIsEqualTo(5.4.dp)
-    }
-
-    @Test
-    fun dp_assertNotEquals() {
-        5.dp.assertIsNotEqualTo(6.dp)
-    }
-
-    @Test
-    fun dp_assertEquals_fail() {
-        expectError<AssertionError> {
-            5.dp.assertIsEqualTo(6.dp)
-        }
-    }
-
-    @Test
-    fun dp_assertNotEquals_fail() {
-        expectError<AssertionError> {
-            5.dp.assertIsNotEqualTo(5.dp)
-            5.dp.assertIsNotEqualTo(5.4.dp)
-        }
-    }
-
-    @Test
     fun assertSizeEquals() {
         composeBox()
 
diff --git a/compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/AndroidAssertions.android.kt b/compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/AndroidAssertions.android.kt
index f96f634..2f13281 100644
--- a/compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/AndroidAssertions.android.kt
+++ b/compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/AndroidAssertions.android.kt
@@ -44,7 +44,7 @@
     }
 
     // check node doesn't clip unintentionally (e.g. row too small for content)
-    val globalRect = node.globalBounds
+    val globalRect = node.boundsInWindow
     if (!node.isInScreenBounds()) {
         return false
     }
diff --git a/compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/AndroidInputDispatcher.android.kt b/compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/AndroidInputDispatcher.android.kt
index adadb76..7589fd4 100644
--- a/compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/AndroidInputDispatcher.android.kt
+++ b/compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/AndroidInputDispatcher.android.kt
@@ -25,9 +25,10 @@
 import android.view.MotionEvent.ACTION_POINTER_INDEX_SHIFT
 import android.view.MotionEvent.ACTION_POINTER_UP
 import android.view.MotionEvent.ACTION_UP
-import androidx.compose.ui.platform.AndroidUiDispatcher
 import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.layout.boundsInWindow
 import androidx.compose.ui.node.RootForTest
+import androidx.compose.ui.platform.AndroidUiDispatcher
 import androidx.compose.ui.platform.ViewRootForTest
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.delay
@@ -49,7 +50,7 @@
 
 internal class AndroidInputDispatcher(
     private val testContext: TestContext,
-    root: ViewRootForTest?,
+    private val root: ViewRootForTest?,
     private val sendEvent: (MotionEvent) -> Unit
 ) : InputDispatcher(testContext, root) {
 
@@ -130,6 +131,12 @@
                 firstEventTime = eventTime
             }
             batchedEvents.add { lateness ->
+                val positionInWindow = if (root != null) {
+                    root.semanticsOwner.rootSemanticsNode.layoutInfo.coordinates.boundsInWindow()
+                        .topLeft
+                } else {
+                    Offset.Zero
+                }
                 MotionEvent.obtain(
                     /* downTime = */ lateness + downTime,
                     /* eventTime = */ lateness + eventTime,
@@ -152,7 +159,9 @@
                     /* edgeFlags = */ 0,
                     /* source = */ 0,
                     /* flags = */ 0
-                )
+                ).apply {
+                    offsetLocation(-positionInWindow.x, -positionInWindow.y)
+                }
             }
         }
     }
@@ -189,7 +198,7 @@
     private fun pumpClock(millis: Long) {
         // Don't bother calling the method if there's nothing to advance
         if (millis > 0) {
-            testContext.testOwner.mainClock.advanceTimeBy(millis)
+            testContext.testOwner.mainClock.advanceTimeBy(millis, ignoreFrameDuration = true)
         }
     }
 
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Actions.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Actions.kt
index 9e67a9d..0d97551 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Actions.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Actions.kt
@@ -64,7 +64,7 @@
     // Figure out the (clipped) bounds of the viewPort in its direct parent's content area, in
     // root coordinates. We only want the clipping from the direct parent on the scrollable, not
     // from any other ancestors.
-    val viewPortInParent = scrollableNode.layoutInfo.coordinates.boundsInParent
+    val viewPortInParent = scrollableNode.layoutInfo.coordinates.boundsInParent()
     val parentInRoot = scrollableNode.layoutInfo.coordinates.parentLayoutCoordinates
         ?.positionInRoot() ?: Offset.Zero
 
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/BoundsAssertions.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/BoundsAssertions.kt
index dc728db..741f754 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/BoundsAssertions.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/BoundsAssertions.kt
@@ -143,9 +143,9 @@
  * Returns the position of an [alignment line][AlignmentLine], or [Dp.Unspecified] if the line is
  * not provided.
  */
-fun SemanticsNodeInteraction.getAlignmentLinePosition(line: AlignmentLine): Dp {
+fun SemanticsNodeInteraction.getAlignmentLinePosition(alignmentLine: AlignmentLine): Dp {
     return withDensity {
-        val pos = it.getAlignmentLinePosition(line)
+        val pos = it.getAlignmentLinePosition(alignmentLine)
         if (pos == AlignmentLine.Unspecified) {
             Dp.Unspecified
         } else {
@@ -168,7 +168,7 @@
  *
  * @throws AssertionError if comparison fails.
  */
-fun Dp.assertIsEqualTo(expected: Dp, subject: String = "", tolerance: Dp = Dp(.5f)) {
+private fun Dp.assertIsEqualTo(expected: Dp, subject: String = "", tolerance: Dp = Dp(.5f)) {
     val diff = (this - expected).value.absoluteValue
     if (diff > tolerance.value) {
         // Comparison failed, report the error in DPs
@@ -178,32 +178,6 @@
     }
 }
 
-/**
- * Asserts that this value is not equal to the given [unexpected] value.
- *
- * Performs the comparison with the given [tolerance] or the default one if none is provided. It is
- * recommended to use tolerance when comparing positions and size coming from the framework as there
- * can be rounding operation performed by individual layouts so the values can be slightly off from
- * the expected ones.
- *
- * @param unexpected The value to which this one should not be equal to.
- * @param subject Used in the error message to identify which item this assertion failed on.
- * @param tolerance The tolerance that is expected to be greater than the difference between the
- * given values to treat them as non-equal.
- *
- * @throws AssertionError if comparison fails.
- */
-fun Dp.assertIsNotEqualTo(unexpected: Dp, subject: String = "", tolerance: Dp = Dp(.5f)) {
-    val diff = (this - unexpected).value.absoluteValue
-    if (diff <= tolerance.value) {
-        // Comparison failed, report the error in DPs
-        throw AssertionError(
-            "Actual $subject is $this, not expected to be equal to $unexpected within a " +
-                "tolerance of $tolerance"
-        )
-    }
-}
-
 internal val SemanticsNode.unclippedBoundsInRoot: Rect
     get() {
         return Rect(positionInRoot, size.toSize())
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/GestureScope.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/GestureScope.kt
index 47279d2..0ad6910 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/GestureScope.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/GestureScope.kt
@@ -18,7 +18,7 @@
 
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.lerp
-import androidx.compose.ui.layout.globalBounds
+import androidx.compose.ui.layout.boundsInWindow
 import androidx.compose.ui.semantics.SemanticsNode
 import androidx.compose.ui.test.InputDispatcher.Companion.eventPeriodMillis
 import androidx.compose.ui.unit.IntSize
@@ -283,14 +283,13 @@
 }
 
 /**
- * Transforms the [position] to global coordinates, as defined by
- * [LayoutCoordinates.localToGlobal][androidx.compose.ui.layout.LayoutCoordinates.localToGlobal]
+ * Transforms the [position] to window coordinates.
  *
  * @param position A position in local coordinates
+ * @return [position] transformed to coordinates relative to the containing window.
  */
-private fun GestureScope.localToGlobal(position: Offset): Offset {
-    @Suppress("DEPRECATION")
-    return position + semanticsNode.layoutInfo.coordinates.globalBounds.topLeft
+private fun GestureScope.localToWindow(position: Offset): Offset {
+    return position + semanticsNode.layoutInfo.coordinates.boundsInWindow().topLeft
 }
 
 /**
@@ -303,7 +302,7 @@
  * omitted, the center position will be used.
  */
 fun GestureScope.click(position: Offset = center) {
-    inputDispatcher.enqueueClick(localToGlobal(position))
+    inputDispatcher.enqueueClick(localToWindow(position))
 }
 
 /**
@@ -344,7 +343,7 @@
     require(delayMillis <= DoubleTapTimeoutMillis - 10) {
         "Time between clicks in double click can be at most ${DoubleTapTimeoutMillis - 10}ms"
     }
-    val globalPosition = localToGlobal(position)
+    val globalPosition = localToWindow(position)
     inputDispatcher.enqueueClick(globalPosition)
     inputDispatcher.enqueueDelay(delayMillis)
     inputDispatcher.enqueueClick(globalPosition)
@@ -365,8 +364,8 @@
     end: Offset,
     durationMillis: Long = 200
 ) {
-    val globalStart = localToGlobal(start)
-    val globalEnd = localToGlobal(end)
+    val globalStart = localToWindow(start)
+    val globalEnd = localToWindow(end)
     inputDispatcher.enqueueSwipe(globalStart, globalEnd, durationMillis)
 }
 
@@ -390,10 +389,10 @@
     end1: Offset,
     durationMillis: Long = 400
 ) {
-    val globalStart0 = localToGlobal(start0)
-    val globalEnd0 = localToGlobal(end0)
-    val globalStart1 = localToGlobal(start1)
-    val globalEnd1 = localToGlobal(end1)
+    val globalStart0 = localToWindow(start0)
+    val globalEnd0 = localToWindow(end0)
+    val globalStart1 = localToWindow(start1)
+    val globalEnd1 = localToWindow(end1)
     val durationFloat = durationMillis.toFloat()
 
     inputDispatcher.enqueueSwipes(
@@ -439,8 +438,8 @@
         "Duration must be at least ${minimumDuration}ms because " +
             "velocity requires at least 3 input events"
     }
-    val globalStart = localToGlobal(start)
-    val globalEnd = localToGlobal(end)
+    val globalStart = localToWindow(start)
+    val globalEnd = localToWindow(end)
 
     // Decompose v into it's x and y components
     val delta = end - start
@@ -615,7 +614,7 @@
  * @param position The position of the down event, in the node's local coordinate system
  */
 fun GestureScope.down(pointerId: Int, position: Offset) {
-    val globalPosition = localToGlobal(position)
+    val globalPosition = localToWindow(position)
     inputDispatcher.enqueueDown(pointerId, globalPosition)
 }
 
@@ -674,7 +673,7 @@
  * @param position The new position of the pointer, in the node's local coordinate system
  */
 fun GestureScope.movePointerTo(pointerId: Int, position: Offset) {
-    val globalPosition = localToGlobal(position)
+    val globalPosition = localToWindow(position)
     inputDispatcher.movePointer(pointerId, globalPosition)
 }
 
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/MainTestClock.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/MainTestClock.kt
index 8970974..a1a76e6 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/MainTestClock.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/MainTestClock.kt
@@ -49,12 +49,14 @@
      *
      * Important: The duration will always be rounded up to the nearest duration that is a
      * multiplier of the frame duration. This is to make sure that any changes get recomposed to
-     * avoid confusing states.
+     * avoid confusing states. This behavior can be turned off via [ignoreFrameDuration].
      *
      * @param milliseconds The minimal duration to advance the main clock by. Will be rounded up
      * to the nearest frame duration.
+     * @param ignoreFrameDuration Whether to avoid rounding up the [milliseconds] to the nearest
+     * multiplier of a frame duration.
      */
-    fun advanceTimeBy(milliseconds: Long)
+    fun advanceTimeBy(milliseconds: Long, ignoreFrameDuration: Boolean = false)
 
     /**
      * Advances the clock until the given condition is satisfied.
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Output.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Output.kt
index 15b8364..f874a85 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Output.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Output.kt
@@ -210,7 +210,7 @@
 
 private val SemanticsNode.unclippedGlobalBounds: Rect
     get() {
-        return Rect(globalPosition, size.toSize())
+        return Rect(positionInWindow, size.toSize())
     }
 
 private fun rectToShortString(rect: Rect): String {
diff --git a/compose/ui/ui-text/api/current.txt b/compose/ui/ui-text/api/current.txt
index c50493d..03711bf 100644
--- a/compose/ui/ui-text/api/current.txt
+++ b/compose/ui/ui-text/api/current.txt
@@ -1,6 +1,9 @@
 // Signature format: 4.0
 package androidx.compose.ui.text {
 
+  public final class ActualAtomicReferenceJvmKt {
+  }
+
   @androidx.compose.runtime.Immutable public final class AnnotatedString implements java.lang.CharSequence {
     ctor public AnnotatedString(String text, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.SpanStyle>> spanStyles, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.ParagraphStyle>> paragraphStyles);
     method public operator char get(int index);
@@ -243,13 +246,6 @@
     enum_constant public static final androidx.compose.ui.text.PlaceholderVerticalAlign Top;
   }
 
-  public final class SoftwareKeyboardController {
-    ctor public SoftwareKeyboardController(androidx.compose.ui.text.input.TextInputService textInputService, int token);
-    method public void hideSoftwareKeyboard();
-    method public void notifyFocusedRect(androidx.compose.ui.geometry.Rect rect);
-    method public void showSoftwareKeyboard();
-  }
-
   @androidx.compose.runtime.Immutable public final class SpanStyle {
     method public androidx.compose.ui.text.SpanStyle copy-D5kMcog(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow);
     method public operator boolean equals(Object? other);
@@ -378,8 +374,6 @@
 
   @androidx.compose.runtime.Immutable public final inline class TextRange {
     ctor public TextRange();
-    method public static long constructor-impl(long packedValue);
-    method public static long constructor-impl(int start, int end);
     method public static operator boolean contains-5zc-tL8(long $this, long other);
     method public static operator boolean contains-impl(long $this, int offset);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
@@ -389,13 +383,11 @@
     method public static int getLength-impl(long $this);
     method public static int getMax-impl(long $this);
     method public static int getMin-impl(long $this);
-    method public long getPackedValue();
     method public static boolean getReversed-impl(long $this);
     method public static int getStart-impl(long $this);
     method @androidx.compose.runtime.Immutable public static inline int hashCode-impl(long p);
     method public static boolean intersects-5zc-tL8(long $this, long other);
     method public static String toString-impl(long $this);
-    property public final long packedValue;
     field public static final androidx.compose.ui.text.TextRange.Companion Companion;
   }
 
@@ -405,6 +397,7 @@
   }
 
   public final class TextRangeKt {
+    method public static long TextRange(int start, int end);
     method public static long TextRange(int index);
     method public static String substring-cWlJSyE(CharSequence, long range);
   }
@@ -715,6 +708,13 @@
   public final class EditCommandKt {
   }
 
+  public final class EditProcessor {
+    ctor public EditProcessor();
+    method public androidx.compose.ui.text.input.TextFieldValue apply(java.util.List<? extends androidx.compose.ui.text.input.EditCommand> editCommands);
+    method public void reset(androidx.compose.ui.text.input.TextFieldValue value, androidx.compose.ui.text.input.TextInputSession? textInputSession);
+    method public androidx.compose.ui.text.input.TextFieldValue toTextFieldValue();
+  }
+
   public final class EditingBuffer {
   }
 
@@ -848,7 +848,6 @@
   }
 
   @androidx.compose.runtime.Immutable public final class TextFieldValue {
-    method public androidx.compose.ui.text.input.TextFieldValue commitComposition();
     method public androidx.compose.ui.text.input.TextFieldValue copy-Dr2r1M0(String text, optional long selection, optional androidx.compose.ui.text.TextRange? composition);
     method public androidx.compose.ui.text.input.TextFieldValue copy-ec4yWi8(optional androidx.compose.ui.text.AnnotatedString annotatedString, optional long selection, optional androidx.compose.ui.text.TextRange? composition);
     method public androidx.compose.ui.text.AnnotatedString getAnnotatedString();
@@ -875,17 +874,21 @@
 
   public class TextInputService {
     ctor public TextInputService(androidx.compose.ui.text.input.PlatformTextInputService platformTextInputService);
-    method public void hideSoftwareKeyboard(int token);
-    method public void notifyFocusedRect(int token, androidx.compose.ui.geometry.Rect rect);
-    method public void showSoftwareKeyboard(int token);
-    method public int startInput(androidx.compose.ui.text.input.TextFieldValue value, androidx.compose.ui.text.input.ImeOptions imeOptions, kotlin.jvm.functions.Function1<? super java.util.List<? extends androidx.compose.ui.text.input.EditCommand>,kotlin.Unit> onEditCommand, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.ImeAction,kotlin.Unit> onImeActionPerformed);
-    method public void stopInput(int token);
-    method public void updateState(int token, androidx.compose.ui.text.input.TextFieldValue? oldValue, androidx.compose.ui.text.input.TextFieldValue newValue);
+    method public final void hideSoftwareKeyboard();
+    method public final void showSoftwareKeyboard();
+    method public androidx.compose.ui.text.input.TextInputSession startInput(androidx.compose.ui.text.input.TextFieldValue value, androidx.compose.ui.text.input.ImeOptions imeOptions, kotlin.jvm.functions.Function1<? super java.util.List<? extends androidx.compose.ui.text.input.EditCommand>,kotlin.Unit> onEditCommand, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.ImeAction,kotlin.Unit> onImeActionPerformed);
+    method public void stopInput(androidx.compose.ui.text.input.TextInputSession session);
   }
 
-  public final class TextInputServiceKt {
-    field public static final int INVALID_SESSION = -1; // 0xffffffff
-    field public static final int NO_SESSION = 0; // 0x0
+  public final class TextInputSession {
+    ctor public TextInputSession(androidx.compose.ui.text.input.TextInputService textInputService, androidx.compose.ui.text.input.PlatformTextInputService platformTextInputService);
+    method public void dispose();
+    method public boolean hideSoftwareKeyboard();
+    method public boolean isOpen();
+    method public boolean notifyFocusedRect(androidx.compose.ui.geometry.Rect rect);
+    method public boolean showSoftwareKeyboard();
+    method public boolean updateState(androidx.compose.ui.text.input.TextFieldValue? oldValue, androidx.compose.ui.text.input.TextFieldValue newValue);
+    property public final boolean isOpen;
   }
 
   public final class TransformedText {
diff --git a/compose/ui/ui-text/api/public_plus_experimental_current.txt b/compose/ui/ui-text/api/public_plus_experimental_current.txt
index c50493d..03711bf 100644
--- a/compose/ui/ui-text/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-text/api/public_plus_experimental_current.txt
@@ -1,6 +1,9 @@
 // Signature format: 4.0
 package androidx.compose.ui.text {
 
+  public final class ActualAtomicReferenceJvmKt {
+  }
+
   @androidx.compose.runtime.Immutable public final class AnnotatedString implements java.lang.CharSequence {
     ctor public AnnotatedString(String text, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.SpanStyle>> spanStyles, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.ParagraphStyle>> paragraphStyles);
     method public operator char get(int index);
@@ -243,13 +246,6 @@
     enum_constant public static final androidx.compose.ui.text.PlaceholderVerticalAlign Top;
   }
 
-  public final class SoftwareKeyboardController {
-    ctor public SoftwareKeyboardController(androidx.compose.ui.text.input.TextInputService textInputService, int token);
-    method public void hideSoftwareKeyboard();
-    method public void notifyFocusedRect(androidx.compose.ui.geometry.Rect rect);
-    method public void showSoftwareKeyboard();
-  }
-
   @androidx.compose.runtime.Immutable public final class SpanStyle {
     method public androidx.compose.ui.text.SpanStyle copy-D5kMcog(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow);
     method public operator boolean equals(Object? other);
@@ -378,8 +374,6 @@
 
   @androidx.compose.runtime.Immutable public final inline class TextRange {
     ctor public TextRange();
-    method public static long constructor-impl(long packedValue);
-    method public static long constructor-impl(int start, int end);
     method public static operator boolean contains-5zc-tL8(long $this, long other);
     method public static operator boolean contains-impl(long $this, int offset);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
@@ -389,13 +383,11 @@
     method public static int getLength-impl(long $this);
     method public static int getMax-impl(long $this);
     method public static int getMin-impl(long $this);
-    method public long getPackedValue();
     method public static boolean getReversed-impl(long $this);
     method public static int getStart-impl(long $this);
     method @androidx.compose.runtime.Immutable public static inline int hashCode-impl(long p);
     method public static boolean intersects-5zc-tL8(long $this, long other);
     method public static String toString-impl(long $this);
-    property public final long packedValue;
     field public static final androidx.compose.ui.text.TextRange.Companion Companion;
   }
 
@@ -405,6 +397,7 @@
   }
 
   public final class TextRangeKt {
+    method public static long TextRange(int start, int end);
     method public static long TextRange(int index);
     method public static String substring-cWlJSyE(CharSequence, long range);
   }
@@ -715,6 +708,13 @@
   public final class EditCommandKt {
   }
 
+  public final class EditProcessor {
+    ctor public EditProcessor();
+    method public androidx.compose.ui.text.input.TextFieldValue apply(java.util.List<? extends androidx.compose.ui.text.input.EditCommand> editCommands);
+    method public void reset(androidx.compose.ui.text.input.TextFieldValue value, androidx.compose.ui.text.input.TextInputSession? textInputSession);
+    method public androidx.compose.ui.text.input.TextFieldValue toTextFieldValue();
+  }
+
   public final class EditingBuffer {
   }
 
@@ -848,7 +848,6 @@
   }
 
   @androidx.compose.runtime.Immutable public final class TextFieldValue {
-    method public androidx.compose.ui.text.input.TextFieldValue commitComposition();
     method public androidx.compose.ui.text.input.TextFieldValue copy-Dr2r1M0(String text, optional long selection, optional androidx.compose.ui.text.TextRange? composition);
     method public androidx.compose.ui.text.input.TextFieldValue copy-ec4yWi8(optional androidx.compose.ui.text.AnnotatedString annotatedString, optional long selection, optional androidx.compose.ui.text.TextRange? composition);
     method public androidx.compose.ui.text.AnnotatedString getAnnotatedString();
@@ -875,17 +874,21 @@
 
   public class TextInputService {
     ctor public TextInputService(androidx.compose.ui.text.input.PlatformTextInputService platformTextInputService);
-    method public void hideSoftwareKeyboard(int token);
-    method public void notifyFocusedRect(int token, androidx.compose.ui.geometry.Rect rect);
-    method public void showSoftwareKeyboard(int token);
-    method public int startInput(androidx.compose.ui.text.input.TextFieldValue value, androidx.compose.ui.text.input.ImeOptions imeOptions, kotlin.jvm.functions.Function1<? super java.util.List<? extends androidx.compose.ui.text.input.EditCommand>,kotlin.Unit> onEditCommand, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.ImeAction,kotlin.Unit> onImeActionPerformed);
-    method public void stopInput(int token);
-    method public void updateState(int token, androidx.compose.ui.text.input.TextFieldValue? oldValue, androidx.compose.ui.text.input.TextFieldValue newValue);
+    method public final void hideSoftwareKeyboard();
+    method public final void showSoftwareKeyboard();
+    method public androidx.compose.ui.text.input.TextInputSession startInput(androidx.compose.ui.text.input.TextFieldValue value, androidx.compose.ui.text.input.ImeOptions imeOptions, kotlin.jvm.functions.Function1<? super java.util.List<? extends androidx.compose.ui.text.input.EditCommand>,kotlin.Unit> onEditCommand, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.ImeAction,kotlin.Unit> onImeActionPerformed);
+    method public void stopInput(androidx.compose.ui.text.input.TextInputSession session);
   }
 
-  public final class TextInputServiceKt {
-    field public static final int INVALID_SESSION = -1; // 0xffffffff
-    field public static final int NO_SESSION = 0; // 0x0
+  public final class TextInputSession {
+    ctor public TextInputSession(androidx.compose.ui.text.input.TextInputService textInputService, androidx.compose.ui.text.input.PlatformTextInputService platformTextInputService);
+    method public void dispose();
+    method public boolean hideSoftwareKeyboard();
+    method public boolean isOpen();
+    method public boolean notifyFocusedRect(androidx.compose.ui.geometry.Rect rect);
+    method public boolean showSoftwareKeyboard();
+    method public boolean updateState(androidx.compose.ui.text.input.TextFieldValue? oldValue, androidx.compose.ui.text.input.TextFieldValue newValue);
+    property public final boolean isOpen;
   }
 
   public final class TransformedText {
diff --git a/compose/ui/ui-text/api/restricted_current.txt b/compose/ui/ui-text/api/restricted_current.txt
index c50493d..03711bf 100644
--- a/compose/ui/ui-text/api/restricted_current.txt
+++ b/compose/ui/ui-text/api/restricted_current.txt
@@ -1,6 +1,9 @@
 // Signature format: 4.0
 package androidx.compose.ui.text {
 
+  public final class ActualAtomicReferenceJvmKt {
+  }
+
   @androidx.compose.runtime.Immutable public final class AnnotatedString implements java.lang.CharSequence {
     ctor public AnnotatedString(String text, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.SpanStyle>> spanStyles, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.ParagraphStyle>> paragraphStyles);
     method public operator char get(int index);
@@ -243,13 +246,6 @@
     enum_constant public static final androidx.compose.ui.text.PlaceholderVerticalAlign Top;
   }
 
-  public final class SoftwareKeyboardController {
-    ctor public SoftwareKeyboardController(androidx.compose.ui.text.input.TextInputService textInputService, int token);
-    method public void hideSoftwareKeyboard();
-    method public void notifyFocusedRect(androidx.compose.ui.geometry.Rect rect);
-    method public void showSoftwareKeyboard();
-  }
-
   @androidx.compose.runtime.Immutable public final class SpanStyle {
     method public androidx.compose.ui.text.SpanStyle copy-D5kMcog(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow);
     method public operator boolean equals(Object? other);
@@ -378,8 +374,6 @@
 
   @androidx.compose.runtime.Immutable public final inline class TextRange {
     ctor public TextRange();
-    method public static long constructor-impl(long packedValue);
-    method public static long constructor-impl(int start, int end);
     method public static operator boolean contains-5zc-tL8(long $this, long other);
     method public static operator boolean contains-impl(long $this, int offset);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
@@ -389,13 +383,11 @@
     method public static int getLength-impl(long $this);
     method public static int getMax-impl(long $this);
     method public static int getMin-impl(long $this);
-    method public long getPackedValue();
     method public static boolean getReversed-impl(long $this);
     method public static int getStart-impl(long $this);
     method @androidx.compose.runtime.Immutable public static inline int hashCode-impl(long p);
     method public static boolean intersects-5zc-tL8(long $this, long other);
     method public static String toString-impl(long $this);
-    property public final long packedValue;
     field public static final androidx.compose.ui.text.TextRange.Companion Companion;
   }
 
@@ -405,6 +397,7 @@
   }
 
   public final class TextRangeKt {
+    method public static long TextRange(int start, int end);
     method public static long TextRange(int index);
     method public static String substring-cWlJSyE(CharSequence, long range);
   }
@@ -715,6 +708,13 @@
   public final class EditCommandKt {
   }
 
+  public final class EditProcessor {
+    ctor public EditProcessor();
+    method public androidx.compose.ui.text.input.TextFieldValue apply(java.util.List<? extends androidx.compose.ui.text.input.EditCommand> editCommands);
+    method public void reset(androidx.compose.ui.text.input.TextFieldValue value, androidx.compose.ui.text.input.TextInputSession? textInputSession);
+    method public androidx.compose.ui.text.input.TextFieldValue toTextFieldValue();
+  }
+
   public final class EditingBuffer {
   }
 
@@ -848,7 +848,6 @@
   }
 
   @androidx.compose.runtime.Immutable public final class TextFieldValue {
-    method public androidx.compose.ui.text.input.TextFieldValue commitComposition();
     method public androidx.compose.ui.text.input.TextFieldValue copy-Dr2r1M0(String text, optional long selection, optional androidx.compose.ui.text.TextRange? composition);
     method public androidx.compose.ui.text.input.TextFieldValue copy-ec4yWi8(optional androidx.compose.ui.text.AnnotatedString annotatedString, optional long selection, optional androidx.compose.ui.text.TextRange? composition);
     method public androidx.compose.ui.text.AnnotatedString getAnnotatedString();
@@ -875,17 +874,21 @@
 
   public class TextInputService {
     ctor public TextInputService(androidx.compose.ui.text.input.PlatformTextInputService platformTextInputService);
-    method public void hideSoftwareKeyboard(int token);
-    method public void notifyFocusedRect(int token, androidx.compose.ui.geometry.Rect rect);
-    method public void showSoftwareKeyboard(int token);
-    method public int startInput(androidx.compose.ui.text.input.TextFieldValue value, androidx.compose.ui.text.input.ImeOptions imeOptions, kotlin.jvm.functions.Function1<? super java.util.List<? extends androidx.compose.ui.text.input.EditCommand>,kotlin.Unit> onEditCommand, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.ImeAction,kotlin.Unit> onImeActionPerformed);
-    method public void stopInput(int token);
-    method public void updateState(int token, androidx.compose.ui.text.input.TextFieldValue? oldValue, androidx.compose.ui.text.input.TextFieldValue newValue);
+    method public final void hideSoftwareKeyboard();
+    method public final void showSoftwareKeyboard();
+    method public androidx.compose.ui.text.input.TextInputSession startInput(androidx.compose.ui.text.input.TextFieldValue value, androidx.compose.ui.text.input.ImeOptions imeOptions, kotlin.jvm.functions.Function1<? super java.util.List<? extends androidx.compose.ui.text.input.EditCommand>,kotlin.Unit> onEditCommand, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.ImeAction,kotlin.Unit> onImeActionPerformed);
+    method public void stopInput(androidx.compose.ui.text.input.TextInputSession session);
   }
 
-  public final class TextInputServiceKt {
-    field public static final int INVALID_SESSION = -1; // 0xffffffff
-    field public static final int NO_SESSION = 0; // 0x0
+  public final class TextInputSession {
+    ctor public TextInputSession(androidx.compose.ui.text.input.TextInputService textInputService, androidx.compose.ui.text.input.PlatformTextInputService platformTextInputService);
+    method public void dispose();
+    method public boolean hideSoftwareKeyboard();
+    method public boolean isOpen();
+    method public boolean notifyFocusedRect(androidx.compose.ui.geometry.Rect rect);
+    method public boolean showSoftwareKeyboard();
+    method public boolean updateState(androidx.compose.ui.text.input.TextFieldValue? oldValue, androidx.compose.ui.text.input.TextFieldValue newValue);
+    property public final boolean isOpen;
   }
 
   public final class TransformedText {
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTest.kt
index 1d10f0a..ce1b4f1 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTest.kt
@@ -19,6 +19,7 @@
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.graphics.Path
 import androidx.compose.ui.graphics.PathOperation
+import androidx.compose.ui.text.AnnotatedString.Range
 import androidx.compose.ui.text.FontTestData.Companion.BASIC_MEASURE_FONT
 import androidx.compose.ui.text.font.toFontFamily
 import androidx.compose.ui.text.intl.LocaleList
@@ -1215,12 +1216,12 @@
         val text = AnnotatedString(
             text = "ab",
             paragraphStyles = listOf(
-                ParagraphStyleRange(
+                Range<ParagraphStyle>(
                     item = ParagraphStyle(textDirection = TextDirection.Content),
                     start = 0,
                     end = "a".length
                 ),
-                ParagraphStyleRange(
+                Range<ParagraphStyle>(
                     // skip setting [TextDirection] on purpose, should inherit from the
                     // main [ParagraphStyle]
                     item = ParagraphStyle(),
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntrinsicIntegrationTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntrinsicIntegrationTest.kt
index da21da5..cd5c2ab 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntrinsicIntegrationTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntrinsicIntegrationTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.compose.ui.text
 
+import androidx.compose.ui.text.AnnotatedString.Range
 import androidx.compose.ui.text.font.toFontFamily
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.TextUnit
@@ -98,7 +99,7 @@
                 text = text,
                 fontSize = fontSize,
                 spanStyles = listOf(
-                    SpanStyleRange(
+                    Range<SpanStyle>(
                         item = SpanStyle(fontSize = styledFontSize),
                         start = "a ".length,
                         end = "a bb ".length
@@ -182,7 +183,7 @@
                 text = text,
                 fontSize = fontSize,
                 spanStyles = listOf(
-                    SpanStyleRange(
+                    Range<SpanStyle>(
                         item = SpanStyle(fontSize = styledFontSize),
                         start = "a".length,
                         end = "a bb ".length
@@ -199,7 +200,7 @@
         text: String = "",
         style: TextStyle? = null,
         fontSize: TextUnit = 14.sp,
-        spanStyles: List<AnnotatedString.Range<SpanStyle>> = listOf()
+        spanStyles: List<Range<SpanStyle>> = listOf()
     ): ParagraphIntrinsics {
         return ParagraphIntrinsics(
             text = text,
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/AnnotatedString.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/AnnotatedString.kt
index 22b4146..7cdc39c 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/AnnotatedString.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/AnnotatedString.kt
@@ -24,32 +24,14 @@
 import androidx.compose.ui.util.fastForEach
 
 /**
- * The class changes the character level style of the specified range.
- * @see AnnotatedString.Builder
- */
-typealias SpanStyleRange = Range<SpanStyle>
-
-/**
- * The class changes the paragraph level style of the specified range.
- * @see AnnotatedString.Builder
- */
-typealias ParagraphStyleRange = Range<ParagraphStyle>
-
-/**
- * The class that stores a string type annotation.
- * @see AnnotatedString.Builder
- */
-typealias StringAnnotation = Range<String>
-
-/**
  * The basic data structure of text with multiple styles. To construct an [AnnotatedString] you
  * can use [Builder].
  */
 @Immutable
 class AnnotatedString internal constructor(
     val text: String,
-    val spanStyles: List<SpanStyleRange> = emptyList(),
-    val paragraphStyles: List<ParagraphStyleRange> = emptyList(),
+    val spanStyles: List<Range<SpanStyle>> = emptyList(),
+    val paragraphStyles: List<Range<ParagraphStyle>> = emptyList(),
     internal val annotations: List<Range<out Any>> = emptyList()
 ) : CharSequence {
     /**
@@ -74,8 +56,8 @@
      */
     constructor(
         text: String,
-        spanStyles: List<SpanStyleRange> = listOf(),
-        paragraphStyles: List<ParagraphStyleRange> = listOf()
+        spanStyles: List<Range<SpanStyle>> = listOf(),
+        paragraphStyles: List<Range<ParagraphStyle>> = listOf()
     ) : this(text, spanStyles, paragraphStyles, listOf())
 
     init {
@@ -150,10 +132,10 @@
      * list will be returned.
      */
     @Suppress("UNCHECKED_CAST")
-    fun getStringAnnotations(tag: String, start: Int, end: Int): List<StringAnnotation> =
+    fun getStringAnnotations(tag: String, start: Int, end: Int): List<Range<String>> =
         annotations.filter {
             it.item is String && tag == it.tag && intersect(start, end, it.start, it.end)
-        } as List<StringAnnotation>
+        } as List<Range<String>>
 
     /**
      * Query all of the string annotations attached on this AnnotatedString.
@@ -165,10 +147,10 @@
      * list will be returned.
      */
     @Suppress("UNCHECKED_CAST")
-    fun getStringAnnotations(start: Int, end: Int): List<StringAnnotation> =
+    fun getStringAnnotations(start: Int, end: Int): List<Range<String>> =
         annotations.filter {
             it.item is String && intersect(start, end, it.start, it.end)
-        } as List<StringAnnotation>
+        } as List<Range<String>>
 
     /**
      * Query all of the string annotations attached on this AnnotatedString.
@@ -489,12 +471,12 @@
  */
 internal fun AnnotatedString.normalizedParagraphStyles(
     defaultParagraphStyle: ParagraphStyle
-): List<ParagraphStyleRange> {
+): List<Range<ParagraphStyle>> {
     val length = text.length
     val paragraphStyles = paragraphStyles
 
     var lastOffset = 0
-    val result = mutableListOf<ParagraphStyleRange>()
+    val result = mutableListOf<Range<ParagraphStyle>>()
     paragraphStyles.fastForEach { (style, start, end) ->
         if (start != lastOffset) {
             result.add(Range(defaultParagraphStyle, lastOffset, start))
@@ -524,7 +506,7 @@
 private fun AnnotatedString.getLocalStyles(
     start: Int,
     end: Int
-): List<SpanStyleRange> {
+): List<Range<SpanStyle>> {
     if (start == end) return listOf()
     // If the given range covers the whole AnnotatedString, return SpanStyles without conversion.
     if (start == 0 && end >= this.text.length) {
@@ -563,7 +545,7 @@
     defaultParagraphStyle: ParagraphStyle,
     crossinline block: (
         annotatedString: AnnotatedString,
-        paragraphStyle: ParagraphStyleRange
+        paragraphStyle: Range<ParagraphStyle>
     ) -> T
 ): List<T> {
     return normalizedParagraphStyles(defaultParagraphStyle).map { paragraphStyleRange ->
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/AtomicReference.kt
similarity index 66%
copy from compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt
copy to compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/AtomicReference.kt
index 63fdeeb..334935a 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/AtomicReference.kt
@@ -1,5 +1,7 @@
+// ktlint-disable filename
+
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +16,11 @@
  * limitations under the License.
  */
 
-package androidx.compose.foundation.layout
+package androidx.compose.ui.text
 
-@RequiresOptIn("The API of this layout is experimental and is likely to change in the future.")
-annotation class ExperimentalLayout
+expect class AtomicReference<V>(value: V) {
+    fun get(): V
+    fun set(value: V)
+    fun getAndSet(value: V): V
+    fun compareAndSet(expect: V, newValue: V): Boolean
+}
\ No newline at end of file
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/SoftwareKeyboardController.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/SoftwareKeyboardController.kt
deleted file mode 100644
index 3a262ef..0000000
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/SoftwareKeyboardController.kt
+++ /dev/null
@@ -1,52 +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.ui.text
-
-import androidx.compose.ui.geometry.Rect
-import androidx.compose.ui.text.input.InputSessionToken
-import androidx.compose.ui.text.input.TextInputService
-
-/**
- * Provide software keyboard control.
- */
-class SoftwareKeyboardController(
-    private val textInputService: TextInputService,
-    private val token: InputSessionToken
-) {
-    /**
-     * Show software keyboard
-     *
-     * There is no guarantee nor callback of the result of this API.
-     * Do nothing if bound text field loses input session.
-     */
-    fun showSoftwareKeyboard() = textInputService.showSoftwareKeyboard(token)
-
-    /**
-     * Hide software keyboard
-     *
-     * Do nothing if bound text field loses input session.
-     */
-    fun hideSoftwareKeyboard() = textInputService.hideSoftwareKeyboard(token)
-
-    /**
-     * Notify to IME about the currently focused rectangle.
-     *
-     * Do nothing if bound text field loses input session.
-     * @param rect focused rectangle in the root view coordinate.
-     */
-    fun notifyFocusedRect(rect: Rect) = textInputService.notifyFocusedRect(token, rect)
-}
\ No newline at end of file
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextRange.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextRange.kt
index 8c30d12..6adb64a 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextRange.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextRange.kt
@@ -27,27 +27,23 @@
  * An immutable text range class, represents a text range from [start] (inclusive) to [end]
  * (exclusive). [end] can be smaller than [start] and in those cases [min] and [max] can be
  * used in order to fetch the values.
+ *
+ * @param start the inclusive start offset of the range. Must be non-negative, otherwise an
+ * exception will be thrown.
+ * @param end the exclusive end offset of the range. Must be non-negative, otherwise an
+ * exception will be thrown.
+ */
+fun TextRange(/*@IntRange(from = 0)*/ start: Int, /*@IntRange(from = 0)*/ end: Int) =
+    TextRange(packWithCheck(start, end))
+
+/**
+ * An immutable text range class, represents a text range from [start] (inclusive) to [end]
+ * (exclusive). [end] can be smaller than [start] and in those cases [min] and [max] can be
+ * used in order to fetch the values.
  */
 @Suppress("EXPERIMENTAL_FEATURE_WARNING")
 @Immutable
-inline class TextRange(val packedValue: Long) {
-
-    /**
-     * An immutable text range class, represents a text range from [start] (inclusive) to [end]
-     * (exclusive). [end] can be smaller than [start] and in those cases [min] and [max] can be
-     * used in order to fetch the values.
-     *
-     * @param start the inclusive start offset of the range. Must be non-negative, otherwise an
-     * exception will be thrown.
-     * @param end the exclusive end offset of the range. Must be non-negative, otherwise an
-     * exception will be thrown.
-     */
-    constructor(
-        /*@IntRange(from = 0)*/
-        start: Int,
-        /*@IntRange(from = 0)*/
-        end: Int
-    ) : this(packWithCheck(start, end))
+inline class TextRange internal constructor(private val packedValue: Long) {
 
     val start: Int get() = unpackInt1(packedValue)
 
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/EditProcessor.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/EditProcessor.kt
index ffb3c59..8c8a24a 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/EditProcessor.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/EditProcessor.kt
@@ -16,24 +16,28 @@
 
 package androidx.compose.ui.text.input
 
-import androidx.compose.ui.text.InternalTextApi
 import androidx.compose.ui.text.TextRange
 import androidx.compose.ui.text.emptyAnnotatedString
 
 /**
- * The core editing implementation
+ * Helper class to apply [EditCommand]s on an internal buffer. Used by TextField Composable
+ * to combine TextFieldValue lifecycle with the editing operations.
  *
- * This class accepts latest text edit state from developer and also receives edit operations from
- * IME.
- *
- * @suppress
+ * * When a [TextFieldValue] is suggested by the developer, [reset] should be called.
+ * * When [TextInputService] provides [EditCommand]s, they should be applied to the internal
+ * buffer using [apply].
  */
-@InternalTextApi // Used by CoreTextTextField in foundation
 class EditProcessor {
 
-    // The last known state of the EditingBuffer
+    /**
+     * The current state of the internal editing buffer as a [TextFieldValue].
+     */
     /*@VisibleForTesting*/
-    var mBufferState: TextFieldValue = TextFieldValue(emptyAnnotatedString(), TextRange.Zero, null)
+    internal var mBufferState: TextFieldValue = TextFieldValue(
+        emptyAnnotatedString(),
+        TextRange.Zero,
+        null
+    )
         private set
 
     // The editing buffer used for applying editor commands from IME.
@@ -42,6 +46,7 @@
         text = mBufferState.annotatedString,
         selection = mBufferState.selection
     )
+        private set
 
     /**
      * Must be called whenever new editor model arrives.
@@ -49,10 +54,9 @@
      * This method updates the internal editing buffer with the given editor model.
      * This method may tell the IME about the selection offset changes or extracted text changes.
      */
-    fun onNewState(
+    fun reset(
         value: TextFieldValue,
-        textInputService: TextInputService?,
-        token: InputSessionToken
+        textInputSession: TextInputSession?,
     ) {
         if (mBufferState.annotatedString != value.annotatedString) {
             mBuffer = EditingBuffer(
@@ -71,17 +75,21 @@
 
         val oldValue = mBufferState
         mBufferState = value
-        textInputService?.updateState(token, oldValue, value)
+        textInputSession?.updateState(oldValue, value)
     }
 
     /**
-     * Must be called whenever new edit operations sent from IMEs arrives.
+     * Applies a set of [editCommands] to the internal text editing buffer.
      *
-     * This method updates internal editing buffer with the given edit operations and returns the
-     * latest editor state representation of the editing buffer.
+     * After applying the changes, returns the final state of the editing buffer as a
+     * [TextFieldValue]
+     *
+     * @param editCommands [EditCommand]s to be applied to the editing buffer.
+     *
+     * @return the [TextFieldValue] representation of the final buffer state.
      */
-    fun onEditCommands(ops: List<EditCommand>): TextFieldValue {
-        ops.forEach { it.applyTo(mBuffer) }
+    fun apply(editCommands: List<EditCommand>): TextFieldValue {
+        editCommands.forEach { it.applyTo(mBuffer) }
 
         val newState = TextFieldValue(
             annotatedString = mBuffer.toAnnotatedString(),
@@ -96,4 +104,9 @@
         mBufferState = newState
         return newState
     }
+
+    /**
+     * Returns the current state of the internal editing buffer as a [TextFieldValue].
+     */
+    fun toTextFieldValue(): TextFieldValue = mBufferState
 }
\ No newline at end of file
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/EditingBuffer.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/EditingBuffer.kt
index 25e8059..23fe9c6 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/EditingBuffer.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/EditingBuffer.kt
@@ -82,6 +82,7 @@
     /**
      * Helper accessor for cursor offset
      */
+    /*VisibleForTesting*/
     internal var cursor: Int
         /**
          * Return the cursor offset.
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/TextFieldValue.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/TextFieldValue.kt
index 04e0967..0ed964d 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/TextFieldValue.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/TextFieldValue.kt
@@ -35,20 +35,25 @@
  * This class stores a snapshot of the input state of the edit buffer and provide utility functions
  * for answering IME requests such as getTextBeforeCursor, getSelectedText.
  *
- * IME [composition] parameter is owned by the IME and it is related to text composition. When a
+ * Input service composition is an instance of text produced by IME. An example visual for the
+ * composition is that the currently composed word is visually separated from others with
+ * underline, or text background. For description of composition please check
+ * [W3C IME Composition](https://www.w3.org/TR/ime-api/#ime-composition).
+ *
+ * IME composition is defined by [composition] parameter and function. When a
  * [TextFieldValue] with null [composition] is passed to a TextField, if there was an
- * active [composition] on the text, the changes will be committed. Please use [copy] functions
- * if you do not want to intentionally commit the IME composition.
+ * active [composition] on the text, the changes will be applied. Applying a composition will
+ * accept the changes that were still being composed by IME. Please use [copy]
+ * functions if you do not want to intentionally apply the ongoing IME composition.
  *
  * @param annotatedString the text to be rendered.
  * @param selection the selection range. If the selection is collapsed, it represents cursor
  * location. When selection range is out of bounds, it is constrained with the text length.
- * @param composition the composition range, null means empty composition or commit if a
+ * @param composition the composition range, null means empty composition or apply if a
  * composition exists on the text. Owned by IME, and if you have an instance of [TextFieldValue]
  * please use [copy] functions if you do not want to intentionally change the value of this
  * field.
  *
- * @see commitComposition
  */
 @Immutable
 class TextFieldValue constructor(
@@ -60,12 +65,10 @@
      * @param text the text to be rendered.
      * @param selection the selection range. If the selection is collapsed, it represents cursor
      * location. When selection range is out of bounds, it is constrained with the text length.
-     * @param composition the composition range, null means empty composition or commit if a
+     * @param composition the composition range, null means empty composition or apply if a
      * composition exists on the text. Owned by IME, and if you have an instance of [TextFieldValue]
      * please use [copy] functions if you do not want to intentionally change the value of this
      * field.
-     *
-     * @see commitComposition
      */
     constructor(
         text: String = "",
@@ -79,18 +82,19 @@
      * The selection range. If the selection is collapsed, it represents cursor
      * location. When selection range is out of bounds, it is constrained with the text length.
      */
-    val selection = selection.constrain(0, text.length)
+    val selection: TextRange = selection.constrain(0, text.length)
 
     /**
      * Composition range created by  IME. If null, there is no composition range.
      *
-     * Composition can be set on the by the system, however it is possible to commit an existing
-     * composition using [commitComposition].
-     *
      * Input service composition is an instance of text produced by IME. An example visual for the
      * composition is that the currently composed word is visually separated from others with
      * underline, or text background. For description of composition please check
      * [W3C IME Composition](https://www.w3.org/TR/ime-api/#ime-composition)
+     *
+     * Composition can be set on the by the system, however it is possible to apply an existing
+     * composition by setting the value to null. Applying a composition will accept the changes
+     * that were still being composed by IME.
      */
     val composition: TextRange? = composition?.constrain(0, text.length)
 
@@ -116,19 +120,6 @@
         return TextFieldValue(AnnotatedString(text), selection, composition)
     }
 
-    /**
-     * Returns a copy of [TextFieldValue] in which [composition] is set to null. When a
-     * [TextFieldValue] with null [composition] is passed to a TextField, if there was an
-     * active [composition] on the text, the changes will be committed.
-     *
-     * @see composition
-     */
-    fun commitComposition() = TextFieldValue(
-        annotatedString = annotatedString,
-        selection = selection,
-        composition = null
-    )
-
     // auto generated equals method
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
@@ -173,12 +164,22 @@
 
 /**
  * Returns the text before the selection.
+ *
+ * @param maxChars maximum number of characters (inclusive) before the minimum value in
+ * [TextFieldValue.selection].
+ *
+ * @see TextRange.min
  */
 fun TextFieldValue.getTextBeforeSelection(maxChars: Int): AnnotatedString =
     annotatedString.subSequence(max(0, selection.min - maxChars), selection.min)
 
 /**
  * Returns the text after the selection.
+ *
+ * @param maxChars maximum number of characters (exclusive) after the maximum value in
+ * [TextFieldValue.selection].
+ *
+ * @see TextRange.max
  */
 fun TextFieldValue.getTextAfterSelection(maxChars: Int): AnnotatedString =
     annotatedString.subSequence(selection.max, min(selection.max + maxChars, text.length))
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/TextInputService.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/TextInputService.kt
index 4bfc7d7..6924d17 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/TextInputService.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/TextInputService.kt
@@ -17,45 +17,30 @@
 package androidx.compose.ui.text.input
 
 import androidx.compose.ui.geometry.Rect
-
-/**
- * The input session token.
- *
- * The positive session token means the input session is alive. The session may be expired though.
- * The zero session token means no session.
- * The negative session token means the input session could not be established with some errors.
- */
-typealias InputSessionToken = Int
-
-/**
- * A special session token which represents there is no active input session.
- */
-const val NO_SESSION: InputSessionToken = 0
-
-/**
- * A special session token which represents the session couldn't be established.
- */
-const val INVALID_SESSION: InputSessionToken = -1
+import androidx.compose.ui.text.AtomicReference
 
 /**
  * Handles communication with the IME. Informs about the IME changes via [EditCommand]s and
  * provides utilities for working with software keyboard.
+ *
+ * This class is responsible for ensuring there is only one open [TextInputSession] which will
+ * interact with software keyboards. Start new a TextInputSession by calling [startInput] and
+ * close it with [stopInput].
  */
 // Open for testing purposes.
 open class TextInputService(private val platformTextInputService: PlatformTextInputService) {
+    private val _currentInputSession: AtomicReference<TextInputSession?> =
+        AtomicReference(null)
 
-    private var nextSessionToken: Int = 1
-    private var currentSessionToken: InputSessionToken = NO_SESSION
-
-    private inline fun ignoreIfExpired(token: InputSessionToken, block: () -> Unit) {
-        if (token > 0 && token == currentSessionToken) {
-            block()
-        }
-    }
+    internal val currentInputSession: TextInputSession?
+        get() = _currentInputSession.get()
 
     /**
      * Start text input session for given client.
      *
+     * If there is a previous [TextInputSession] open, it will immediately be closed by this call
+     * to [startInput].
+     *
      * @param value initial [TextFieldValue]
      * @param imeOptions IME configuration
      * @param onEditCommand callback to inform about changes requested by IME
@@ -67,51 +52,109 @@
         imeOptions: ImeOptions,
         onEditCommand: (List<EditCommand>) -> Unit,
         onImeActionPerformed: (ImeAction) -> Unit
-    ): InputSessionToken {
+    ): TextInputSession {
         platformTextInputService.startInput(
             value,
             imeOptions,
             onEditCommand,
             onImeActionPerformed
         )
-        currentSessionToken = nextSessionToken++
-        return currentSessionToken
+        val nextSession = TextInputSession(this, platformTextInputService)
+        _currentInputSession.set(nextSession)
+        return nextSession
     }
 
     /**
      * Stop text input session.
      *
-     * If the [token] is not valid no action will be performed.
+     * If the [session] is not the currently open session, no action will occur.
      *
-     * @param token the token returned by [startInput] call.
+     * @param session the session returned by [startInput] call.
      */
-    open fun stopInput(token: InputSessionToken) = ignoreIfExpired(token) {
-        platformTextInputService.stopInput()
+    open fun stopInput(session: TextInputSession) {
+        if (_currentInputSession.compareAndSet(session, null)) {
+            platformTextInputService.stopInput()
+        }
     }
 
     /**
      * Request showing onscreen keyboard.
      *
+     * This call will be ignored if there is not an open [TextInputSession], as it means there is
+     * nothing that will accept typed input. The most common way to open a TextInputSession is to
+     * set the focus to an editable text composable.
+     *
      * There is no guarantee that the keyboard will be shown. The software keyboard or
      * system service may silently ignore this request.
-     *
-     * If the [token] is not valid no action will be performed.
-     *
-     * @param token the token returned by [startInput] call.
      */
-    open fun showSoftwareKeyboard(token: InputSessionToken) = ignoreIfExpired(token) {
-        platformTextInputService.showSoftwareKeyboard()
+    fun showSoftwareKeyboard() {
+        if (_currentInputSession.get() != null) {
+            platformTextInputService.showSoftwareKeyboard()
+        }
     }
 
     /**
      * Hide onscreen keyboard.
-     *
-     * If the [token] is not valid no action will be performed.
-     *
-     * @param token the token returned by [startInput] call.
      */
-    open fun hideSoftwareKeyboard(token: InputSessionToken) = ignoreIfExpired(token) {
-        platformTextInputService.hideSoftwareKeyboard()
+    fun hideSoftwareKeyboard(): Unit = platformTextInputService.hideSoftwareKeyboard()
+}
+/**
+ * Represents a input session for interactions between a soft keyboard and editable text.
+ *
+ * This session may be closed at any time by [TextInputService] or by calling [dispose], after
+ * which [isOpen] will return false and all further calls will have no effect.
+ */
+class TextInputSession(
+    private val textInputService: TextInputService,
+    private val platformTextInputService: PlatformTextInputService
+) {
+    /**
+     * If this session is currently open.
+     *
+     * A session may be closed at any time by [TextInputService] or by calling [dispose].
+     */
+    val isOpen: Boolean
+        get() = textInputService.currentInputSession == this
+
+    /**
+     * Close this input session.
+     *
+     * All further calls to this object will have no effect, and [isOpen] will return false.
+     *
+     * Note, [TextInputService] may also close this input session at any time without calling
+     * dispose. Calling dispose after this session has been closed has no effect.
+     */
+    fun dispose() {
+        textInputService.stopInput(this)
+    }
+
+    /**
+     * Execute [block] if [isOpen] is true.
+     *
+     * This function will only check [isOpen] once, and may execute the action after the input
+     * session closes in the case of concurrent execution.
+     *
+     * @param block action to take if isOpen
+     * @return true if an action was performed
+     */
+    private inline fun ensureOpenSession(block: () -> Unit): Boolean {
+        return isOpen.also { applying ->
+            if (applying) {
+                block()
+            }
+        }
+    }
+
+    /**
+     * Notify the focused rectangle to the system.
+     *
+     * If the session is not open, no action will be performed.
+     *
+     * @param rect the rectangle that describes the boundaries on the screen that requires focus
+     * @return false if this session expired and no action was performed
+     */
+    fun notifyFocusedRect(rect: Rect): Boolean = ensureOpenSession {
+        platformTextInputService.notifyFocusedRect(rect)
     }
 
     /**
@@ -123,30 +166,50 @@
      * where [oldValue] is not equal to [newValue], it would mean the IME suggested value is
      * rejected, and the IME connection will be restarted with the newValue.
      *
-     * If the [token] is not valid no action will be performed.
+     * If the session is not open, action will be performed.
      *
-     * @param token the token returned by [startInput] call.
      * @param oldValue the value that was requested by IME on the buffer
      * @param newValue final state of the editing buffer that was requested by the application
+     * @return false if this session expired and no action was performed
      */
-    open fun updateState(
-        token: InputSessionToken,
+    fun updateState(
         oldValue: TextFieldValue?,
         newValue: TextFieldValue
-    ) = ignoreIfExpired(token) {
+    ): Boolean = ensureOpenSession {
         platformTextInputService.updateState(oldValue, newValue)
     }
 
     /**
-     * Notify the focused rectangle to the system.
+     * Request showing onscreen keyboard.
      *
-     * If the [token] is not valid no action will be performed.
+     * This call will have no effect if this session is not open.
      *
-     * @param token the token returned by [startInput] call.
-     * @param rect the rectangle that describes the boundaries on the screen that requires focus
+     * This should be used instead of [TextInputService.showSoftwareKeyboard] when implementing a
+     * new editable text composable to show the keyboard in response to events related to that
+     * composable.
+     *
+     * There is no guarantee that the keyboard will be shown. The software keyboard or
+     * system service may silently ignore this request.
+     *
+     * @return false if this session expired and no action was performed
      */
-    open fun notifyFocusedRect(token: InputSessionToken, rect: Rect) = ignoreIfExpired(token) {
-        platformTextInputService.notifyFocusedRect(rect)
+    fun showSoftwareKeyboard(): Boolean = ensureOpenSession {
+        textInputService.showSoftwareKeyboard()
+    }
+
+    /**
+     * Hide onscreen keyboard for a specific [TextInputSession].
+     *
+     * This call will have no effect if this session is not open.
+     *
+     * This should be used instead of [TextInputService.showSoftwareKeyboard] when implementing a
+     * new editable text composable to hide the keyboard in response to events related to that
+     * composable.
+     *
+     * @return false if this session expired and no action was performed
+     */
+    fun hideSoftwareKeyboard(): Boolean = ensureOpenSession {
+        textInputService.hideSoftwareKeyboard()
     }
 }
 
@@ -199,7 +262,7 @@
     /**
      * Notify the focused rectangle to the system.
      *
-     * @see TextInputService.notifyFocusedRect
+     * @see TextInputSession.notifyFocusedRect
      */
     fun notifyFocusedRect(rect: Rect)
 }
diff --git a/compose/ui/ui-text/src/desktopMain/kotlin/androidx/compose/ui/text/platform/DesktopParagraph.desktop.kt b/compose/ui/ui-text/src/desktopMain/kotlin/androidx/compose/ui/text/platform/DesktopParagraph.desktop.kt
index 576cf09..ecc16cb 100644
--- a/compose/ui/ui-text/src/desktopMain/kotlin/androidx/compose/ui/text/platform/DesktopParagraph.desktop.kt
+++ b/compose/ui/ui-text/src/desktopMain/kotlin/androidx/compose/ui/text/platform/DesktopParagraph.desktop.kt
@@ -26,13 +26,12 @@
 import androidx.compose.ui.graphics.nativeCanvas
 import androidx.compose.ui.graphics.toArgb
 import androidx.compose.ui.graphics.toComposeRect
-import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.text.AnnotatedString.Range
 import androidx.compose.ui.text.Paragraph
 import androidx.compose.ui.text.ParagraphIntrinsics
 import androidx.compose.ui.text.Placeholder
 import androidx.compose.ui.text.PlaceholderVerticalAlign
 import androidx.compose.ui.text.SpanStyle
-import androidx.compose.ui.text.SpanStyleRange
 import androidx.compose.ui.text.TextRange
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.font.Font
@@ -80,8 +79,8 @@
 internal actual fun ActualParagraph(
     text: String,
     style: TextStyle,
-    spanStyles: List<AnnotatedString.Range<SpanStyle>>,
-    placeholders: List<AnnotatedString.Range<Placeholder>>,
+    spanStyles: List<Range<SpanStyle>>,
+    placeholders: List<Range<Placeholder>>,
     maxLines: Int,
     ellipsis: Boolean,
     width: Float,
@@ -502,8 +501,8 @@
     var textStyle: TextStyle,
     var ellipsis: String = "",
     var maxLines: Int = Int.MAX_VALUE,
-    val spanStyles: List<SpanStyleRange>,
-    val placeholders: List<AnnotatedString.Range<Placeholder>>,
+    val spanStyles: List<Range<SpanStyle>>,
+    val placeholders: List<Range<Placeholder>>,
     val density: Density
 ) {
     private lateinit var initialStyle: SpanStyle
@@ -631,8 +630,8 @@
     }
 
     private fun makeOps(
-        spans: List<SpanStyleRange>,
-        placeholders: List<AnnotatedString.Range<Placeholder>>
+        spans: List<Range<SpanStyle>>,
+        placeholders: List<Range<Placeholder>>
     ): List<Op> {
         val cuts = mutableListOf<Cut>()
         for (span in spans) {
diff --git a/compose/ui/ui-text/src/desktopMain/kotlin/androidx/compose/ui/text/platform/DesktopParagraphIntrinsics.desktop.kt b/compose/ui/ui-text/src/desktopMain/kotlin/androidx/compose/ui/text/platform/DesktopParagraphIntrinsics.desktop.kt
index 9d9b0c3..5aca88f 100644
--- a/compose/ui/ui-text/src/desktopMain/kotlin/androidx/compose/ui/text/platform/DesktopParagraphIntrinsics.desktop.kt
+++ b/compose/ui/ui-text/src/desktopMain/kotlin/androidx/compose/ui/text/platform/DesktopParagraphIntrinsics.desktop.kt
@@ -15,11 +15,10 @@
  */
 package androidx.compose.ui.text.platform
 
-import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.text.AnnotatedString.Range
 import androidx.compose.ui.text.ParagraphIntrinsics
 import androidx.compose.ui.text.Placeholder
 import androidx.compose.ui.text.SpanStyle
-import androidx.compose.ui.text.SpanStyleRange
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.font.Font
 import androidx.compose.ui.unit.Density
@@ -29,8 +28,8 @@
 internal actual fun ActualParagraphIntrinsics(
     text: String,
     style: TextStyle,
-    spanStyles: List<AnnotatedString.Range<SpanStyle>>,
-    placeholders: List<AnnotatedString.Range<Placeholder>>,
+    spanStyles: List<Range<SpanStyle>>,
+    placeholders: List<Range<Placeholder>>,
     density: Density,
     resourceLoader: Font.ResourceLoader
 ): ParagraphIntrinsics =
@@ -46,8 +45,8 @@
 internal class DesktopParagraphIntrinsics(
     val text: String,
     style: TextStyle,
-    spanStyles: List<SpanStyleRange>,
-    placeholders: List<AnnotatedString.Range<Placeholder>>,
+    spanStyles: List<Range<SpanStyle>>,
+    placeholders: List<Range<Placeholder>>,
     density: Density,
     resourceLoader: Font.ResourceLoader
 ) : ParagraphIntrinsics {
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt b/compose/ui/ui-text/src/jvmMain/kotlin/androidx/compose/ui/text/ActualAtomicReferenceJvm.kt
similarity index 72%
copy from compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt
copy to compose/ui/ui-text/src/jvmMain/kotlin/androidx/compose/ui/text/ActualAtomicReferenceJvm.kt
index bae8c9a..02893a8 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/Mouse.kt
+++ b/compose/ui/ui-text/src/jvmMain/kotlin/androidx/compose/ui/text/ActualAtomicReferenceJvm.kt
@@ -1,5 +1,7 @@
+// ktlint-disable filename
+
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +16,6 @@
  * limitations under the License.
  */
 
-package androidx.compose.ui.input.pointer
+package androidx.compose.ui.text
 
-@MouseTemporaryApi
-expect val isMouseInput: Boolean
\ No newline at end of file
+internal actual typealias AtomicReference<V> = java.util.concurrent.atomic.AtomicReference<V>
diff --git a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/AnnotatedStringBuilderTest.kt b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/AnnotatedStringBuilderTest.kt
index a3ef51d..121da01 100644
--- a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/AnnotatedStringBuilderTest.kt
+++ b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/AnnotatedStringBuilderTest.kt
@@ -17,6 +17,7 @@
 package androidx.compose.ui.text
 
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.AnnotatedString.Range
 import androidx.compose.ui.text.font.FontStyle
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.text.style.TextAlign
@@ -70,7 +71,7 @@
         }
 
         val expectedSpanStyles = listOf(
-            AnnotatedString.Range(style, range.start, range.end)
+            Range(style, range.start, range.end)
         )
 
         assertThat(annotatedString.paragraphStyles).isEmpty()
@@ -87,7 +88,7 @@
         }
 
         val expectedParagraphStyles = listOf(
-            AnnotatedString.Range(style, range.start, range.end)
+            Range(style, range.start, range.end)
         )
 
         assertThat(annotatedString.spanStyles).isEmpty()
@@ -148,12 +149,12 @@
 
         val expectedString = "$text$appendedText"
         val expectedSpanStyles = listOf(
-            SpanStyleRange(
+            Range<SpanStyle>(
                 item = SpanStyle(color),
                 start = 0,
                 end = text.length
             ),
-            SpanStyleRange(
+            Range<SpanStyle>(
                 item = SpanStyle(appendedColor),
                 start = text.length,
                 end = expectedString.length
@@ -161,12 +162,12 @@
         )
 
         val expectedParagraphStyles = listOf(
-            ParagraphStyleRange(
+            Range<ParagraphStyle>(
                 item = ParagraphStyle(lineHeight = lineHeight),
                 start = 0,
                 end = text.length
             ),
-            ParagraphStyleRange(
+            Range<ParagraphStyle>(
                 item = ParagraphStyle(lineHeight = appendedLineHeight),
                 start = text.length,
                 end = expectedString.length
@@ -451,7 +452,7 @@
 
         assertThat(buildResult.paragraphStyles).isEmpty()
         assertThat(buildResult.spanStyles).isEqualTo(
-            listOf(SpanStyleRange(style, 0, buildResult.length))
+            listOf(Range<SpanStyle>(style, 0, buildResult.length))
         )
     }
 
@@ -467,7 +468,7 @@
 
         assertThat(buildResult.spanStyles).isEmpty()
         assertThat(buildResult.paragraphStyles).isEqualTo(
-            listOf(ParagraphStyleRange(style, 0, buildResult.length))
+            listOf(Range<ParagraphStyle>(style, 0, buildResult.length))
         )
     }
 
@@ -506,12 +507,12 @@
 
         val expectedString = "$text1 $text2"
         val expectedSpanStyles = listOf(
-            SpanStyleRange(spanStyle1, 0, text1.length),
-            SpanStyleRange(spanStyle2, text1.length + 1, expectedString.length)
+            Range<SpanStyle>(spanStyle1, 0, text1.length),
+            Range<SpanStyle>(spanStyle2, text1.length + 1, expectedString.length)
         )
         val expectedParagraphStyles = listOf(
-            ParagraphStyleRange(paragraphStyle1, 0, text1.length),
-            ParagraphStyleRange(paragraphStyle2, text1.length + 1, expectedString.length)
+            Range<ParagraphStyle>(paragraphStyle1, 0, text1.length),
+            Range<ParagraphStyle>(paragraphStyle2, text1.length + 1, expectedString.length)
         )
 
         assertThat(buildResult.text).isEqualTo(expectedString)
@@ -578,7 +579,7 @@
         val stringAnnotations = buildResult.getStringAnnotations(tag, 0, text.length)
         assertThat(stringAnnotations).hasSize(1)
         assertThat(stringAnnotations.first()).isEqualTo(
-            AnnotatedString.Range(annotation, 0, text.length, tag)
+            Range(annotation, 0, text.length, tag)
         )
     }
 
@@ -607,10 +608,10 @@
         assertThat(buildResult.getStringAnnotations(tag, 10, 11)).hasSize(1)
         val annotations = buildResult.getStringAnnotations(tag, 0, 11)
         assertThat(annotations[0]).isEqualTo(
-            AnnotatedString.Range(annotation1, 0, 11, tag)
+            Range(annotation1, 0, 11, tag)
         )
         assertThat(annotations[1]).isEqualTo(
-            AnnotatedString.Range(annotation2, 5, 10, tag)
+            Range(annotation2, 5, 10, tag)
         )
     }
 
@@ -638,11 +639,11 @@
         assertThat(buildResult.getStringAnnotations(tag1, 0, 5)).hasSize(1)
         assertThat(buildResult.getStringAnnotations(tag1, 5, 10)).hasSize(1)
         assertThat(buildResult.getStringAnnotations(tag1, 5, 10).first())
-            .isEqualTo(AnnotatedString.Range(annotation1, 0, 11, tag1))
+            .isEqualTo(Range(annotation1, 0, 11, tag1))
 
         assertThat(buildResult.getStringAnnotations(tag2, 5, 10)).hasSize(1)
         assertThat(buildResult.getStringAnnotations(tag2, 5, 10).first())
-            .isEqualTo(AnnotatedString.Range(annotation2, 5, 10, tag2))
+            .isEqualTo(Range(annotation2, 5, 10, tag2))
         assertThat(buildResult.getStringAnnotations(tag2, 10, 11)).hasSize(0)
     }
 
@@ -694,18 +695,18 @@
         //                     [         ]
         //                          [   ]
         assertThat(buildResult.getStringAnnotations(0, 5)).isEqualTo(
-            listOf(AnnotatedString.Range(annotation1, 0, 11, tag1))
+            listOf(Range(annotation1, 0, 11, tag1))
         )
 
         assertThat(buildResult.getStringAnnotations(5, 6)).isEqualTo(
             listOf(
-                AnnotatedString.Range(annotation1, 0, 11, tag1),
-                AnnotatedString.Range(annotation2, 5, 10, tag2)
+                Range(annotation1, 0, 11, tag1),
+                Range(annotation2, 5, 10, tag2)
             )
         )
 
         assertThat(buildResult.getStringAnnotations(10, 11)).isEqualTo(
-            listOf(AnnotatedString.Range(annotation1, 0, 11, tag1))
+            listOf(Range(annotation1, 0, 11, tag1))
         )
     }
 
@@ -726,17 +727,17 @@
 
         // The final result is Helloworld!
         //                     [         ] TtsAnnotation
-        //                          [   ]  StringAnnotation
+        //                          [   ]  Range<String>
         assertThat(buildResult.getTtsAnnotations(0, 5)).isEqualTo(
-            listOf(AnnotatedString.Range(annotation1, 0, 11, ""))
+            listOf(Range(annotation1, 0, 11, ""))
         )
         assertThat(buildResult.getTtsAnnotations(5, 6)).isEqualTo(
-            listOf(AnnotatedString.Range(annotation1, 0, 11, ""))
+            listOf(Range(annotation1, 0, 11, ""))
         )
 
         assertThat(buildResult.getStringAnnotations(0, 5)).isEmpty()
         assertThat(buildResult.getStringAnnotations(5, 6)).isEqualTo(
-            listOf(AnnotatedString.Range(annotation2, 5, 10, tag))
+            listOf(Range(annotation2, 5, 10, tag))
         )
         assertThat(buildResult.getStringAnnotations(10, 11)).isEmpty()
     }
@@ -758,10 +759,10 @@
 
         // The final result is Helloworld!
         //                     [         ] TtsAnnotation
-        //                          [   ]  StringAnnotation
+        //                          [   ]  Range<String>
         assertThat(buildResult.getStringAnnotations(tag, 0, 5)).isEmpty()
         assertThat(buildResult.getStringAnnotations(tag, 5, 6)).isEqualTo(
-            listOf(AnnotatedString.Range(annotation2, 5, 10, tag))
+            listOf(Range(annotation2, 5, 10, tag))
         )
         // The tag doesn't match, return empty list.
         assertThat(buildResult.getStringAnnotations("tag1", 5, 6)).isEmpty()
@@ -776,14 +777,14 @@
         return AnnotatedString(
             text = text,
             spanStyles = listOf(
-                SpanStyleRange(
+                Range<SpanStyle>(
                     item = SpanStyle(color),
                     start = 0,
                     end = text.length
                 )
             ),
             paragraphStyles = listOf(
-                ParagraphStyleRange(
+                Range<ParagraphStyle>(
                     item = ParagraphStyle(lineHeight = lineHeight),
                     start = 0,
                     end = text.length
diff --git a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextInputServiceTest.kt b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextInputServiceTest.kt
index c28042f..92c1bb1 100644
--- a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextInputServiceTest.kt
+++ b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextInputServiceTest.kt
@@ -43,46 +43,68 @@
 
         val textInputService = TextInputService(platformService)
 
-        val firstToken = textInputService.startInput(
+        val firstSession = textInputService.startInput(
             TextFieldValue(),
             ImeOptions.Default,
             {}, // onEditCommand
             {} // onImeActionPerformed
         )
-        val secondToken = textInputService.startInput(
+        val secondSession = textInputService.startInput(
             TextFieldValue(),
             ImeOptions.Default,
             {}, // onEditCommand
             {} // onImeActionPerformed
         )
 
-        assertThat(firstToken).isNotEqualTo(secondToken)
+        assertThat(firstSession).isNotEqualTo(secondSession)
     }
 
     @Test
-    fun stopInput_with_valid_token() {
+    fun startInput_stopsOldSession_onRestart() {
+        val platformService = mock<PlatformTextInputService>()
+        val textInputService = TextInputService(platformService)
+
+        val firstSession = textInputService.startInput(
+            TextFieldValue(),
+            ImeOptions.Default,
+            {}, // onEditCommand
+            {} // onImeActionPerformed
+        )
+        val secondSession = textInputService.startInput(
+            TextFieldValue(),
+            ImeOptions.Default,
+            {}, // onEditCommand
+            {} // onImeActionPerformed
+        )
+
+        assertThat(firstSession.isOpen).isFalse()
+        assertThat(secondSession.isOpen).isTrue()
+    }
+
+    @Test
+    fun stopInput_with_valid_session() {
         val platformService = mock<PlatformTextInputService>()
 
         val textInputService = TextInputService(platformService)
 
-        val firstToken = textInputService.startInput(
+        val session = textInputService.startInput(
             TextFieldValue(),
             ImeOptions.Default,
             {}, // onEditCommand
             {} // onImeActionPerformed
         )
 
-        textInputService.stopInput(firstToken)
+        textInputService.stopInput(session)
         verify(platformService, times(1)).stopInput()
     }
 
     @Test
-    fun stopInput_with_expired_token() {
+    fun stopInput_with_expired_session() {
         val platformService = mock<PlatformTextInputService>()
 
         val textInputService = TextInputService(platformService)
 
-        val firstToken = textInputService.startInput(
+        val firstSession = textInputService.startInput(
             TextFieldValue(),
             ImeOptions.Default,
             {}, // onEditCommand
@@ -97,34 +119,34 @@
             {} // onImeActionPerformed
         )
 
-        textInputService.stopInput(firstToken)
+        textInputService.stopInput(firstSession)
         verify(platformService, never()).stopInput()
     }
 
     @Test
-    fun showSoftwareKeyboard_with_valid_token() {
+    fun showSoftwareKeyboard_with_valid_session() {
         val platformService = mock<PlatformTextInputService>()
 
         val textInputService = TextInputService(platformService)
 
-        val firstToken = textInputService.startInput(
+        textInputService.startInput(
             TextFieldValue(),
             ImeOptions.Default,
             {}, // onEditCommand
             {} // onImeActionPerformed
         )
 
-        textInputService.showSoftwareKeyboard(firstToken)
+        textInputService.showSoftwareKeyboard()
         verify(platformService, times(1)).showSoftwareKeyboard()
     }
 
     @Test
-    fun showSoftwareKeyboard_with_expired_token() {
+    fun showSoftwareKeyboard_with_a_second_valid_session() {
         val platformService = mock<PlatformTextInputService>()
 
         val textInputService = TextInputService(platformService)
 
-        val firstToken = textInputService.startInput(
+        textInputService.startInput(
             TextFieldValue(),
             ImeOptions.Default,
             {}, // onEditCommand
@@ -139,7 +161,34 @@
             {} // onImeActionPerformed
         )
 
-        textInputService.showSoftwareKeyboard(firstToken)
+        textInputService.showSoftwareKeyboard()
+        verify(platformService).showSoftwareKeyboard()
+    }
+
+    @Test
+    fun showSoftwareKeyboard_with_disposed_session() {
+        val platformService = mock<PlatformTextInputService>()
+
+        val textInputService = TextInputService(platformService)
+
+        textInputService.startInput(
+            TextFieldValue(),
+            ImeOptions.Default,
+            {}, // onEditCommand
+            {} // onImeActionPerformed
+        ).dispose()
+
+        textInputService.showSoftwareKeyboard()
+        verify(platformService, never()).showSoftwareKeyboard()
+    }
+
+    @Test
+    fun showSoftwareKeyboard_with_no_started_session() {
+        val platformService = mock<PlatformTextInputService>()
+
+        val textInputService = TextInputService(platformService)
+
+        textInputService.showSoftwareKeyboard()
         verify(platformService, never()).showSoftwareKeyboard()
     }
 
@@ -149,7 +198,7 @@
 
         val textInputService = TextInputService(platformService)
 
-        val firstToken = textInputService.startInput(
+        val firstSession = textInputService.startInput(
             TextFieldValue(),
             ImeOptions.Default,
             {}, // onEditCommand
@@ -157,7 +206,7 @@
         )
 
         val editorModel = TextFieldValue()
-        textInputService.updateState(firstToken, null, editorModel)
+        firstSession.updateState(null, editorModel)
         verify(platformService, times(1)).updateState(eq(null), eq(editorModel))
     }
 
@@ -167,7 +216,7 @@
 
         val textInputService = TextInputService(platformService)
 
-        val firstToken = textInputService.startInput(
+        val firstSession = textInputService.startInput(
             TextFieldValue(),
             ImeOptions.Default,
             {}, // onEditCommand
@@ -175,7 +224,7 @@
         )
 
         // Start another session. The firstToken is now expired.
-        textInputService.startInput(
+        val secondSession = textInputService.startInput(
             TextFieldValue(),
             ImeOptions.Default,
             {}, // onEditCommand
@@ -183,8 +232,11 @@
         )
 
         val editorModel = TextFieldValue()
-        textInputService.updateState(firstToken, null, editorModel)
+        firstSession.updateState(null, editorModel)
         verify(platformService, never()).updateState(any(), any())
+
+        secondSession.updateState(null, editorModel)
+        verify(platformService).updateState(eq(null), eq(editorModel))
     }
 
     @Test
@@ -193,7 +245,7 @@
 
         val textInputService = TextInputService(platformService)
 
-        val firstToken = textInputService.startInput(
+        val firstSession = textInputService.startInput(
             TextFieldValue(),
             ImeOptions.Default,
             {}, // onEditCommand
@@ -201,7 +253,7 @@
         )
 
         val rect = Rect(Offset.Zero, Size(100f, 100f))
-        textInputService.notifyFocusedRect(firstToken, rect)
+        firstSession.notifyFocusedRect(rect)
         verify(platformService, times(1)).notifyFocusedRect(eq(rect))
     }
 
@@ -211,7 +263,7 @@
 
         val textInputService = TextInputService(platformService)
 
-        val firstToken = textInputService.startInput(
+        val firstSession = textInputService.startInput(
             TextFieldValue(),
             ImeOptions.Default,
             {}, // onEditCommand
@@ -219,7 +271,7 @@
         )
 
         // Start another session. The firstToken is now expired.
-        textInputService.startInput(
+        val secondSession = textInputService.startInput(
             TextFieldValue(),
             ImeOptions.Default,
             {}, // onEditCommand
@@ -227,7 +279,10 @@
         )
 
         val rect = Rect(Offset.Zero, Size(100f, 100f))
-        textInputService.notifyFocusedRect(firstToken, rect)
+        firstSession.notifyFocusedRect(rect)
         verify(platformService, never()).notifyFocusedRect(any())
+
+        secondSession.notifyFocusedRect(rect)
+        verify(platformService, times(1)).notifyFocusedRect(eq(rect))
     }
 }
diff --git a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/input/EditProcessorTest.kt b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/input/EditProcessorTest.kt
index 4fa7fe2..48ceffd 100644
--- a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/input/EditProcessorTest.kt
+++ b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/input/EditProcessorTest.kt
@@ -39,16 +39,14 @@
     @Test
     fun test_new_state_and_edit_commands() {
         val proc = EditProcessor()
-        val tis: TextInputService = mock()
-        val inputSessionToken = 10 // We are not using this value in this test.
+        val tis: TextInputSession = mock()
 
         val model = TextFieldValue("ABCDE", TextRange.Zero)
-        proc.onNewState(model, tis, inputSessionToken)
+        proc.reset(model, tis)
 
         assertEquals(model, proc.mBufferState)
         val captor = argumentCaptor<TextFieldValue>()
         verify(tis, times(1)).updateState(
-            eq(inputSessionToken),
             eq(TextFieldValue("", TextRange.Zero)),
             captor.capture()
         )
@@ -59,7 +57,7 @@
 
         reset(tis)
 
-        val newState = proc.onEditCommands(
+        val newState = proc.apply(
             listOf(
                 CommitTextCommand("X", 1)
             )
@@ -69,28 +67,25 @@
         assertEquals(1, newState.selection.min)
         assertEquals(1, newState.selection.max)
         // onEditCommands should not fire onStateUpdated since need to pass it to developer first.
-        verify(tis, never()).updateState(any(), any(), any())
+        verify(tis, never()).updateState(any(), any())
     }
 
     @Test
     fun testNewState_bufferNotUpdated_ifSameModelStructurally() {
         val processor = EditProcessor()
-        val textInputService = mock<TextInputService>()
-        val token = 10 // mock token value
+        val textInputSession = mock<TextInputSession>()
 
         val initialBuffer = processor.mBuffer
-        processor.onNewState(
+        processor.reset(
             TextFieldValue("qwerty", TextRange.Zero, TextRange.Zero),
-            textInputService,
-            token
+            textInputSession
         )
         assertNotEquals(initialBuffer, processor.mBuffer)
 
         val updatedBuffer = processor.mBuffer
-        processor.onNewState(
+        processor.reset(
             TextFieldValue("qwerty", TextRange.Zero, TextRange.Zero),
-            textInputService,
-            token
+            textInputSession
         )
         assertEquals(updatedBuffer, processor.mBuffer)
     }
@@ -98,21 +93,19 @@
     @Test
     fun testNewState_new_buffer_created_if_text_is_different() {
         val processor = EditProcessor()
-        val textInputService = mock<TextInputService>()
-        val token = 10 // mock token value
+        val textInputSession = mock<TextInputSession>()
+
         val textFieldValue = TextFieldValue("qwerty", TextRange.Zero, TextRange.Zero)
-        processor.onNewState(
+        processor.reset(
             textFieldValue,
-            textInputService,
-            token
+            textInputSession
         )
         val initialBuffer = processor.mBuffer
 
         val newTextFieldValue = textFieldValue.copy("abc")
-        processor.onNewState(
+        processor.reset(
             newTextFieldValue,
-            textInputService,
-            token
+            textInputSession
         )
 
         assertNotEquals(initialBuffer, processor.mBuffer)
@@ -121,21 +114,18 @@
     @Test
     fun testNewState_buffer_not_recreated_if_selection_is_different() {
         val processor = EditProcessor()
-        val textInputService = mock<TextInputService>()
-        val token = 10 // mock token value
+        val textInputSession = mock<TextInputSession>()
         val textFieldValue = TextFieldValue("qwerty", TextRange.Zero, TextRange.Zero)
-        processor.onNewState(
+        processor.reset(
             textFieldValue,
-            textInputService,
-            token
+            textInputSession
         )
         val initialBuffer = processor.mBuffer
 
         val newTextFieldValue = textFieldValue.copy(selection = TextRange(1))
-        processor.onNewState(
+        processor.reset(
             newTextFieldValue,
-            textInputService,
-            token
+            textInputSession
         )
 
         assertEquals(initialBuffer, processor.mBuffer)
@@ -146,13 +136,11 @@
     @Test
     fun testNewState_buffer_not_recreated_if_composition_is_different() {
         val processor = EditProcessor()
-        val textInputService = mock<TextInputService>()
-        val token = 10 // mock token value
+        val textInputSeson = mock<TextInputSession>()
         val textFieldValue = TextFieldValue("qwerty", TextRange.Zero, TextRange(1))
-        processor.onNewState(
+        processor.reset(
             textFieldValue,
-            textInputService,
-            token
+            textInputSeson
         )
         val initialBuffer = processor.mBuffer
 
@@ -160,11 +148,10 @@
         assertEquals(initialBuffer.compositionStart, EditingBuffer.NOWHERE)
         assertEquals(initialBuffer.compositionEnd, EditingBuffer.NOWHERE)
 
-        val newTextFieldValue = textFieldValue.commitComposition()
-        processor.onNewState(
+        val newTextFieldValue = textFieldValue.copy(composition = null)
+        processor.reset(
             newTextFieldValue,
-            textInputService,
-            token
+            textInputSeson
         )
 
         assertEquals(initialBuffer, processor.mBuffer)
@@ -175,16 +162,14 @@
     @Test
     fun testNewState_reversedSelection_setsTheSelection() {
         val processor = EditProcessor()
-        val textInputService = mock<TextInputService>()
-        val token = 10 // mock token value
+        val textInputSession = mock<TextInputSession>()
         val initialSelection = TextRange(2, 1)
         val textFieldValue = TextFieldValue("qwerty", initialSelection, TextRange(1))
 
         // set the initial selection to be reversed
-        processor.onNewState(
+        processor.reset(
             textFieldValue,
-            textInputService,
-            token
+            textInputSession
         )
         val initialBuffer = processor.mBuffer
 
@@ -194,10 +179,9 @@
         val updatedSelection = TextRange(3, 0)
         val newTextFieldValue = textFieldValue.copy(selection = updatedSelection)
         // set the new selection
-        processor.onNewState(
+        processor.reset(
             newTextFieldValue,
-            textInputService,
-            token
+            textInputSession
         )
 
         assertEquals(initialBuffer, processor.mBuffer)
diff --git a/compose/ui/ui-tooling/src/androidTest/java/androidx/compose/ui/tooling/inspector/LayoutInspectorTreeTest.kt b/compose/ui/ui-tooling/src/androidTest/java/androidx/compose/ui/tooling/inspector/LayoutInspectorTreeTest.kt
index 835a64d..244c29d 100644
--- a/compose/ui/ui-tooling/src/androidTest/java/androidx/compose/ui/tooling/inspector/LayoutInspectorTreeTest.kt
+++ b/compose/ui/ui-tooling/src/androidTest/java/androidx/compose/ui/tooling/inspector/LayoutInspectorTreeTest.kt
@@ -205,7 +205,7 @@
                 name = "MaterialTheme",
                 hasTransformations = true,
                 fileName = "LayoutInspectorTreeTest.kt",
-                left = 68.0.dp, top = 49.7.dp, width = 88.5.dp, height = 21.7.dp,
+                left = 65.8.dp, top = 49.7.dp, width = 86.2.dp, height = 21.7.dp,
                 children = listOf("Text")
             )
             node(
@@ -213,7 +213,7 @@
                 isRenderNode = true,
                 hasTransformations = true,
                 fileName = "LayoutInspectorTreeTest.kt",
-                left = 68.0.dp, top = 49.7.dp, width = 88.5.dp, height = 21.7.dp,
+                left = 65.8.dp, top = 49.7.dp, width = 86.2.dp, height = 21.7.dp,
             )
         }
     }
diff --git a/compose/ui/ui-tooling/src/androidTest/java/androidx/compose/ui/tooling/inspector/ParameterFactoryTest.kt b/compose/ui/ui-tooling/src/androidTest/java/androidx/compose/ui/tooling/inspector/ParameterFactoryTest.kt
index d184a93..83459eb 100644
--- a/compose/ui/ui-tooling/src/androidTest/java/androidx/compose/ui/tooling/inspector/ParameterFactoryTest.kt
+++ b/compose/ui/ui-tooling/src/androidTest/java/androidx/compose/ui/tooling/inspector/ParameterFactoryTest.kt
@@ -70,7 +70,7 @@
 import androidx.compose.ui.unit.em
 import androidx.compose.ui.unit.sp
 import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.LargeTest
+import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
 import kotlinx.coroutines.runBlocking
@@ -82,7 +82,7 @@
 @Suppress("unused")
 private fun topLevelFunction() {}
 
-@LargeTest
+@MediumTest
 @RunWith(AndroidJUnit4::class)
 class ParameterFactoryTest {
     private val factory = ParameterFactory(InlineClassConverter())
@@ -554,6 +554,14 @@
     }
 
     @Test
+    fun testDoNotRecurseIntoAndroidAndJavaPackages() {
+        runBlocking {
+            assertThat(factory.create(node, "v1", java.net.URL("http://domain.com"))).isNull()
+            assertThat(factory.create(node, "v1", android.app.Notification())).isNull()
+        }
+    }
+
+    @Test
     fun testShadow() {
         assertThat(lookup(Shadow.None)).isEqualTo(ParameterType.String to "None")
         validate(factory.create(node, "shadow", Shadow(Color.Cyan, Offset.Zero, 2.5f))!!) {
diff --git a/compose/ui/ui-tooling/src/main/java/androidx/compose/ui/tooling/inspector/ParameterFactory.kt b/compose/ui/ui-tooling/src/main/java/androidx/compose/ui/tooling/inspector/ParameterFactory.kt
index f586339..ded432e 100644
--- a/compose/ui/ui-tooling/src/main/java/androidx/compose/ui/tooling/inspector/ParameterFactory.kt
+++ b/compose/ui/ui-tooling/src/main/java/androidx/compose/ui/tooling/inspector/ParameterFactory.kt
@@ -92,9 +92,9 @@
     }
 
     /**
-     * Do not decompose instances from these package prefixes.
+     * Do not decompose instances or lookup constants from these package prefixes
      */
-    private val ignoredPackagePrefixes = listOf("android.graphics.")
+    private val ignoredPackagePrefixes = listOf("android.", "java.", "javax.")
 
     var density = Density(1.0f)
 
@@ -129,7 +129,9 @@
     }
 
     private fun loadConstantsFrom(javaClass: Class<*>) {
-        if (valuesLoaded.contains(javaClass)) {
+        if (valuesLoaded.contains(javaClass) ||
+            ignoredPackagePrefixes.any { javaClass.name.startsWith(it) }
+        ) {
             return
         }
         val related = generateSequence(javaClass) { it.superclass }.plus(javaClass.interfaces)
diff --git a/compose/ui/ui-tooling/src/main/java/androidx/compose/ui/tooling/preview/ComposeViewAdapter.kt b/compose/ui/ui-tooling/src/main/java/androidx/compose/ui/tooling/preview/ComposeViewAdapter.kt
index 46d40c2..a0f97dc 100644
--- a/compose/ui/ui-tooling/src/main/java/androidx/compose/ui/tooling/preview/ComposeViewAdapter.kt
+++ b/compose/ui/ui-tooling/src/main/java/androidx/compose/ui/tooling/preview/ComposeViewAdapter.kt
@@ -27,7 +27,6 @@
 import androidx.annotation.VisibleForTesting
 import androidx.compose.animation.core.InternalAnimationApi
 import androidx.compose.animation.core.Transition
-import androidx.compose.runtime.AtomicReference
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composition
 import androidx.compose.runtime.CompositionLocalProvider
@@ -144,7 +143,12 @@
      * composition, we save it and throw it during onLayout, this allows Studio to catch it and
      * display it to the user.
      */
-    private val delayedException = AtomicReference<Throwable?>(null)
+    private var delayedException: Throwable? = null
+
+    /**
+     * A lock to take to access delayedException.
+     */
+    private val delayExceptionLock = Any()
 
     /**
      * The [Composable] to be rendered in the preview. It is initialized when this adapter
@@ -250,10 +254,12 @@
     override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
         super.onLayout(changed, left, top, right, bottom)
 
-        delayedException.getAndSet(null)?.let { exception ->
-            // There was a pending exception. Throw it here since Studio will catch it and show
-            // it to the user.
-            throw exception
+        synchronized(delayExceptionLock) {
+            delayedException?.let { exception ->
+                // There was a pending exception. Throw it here since Studio will catch it and show
+                // it to the user.
+                throw exception
+            }
         }
 
         processViewInfos()
@@ -455,7 +461,9 @@
                         while (exception is ReflectiveOperationException) {
                             exception = exception.cause ?: break
                         }
-                        delayedException.set(exception)
+                        synchronized(delayExceptionLock) {
+                            delayedException = exception
+                        }
                         throw t
                     }
                 }
diff --git a/compose/ui/ui-unit/api/current.txt b/compose/ui/ui-unit/api/current.txt
index ad601a9..747f176 100644
--- a/compose/ui/ui-unit/api/current.txt
+++ b/compose/ui/ui-unit/api/current.txt
@@ -96,7 +96,7 @@
   }
 
   public final class DpKt {
-    method @androidx.compose.runtime.Stable public static inline long DpOffset-ioHfwGI(float x, float y);
+    method @androidx.compose.runtime.Stable public static long DpOffset-ioHfwGI(float x, float y);
     method @androidx.compose.runtime.Stable public static inline float coerceAtLeast-ioHfwGI(float, float minimumValue);
     method @androidx.compose.runtime.Stable public static inline float coerceAtMost-ioHfwGI(float, float maximumValue);
     method @androidx.compose.runtime.Stable public static inline float coerceIn-qYQSm_w(float, float minimumValue, float maximumValue);
@@ -120,7 +120,6 @@
 
   @androidx.compose.runtime.Immutable public final inline class DpOffset {
     ctor public DpOffset();
-    method public static long constructor-impl(long packedValue);
     method public static long copy-ioHfwGI(long $this, optional float x, optional float y);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
@@ -162,7 +161,6 @@
     ctor public IntOffset();
     method @androidx.compose.runtime.Stable public static operator int component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static operator int component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-nOcc-ac(long $this, optional int x, optional int y);
     method @androidx.compose.runtime.Stable public static operator long div-nOcc-ac(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
@@ -185,7 +183,7 @@
   }
 
   public final class IntOffsetKt {
-    method @androidx.compose.runtime.Stable public static inline long IntOffset(int x, int y);
+    method @androidx.compose.runtime.Stable public static long IntOffset(int x, int y);
     method @androidx.compose.runtime.Stable public static long lerp-t0UgTr0(long start, long stop, float fraction);
     method @androidx.compose.runtime.Stable public static operator long minus-k5bmQ1s(long, long offset);
     method @androidx.compose.runtime.Stable public static operator long minus-tRj9Ofw(long, long offset);
@@ -266,7 +264,6 @@
     ctor public IntSize();
     method @androidx.compose.runtime.Stable public static inline operator int component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static inline operator int component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method @androidx.compose.runtime.Stable public static operator long div-YbymL2g(long $this, int other);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
@@ -299,13 +296,11 @@
   @androidx.compose.runtime.Immutable public final inline class TextUnit {
     ctor public TextUnit();
     method public static inline operator int compareTo--R2X_6o(long $this, long other);
-    method public static long constructor-impl(long packedValue);
     method public static inline operator long div-XSAIIZE(long $this, float other);
     method public static inline operator long div-XSAIIZE(long $this, double other);
     method public static inline operator long div-XSAIIZE(long $this, int other);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
-    method public long getPackedValue();
     method public static androidx.compose.ui.unit.TextUnitType getType-impl(long $this);
     method public static float getValue-impl(long $this);
     method @androidx.compose.runtime.Immutable public static inline int hashCode-impl(long p);
@@ -316,7 +311,6 @@
     method public static inline operator long times-XSAIIZE(long $this, int other);
     method public static String toString-impl(long $this);
     method public static inline operator long unaryMinus-XSAIIZE(long $this);
-    property public final long packedValue;
     field public static final androidx.compose.ui.unit.TextUnit.Companion Companion;
   }
 
@@ -351,12 +345,10 @@
     ctor public Velocity();
     method @androidx.compose.runtime.Stable public static operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-9UxMQ8M(long $this, optional float x, optional float y);
     method @androidx.compose.runtime.Stable public static operator long div-9UxMQ8M(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
-    method public long getPackedValue();
     method public static float getX-impl(long $this);
     method public static float getY-impl(long $this);
     method @androidx.compose.runtime.Immutable public static inline int hashCode-impl(long p);
@@ -366,7 +358,6 @@
     method @androidx.compose.runtime.Stable public static operator long times-9UxMQ8M(long $this, float operand);
     method public static String toString-impl(long $this);
     method @androidx.compose.runtime.Stable public static operator long unaryMinus-9UxMQ8M(long $this);
-    property public final long packedValue;
     field public static final androidx.compose.ui.unit.Velocity.Companion Companion;
   }
 
@@ -376,7 +367,7 @@
   }
 
   public final class VelocityKt {
-    method @androidx.compose.runtime.Stable public static inline long Velocity(float x, float y);
+    method @androidx.compose.runtime.Stable public static long Velocity(float x, float y);
   }
 
 }
diff --git a/compose/ui/ui-unit/api/public_plus_experimental_current.txt b/compose/ui/ui-unit/api/public_plus_experimental_current.txt
index ad601a9..747f176 100644
--- a/compose/ui/ui-unit/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-unit/api/public_plus_experimental_current.txt
@@ -96,7 +96,7 @@
   }
 
   public final class DpKt {
-    method @androidx.compose.runtime.Stable public static inline long DpOffset-ioHfwGI(float x, float y);
+    method @androidx.compose.runtime.Stable public static long DpOffset-ioHfwGI(float x, float y);
     method @androidx.compose.runtime.Stable public static inline float coerceAtLeast-ioHfwGI(float, float minimumValue);
     method @androidx.compose.runtime.Stable public static inline float coerceAtMost-ioHfwGI(float, float maximumValue);
     method @androidx.compose.runtime.Stable public static inline float coerceIn-qYQSm_w(float, float minimumValue, float maximumValue);
@@ -120,7 +120,6 @@
 
   @androidx.compose.runtime.Immutable public final inline class DpOffset {
     ctor public DpOffset();
-    method public static long constructor-impl(long packedValue);
     method public static long copy-ioHfwGI(long $this, optional float x, optional float y);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
@@ -162,7 +161,6 @@
     ctor public IntOffset();
     method @androidx.compose.runtime.Stable public static operator int component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static operator int component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-nOcc-ac(long $this, optional int x, optional int y);
     method @androidx.compose.runtime.Stable public static operator long div-nOcc-ac(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
@@ -185,7 +183,7 @@
   }
 
   public final class IntOffsetKt {
-    method @androidx.compose.runtime.Stable public static inline long IntOffset(int x, int y);
+    method @androidx.compose.runtime.Stable public static long IntOffset(int x, int y);
     method @androidx.compose.runtime.Stable public static long lerp-t0UgTr0(long start, long stop, float fraction);
     method @androidx.compose.runtime.Stable public static operator long minus-k5bmQ1s(long, long offset);
     method @androidx.compose.runtime.Stable public static operator long minus-tRj9Ofw(long, long offset);
@@ -266,7 +264,6 @@
     ctor public IntSize();
     method @androidx.compose.runtime.Stable public static inline operator int component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static inline operator int component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method @androidx.compose.runtime.Stable public static operator long div-YbymL2g(long $this, int other);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
@@ -299,13 +296,11 @@
   @androidx.compose.runtime.Immutable public final inline class TextUnit {
     ctor public TextUnit();
     method public static inline operator int compareTo--R2X_6o(long $this, long other);
-    method public static long constructor-impl(long packedValue);
     method public static inline operator long div-XSAIIZE(long $this, float other);
     method public static inline operator long div-XSAIIZE(long $this, double other);
     method public static inline operator long div-XSAIIZE(long $this, int other);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
-    method public long getPackedValue();
     method public static androidx.compose.ui.unit.TextUnitType getType-impl(long $this);
     method public static float getValue-impl(long $this);
     method @androidx.compose.runtime.Immutable public static inline int hashCode-impl(long p);
@@ -316,7 +311,6 @@
     method public static inline operator long times-XSAIIZE(long $this, int other);
     method public static String toString-impl(long $this);
     method public static inline operator long unaryMinus-XSAIIZE(long $this);
-    property public final long packedValue;
     field public static final androidx.compose.ui.unit.TextUnit.Companion Companion;
   }
 
@@ -351,12 +345,10 @@
     ctor public Velocity();
     method @androidx.compose.runtime.Stable public static operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-9UxMQ8M(long $this, optional float x, optional float y);
     method @androidx.compose.runtime.Stable public static operator long div-9UxMQ8M(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
-    method public long getPackedValue();
     method public static float getX-impl(long $this);
     method public static float getY-impl(long $this);
     method @androidx.compose.runtime.Immutable public static inline int hashCode-impl(long p);
@@ -366,7 +358,6 @@
     method @androidx.compose.runtime.Stable public static operator long times-9UxMQ8M(long $this, float operand);
     method public static String toString-impl(long $this);
     method @androidx.compose.runtime.Stable public static operator long unaryMinus-9UxMQ8M(long $this);
-    property public final long packedValue;
     field public static final androidx.compose.ui.unit.Velocity.Companion Companion;
   }
 
@@ -376,7 +367,7 @@
   }
 
   public final class VelocityKt {
-    method @androidx.compose.runtime.Stable public static inline long Velocity(float x, float y);
+    method @androidx.compose.runtime.Stable public static long Velocity(float x, float y);
   }
 
 }
diff --git a/compose/ui/ui-unit/api/restricted_current.txt b/compose/ui/ui-unit/api/restricted_current.txt
index 0e2632f..5e27162 100644
--- a/compose/ui/ui-unit/api/restricted_current.txt
+++ b/compose/ui/ui-unit/api/restricted_current.txt
@@ -96,7 +96,7 @@
   }
 
   public final class DpKt {
-    method @androidx.compose.runtime.Stable public static inline long DpOffset-ioHfwGI(float x, float y);
+    method @androidx.compose.runtime.Stable public static long DpOffset-ioHfwGI(float x, float y);
     method @androidx.compose.runtime.Stable public static inline float coerceAtLeast-ioHfwGI(float, float minimumValue);
     method @androidx.compose.runtime.Stable public static inline float coerceAtMost-ioHfwGI(float, float maximumValue);
     method @androidx.compose.runtime.Stable public static inline float coerceIn-qYQSm_w(float, float minimumValue, float maximumValue);
@@ -120,7 +120,6 @@
 
   @androidx.compose.runtime.Immutable public final inline class DpOffset {
     ctor public DpOffset();
-    method public static long constructor-impl(long packedValue);
     method public static long copy-ioHfwGI(long $this, optional float x, optional float y);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
@@ -162,7 +161,6 @@
     ctor public IntOffset();
     method @androidx.compose.runtime.Stable public static operator int component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static operator int component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-nOcc-ac(long $this, optional int x, optional int y);
     method @androidx.compose.runtime.Stable public static operator long div-nOcc-ac(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
@@ -185,7 +183,7 @@
   }
 
   public final class IntOffsetKt {
-    method @androidx.compose.runtime.Stable public static inline long IntOffset(int x, int y);
+    method @androidx.compose.runtime.Stable public static long IntOffset(int x, int y);
     method @androidx.compose.runtime.Stable public static long lerp-t0UgTr0(long start, long stop, float fraction);
     method @androidx.compose.runtime.Stable public static operator long minus-k5bmQ1s(long, long offset);
     method @androidx.compose.runtime.Stable public static operator long minus-tRj9Ofw(long, long offset);
@@ -266,7 +264,6 @@
     ctor public IntSize();
     method @androidx.compose.runtime.Stable public static inline operator int component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static inline operator int component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method @androidx.compose.runtime.Stable public static operator long div-YbymL2g(long $this, int other);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
@@ -299,13 +296,11 @@
   @androidx.compose.runtime.Immutable public final inline class TextUnit {
     ctor public TextUnit();
     method public static inline operator int compareTo--R2X_6o(long $this, long other);
-    method public static long constructor-impl(long packedValue);
     method public static inline operator long div-XSAIIZE(long $this, float other);
     method public static inline operator long div-XSAIIZE(long $this, double other);
     method public static inline operator long div-XSAIIZE(long $this, int other);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
-    method public long getPackedValue();
     method public static androidx.compose.ui.unit.TextUnitType getType-impl(long $this);
     method public static float getValue-impl(long $this);
     method @androidx.compose.runtime.Immutable public static inline int hashCode-impl(long p);
@@ -316,7 +311,6 @@
     method public static inline operator long times-XSAIIZE(long $this, int other);
     method public static String toString-impl(long $this);
     method public static inline operator long unaryMinus-XSAIIZE(long $this);
-    property public final long packedValue;
     field public static final androidx.compose.ui.unit.TextUnit.Companion Companion;
   }
 
@@ -338,7 +332,7 @@
     method public static inline boolean isSpecified--R2X_6o(long);
     method public static boolean isUnspecified--R2X_6o(long);
     method @androidx.compose.runtime.Stable public static long lerp-KeuwX78(long start, long stop, float fraction);
-    method @kotlin.PublishedApi internal static inline long pack(long unitType, float v);
+    method @kotlin.PublishedApi internal static long pack(long unitType, float v);
     method public static inline long takeOrElse-bAewZlA(long, kotlin.jvm.functions.Function0<androidx.compose.ui.unit.TextUnit> block);
     method @androidx.compose.runtime.Stable public static inline operator long times-0PRCd3Q(double, long other);
     method @androidx.compose.runtime.Stable public static inline operator long times-Ew26DjI(float, long other);
@@ -355,12 +349,10 @@
     ctor public Velocity();
     method @androidx.compose.runtime.Stable public static operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-9UxMQ8M(long $this, optional float x, optional float y);
     method @androidx.compose.runtime.Stable public static operator long div-9UxMQ8M(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
-    method public long getPackedValue();
     method public static float getX-impl(long $this);
     method public static float getY-impl(long $this);
     method @androidx.compose.runtime.Immutable public static inline int hashCode-impl(long p);
@@ -370,7 +362,6 @@
     method @androidx.compose.runtime.Stable public static operator long times-9UxMQ8M(long $this, float operand);
     method public static String toString-impl(long $this);
     method @androidx.compose.runtime.Stable public static operator long unaryMinus-9UxMQ8M(long $this);
-    property public final long packedValue;
     field public static final androidx.compose.ui.unit.Velocity.Companion Companion;
   }
 
@@ -380,7 +371,7 @@
   }
 
   public final class VelocityKt {
-    method @androidx.compose.runtime.Stable public static inline long Velocity(float x, float y);
+    method @androidx.compose.runtime.Stable public static long Velocity(float x, float y);
   }
 
 }
diff --git a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Dp.kt b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Dp.kt
index adca0dd..fb94b89 100644
--- a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Dp.kt
+++ b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Dp.kt
@@ -249,12 +249,19 @@
 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
 /**
+ * Constructs a [DpOffset] from [x] and [y] position [Dp] values.
+ */
+@Stable
+fun DpOffset(x: Dp, y: Dp): DpOffset = DpOffset(packFloats(x.value, y.value))
+
+/**
  * A two-dimensional offset using [Dp] for units
  */
 @OptIn(ExperimentalUnsignedTypes::class)
 @Suppress("EXPERIMENTAL_FEATURE_WARNING")
 @Immutable
-inline class DpOffset(@PublishedApi internal val packedValue: Long) {
+inline class DpOffset internal constructor(@PublishedApi internal val packedValue: Long) {
+
     /**
      * The horizontal aspect of the offset in [Dp]
      */
@@ -301,13 +308,6 @@
 }
 
 /**
- * Constructs a [DpOffset] from [x] and [y] position [Dp] values.
- */
-@OptIn(ExperimentalUnsignedTypes::class)
-@Stable
-inline fun DpOffset(x: Dp, y: Dp): DpOffset = DpOffset(packFloats(x.value, y.value))
-
-/**
  * Linearly interpolate between two [DpOffset]s.
  *
  * The [fraction] argument represents position on the timeline, with 0.0 meaning
diff --git a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntOffset.kt b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntOffset.kt
index 803cf62..97f0e72 100644
--- a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntOffset.kt
+++ b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntOffset.kt
@@ -28,12 +28,18 @@
 import kotlin.math.roundToInt
 
 /**
+ * Constructs a [IntOffset] from [x] and [y] position [Int] values.
+ */
+@Stable
+fun IntOffset(x: Int, y: Int): IntOffset =
+    IntOffset(packInts(x, y))
+
+/**
  * A two-dimensional position using [Int] pixels for units
  */
 @Immutable
-inline class IntOffset(
-    @PublishedApi internal val packedValue: Long
-) {
+inline class IntOffset internal constructor(@PublishedApi internal val packedValue: Long) {
+
     /**
      * The horizontal aspect of the position in [Int] pixels.
      */
@@ -125,13 +131,6 @@
 }
 
 /**
- * Constructs a [IntOffset] from [x] and [y] position [Int] values.
- */
-@Stable
-inline fun IntOffset(x: Int, y: Int): IntOffset =
-    IntOffset(packInts(x, y))
-
-/**
  * Linearly interpolate between two [IntOffset]s.
  *
  * The [fraction] argument represents position on the timeline, with 0.0 meaning
diff --git a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntSize.kt b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntSize.kt
index a65577d..bc7880e 100644
--- a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntSize.kt
+++ b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntSize.kt
@@ -26,10 +26,17 @@
 import androidx.compose.ui.util.unpackInt2
 
 /**
+ * Constructs an [IntSize] from width and height [Int] values.
+ */
+@Stable
+fun IntSize(width: Int, height: Int): IntSize = IntSize(packInts(width, height))
+
+/**
  * A two-dimensional size class used for measuring in [Int] pixels.
  */
 @Immutable
-inline class IntSize(@PublishedApi internal val packedValue: Long) {
+inline class IntSize internal constructor(@PublishedApi internal val packedValue: Long) {
+
     /**
      * The horizontal aspect of the size in [Int] pixels.
      */
@@ -91,13 +98,6 @@
 }
 
 /**
- * Constructs an [IntSize] from width and height [Int] values.
- */
-@Stable
-fun IntSize(width: Int, height: Int): IntSize =
-    IntSize(packInts(width, height))
-
-/**
  * Returns the [IntOffset] of the center of the rect from the point of [0, 0]
  * with this [IntSize].
  */
diff --git a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/TextUnit.kt b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/TextUnit.kt
index a83bf57f..fb512b1 100644
--- a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/TextUnit.kt
+++ b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/TextUnit.kt
@@ -61,7 +61,7 @@
  */
 @Suppress("EXPERIMENTAL_FEATURE_WARNING")
 @Immutable
-inline class TextUnit(val packedValue: Long) {
+inline class TextUnit internal constructor(internal val packedValue: Long) {
     /**
      * This is the same as multiplying the [TextUnit] by -1.0.
      *
@@ -315,7 +315,7 @@
 }
 
 @PublishedApi
-internal inline fun pack(unitType: Long, v: Float): TextUnit =
+internal fun pack(unitType: Long, v: Float): TextUnit =
     TextUnit(unitType or (v.toBits().toLong() and 0xFFFF_FFFFL))
 
 @PublishedApi
diff --git a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Velocity.kt b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Velocity.kt
index 6bd391a..a0ef63e 100644
--- a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Velocity.kt
+++ b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Velocity.kt
@@ -28,16 +28,16 @@
  * @param x Horizontal component of the velocity in pixels per second
  * @param y Vertical component of the velocity in pixels per second
  */
-@Suppress("NOTHING_TO_INLINE")
 @Stable
-inline fun Velocity(x: Float, y: Float) = Velocity(packFloats(x, y))
+fun Velocity(x: Float, y: Float) = Velocity(packFloats(x, y))
 
 /**
  * A two dimensional velocity in pixels per second.
  */
 @Suppress("EXPERIMENTAL_FEATURE_WARNING")
 @Immutable
-inline class Velocity(val packedValue: Long) {
+inline class Velocity internal constructor(private val packedValue: Long) {
+
     /**
      * The horizontal component of the velocity in pixels per second.
      */
diff --git a/compose/ui/ui-viewbinding/api/current.txt b/compose/ui/ui-viewbinding/api/current.txt
index 899836d..742107f 100644
--- a/compose/ui/ui-viewbinding/api/current.txt
+++ b/compose/ui/ui-viewbinding/api/current.txt
@@ -2,7 +2,7 @@
 package androidx.compose.ui.viewinterop {
 
   public final class AndroidViewBindingKt {
-    method @androidx.compose.runtime.Composable public static <T extends androidx.viewbinding.ViewBinding> void AndroidViewBinding(kotlin.jvm.functions.Function3<? super android.view.LayoutInflater,? super android.view.ViewGroup,? super java.lang.Boolean,? extends T> bindingBlock, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
+    method @androidx.compose.runtime.Composable public static <T extends androidx.viewbinding.ViewBinding> void AndroidViewBinding(kotlin.jvm.functions.Function3<? super android.view.LayoutInflater,? super android.view.ViewGroup,? super java.lang.Boolean,? extends T> factory, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
   }
 
 }
diff --git a/compose/ui/ui-viewbinding/api/public_plus_experimental_current.txt b/compose/ui/ui-viewbinding/api/public_plus_experimental_current.txt
index 899836d..742107f 100644
--- a/compose/ui/ui-viewbinding/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-viewbinding/api/public_plus_experimental_current.txt
@@ -2,7 +2,7 @@
 package androidx.compose.ui.viewinterop {
 
   public final class AndroidViewBindingKt {
-    method @androidx.compose.runtime.Composable public static <T extends androidx.viewbinding.ViewBinding> void AndroidViewBinding(kotlin.jvm.functions.Function3<? super android.view.LayoutInflater,? super android.view.ViewGroup,? super java.lang.Boolean,? extends T> bindingBlock, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
+    method @androidx.compose.runtime.Composable public static <T extends androidx.viewbinding.ViewBinding> void AndroidViewBinding(kotlin.jvm.functions.Function3<? super android.view.LayoutInflater,? super android.view.ViewGroup,? super java.lang.Boolean,? extends T> factory, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
   }
 
 }
diff --git a/compose/ui/ui-viewbinding/api/restricted_current.txt b/compose/ui/ui-viewbinding/api/restricted_current.txt
index 899836d..742107f 100644
--- a/compose/ui/ui-viewbinding/api/restricted_current.txt
+++ b/compose/ui/ui-viewbinding/api/restricted_current.txt
@@ -2,7 +2,7 @@
 package androidx.compose.ui.viewinterop {
 
   public final class AndroidViewBindingKt {
-    method @androidx.compose.runtime.Composable public static <T extends androidx.viewbinding.ViewBinding> void AndroidViewBinding(kotlin.jvm.functions.Function3<? super android.view.LayoutInflater,? super android.view.ViewGroup,? super java.lang.Boolean,? extends T> bindingBlock, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
+    method @androidx.compose.runtime.Composable public static <T extends androidx.viewbinding.ViewBinding> void AndroidViewBinding(kotlin.jvm.functions.Function3<? super android.view.LayoutInflater,? super android.view.ViewGroup,? super java.lang.Boolean,? extends T> factory, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
   }
 
 }
diff --git a/compose/ui/ui-viewbinding/src/main/java/androidx/compose/ui/viewinterop/AndroidViewBinding.kt b/compose/ui/ui-viewbinding/src/main/java/androidx/compose/ui/viewinterop/AndroidViewBinding.kt
index 1f8694e..55eaac8 100644
--- a/compose/ui/ui-viewbinding/src/main/java/androidx/compose/ui/viewinterop/AndroidViewBinding.kt
+++ b/compose/ui/ui-viewbinding/src/main/java/androidx/compose/ui/viewinterop/AndroidViewBinding.kt
@@ -29,24 +29,24 @@
 
 /**
  * Composes an Android layout resource in the presence of [ViewBinding]. The binding is obtained
- * from the [bindingBlock] block, which will be called exactly once to obtain the [ViewBinding]
+ * from the [factory] block, which will be called exactly once to obtain the [ViewBinding]
  * to be composed, and it is also guaranteed to be invoked on the UI thread.
  * Therefore, in addition to creating the [ViewBinding], the block can also be used
  * to perform one-off initializations and [View] constant properties' setting.
  * The [update] block can be run multiple times (on the UI thread as well) due to recomposition,
  * and it is the right place to set [View] properties depending on state. When state changes,
  * the block will be reexecuted to set the new properties. Note the block will also be ran once
- * right after the [bindingBlock] block completes.
+ * right after the [factory] block completes.
  *
  * @sample androidx.compose.ui.samples.AndroidViewBindingSample
  *
- * @param bindingBlock The block creating the [ViewBinding] to be composed.
+ * @param factory The block creating the [ViewBinding] to be composed.
  * @param modifier The modifier to be applied to the layout.
  * @param update The callback to be invoked after the layout is inflated.
  */
 @Composable
 fun <T : ViewBinding> AndroidViewBinding(
-    bindingBlock: (inflater: LayoutInflater, parent: ViewGroup, attachToParent: Boolean) -> T,
+    factory: (inflater: LayoutInflater, parent: ViewGroup, attachToParent: Boolean) -> T,
     modifier: Modifier = Modifier,
     update: T.() -> Unit = {}
 ) {
@@ -54,13 +54,13 @@
     val viewBlock: (Context) -> View = remember {
         { context ->
             val inflater = LayoutInflater.from(context)
-            val viewBinding = bindingBlock(inflater, FrameLayout(context), false)
+            val viewBinding = factory(inflater, FrameLayout(context), false)
             viewBindingRef.value = viewBinding
             viewBinding.root
         }
     }
     AndroidView(
-        viewBlock = viewBlock,
+        factory = viewBlock,
         modifier = modifier,
         update = { viewBindingRef.value?.update() }
     )
diff --git a/compose/ui/ui/api/current.txt b/compose/ui/ui/api/current.txt
index acb6aa9..e83c164 100644
--- a/compose/ui/ui/api/current.txt
+++ b/compose/ui/ui/api/current.txt
@@ -493,7 +493,6 @@
     ctor public TransformOrigin();
     method @androidx.compose.runtime.Stable public static inline operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static inline operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-SzJe1aQ(long $this, optional float pivotFractionX, optional float pivotFractionY);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
@@ -510,7 +509,7 @@
   }
 
   public final class TransformOriginKt {
-    method public static inline long TransformOrigin(float pivotFractionX, float pivotFractionY);
+    method public static long TransformOrigin(float pivotFractionX, float pivotFractionY);
   }
 
 }
@@ -1374,10 +1373,6 @@
 
 package androidx.compose.ui.input.pointer {
 
-  public final class AndroidMouse_androidKt {
-    method public static boolean isMouseInput();
-  }
-
   @kotlin.coroutines.RestrictsSuspension public interface AwaitPointerEventScope extends androidx.compose.ui.unit.Density {
     method public suspend Object? awaitPointerEvent(optional androidx.compose.ui.input.pointer.PointerEventPass pass, optional kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerEvent> p);
     method public androidx.compose.ui.input.pointer.PointerEvent getCurrentEvent();
@@ -1405,9 +1400,6 @@
   public final class MotionEventAdapter_androidKt {
   }
 
-  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level, message="This is a temporary API and should be removed after proper mouse handling is " + "settled (b/171402426).") @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget}) public @interface MouseTemporaryApi {
-  }
-
   public final class PointerEvent {
     ctor public PointerEvent(java.util.List<androidx.compose.ui.input.pointer.PointerInputChange> changes);
     method public java.util.List<androidx.compose.ui.input.pointer.PointerInputChange> component1();
@@ -1618,18 +1610,14 @@
   }
 
   public interface LayoutCoordinates {
-    method @Deprecated public androidx.compose.ui.geometry.Rect childBoundingBox(androidx.compose.ui.layout.LayoutCoordinates child);
-    method @Deprecated public long childToLocal-YJiYy8w(androidx.compose.ui.layout.LayoutCoordinates child, long childLocal);
-    method public operator int get(androidx.compose.ui.layout.AlignmentLine line);
+    method public operator int get(androidx.compose.ui.layout.AlignmentLine alignmentLine);
     method public androidx.compose.ui.layout.LayoutCoordinates? getParentCoordinates();
     method public androidx.compose.ui.layout.LayoutCoordinates? getParentLayoutCoordinates();
     method public java.util.Set<androidx.compose.ui.layout.AlignmentLine> getProvidedAlignmentLines();
     method public long getSize-YbymL2g();
-    method @Deprecated public long globalToLocal-k-4lQ0M(long global);
     method public boolean isAttached();
     method public androidx.compose.ui.geometry.Rect localBoundingBoxOf(androidx.compose.ui.layout.LayoutCoordinates sourceCoordinates, optional boolean clipBounds);
     method public long localPositionOf-YJiYy8w(androidx.compose.ui.layout.LayoutCoordinates sourceCoordinates, long relativeToSource);
-    method @Deprecated public long localToGlobal-k-4lQ0M(long local);
     method public long localToRoot-k-4lQ0M(long relativeToLocal);
     method public long localToWindow-k-4lQ0M(long relativeToLocal);
     method public long windowToLocal-k-4lQ0M(long relativeToWindow);
@@ -1641,14 +1629,10 @@
   }
 
   public final class LayoutCoordinatesKt {
+    method public static androidx.compose.ui.geometry.Rect boundsInParent(androidx.compose.ui.layout.LayoutCoordinates);
     method public static androidx.compose.ui.geometry.Rect boundsInRoot(androidx.compose.ui.layout.LayoutCoordinates);
     method public static androidx.compose.ui.geometry.Rect boundsInWindow(androidx.compose.ui.layout.LayoutCoordinates);
-    method public static androidx.compose.ui.geometry.Rect getBoundsInParent(androidx.compose.ui.layout.LayoutCoordinates);
-    method @Deprecated public static androidx.compose.ui.geometry.Rect getBoundsInRoot(androidx.compose.ui.layout.LayoutCoordinates);
-    method @Deprecated public static androidx.compose.ui.geometry.Rect getGlobalBounds(androidx.compose.ui.layout.LayoutCoordinates);
-    method @Deprecated public static inline long getGlobalPosition(androidx.compose.ui.layout.LayoutCoordinates);
-    method public static long getPositionInParent(androidx.compose.ui.layout.LayoutCoordinates);
-    method @Deprecated public static inline long getPositionInRoot(androidx.compose.ui.layout.LayoutCoordinates);
+    method public static long positionInParent(androidx.compose.ui.layout.LayoutCoordinates);
     method public static long positionInRoot(androidx.compose.ui.layout.LayoutCoordinates);
     method public static long positionInWindow(androidx.compose.ui.layout.LayoutCoordinates);
   }
@@ -1680,12 +1664,8 @@
   }
 
   public final class LayoutKt {
-    method @androidx.compose.runtime.Composable public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> content, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> minIntrinsicWidthMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> minIntrinsicHeightMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> maxIntrinsicWidthMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> maxIntrinsicHeightMeasureBlock, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.Measurable>,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
-    method @androidx.compose.runtime.Composable public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> content, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.Measurable>,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
-    method @androidx.compose.runtime.Composable public static inline void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> content, androidx.compose.ui.node.MeasureBlocks measureBlocks, optional androidx.compose.ui.Modifier modifier);
-    method public static androidx.compose.ui.node.MeasureBlocks MeasuringIntrinsicsMeasureBlocks(kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.Measurable>,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
-    method @Deprecated @androidx.compose.runtime.Composable public static void MultiMeasureLayout(optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.Measurable>,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
-    method public static androidx.compose.ui.node.MeasureBlocks measureBlocksOf(kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> minIntrinsicWidthMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> minIntrinsicHeightMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> maxIntrinsicWidthMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> maxIntrinsicHeightMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.Measurable>,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
+    method @androidx.compose.runtime.Composable public static inline void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> content, optional androidx.compose.ui.Modifier modifier, androidx.compose.ui.layout.MeasurePolicy measurePolicy);
+    method @Deprecated @androidx.compose.runtime.Composable public static void MultiMeasureLayout(optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> content, androidx.compose.ui.layout.MeasurePolicy measurePolicy);
   }
 
   public interface LayoutModifier extends androidx.compose.ui.Modifier.Element {
@@ -1704,6 +1684,14 @@
     method public androidx.compose.ui.layout.Placeable measure-BRTryo0(long constraints);
   }
 
+  @androidx.compose.runtime.Stable public fun interface MeasurePolicy {
+    method public default int maxIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int width);
+    method public default int maxIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int height);
+    method public androidx.compose.ui.layout.MeasureResult measure-8A2P9vY(androidx.compose.ui.layout.MeasureScope, java.util.List<? extends androidx.compose.ui.layout.Measurable> measurables, long constraints);
+    method public default int minIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int width);
+    method public default int minIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int height);
+  }
+
   public interface MeasureResult {
     method public java.util.Map<androidx.compose.ui.layout.AlignmentLine,java.lang.Integer> getAlignmentLines();
     method public int getHeight();
@@ -1721,16 +1709,12 @@
   public final class MeasureScopeKt {
   }
 
-  public final inline class Measured {
-    ctor public Measured();
-    method public static androidx.compose.ui.layout.Placeable! constructor-impl(androidx.compose.ui.layout.Placeable placeable);
-    method public static inline boolean equals-impl(androidx.compose.ui.layout.Placeable! p, Object? p1);
-    method public static boolean equals-impl0(androidx.compose.ui.layout.Placeable p1, androidx.compose.ui.layout.Placeable p2);
-    method public static operator int get-impl(androidx.compose.ui.layout.Placeable $this, androidx.compose.ui.layout.AlignmentLine alignmentLine);
-    method public static int getHeight-impl(androidx.compose.ui.layout.Placeable! $this);
-    method public static int getWidth-impl(androidx.compose.ui.layout.Placeable! $this);
-    method public static inline int hashCode-impl(androidx.compose.ui.layout.Placeable! p);
-    method public static inline String! toString-impl(androidx.compose.ui.layout.Placeable! p);
+  public interface Measured {
+    method public operator int get(androidx.compose.ui.layout.AlignmentLine alignmentLine);
+    method public int getMeasuredHeight();
+    method public int getMeasuredWidth();
+    property public abstract int measuredHeight;
+    property public abstract int measuredWidth;
   }
 
   public final class ModifierInfo {
@@ -1763,12 +1747,13 @@
     method public Object? modifyParentData(androidx.compose.ui.unit.Density, Object? parentData);
   }
 
-  public abstract class Placeable {
+  public abstract class Placeable implements androidx.compose.ui.layout.Measured {
     ctor public Placeable();
-    method public abstract operator int get(androidx.compose.ui.layout.AlignmentLine line);
     method protected final long getApparentToRealOffset-nOcc-ac();
     method public final int getHeight();
+    method public int getMeasuredHeight();
     method protected final long getMeasuredSize-YbymL2g();
+    method public int getMeasuredWidth();
     method protected final long getMeasurementConstraints-msEJaDk();
     method public final int getWidth();
     method protected abstract void placeAt-rMeLuDI(long position, float zIndex, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.GraphicsLayerScope,kotlin.Unit>? layerBlock);
@@ -1776,7 +1761,9 @@
     method protected final void setMeasurementConstraints-BRTryo0(long p);
     property protected final long apparentToRealOffset;
     property public final int height;
+    property public int measuredHeight;
     property protected final long measuredSize;
+    property public int measuredWidth;
     property protected final long measurementConstraints;
     property public final int width;
   }
@@ -1812,7 +1799,6 @@
     ctor public ScaleFactor();
     method @androidx.compose.runtime.Stable public static inline operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static inline operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-_hLwfpc(long $this, optional float scaleX, optional float scaleY);
     method @androidx.compose.runtime.Stable public static operator long div-_hLwfpc(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
@@ -1842,7 +1828,7 @@
   }
 
   public final class SubcomposeLayoutKt {
-    method @androidx.compose.runtime.Composable public static void SubcomposeLayout(optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.layout.SubcomposeMeasureScope,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
+    method @androidx.compose.runtime.Composable public static void SubcomposeLayout(optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.layout.SubcomposeMeasureScope,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measurePolicy);
   }
 
   public interface SubcomposeMeasureScope extends androidx.compose.ui.layout.MeasureScope {
@@ -1866,14 +1852,6 @@
   public final class LayoutNodeKt {
   }
 
-  public interface MeasureBlocks {
-    method public int maxIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope intrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int w);
-    method public int maxIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope intrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int h);
-    method public androidx.compose.ui.layout.MeasureResult measure-8A2P9vY(androidx.compose.ui.layout.MeasureScope measureScope, java.util.List<? extends androidx.compose.ui.layout.Measurable> measurables, long constraints);
-    method public int minIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope intrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int w);
-    method public int minIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope intrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int h);
-  }
-
   public final class Ref<T> {
     ctor public Ref();
     method public T? getValue();
@@ -1918,6 +1896,10 @@
     property public final boolean showLayoutBounds;
   }
 
+  public interface AccessibilityManager {
+    method public long calculateRecommendedTimeoutMillis(long originalTimeoutMillis, optional boolean containsIcons, optional boolean containsText, optional boolean containsControls);
+  }
+
   public final class AndroidClipboardManager_androidKt {
   }
 
@@ -1993,6 +1975,7 @@
   }
 
   public final class CompositionLocalsKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.AccessibilityManager> getLocalAccessibilityManager();
     method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.Autofill> getLocalAutofill();
     method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.AutofillTree> getLocalAutofillTree();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ClipboardManager> getLocalClipboardManager();
@@ -2357,31 +2340,31 @@
   }
 
   public final class SemanticsNode {
-    method public int getAlignmentLinePosition(androidx.compose.ui.layout.AlignmentLine line);
+    method public int getAlignmentLinePosition(androidx.compose.ui.layout.AlignmentLine alignmentLine);
     method public androidx.compose.ui.geometry.Rect getBoundsInRoot();
+    method public androidx.compose.ui.geometry.Rect getBoundsInWindow();
     method public java.util.List<androidx.compose.ui.semantics.SemanticsNode> getChildren();
     method public androidx.compose.ui.semantics.SemanticsConfiguration getConfig();
-    method public androidx.compose.ui.geometry.Rect getGlobalBounds();
-    method public long getGlobalPosition-F1C5BW0();
     method public int getId();
     method public androidx.compose.ui.layout.LayoutInfo getLayoutInfo();
     method public boolean getMergingEnabled();
     method public androidx.compose.ui.semantics.SemanticsNode? getParent();
     method public long getPositionInRoot-F1C5BW0();
+    method public long getPositionInWindow-F1C5BW0();
     method public androidx.compose.ui.node.RootForTest? getRoot();
     method public long getSize-YbymL2g();
     method public boolean isRoot();
     property public final androidx.compose.ui.geometry.Rect boundsInRoot;
+    property public final androidx.compose.ui.geometry.Rect boundsInWindow;
     property public final java.util.List<androidx.compose.ui.semantics.SemanticsNode> children;
     property public final androidx.compose.ui.semantics.SemanticsConfiguration config;
-    property public final androidx.compose.ui.geometry.Rect globalBounds;
-    property public final long globalPosition;
     property public final int id;
     property public final boolean isRoot;
     property public final androidx.compose.ui.layout.LayoutInfo layoutInfo;
     property public final boolean mergingEnabled;
     property public final androidx.compose.ui.semantics.SemanticsNode? parent;
     property public final long positionInRoot;
+    property public final long positionInWindow;
     property public final androidx.compose.ui.node.RootForTest? root;
     property public final long size;
   }
@@ -2415,6 +2398,7 @@
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getPassword();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.ProgressBarRangeInfo> getProgressBarRangeInfo();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.Role> getRole();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getSelectableGroup();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getSelected();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> getStateDescription();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> getTestTag();
@@ -2436,6 +2420,7 @@
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> Password;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.ProgressBarRangeInfo> ProgressBarRangeInfo;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.Role> Role;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> SelectableGroup;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Selected;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> StateDescription;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> TestTag;
@@ -2479,6 +2464,7 @@
     method public static void pasteText(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
     method public static void popup(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static void scrollBy(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,java.lang.Boolean>? action);
+    method public static void selectableGroup(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static void setContentDescription(androidx.compose.ui.semantics.SemanticsPropertyReceiver, String p);
     method public static void setCustomActions(androidx.compose.ui.semantics.SemanticsPropertyReceiver, java.util.List<androidx.compose.ui.semantics.CustomAccessibilityAction> p);
     method public static void setEditableText(androidx.compose.ui.semantics.SemanticsPropertyReceiver, androidx.compose.ui.text.AnnotatedString p);
@@ -2545,7 +2531,7 @@
   }
 
   public final class AndroidView_androidKt {
-    method @androidx.compose.runtime.Composable public static <T extends android.view.View> void AndroidView(kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> viewBlock, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
+    method @androidx.compose.runtime.Composable public static <T extends android.view.View> void AndroidView(kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> factory, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
     method public static kotlin.jvm.functions.Function1<android.view.View,kotlin.Unit> getNoOpUpdate();
   }
 
diff --git a/compose/ui/ui/api/public_plus_experimental_current.txt b/compose/ui/ui/api/public_plus_experimental_current.txt
index acb6aa9..e83c164 100644
--- a/compose/ui/ui/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui/api/public_plus_experimental_current.txt
@@ -493,7 +493,6 @@
     ctor public TransformOrigin();
     method @androidx.compose.runtime.Stable public static inline operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static inline operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-SzJe1aQ(long $this, optional float pivotFractionX, optional float pivotFractionY);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
@@ -510,7 +509,7 @@
   }
 
   public final class TransformOriginKt {
-    method public static inline long TransformOrigin(float pivotFractionX, float pivotFractionY);
+    method public static long TransformOrigin(float pivotFractionX, float pivotFractionY);
   }
 
 }
@@ -1374,10 +1373,6 @@
 
 package androidx.compose.ui.input.pointer {
 
-  public final class AndroidMouse_androidKt {
-    method public static boolean isMouseInput();
-  }
-
   @kotlin.coroutines.RestrictsSuspension public interface AwaitPointerEventScope extends androidx.compose.ui.unit.Density {
     method public suspend Object? awaitPointerEvent(optional androidx.compose.ui.input.pointer.PointerEventPass pass, optional kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerEvent> p);
     method public androidx.compose.ui.input.pointer.PointerEvent getCurrentEvent();
@@ -1405,9 +1400,6 @@
   public final class MotionEventAdapter_androidKt {
   }
 
-  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level, message="This is a temporary API and should be removed after proper mouse handling is " + "settled (b/171402426).") @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget}) public @interface MouseTemporaryApi {
-  }
-
   public final class PointerEvent {
     ctor public PointerEvent(java.util.List<androidx.compose.ui.input.pointer.PointerInputChange> changes);
     method public java.util.List<androidx.compose.ui.input.pointer.PointerInputChange> component1();
@@ -1618,18 +1610,14 @@
   }
 
   public interface LayoutCoordinates {
-    method @Deprecated public androidx.compose.ui.geometry.Rect childBoundingBox(androidx.compose.ui.layout.LayoutCoordinates child);
-    method @Deprecated public long childToLocal-YJiYy8w(androidx.compose.ui.layout.LayoutCoordinates child, long childLocal);
-    method public operator int get(androidx.compose.ui.layout.AlignmentLine line);
+    method public operator int get(androidx.compose.ui.layout.AlignmentLine alignmentLine);
     method public androidx.compose.ui.layout.LayoutCoordinates? getParentCoordinates();
     method public androidx.compose.ui.layout.LayoutCoordinates? getParentLayoutCoordinates();
     method public java.util.Set<androidx.compose.ui.layout.AlignmentLine> getProvidedAlignmentLines();
     method public long getSize-YbymL2g();
-    method @Deprecated public long globalToLocal-k-4lQ0M(long global);
     method public boolean isAttached();
     method public androidx.compose.ui.geometry.Rect localBoundingBoxOf(androidx.compose.ui.layout.LayoutCoordinates sourceCoordinates, optional boolean clipBounds);
     method public long localPositionOf-YJiYy8w(androidx.compose.ui.layout.LayoutCoordinates sourceCoordinates, long relativeToSource);
-    method @Deprecated public long localToGlobal-k-4lQ0M(long local);
     method public long localToRoot-k-4lQ0M(long relativeToLocal);
     method public long localToWindow-k-4lQ0M(long relativeToLocal);
     method public long windowToLocal-k-4lQ0M(long relativeToWindow);
@@ -1641,14 +1629,10 @@
   }
 
   public final class LayoutCoordinatesKt {
+    method public static androidx.compose.ui.geometry.Rect boundsInParent(androidx.compose.ui.layout.LayoutCoordinates);
     method public static androidx.compose.ui.geometry.Rect boundsInRoot(androidx.compose.ui.layout.LayoutCoordinates);
     method public static androidx.compose.ui.geometry.Rect boundsInWindow(androidx.compose.ui.layout.LayoutCoordinates);
-    method public static androidx.compose.ui.geometry.Rect getBoundsInParent(androidx.compose.ui.layout.LayoutCoordinates);
-    method @Deprecated public static androidx.compose.ui.geometry.Rect getBoundsInRoot(androidx.compose.ui.layout.LayoutCoordinates);
-    method @Deprecated public static androidx.compose.ui.geometry.Rect getGlobalBounds(androidx.compose.ui.layout.LayoutCoordinates);
-    method @Deprecated public static inline long getGlobalPosition(androidx.compose.ui.layout.LayoutCoordinates);
-    method public static long getPositionInParent(androidx.compose.ui.layout.LayoutCoordinates);
-    method @Deprecated public static inline long getPositionInRoot(androidx.compose.ui.layout.LayoutCoordinates);
+    method public static long positionInParent(androidx.compose.ui.layout.LayoutCoordinates);
     method public static long positionInRoot(androidx.compose.ui.layout.LayoutCoordinates);
     method public static long positionInWindow(androidx.compose.ui.layout.LayoutCoordinates);
   }
@@ -1680,12 +1664,8 @@
   }
 
   public final class LayoutKt {
-    method @androidx.compose.runtime.Composable public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> content, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> minIntrinsicWidthMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> minIntrinsicHeightMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> maxIntrinsicWidthMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> maxIntrinsicHeightMeasureBlock, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.Measurable>,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
-    method @androidx.compose.runtime.Composable public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> content, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.Measurable>,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
-    method @androidx.compose.runtime.Composable public static inline void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> content, androidx.compose.ui.node.MeasureBlocks measureBlocks, optional androidx.compose.ui.Modifier modifier);
-    method public static androidx.compose.ui.node.MeasureBlocks MeasuringIntrinsicsMeasureBlocks(kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.Measurable>,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
-    method @Deprecated @androidx.compose.runtime.Composable public static void MultiMeasureLayout(optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.Measurable>,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
-    method public static androidx.compose.ui.node.MeasureBlocks measureBlocksOf(kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> minIntrinsicWidthMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> minIntrinsicHeightMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> maxIntrinsicWidthMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> maxIntrinsicHeightMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.Measurable>,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
+    method @androidx.compose.runtime.Composable public static inline void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> content, optional androidx.compose.ui.Modifier modifier, androidx.compose.ui.layout.MeasurePolicy measurePolicy);
+    method @Deprecated @androidx.compose.runtime.Composable public static void MultiMeasureLayout(optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> content, androidx.compose.ui.layout.MeasurePolicy measurePolicy);
   }
 
   public interface LayoutModifier extends androidx.compose.ui.Modifier.Element {
@@ -1704,6 +1684,14 @@
     method public androidx.compose.ui.layout.Placeable measure-BRTryo0(long constraints);
   }
 
+  @androidx.compose.runtime.Stable public fun interface MeasurePolicy {
+    method public default int maxIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int width);
+    method public default int maxIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int height);
+    method public androidx.compose.ui.layout.MeasureResult measure-8A2P9vY(androidx.compose.ui.layout.MeasureScope, java.util.List<? extends androidx.compose.ui.layout.Measurable> measurables, long constraints);
+    method public default int minIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int width);
+    method public default int minIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int height);
+  }
+
   public interface MeasureResult {
     method public java.util.Map<androidx.compose.ui.layout.AlignmentLine,java.lang.Integer> getAlignmentLines();
     method public int getHeight();
@@ -1721,16 +1709,12 @@
   public final class MeasureScopeKt {
   }
 
-  public final inline class Measured {
-    ctor public Measured();
-    method public static androidx.compose.ui.layout.Placeable! constructor-impl(androidx.compose.ui.layout.Placeable placeable);
-    method public static inline boolean equals-impl(androidx.compose.ui.layout.Placeable! p, Object? p1);
-    method public static boolean equals-impl0(androidx.compose.ui.layout.Placeable p1, androidx.compose.ui.layout.Placeable p2);
-    method public static operator int get-impl(androidx.compose.ui.layout.Placeable $this, androidx.compose.ui.layout.AlignmentLine alignmentLine);
-    method public static int getHeight-impl(androidx.compose.ui.layout.Placeable! $this);
-    method public static int getWidth-impl(androidx.compose.ui.layout.Placeable! $this);
-    method public static inline int hashCode-impl(androidx.compose.ui.layout.Placeable! p);
-    method public static inline String! toString-impl(androidx.compose.ui.layout.Placeable! p);
+  public interface Measured {
+    method public operator int get(androidx.compose.ui.layout.AlignmentLine alignmentLine);
+    method public int getMeasuredHeight();
+    method public int getMeasuredWidth();
+    property public abstract int measuredHeight;
+    property public abstract int measuredWidth;
   }
 
   public final class ModifierInfo {
@@ -1763,12 +1747,13 @@
     method public Object? modifyParentData(androidx.compose.ui.unit.Density, Object? parentData);
   }
 
-  public abstract class Placeable {
+  public abstract class Placeable implements androidx.compose.ui.layout.Measured {
     ctor public Placeable();
-    method public abstract operator int get(androidx.compose.ui.layout.AlignmentLine line);
     method protected final long getApparentToRealOffset-nOcc-ac();
     method public final int getHeight();
+    method public int getMeasuredHeight();
     method protected final long getMeasuredSize-YbymL2g();
+    method public int getMeasuredWidth();
     method protected final long getMeasurementConstraints-msEJaDk();
     method public final int getWidth();
     method protected abstract void placeAt-rMeLuDI(long position, float zIndex, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.GraphicsLayerScope,kotlin.Unit>? layerBlock);
@@ -1776,7 +1761,9 @@
     method protected final void setMeasurementConstraints-BRTryo0(long p);
     property protected final long apparentToRealOffset;
     property public final int height;
+    property public int measuredHeight;
     property protected final long measuredSize;
+    property public int measuredWidth;
     property protected final long measurementConstraints;
     property public final int width;
   }
@@ -1812,7 +1799,6 @@
     ctor public ScaleFactor();
     method @androidx.compose.runtime.Stable public static inline operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static inline operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-_hLwfpc(long $this, optional float scaleX, optional float scaleY);
     method @androidx.compose.runtime.Stable public static operator long div-_hLwfpc(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
@@ -1842,7 +1828,7 @@
   }
 
   public final class SubcomposeLayoutKt {
-    method @androidx.compose.runtime.Composable public static void SubcomposeLayout(optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.layout.SubcomposeMeasureScope,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
+    method @androidx.compose.runtime.Composable public static void SubcomposeLayout(optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.layout.SubcomposeMeasureScope,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measurePolicy);
   }
 
   public interface SubcomposeMeasureScope extends androidx.compose.ui.layout.MeasureScope {
@@ -1866,14 +1852,6 @@
   public final class LayoutNodeKt {
   }
 
-  public interface MeasureBlocks {
-    method public int maxIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope intrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int w);
-    method public int maxIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope intrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int h);
-    method public androidx.compose.ui.layout.MeasureResult measure-8A2P9vY(androidx.compose.ui.layout.MeasureScope measureScope, java.util.List<? extends androidx.compose.ui.layout.Measurable> measurables, long constraints);
-    method public int minIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope intrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int w);
-    method public int minIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope intrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int h);
-  }
-
   public final class Ref<T> {
     ctor public Ref();
     method public T? getValue();
@@ -1918,6 +1896,10 @@
     property public final boolean showLayoutBounds;
   }
 
+  public interface AccessibilityManager {
+    method public long calculateRecommendedTimeoutMillis(long originalTimeoutMillis, optional boolean containsIcons, optional boolean containsText, optional boolean containsControls);
+  }
+
   public final class AndroidClipboardManager_androidKt {
   }
 
@@ -1993,6 +1975,7 @@
   }
 
   public final class CompositionLocalsKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.AccessibilityManager> getLocalAccessibilityManager();
     method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.Autofill> getLocalAutofill();
     method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.AutofillTree> getLocalAutofillTree();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ClipboardManager> getLocalClipboardManager();
@@ -2357,31 +2340,31 @@
   }
 
   public final class SemanticsNode {
-    method public int getAlignmentLinePosition(androidx.compose.ui.layout.AlignmentLine line);
+    method public int getAlignmentLinePosition(androidx.compose.ui.layout.AlignmentLine alignmentLine);
     method public androidx.compose.ui.geometry.Rect getBoundsInRoot();
+    method public androidx.compose.ui.geometry.Rect getBoundsInWindow();
     method public java.util.List<androidx.compose.ui.semantics.SemanticsNode> getChildren();
     method public androidx.compose.ui.semantics.SemanticsConfiguration getConfig();
-    method public androidx.compose.ui.geometry.Rect getGlobalBounds();
-    method public long getGlobalPosition-F1C5BW0();
     method public int getId();
     method public androidx.compose.ui.layout.LayoutInfo getLayoutInfo();
     method public boolean getMergingEnabled();
     method public androidx.compose.ui.semantics.SemanticsNode? getParent();
     method public long getPositionInRoot-F1C5BW0();
+    method public long getPositionInWindow-F1C5BW0();
     method public androidx.compose.ui.node.RootForTest? getRoot();
     method public long getSize-YbymL2g();
     method public boolean isRoot();
     property public final androidx.compose.ui.geometry.Rect boundsInRoot;
+    property public final androidx.compose.ui.geometry.Rect boundsInWindow;
     property public final java.util.List<androidx.compose.ui.semantics.SemanticsNode> children;
     property public final androidx.compose.ui.semantics.SemanticsConfiguration config;
-    property public final androidx.compose.ui.geometry.Rect globalBounds;
-    property public final long globalPosition;
     property public final int id;
     property public final boolean isRoot;
     property public final androidx.compose.ui.layout.LayoutInfo layoutInfo;
     property public final boolean mergingEnabled;
     property public final androidx.compose.ui.semantics.SemanticsNode? parent;
     property public final long positionInRoot;
+    property public final long positionInWindow;
     property public final androidx.compose.ui.node.RootForTest? root;
     property public final long size;
   }
@@ -2415,6 +2398,7 @@
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getPassword();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.ProgressBarRangeInfo> getProgressBarRangeInfo();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.Role> getRole();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getSelectableGroup();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getSelected();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> getStateDescription();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> getTestTag();
@@ -2436,6 +2420,7 @@
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> Password;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.ProgressBarRangeInfo> ProgressBarRangeInfo;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.Role> Role;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> SelectableGroup;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Selected;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> StateDescription;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> TestTag;
@@ -2479,6 +2464,7 @@
     method public static void pasteText(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
     method public static void popup(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static void scrollBy(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,java.lang.Boolean>? action);
+    method public static void selectableGroup(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static void setContentDescription(androidx.compose.ui.semantics.SemanticsPropertyReceiver, String p);
     method public static void setCustomActions(androidx.compose.ui.semantics.SemanticsPropertyReceiver, java.util.List<androidx.compose.ui.semantics.CustomAccessibilityAction> p);
     method public static void setEditableText(androidx.compose.ui.semantics.SemanticsPropertyReceiver, androidx.compose.ui.text.AnnotatedString p);
@@ -2545,7 +2531,7 @@
   }
 
   public final class AndroidView_androidKt {
-    method @androidx.compose.runtime.Composable public static <T extends android.view.View> void AndroidView(kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> viewBlock, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
+    method @androidx.compose.runtime.Composable public static <T extends android.view.View> void AndroidView(kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> factory, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
     method public static kotlin.jvm.functions.Function1<android.view.View,kotlin.Unit> getNoOpUpdate();
   }
 
diff --git a/compose/ui/ui/api/restricted_current.txt b/compose/ui/ui/api/restricted_current.txt
index 729a3e7..e908409 100644
--- a/compose/ui/ui/api/restricted_current.txt
+++ b/compose/ui/ui/api/restricted_current.txt
@@ -493,7 +493,6 @@
     ctor public TransformOrigin();
     method @androidx.compose.runtime.Stable public static inline operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static inline operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-SzJe1aQ(long $this, optional float pivotFractionX, optional float pivotFractionY);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
     method public static boolean equals-impl0(long p1, long p2);
@@ -510,7 +509,7 @@
   }
 
   public final class TransformOriginKt {
-    method public static inline long TransformOrigin(float pivotFractionX, float pivotFractionY);
+    method public static long TransformOrigin(float pivotFractionX, float pivotFractionY);
   }
 
 }
@@ -1374,10 +1373,6 @@
 
 package androidx.compose.ui.input.pointer {
 
-  public final class AndroidMouse_androidKt {
-    method public static boolean isMouseInput();
-  }
-
   @kotlin.coroutines.RestrictsSuspension public interface AwaitPointerEventScope extends androidx.compose.ui.unit.Density {
     method public suspend Object? awaitPointerEvent(optional androidx.compose.ui.input.pointer.PointerEventPass pass, optional kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerEvent> p);
     method public androidx.compose.ui.input.pointer.PointerEvent getCurrentEvent();
@@ -1405,9 +1400,6 @@
   public final class MotionEventAdapter_androidKt {
   }
 
-  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level, message="This is a temporary API and should be removed after proper mouse handling is " + "settled (b/171402426).") @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget}) public @interface MouseTemporaryApi {
-  }
-
   public final class PointerEvent {
     ctor public PointerEvent(java.util.List<androidx.compose.ui.input.pointer.PointerInputChange> changes);
     method public java.util.List<androidx.compose.ui.input.pointer.PointerInputChange> component1();
@@ -1582,23 +1574,6 @@
   public final class ContentScaleKt {
   }
 
-  @kotlin.PublishedApi internal final class DefaultIntrinsicMeasurable implements androidx.compose.ui.layout.Measurable {
-    ctor public DefaultIntrinsicMeasurable(androidx.compose.ui.layout.IntrinsicMeasurable measurable, androidx.compose.ui.layout.IntrinsicMinMax minMax, androidx.compose.ui.layout.IntrinsicWidthHeight widthHeight);
-    method public androidx.compose.ui.layout.IntrinsicMeasurable getMeasurable();
-    method public androidx.compose.ui.layout.IntrinsicMinMax getMinMax();
-    method public Object? getParentData();
-    method public androidx.compose.ui.layout.IntrinsicWidthHeight getWidthHeight();
-    method public int maxIntrinsicHeight(int width);
-    method public int maxIntrinsicWidth(int height);
-    method public androidx.compose.ui.layout.Placeable measure-BRTryo0(long constraints);
-    method public int minIntrinsicHeight(int width);
-    method public int minIntrinsicWidth(int height);
-    property public final androidx.compose.ui.layout.IntrinsicMeasurable measurable;
-    property public final androidx.compose.ui.layout.IntrinsicMinMax minMax;
-    property public Object? parentData;
-    property public final androidx.compose.ui.layout.IntrinsicWidthHeight widthHeight;
-  }
-
   @androidx.compose.runtime.Immutable public final class FixedScale implements androidx.compose.ui.layout.ContentScale {
     ctor public FixedScale(float value);
     method public float component1();
@@ -1634,48 +1609,15 @@
     property public abstract androidx.compose.ui.unit.LayoutDirection layoutDirection;
   }
 
-  @kotlin.PublishedApi internal enum IntrinsicMinMax {
-    enum_constant public static final androidx.compose.ui.layout.IntrinsicMinMax Max;
-    enum_constant public static final androidx.compose.ui.layout.IntrinsicMinMax Min;
-  }
-
-  @kotlin.PublishedApi internal enum IntrinsicWidthHeight {
-    enum_constant public static final androidx.compose.ui.layout.IntrinsicWidthHeight Height;
-    enum_constant public static final androidx.compose.ui.layout.IntrinsicWidthHeight Width;
-  }
-
-  @kotlin.PublishedApi internal final class IntrinsicsMeasureScope implements androidx.compose.ui.unit.Density androidx.compose.ui.layout.MeasureScope {
-    ctor public IntrinsicsMeasureScope(androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection);
-    method public float getDensity();
-    method public float getFontScale();
-    method public androidx.compose.ui.unit.LayoutDirection getLayoutDirection();
-    method @androidx.compose.runtime.Stable public int roundToPx--R2X_6o(long);
-    method @androidx.compose.runtime.Stable public int roundToPx-0680j_4(float);
-    method @androidx.compose.runtime.Stable public float toDp--R2X_6o(long);
-    method @androidx.compose.runtime.Stable public float toDp-D9Ej5fM(float);
-    method @androidx.compose.runtime.Stable public float toDp-D9Ej5fM(int);
-    method @androidx.compose.runtime.Stable public float toPx--R2X_6o(long);
-    method @androidx.compose.runtime.Stable public float toPx-0680j_4(float);
-    method @androidx.compose.runtime.Stable public androidx.compose.ui.geometry.Rect toRect(androidx.compose.ui.unit.DpRect);
-    method @androidx.compose.runtime.Stable public long toSp-0680j_4(float);
-    method @androidx.compose.runtime.Stable public long toSp-XSAIIZE(float);
-    method @androidx.compose.runtime.Stable public long toSp-XSAIIZE(int);
-    property public androidx.compose.ui.unit.LayoutDirection layoutDirection;
-  }
-
   public interface LayoutCoordinates {
-    method @Deprecated public androidx.compose.ui.geometry.Rect childBoundingBox(androidx.compose.ui.layout.LayoutCoordinates child);
-    method @Deprecated public long childToLocal-YJiYy8w(androidx.compose.ui.layout.LayoutCoordinates child, long childLocal);
-    method public operator int get(androidx.compose.ui.layout.AlignmentLine line);
+    method public operator int get(androidx.compose.ui.layout.AlignmentLine alignmentLine);
     method public androidx.compose.ui.layout.LayoutCoordinates? getParentCoordinates();
     method public androidx.compose.ui.layout.LayoutCoordinates? getParentLayoutCoordinates();
     method public java.util.Set<androidx.compose.ui.layout.AlignmentLine> getProvidedAlignmentLines();
     method public long getSize-YbymL2g();
-    method @Deprecated public long globalToLocal-k-4lQ0M(long global);
     method public boolean isAttached();
     method public androidx.compose.ui.geometry.Rect localBoundingBoxOf(androidx.compose.ui.layout.LayoutCoordinates sourceCoordinates, optional boolean clipBounds);
     method public long localPositionOf-YJiYy8w(androidx.compose.ui.layout.LayoutCoordinates sourceCoordinates, long relativeToSource);
-    method @Deprecated public long localToGlobal-k-4lQ0M(long local);
     method public long localToRoot-k-4lQ0M(long relativeToLocal);
     method public long localToWindow-k-4lQ0M(long relativeToLocal);
     method public long windowToLocal-k-4lQ0M(long relativeToWindow);
@@ -1687,14 +1629,10 @@
   }
 
   public final class LayoutCoordinatesKt {
+    method public static androidx.compose.ui.geometry.Rect boundsInParent(androidx.compose.ui.layout.LayoutCoordinates);
     method public static androidx.compose.ui.geometry.Rect boundsInRoot(androidx.compose.ui.layout.LayoutCoordinates);
     method public static androidx.compose.ui.geometry.Rect boundsInWindow(androidx.compose.ui.layout.LayoutCoordinates);
-    method public static androidx.compose.ui.geometry.Rect getBoundsInParent(androidx.compose.ui.layout.LayoutCoordinates);
-    method @Deprecated public static androidx.compose.ui.geometry.Rect getBoundsInRoot(androidx.compose.ui.layout.LayoutCoordinates);
-    method @Deprecated public static androidx.compose.ui.geometry.Rect getGlobalBounds(androidx.compose.ui.layout.LayoutCoordinates);
-    method @Deprecated public static inline long getGlobalPosition(androidx.compose.ui.layout.LayoutCoordinates);
-    method public static long getPositionInParent(androidx.compose.ui.layout.LayoutCoordinates);
-    method @Deprecated public static inline long getPositionInRoot(androidx.compose.ui.layout.LayoutCoordinates);
+    method public static long positionInParent(androidx.compose.ui.layout.LayoutCoordinates);
     method public static long positionInRoot(androidx.compose.ui.layout.LayoutCoordinates);
     method public static long positionInWindow(androidx.compose.ui.layout.LayoutCoordinates);
   }
@@ -1726,13 +1664,9 @@
   }
 
   public final class LayoutKt {
-    method @androidx.compose.runtime.Composable public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> content, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> minIntrinsicWidthMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> minIntrinsicHeightMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> maxIntrinsicWidthMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> maxIntrinsicHeightMeasureBlock, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.Measurable>,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
-    method @androidx.compose.runtime.Composable public static void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> content, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.Measurable>,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
-    method @androidx.compose.runtime.Composable public static inline void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> content, androidx.compose.ui.node.MeasureBlocks measureBlocks, optional androidx.compose.ui.Modifier modifier);
-    method public static androidx.compose.ui.node.MeasureBlocks MeasuringIntrinsicsMeasureBlocks(kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.Measurable>,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
-    method @Deprecated @androidx.compose.runtime.Composable public static void MultiMeasureLayout(optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> children, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.Measurable>,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
+    method @androidx.compose.runtime.Composable public static inline void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> content, optional androidx.compose.ui.Modifier modifier, androidx.compose.ui.layout.MeasurePolicy measurePolicy);
+    method @Deprecated @androidx.compose.runtime.Composable 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.Function1<androidx.compose.runtime.SkippableUpdater<androidx.compose.ui.node.ComposeUiNode>,kotlin.Unit> materializerOf(androidx.compose.ui.Modifier modifier);
-    method public static androidx.compose.ui.node.MeasureBlocks measureBlocksOf(kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> minIntrinsicWidthMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> minIntrinsicHeightMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> maxIntrinsicWidthMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntrinsicMeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>,? super java.lang.Integer,java.lang.Integer> maxIntrinsicHeightMeasureBlock, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super java.util.List<? extends androidx.compose.ui.layout.Measurable>,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
   }
 
   public interface LayoutModifier extends androidx.compose.ui.Modifier.Element {
@@ -1751,6 +1685,14 @@
     method public androidx.compose.ui.layout.Placeable measure-BRTryo0(long constraints);
   }
 
+  @androidx.compose.runtime.Stable public fun interface MeasurePolicy {
+    method public default int maxIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int width);
+    method public default int maxIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int height);
+    method public androidx.compose.ui.layout.MeasureResult measure-8A2P9vY(androidx.compose.ui.layout.MeasureScope, java.util.List<? extends androidx.compose.ui.layout.Measurable> measurables, long constraints);
+    method public default int minIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int width);
+    method public default int minIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int height);
+  }
+
   public interface MeasureResult {
     method public java.util.Map<androidx.compose.ui.layout.AlignmentLine,java.lang.Integer> getAlignmentLines();
     method public int getHeight();
@@ -1768,16 +1710,12 @@
   public final class MeasureScopeKt {
   }
 
-  public final inline class Measured {
-    ctor public Measured();
-    method public static androidx.compose.ui.layout.Placeable! constructor-impl(androidx.compose.ui.layout.Placeable placeable);
-    method public static inline boolean equals-impl(androidx.compose.ui.layout.Placeable! p, Object? p1);
-    method public static boolean equals-impl0(androidx.compose.ui.layout.Placeable p1, androidx.compose.ui.layout.Placeable p2);
-    method public static operator int get-impl(androidx.compose.ui.layout.Placeable $this, androidx.compose.ui.layout.AlignmentLine alignmentLine);
-    method public static int getHeight-impl(androidx.compose.ui.layout.Placeable! $this);
-    method public static int getWidth-impl(androidx.compose.ui.layout.Placeable! $this);
-    method public static inline int hashCode-impl(androidx.compose.ui.layout.Placeable! p);
-    method public static inline String! toString-impl(androidx.compose.ui.layout.Placeable! p);
+  public interface Measured {
+    method public operator int get(androidx.compose.ui.layout.AlignmentLine alignmentLine);
+    method public int getMeasuredHeight();
+    method public int getMeasuredWidth();
+    property public abstract int measuredHeight;
+    property public abstract int measuredWidth;
   }
 
   public final class ModifierInfo {
@@ -1810,12 +1748,13 @@
     method public Object? modifyParentData(androidx.compose.ui.unit.Density, Object? parentData);
   }
 
-  public abstract class Placeable {
+  public abstract class Placeable implements androidx.compose.ui.layout.Measured {
     ctor public Placeable();
-    method public abstract operator int get(androidx.compose.ui.layout.AlignmentLine line);
     method protected final long getApparentToRealOffset-nOcc-ac();
     method public final int getHeight();
+    method public int getMeasuredHeight();
     method protected final long getMeasuredSize-YbymL2g();
+    method public int getMeasuredWidth();
     method protected final long getMeasurementConstraints-msEJaDk();
     method public final int getWidth();
     method protected abstract void placeAt-rMeLuDI(long position, float zIndex, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.GraphicsLayerScope,kotlin.Unit>? layerBlock);
@@ -1823,7 +1762,9 @@
     method protected final void setMeasurementConstraints-BRTryo0(long p);
     property protected final long apparentToRealOffset;
     property public final int height;
+    property public int measuredHeight;
     property protected final long measuredSize;
+    property public int measuredWidth;
     property protected final long measurementConstraints;
     property public final int width;
   }
@@ -1859,7 +1800,6 @@
     ctor public ScaleFactor();
     method @androidx.compose.runtime.Stable public static inline operator float component1-impl(long $this);
     method @androidx.compose.runtime.Stable public static inline operator float component2-impl(long $this);
-    method public static long constructor-impl(long packedValue);
     method public static long copy-_hLwfpc(long $this, optional float scaleX, optional float scaleY);
     method @androidx.compose.runtime.Stable public static operator long div-_hLwfpc(long $this, float operand);
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(long p, Object? p1);
@@ -1889,7 +1829,7 @@
   }
 
   public final class SubcomposeLayoutKt {
-    method @androidx.compose.runtime.Composable public static void SubcomposeLayout(optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.layout.SubcomposeMeasureScope,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measureBlock);
+    method @androidx.compose.runtime.Composable public static void SubcomposeLayout(optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.layout.SubcomposeMeasureScope,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measurePolicy);
   }
 
   public interface SubcomposeMeasureScope extends androidx.compose.ui.layout.MeasureScope {
@@ -1910,15 +1850,15 @@
   @kotlin.PublishedApi internal interface ComposeUiNode {
     method public androidx.compose.ui.unit.Density getDensity();
     method public androidx.compose.ui.unit.LayoutDirection getLayoutDirection();
-    method public androidx.compose.ui.node.MeasureBlocks getMeasureBlocks();
+    method public androidx.compose.ui.layout.MeasurePolicy getMeasurePolicy();
     method public androidx.compose.ui.Modifier getModifier();
     method public void setDensity(androidx.compose.ui.unit.Density p);
     method public void setLayoutDirection(androidx.compose.ui.unit.LayoutDirection p);
-    method public void setMeasureBlocks(androidx.compose.ui.node.MeasureBlocks p);
+    method public void setMeasurePolicy(androidx.compose.ui.layout.MeasurePolicy p);
     method public void setModifier(androidx.compose.ui.Modifier p);
     property public abstract androidx.compose.ui.unit.Density density;
     property public abstract androidx.compose.ui.unit.LayoutDirection layoutDirection;
-    property public abstract androidx.compose.ui.node.MeasureBlocks measureBlocks;
+    property public abstract androidx.compose.ui.layout.MeasurePolicy measurePolicy;
     property public abstract androidx.compose.ui.Modifier modifier;
     field public static final androidx.compose.ui.node.ComposeUiNode.Companion Companion;
   }
@@ -1927,12 +1867,12 @@
     method public kotlin.jvm.functions.Function0<androidx.compose.ui.node.ComposeUiNode> getConstructor();
     method public kotlin.jvm.functions.Function2<androidx.compose.ui.node.ComposeUiNode,androidx.compose.ui.unit.Density,kotlin.Unit> getSetDensity();
     method public kotlin.jvm.functions.Function2<androidx.compose.ui.node.ComposeUiNode,androidx.compose.ui.unit.LayoutDirection,kotlin.Unit> getSetLayoutDirection();
-    method public kotlin.jvm.functions.Function2<androidx.compose.ui.node.ComposeUiNode,androidx.compose.ui.node.MeasureBlocks,kotlin.Unit> getSetMeasureBlocks();
+    method public kotlin.jvm.functions.Function2<androidx.compose.ui.node.ComposeUiNode,androidx.compose.ui.layout.MeasurePolicy,kotlin.Unit> getSetMeasurePolicy();
     method public kotlin.jvm.functions.Function2<androidx.compose.ui.node.ComposeUiNode,androidx.compose.ui.Modifier,kotlin.Unit> getSetModifier();
     property public final kotlin.jvm.functions.Function0<androidx.compose.ui.node.ComposeUiNode> Constructor;
     property public final kotlin.jvm.functions.Function2<androidx.compose.ui.node.ComposeUiNode,androidx.compose.ui.unit.Density,kotlin.Unit> SetDensity;
     property public final kotlin.jvm.functions.Function2<androidx.compose.ui.node.ComposeUiNode,androidx.compose.ui.unit.LayoutDirection,kotlin.Unit> SetLayoutDirection;
-    property public final kotlin.jvm.functions.Function2<androidx.compose.ui.node.ComposeUiNode,androidx.compose.ui.node.MeasureBlocks,kotlin.Unit> SetMeasureBlocks;
+    property public final kotlin.jvm.functions.Function2<androidx.compose.ui.node.ComposeUiNode,androidx.compose.ui.layout.MeasurePolicy,kotlin.Unit> SetMeasurePolicy;
     property public final kotlin.jvm.functions.Function2<androidx.compose.ui.node.ComposeUiNode,androidx.compose.ui.Modifier,kotlin.Unit> SetModifier;
   }
 
@@ -1942,14 +1882,6 @@
   public final class LayoutNodeKt {
   }
 
-  public interface MeasureBlocks {
-    method public int maxIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope intrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int w);
-    method public int maxIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope intrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int h);
-    method public androidx.compose.ui.layout.MeasureResult measure-8A2P9vY(androidx.compose.ui.layout.MeasureScope measureScope, java.util.List<? extends androidx.compose.ui.layout.Measurable> measurables, long constraints);
-    method public int minIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope intrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int w);
-    method public int minIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope intrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int h);
-  }
-
   public final class Ref<T> {
     ctor public Ref();
     method public T? getValue();
@@ -1994,6 +1926,10 @@
     property public final boolean showLayoutBounds;
   }
 
+  public interface AccessibilityManager {
+    method public long calculateRecommendedTimeoutMillis(long originalTimeoutMillis, optional boolean containsIcons, optional boolean containsText, optional boolean containsControls);
+  }
+
   public final class AndroidClipboardManager_androidKt {
   }
 
@@ -2069,6 +2005,7 @@
   }
 
   public final class CompositionLocalsKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.AccessibilityManager> getLocalAccessibilityManager();
     method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.Autofill> getLocalAutofill();
     method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.AutofillTree> getLocalAutofillTree();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ClipboardManager> getLocalClipboardManager();
@@ -2435,31 +2372,31 @@
   }
 
   public final class SemanticsNode {
-    method public int getAlignmentLinePosition(androidx.compose.ui.layout.AlignmentLine line);
+    method public int getAlignmentLinePosition(androidx.compose.ui.layout.AlignmentLine alignmentLine);
     method public androidx.compose.ui.geometry.Rect getBoundsInRoot();
+    method public androidx.compose.ui.geometry.Rect getBoundsInWindow();
     method public java.util.List<androidx.compose.ui.semantics.SemanticsNode> getChildren();
     method public androidx.compose.ui.semantics.SemanticsConfiguration getConfig();
-    method public androidx.compose.ui.geometry.Rect getGlobalBounds();
-    method public long getGlobalPosition-F1C5BW0();
     method public int getId();
     method public androidx.compose.ui.layout.LayoutInfo getLayoutInfo();
     method public boolean getMergingEnabled();
     method public androidx.compose.ui.semantics.SemanticsNode? getParent();
     method public long getPositionInRoot-F1C5BW0();
+    method public long getPositionInWindow-F1C5BW0();
     method public androidx.compose.ui.node.RootForTest? getRoot();
     method public long getSize-YbymL2g();
     method public boolean isRoot();
     property public final androidx.compose.ui.geometry.Rect boundsInRoot;
+    property public final androidx.compose.ui.geometry.Rect boundsInWindow;
     property public final java.util.List<androidx.compose.ui.semantics.SemanticsNode> children;
     property public final androidx.compose.ui.semantics.SemanticsConfiguration config;
-    property public final androidx.compose.ui.geometry.Rect globalBounds;
-    property public final long globalPosition;
     property public final int id;
     property public final boolean isRoot;
     property public final androidx.compose.ui.layout.LayoutInfo layoutInfo;
     property public final boolean mergingEnabled;
     property public final androidx.compose.ui.semantics.SemanticsNode? parent;
     property public final long positionInRoot;
+    property public final long positionInWindow;
     property public final androidx.compose.ui.node.RootForTest? root;
     property public final long size;
   }
@@ -2493,6 +2430,7 @@
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getPassword();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.ProgressBarRangeInfo> getProgressBarRangeInfo();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.Role> getRole();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getSelectableGroup();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getSelected();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> getStateDescription();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> getTestTag();
@@ -2514,6 +2452,7 @@
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> Password;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.ProgressBarRangeInfo> ProgressBarRangeInfo;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.Role> Role;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> SelectableGroup;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Selected;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> StateDescription;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> TestTag;
@@ -2557,6 +2496,7 @@
     method public static void pasteText(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
     method public static void popup(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static void scrollBy(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,java.lang.Boolean>? action);
+    method public static void selectableGroup(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static void setContentDescription(androidx.compose.ui.semantics.SemanticsPropertyReceiver, String p);
     method public static void setCustomActions(androidx.compose.ui.semantics.SemanticsPropertyReceiver, java.util.List<androidx.compose.ui.semantics.CustomAccessibilityAction> p);
     method public static void setEditableText(androidx.compose.ui.semantics.SemanticsPropertyReceiver, androidx.compose.ui.text.AnnotatedString p);
@@ -2623,7 +2563,7 @@
   }
 
   public final class AndroidView_androidKt {
-    method @androidx.compose.runtime.Composable public static <T extends android.view.View> void AndroidView(kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> viewBlock, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
+    method @androidx.compose.runtime.Composable public static <T extends android.view.View> void AndroidView(kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> factory, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
     method public static kotlin.jvm.functions.Function1<android.view.View,kotlin.Unit> getNoOpUpdate();
   }
 
diff --git a/compose/ui/ui/build.gradle b/compose/ui/ui/build.gradle
index 5119ea18..7e705a2 100644
--- a/compose/ui/ui/build.gradle
+++ b/compose/ui/ui/build.gradle
@@ -66,7 +66,7 @@
         // used if the user adds these dependencies as otherwise AppCompatActivity and Fragment
         // will not propagate ViewTree*Owners we are relying on and we will crash.
         // TODO: remove these dependencies at some point: b/161814404
-        implementation "androidx.fragment:fragment:1.3.0-rc02"
+        implementation "androidx.fragment:fragment:1.3.0"
         implementation "androidx.appcompat:appcompat:1.3.0-beta01"
 
         testImplementation(ANDROIDX_TEST_RULES)
@@ -82,7 +82,7 @@
         testImplementation project(":compose:ui:ui-test-junit4")
         testImplementation project(":compose:test-utils")
 
-        androidTestImplementation "androidx.fragment:fragment:1.2.4"
+        androidTestImplementation "androidx.fragment:fragment:1.3.0"
         androidTestImplementation "androidx.appcompat:appcompat:1.1.0"
         androidTestImplementation(ANDROIDX_TEST_UIAUTOMATOR)
         androidTestImplementation(ANDROIDX_TEST_RULES)
@@ -155,7 +155,7 @@
                 // used if the user adds these dependencies as otherwise AppCompatActivity and Fragment
                 // will not propagate ViewTree*Owners we are relying on and we will crash.
                 // TODO: remove these dependencies at some point: b/161814404
-                implementation "androidx.fragment:fragment:1.3.0-alpha07"
+                implementation "androidx.fragment:fragment:1.3.0"
                 implementation "androidx.appcompat:appcompat:1.3.0-alpha01"
             }
 
@@ -187,7 +187,7 @@
             }
 
             androidAndroidTest.dependencies {
-                implementation "androidx.fragment:fragment:1.2.4"
+                implementation "androidx.fragment:fragment:1.3.0"
                 implementation "androidx.appcompat:appcompat:1.1.0"
                 implementation(ANDROIDX_TEST_UIAUTOMATOR)
                 implementation(ANDROIDX_TEST_RULES)
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/autofill/ExplicitAutofillTypesDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/autofill/ExplicitAutofillTypesDemo.kt
index 8eefbf1..e8cd2f5 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/autofill/ExplicitAutofillTypesDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/autofill/ExplicitAutofillTypesDemo.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.ui.demos.autofill
 
-import android.graphics.Rect
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
@@ -35,9 +34,7 @@
 import androidx.compose.ui.autofill.AutofillType
 import androidx.compose.ui.focus.isFocused
 import androidx.compose.ui.focus.onFocusChanged
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.graphics.toComposeRect
-import androidx.compose.ui.layout.LayoutCoordinates
+import androidx.compose.ui.layout.boundsInWindow
 import androidx.compose.ui.layout.onGloballyPositioned
 import androidx.compose.ui.platform.LocalAutofill
 import androidx.compose.ui.platform.LocalAutofillTree
@@ -123,19 +120,9 @@
 
     Box(
         Modifier.onGloballyPositioned {
-            autofillNode.boundingBox = it.boundingBox().toComposeRect()
+            autofillNode.boundingBox = it.boundsInWindow()
         }
     ) {
         content(autofillNode)
     }
 }
-
-@Suppress("DEPRECATION")
-private fun LayoutCoordinates.boundingBox() = localToGlobal(Offset.Zero).run {
-    Rect(
-        x.toInt(),
-        y.toInt(),
-        x.toInt() + size.width,
-        y.toInt() + size.height
-    )
-}
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/HorizontalScrollersInVerticalScrollerDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/HorizontalScrollersInVerticalScrollerDemo.kt
index c48f1f1..d11018e 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/HorizontalScrollersInVerticalScrollerDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/HorizontalScrollersInVerticalScrollerDemo.kt
@@ -106,7 +106,7 @@
             }
         )
             .then(ClipModifier),
-        measureBlock = { measurables, constraints ->
+        measurePolicy = { measurables, constraints ->
             val placeable =
                 when (orientation) {
                     Orientation.Horizontal -> measurables.first().measure(
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/NestedScrollingDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/NestedScrollingDemo.kt
index f86dee8..3978b89 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/NestedScrollingDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/NestedScrollingDemo.kt
@@ -106,7 +106,7 @@
                 }
             )
             .clipToBounds(),
-        measureBlock = { measurables, constraints ->
+        measurePolicy = { measurables, constraints ->
             val placeable =
                 measurables.first()
                     .measure(constraints.copy(minHeight = 0, maxHeight = Constraints.Infinity))
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/ScrollGestureFilterDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/ScrollGestureFilterDemo.kt
index 888edcc..fea7034 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/ScrollGestureFilterDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/ScrollGestureFilterDemo.kt
@@ -16,11 +16,11 @@
 
 package androidx.compose.ui.demos.gestures
 
-import androidx.compose.foundation.Interaction.Dragged
-import androidx.compose.foundation.InteractionState
+import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.background
 import androidx.compose.foundation.gestures.rememberScrollableState
 import androidx.compose.foundation.gestures.scrollable
+import androidx.compose.foundation.interaction.collectIsDraggedAsState
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxSize
@@ -68,8 +68,8 @@
     content: @Composable () -> Unit = {}
 ) {
 
-    val interactionState = remember { InteractionState() }
-    val color = if (interactionState.contains(Dragged)) activeColor else idleColor
+    val interactionSource = remember { MutableInteractionSource() }
+    val color = if (interactionSource.collectIsDraggedAsState().value) activeColor else idleColor
     val offsetPx = remember { mutableStateOf(0f) }
 
     val offsetDp = with(LocalDensity.current) {
@@ -85,7 +85,7 @@
             .fillMaxSize()
             .wrapContentSize(Alignment.Center)
             .scrollable(
-                interactionState = interactionState,
+                interactionSource = interactionSource,
                 orientation = orientation,
                 state = rememberScrollableState { scrollDistance ->
                     offsetPx.value += scrollDistance
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/VerticalScrollerInDrawerLayoutDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/VerticalScrollerInDrawerLayoutDemo.kt
index e5303c7..54f7016 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/VerticalScrollerInDrawerLayoutDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/VerticalScrollerInDrawerLayoutDemo.kt
@@ -149,7 +149,7 @@
                 toConsume
             }
         ).then(ClipModifier),
-        measureBlock = { measurables, constraints ->
+        measurePolicy = { measurables, constraints ->
             val placeable =
                 when (orientation) {
                     Orientation.Horizontal -> measurables.first().measure(
diff --git a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LayoutSample.kt b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LayoutSample.kt
index 9beccc6..d3aca71 100644
--- a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LayoutSample.kt
+++ b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LayoutSample.kt
@@ -24,104 +24,19 @@
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.IntrinsicMeasurable
+import androidx.compose.ui.layout.IntrinsicMeasureScope
+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.layout
 import androidx.compose.ui.layout.layoutId
-import androidx.compose.ui.layout.measureBlocksOf
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.offset
 
 @Sampled
 @Composable
-fun LayoutWithProvidedIntrinsicsUsage(content: @Composable () -> Unit) {
-    // We build a layout that will occupy twice as much space as its children,
-    // and will position them to be bottom right aligned.
-    Layout(
-        content,
-        minIntrinsicWidthMeasureBlock = { measurables, h ->
-            // The min intrinsic width of this layout will be twice the largest min intrinsic
-            // width of a child. Note that we call minIntrinsicWidth with h / 2 for children,
-            // since we should be double the size of the children.
-            (measurables.map { it.minIntrinsicWidth(h / 2) }.maxByOrNull { it } ?: 0) * 2
-        },
-        minIntrinsicHeightMeasureBlock = { measurables, w ->
-            (measurables.map { it.minIntrinsicHeight(w / 2) }.maxByOrNull { it } ?: 0) * 2
-        },
-        maxIntrinsicWidthMeasureBlock = { measurables, h ->
-            (measurables.map { it.maxIntrinsicHeight(h / 2) }.maxByOrNull { it } ?: 0) * 2
-        },
-        maxIntrinsicHeightMeasureBlock = { measurables, w ->
-            (measurables.map { it.maxIntrinsicHeight(w / 2) }.maxByOrNull { it } ?: 0) * 2
-        }
-    ) { measurables, constraints ->
-        // measurables contains one element corresponding to each of our layout children.
-        // constraints are the constraints that our parent is currently measuring us with.
-        val childConstraints = Constraints(
-            minWidth = constraints.minWidth / 2,
-            minHeight = constraints.minHeight / 2,
-            maxWidth = constraints.maxWidth / 2,
-            maxHeight = constraints.maxHeight / 2
-        )
-        // We measure the children with half our constraints, to ensure we can be double
-        // the size of the children.
-        val placeables = measurables.map { it.measure(childConstraints) }
-        val layoutWidth = (placeables.maxByOrNull { it.width }?.width ?: 0) * 2
-        val layoutHeight = (placeables.maxByOrNull { it.height }?.height ?: 0) * 2
-        // We call layout to set the size of the current layout and to provide the positioning
-        // of the children. The children are placed relative to the current layout place.
-        layout(layoutWidth, layoutHeight) {
-            placeables.forEach {
-                it.placeRelative(layoutWidth - it.width, layoutHeight - it.height)
-            }
-        }
-    }
-}
-
-@Sampled
-@Composable
-fun LayoutWithMeasureBlocksWithIntrinsicUsage(content: @Composable () -> Unit) {
-    val measureBlocks = measureBlocksOf(
-        minIntrinsicWidthMeasureBlock = { measurables, h ->
-            // The min intrinsic width of this layout will be twice the largest min intrinsic
-            // width of a child. Note that we call minIntrinsicWidth with h / 2 for children,
-            // since we should be double the size of the children.
-            (measurables.map { it.minIntrinsicWidth(h / 2) }.maxByOrNull { it } ?: 0) * 2
-        },
-        minIntrinsicHeightMeasureBlock = { measurables, w ->
-            (measurables.map { it.minIntrinsicHeight(w / 2) }.maxByOrNull { it } ?: 0) * 2
-        },
-        maxIntrinsicWidthMeasureBlock = { measurables, h ->
-            (measurables.map { it.maxIntrinsicHeight(h / 2) }.maxByOrNull { it } ?: 0) * 2
-        },
-        maxIntrinsicHeightMeasureBlock = { measurables, w ->
-            (measurables.map { it.maxIntrinsicHeight(w / 2) }.maxByOrNull { it } ?: 0) * 2
-        }
-    ) { measurables, constraints ->
-        // measurables contains one element corresponding to each of our layout children.
-        // constraints are the constraints that our parent is currently measuring us with.
-        val childConstraints = Constraints(
-            minWidth = constraints.minWidth / 2,
-            minHeight = constraints.minHeight / 2,
-            maxWidth = constraints.maxWidth / 2,
-            maxHeight = constraints.maxHeight / 2
-        )
-        // We measure the children with half our constraints, to ensure we can be double
-        // the size of the children.
-        val placeables = measurables.map { it.measure(childConstraints) }
-        val layoutWidth = (placeables.maxByOrNull { it.width }?.width ?: 0) * 2
-        val layoutHeight = (placeables.maxByOrNull { it.height }?.height ?: 0) * 2
-        // We call layout to set the size of the current layout and to provide the positioning
-        // of the children. The children are placed relative to the current layout place.
-        layout(layoutWidth, layoutHeight) {
-            placeables.forEach {
-                it.placeRelative(layoutWidth - it.width, layoutHeight - it.height)
-            }
-        }
-    }
-    Layout(content = content, measureBlocks = measureBlocks)
-}
-
-@Sampled
-@Composable
 fun LayoutUsage(content: @Composable () -> Unit) {
     // We build a layout that will occupy twice as much space as its children,
     // and will position them to be bottom right aligned.
@@ -151,6 +66,65 @@
 
 @Sampled
 @Composable
+fun LayoutWithProvidedIntrinsicsUsage(content: @Composable () -> Unit) {
+    // We build a layout that will occupy twice as much space as its children,
+    // and will position them to be bottom right aligned.
+    val measurePolicy = object : MeasurePolicy {
+        override fun MeasureScope.measure(
+            measurables: List<Measurable>,
+            constraints: Constraints
+        ): MeasureResult {
+            // measurables contains one element corresponding to each of our layout children.
+            // constraints are the constraints that our parent is currently measuring us with.
+            val childConstraints = Constraints(
+                minWidth = constraints.minWidth / 2,
+                minHeight = constraints.minHeight / 2,
+                maxWidth = constraints.maxWidth / 2,
+                maxHeight = constraints.maxHeight / 2
+            )
+            // We measure the children with half our constraints, to ensure we can be double
+            // the size of the children.
+            val placeables = measurables.map { it.measure(childConstraints) }
+            val layoutWidth = (placeables.maxByOrNull { it.width }?.width ?: 0) * 2
+            val layoutHeight = (placeables.maxByOrNull { it.height }?.height ?: 0) * 2
+            // We call layout to set the size of the current layout and to provide the positioning
+            // of the children. The children are placed relative to the current layout place.
+            return layout(layoutWidth, layoutHeight) {
+                placeables.forEach {
+                    it.placeRelative(layoutWidth - it.width, layoutHeight - it.height)
+                }
+            }
+        }
+
+        // The min intrinsic width of this layout will be twice the largest min intrinsic
+        // width of a child. Note that we call minIntrinsicWidth with h / 2 for children,
+        // since we should be double the size of the children.
+        override fun IntrinsicMeasureScope.minIntrinsicWidth(
+            measurables: List<IntrinsicMeasurable>,
+            height: Int
+        ) = (measurables.map { it.minIntrinsicWidth(height / 2) }.maxByOrNull { it } ?: 0) * 2
+
+        override fun IntrinsicMeasureScope.minIntrinsicHeight(
+            measurables: List<IntrinsicMeasurable>,
+            width: Int
+        ) = (measurables.map { it.minIntrinsicHeight(width / 2) }.maxByOrNull { it } ?: 0) * 2
+
+        override fun IntrinsicMeasureScope.maxIntrinsicWidth(
+            measurables: List<IntrinsicMeasurable>,
+            height: Int
+        ) = (measurables.map { it.maxIntrinsicHeight(height / 2) }.maxByOrNull { it } ?: 0) * 2
+
+        override fun IntrinsicMeasureScope.maxIntrinsicHeight(
+            measurables: List<IntrinsicMeasurable>,
+            width: Int
+        ) = (measurables.map { it.maxIntrinsicHeight(width / 2) }.maxByOrNull { it } ?: 0) * 2
+    }
+
+    Layout(content = content, measurePolicy = measurePolicy)
+}
+
+@Sampled
+@Composable
 fun LayoutTagChildrenUsage(header: @Composable () -> Unit, footer: @Composable () -> Unit) {
     Layout({
         // Here the Containers are only needed to apply the modifiers. You could use the
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AccessibilityIteratorsTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AccessibilityIteratorsTest.kt
index 259cb0b..2639fd4 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AccessibilityIteratorsTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AccessibilityIteratorsTest.kt
@@ -389,7 +389,7 @@
         val lineHeight = textLayoutResult.getLineBottom(endLine) -
             textLayoutResult.getLineTop(endLine)
         val iteratorStep = endLineTop - startLineTop
-        val nodeHeight = textFieldNode.globalBounds.bottom - textFieldNode.globalBounds.top
+        val nodeHeight = textFieldNode.boundsInWindow.bottom - textFieldNode.boundsInWindow.top
         Truth.assertThat(abs(iteratorStep - nodeHeight) < lineHeight)
         currentOffset = InputText.length
         range = pageIterator.following(currentOffset)
@@ -412,7 +412,7 @@
         val lineHeight = textLayoutResult.getLineBottom(endLine) -
             textLayoutResult.getLineTop(endLine)
         val iteratorStep = endLineTop - startLineTop
-        val nodeHeight = textFieldNode.globalBounds.bottom - textFieldNode.globalBounds.top
+        val nodeHeight = textFieldNode.boundsInWindow.bottom - textFieldNode.boundsInWindow.top
         Truth.assertThat(abs(iteratorStep - nodeHeight) < lineHeight)
         currentOffset = 0
         range = pageIterator.preceding(currentOffset)
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 4ebea71..bc85617 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
@@ -405,7 +405,7 @@
         val rectF = data[0] as RectF
         val expectedRect = textLayoutResult.getBoundingBox(0).translate(
             textFieldNode
-                .globalPosition
+                .positionInWindow
         )
         assertEquals(expectedRect.left, rectF.left)
         assertEquals(expectedRect.top, rectF.top)
@@ -687,12 +687,12 @@
         var rootNodeBoundsTop = 0f
         rule.runOnIdle {
             val rootNode = androidComposeView.semanticsOwner.rootSemanticsNode
-            rootNodeBoundsLeft = rootNode.globalBounds.left
-            rootNodeBoundsTop = rootNode.globalBounds.top
+            rootNodeBoundsLeft = rootNode.boundsInWindow.left
+            rootNodeBoundsTop = rootNode.boundsInWindow.top
         }
         val toggleableNode = rule.onNodeWithTag(ToggleableTag)
             .fetchSemanticsNode("couldn't find node with tag $ToggleableTag")
-        val toggleableNodeBounds = toggleableNode.globalBounds
+        val toggleableNodeBounds = toggleableNode.boundsInWindow
 
         val toggleableNodeId = delegate.getVirtualViewAt(
             (toggleableNodeBounds.left + toggleableNodeBounds.right) / 2 - rootNodeBoundsLeft,
@@ -704,7 +704,7 @@
             .fetchSemanticsNode("couldn't find node with tag $OverlappedChildOneTag")
         val overlappedChildTwoNode = rule.onNodeWithTag(OverlappedChildTwoTag)
             .fetchSemanticsNode("couldn't find node with tag $OverlappedChildTwoTag")
-        val overlappedChildNodeBounds = overlappedChildTwoNode.globalBounds
+        val overlappedChildNodeBounds = overlappedChildTwoNode.boundsInWindow
         val overlappedChildNodeId = delegate.getVirtualViewAt(
             (overlappedChildNodeBounds.left + overlappedChildNodeBounds.right) / 2 -
                 rootNodeBoundsLeft,
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 a373b13..06683f7 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
@@ -23,11 +23,17 @@
 import android.view.accessibility.AccessibilityNodeInfo
 import android.widget.FrameLayout
 import androidx.activity.ComponentActivity
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.selection.selectable
+import androidx.compose.foundation.selection.selectableGroup
 import androidx.compose.ui.node.InnerPlaceable
 import androidx.compose.ui.node.LayoutNode
 import androidx.compose.ui.platform.AndroidComposeView
 import androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat
 import androidx.compose.ui.platform.LocalClipboardManager
+import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.semantics.ProgressBarRangeInfo
 import androidx.compose.ui.semantics.ScrollAxisRange
 import androidx.compose.ui.semantics.SemanticsModifierCore
@@ -51,6 +57,7 @@
 import androidx.compose.ui.semantics.onLongClick
 import androidx.compose.ui.semantics.pasteText
 import androidx.compose.ui.semantics.role
+import androidx.compose.ui.semantics.selected
 import androidx.compose.ui.semantics.setProgress
 import androidx.compose.ui.semantics.setSelection
 import androidx.compose.ui.semantics.setText
@@ -58,8 +65,10 @@
 import androidx.compose.ui.semantics.textSelectionRange
 import androidx.compose.ui.semantics.verticalScrollAxisRange
 import androidx.compose.ui.test.junit4.createAndroidComposeRule
+import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.text.AnnotatedString
 import androidx.compose.ui.text.TextRange
+import androidx.compose.ui.unit.dp
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -113,9 +122,6 @@
             )
             accessibilityDelegate.accessibilityForceEnabledForTesting = true
         }
-        rule.setContent {
-            LocalClipboardManager.current.setText(AnnotatedString("test"))
-        }
         info = AccessibilityNodeInfoCompat.obtain()
     }
 
@@ -198,6 +204,10 @@
 
     @Test
     fun testPopulateAccessibilityNodeInfoProperties_disabled() {
+        rule.setContent {
+            LocalClipboardManager.current.setText(AnnotatedString("test"))
+        }
+
         val semanticsNode = createSemanticsNodeWithProperties(1, true) {
             disabled()
             text = AnnotatedString("text")
@@ -443,6 +453,10 @@
 
     @Test
     fun test_PasteAction_ifFocused() {
+        rule.setContent {
+            LocalClipboardManager.current.setText(AnnotatedString("test"))
+        }
+
         val semanticsNode = createSemanticsNodeWithProperties(1, true) {
             focused = true
             pasteText {
@@ -465,6 +479,10 @@
 
     @Test
     fun test_noPasteAction_ifUnfocused() {
+        rule.setContent {
+            LocalClipboardManager.current.setText(AnnotatedString("test"))
+        }
+
         val semanticsNode = createSemanticsNodeWithProperties(1, true) {
             pasteText {
                 true
@@ -646,6 +664,46 @@
         )
     }
 
+    @Test
+    fun testCollectionItemInfo() {
+        rule.setContent {
+            Column(Modifier.selectableGroup()) {
+                Box(Modifier.selectable(selected = true, onClick = {}).testTag("item"))
+                Box(Modifier.selectable(selected = false, onClick = {}))
+            }
+        }
+        val itemNode = rule.onNodeWithTag("item").fetchSemanticsNode()
+        accessibilityDelegate.populateAccessibilityNodeInfoProperties(1, info, itemNode)
+
+        val resultCollectionItemInfo = info.collectionItemInfo
+        assertEquals(0, resultCollectionItemInfo.rowIndex)
+        assertEquals(1, resultCollectionItemInfo.rowSpan)
+        assertEquals(0, resultCollectionItemInfo.columnIndex)
+        assertEquals(1, resultCollectionItemInfo.columnSpan)
+        assertEquals(true, resultCollectionItemInfo.isSelected)
+    }
+
+    @Test
+    fun testCollectionInfo() {
+        rule.setContent {
+            Column(Modifier.selectableGroup().testTag("collection")) {
+                Box(Modifier.size(50.dp).selectable(selected = true, onClick = {}))
+                Box(Modifier.size(50.dp).selectable(selected = false, onClick = {}))
+            }
+        }
+        val collectionNode = rule.onNodeWithTag("collection").fetchSemanticsNode()
+        accessibilityDelegate.populateAccessibilityNodeInfoProperties(1, info, collectionNode)
+
+        val resultCollectionInfo = info.collectionInfo
+        assertEquals(2, resultCollectionInfo.rowCount)
+        assertEquals(1, resultCollectionInfo.columnCount)
+        assertEquals(false, resultCollectionInfo.isHierarchical)
+        assertEquals(
+            AccessibilityNodeInfoCompat.CollectionInfoCompat.SELECTION_MODE_SINGLE,
+            resultCollectionInfo.selectionMode
+        )
+    }
+
     private fun createSemanticsNodeWithProperties(
         id: Int,
         mergeDescendants: Boolean,
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidLayoutDrawTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidLayoutDrawTest.kt
index df8a067..96f2d1a 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidLayoutDrawTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidLayoutDrawTest.kt
@@ -72,6 +72,7 @@
 import androidx.compose.ui.layout.LayoutCoordinates
 import androidx.compose.ui.layout.LayoutModifier
 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.ParentDataModifier
@@ -442,7 +443,7 @@
                             modifier = Modifier.fillColor(model, isInner = true)
                         ) { }
                     },
-                    measureBlock = { measurables, constraints ->
+                    measurePolicy = { measurables, constraints ->
                         val placeables = measurables.map { it.measure(constraints) }
                         layout(placeables[0].width, placeables[0].height) {
                             placeables[0].place(0, 0)
@@ -528,7 +529,7 @@
             activity.setContent {
                 val header = @Composable {
                     Layout(
-                        measureBlock = { _, constraints ->
+                        measurePolicy = { _, constraints ->
                             assertEquals(childConstraints[0], constraints)
                             layout(0, 0) {}
                         },
@@ -537,14 +538,14 @@
                 }
                 val footer = @Composable {
                     Layout(
-                        measureBlock = { _, constraints ->
+                        measurePolicy = { _, constraints ->
                             assertEquals(childConstraints[1], constraints)
                             layout(0, 0) {}
                         },
                         content = {}, modifier = Modifier.layoutId("footer")
                     )
                     Layout(
-                        measureBlock = { _, constraints ->
+                        measurePolicy = { _, constraints ->
                             assertEquals(childConstraints[2], constraints)
                             layout(0, 0) {}
                         },
@@ -585,8 +586,10 @@
         activityTestRule.runOnUiThreadIR {
             activity.setContent {
                 Layout(
-                    modifier = Modifier.drawBehind {
-                        drawRect(model.outerColor)
+                    modifier = remember {
+                        Modifier.drawBehind {
+                            drawRect(model.outerColor)
+                        }
                     },
                     content = {
                         AtLeastSize(
@@ -597,16 +600,18 @@
                             }
                         )
                     },
-                    measureBlock = { measurables, constraints ->
-                        measureCalls++
-                        layout(30, 30) {
-                            layoutCalls++
-                            layoutLatch.countDown()
-                            val placeable = measurables[0].measure(constraints)
-                            placeable.place(
-                                (30 - placeable.width) / 2,
-                                (30 - placeable.height) / 2
-                            )
+                    measurePolicy = remember {
+                        MeasurePolicy { measurables, constraints ->
+                            measureCalls++
+                            layout(30, 30) {
+                                layoutCalls++
+                                layoutLatch.countDown()
+                                val placeable = measurables[0].measure(constraints)
+                                placeable.place(
+                                    (30 - placeable.width) / 2,
+                                    (30 - placeable.height) / 2
+                                )
+                            }
                         }
                     }
                 )
@@ -638,7 +643,7 @@
         ) {
             Layout(
                 content = content,
-                measureBlock = { measurables, constraints ->
+                measurePolicy = { measurables, constraints ->
                     val resolvedWidth = constraints.constrainWidth(width)
                     val resolvedHeight = constraints.constrainHeight(height)
                     layout(resolvedWidth, resolvedHeight) {
@@ -676,7 +681,7 @@
                     drawn.value = true
                     latch.countDown()
                 },
-                measureBlock = { _, constraints ->
+                measurePolicy = { _, constraints ->
                     measured.value = true
                     val resolvedWidth = constraints.constrainWidth(width)
                     val resolvedHeight = constraints.minHeight
@@ -1957,7 +1962,7 @@
                         FixedSize(size, layoutModifier)
                         FixedSize(size, parentDataModifier)
                     },
-                    measureBlock = { measurables, constraints ->
+                    measurePolicy = { measurables, constraints ->
                         for (i in 0 until measurables.size) {
                             val child = measurables[i]
                             val placeable = child.measure(constraints)
@@ -3367,6 +3372,33 @@
         validateSquareColors(outerColor = Color.Blue, innerColor = Color.Yellow, size = 10)
     }
 
+    @Test
+    fun placeableMeasuredSize() = with(density) {
+        val realSize = 100.dp
+        val constrainedSize = 50.dp
+        val latch = CountDownLatch(1)
+        activityTestRule.runOnUiThread {
+            activity.setContent {
+                Layout(
+                    content = {
+                        Box(Modifier.requiredSize(realSize))
+                    }
+                ) { measurables, _ ->
+                    val placeable = measurables[0].measure(
+                        Constraints.fixed(constrainedSize.roundToPx(), constrainedSize.roundToPx())
+                    )
+                    assertEquals(realSize.roundToPx(), placeable.measuredWidth)
+                    assertEquals(realSize.roundToPx(), placeable.measuredHeight)
+                    assertEquals(constrainedSize.roundToPx(), placeable.width)
+                    assertEquals(constrainedSize.roundToPx(), placeable.height)
+                    latch.countDown()
+                    layout(1, 1) { }
+                }
+            }
+        }
+        assertTrue(latch.await(1, TimeUnit.SECONDS))
+    }
+
     private fun composeSquares(model: SquareModel) {
         activityTestRule.runOnUiThreadIR {
             activity.setContent {
@@ -3599,7 +3631,7 @@
     content: @Composable () -> Unit = {}
 ) {
     Layout(
-        measureBlock = { measurables, constraints ->
+        measurePolicy = { measurables, constraints ->
             val newConstraints = Constraints(
                 minWidth = max(size, constraints.minWidth),
                 maxWidth = if (constraints.hasBoundedWidth) {
@@ -3657,7 +3689,7 @@
 fun Align(modifier: Modifier = Modifier, content: @Composable () -> Unit) {
     Layout(
         modifier = modifier,
-        measureBlock = { measurables, constraints ->
+        measurePolicy = { measurables, constraints ->
             val newConstraints = Constraints(
                 minWidth = 0,
                 maxWidth = constraints.maxWidth,
@@ -3691,7 +3723,7 @@
 ) {
     Layout(
         modifier = modifier,
-        measureBlock = { measurables, constraints ->
+        measurePolicy = { measurables, constraints ->
             val totalDiff = size * 2
             val targetMinWidth = constraints.minWidth - totalDiff
             val targetMaxWidth = if (constraints.hasBoundedWidth) {
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/ParentDataModifierTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/ParentDataModifierTest.kt
index 5d7ff74..63b75aa 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/ParentDataModifierTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/ParentDataModifierTest.kt
@@ -64,7 +64,7 @@
                     content = {
                         SimpleDrawChild(drawLatch = drawLatch)
                     },
-                    measureBlock = { measurables, constraints ->
+                    measurePolicy = { measurables, constraints ->
                         assertEquals(1, measurables.size)
                         parentData.value = measurables[0].parentData
 
@@ -92,7 +92,7 @@
                     content = {
                         SimpleDrawChild(drawLatch = drawLatch)
                     },
-                    measureBlock = { measurables, constraints ->
+                    measurePolicy = { measurables, constraints ->
                         assertEquals(1, measurables.size)
                         parentData.value = measurables[0].parentData
 
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 cb9746b..e21da4b 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
@@ -18,6 +18,7 @@
 
 import android.content.Context
 import android.view.MotionEvent
+import android.view.View
 import android.view.ViewGroup
 import androidx.activity.ComponentActivity
 import androidx.compose.foundation.gestures.detectTapGestures
@@ -111,7 +112,7 @@
             )
 
             // Act
-            val actual = container.dispatchTouchEvent(motionEvent)
+            val actual = findRootView(container).dispatchTouchEvent(motionEvent)
 
             // Assert
             assertThat(actual).isFalse()
@@ -150,7 +151,7 @@
             )
 
             // Act
-            val actual = container.dispatchTouchEvent(motionEvent)
+            val actual = findRootView(container).dispatchTouchEvent(motionEvent)
 
             // Assert
             assertThat(actual).isTrue()
@@ -176,7 +177,7 @@
     @Test
     fun dispatchTouchEvent_notMeasuredLayoutsAreMeasuredFirst() {
         val size = mutableStateOf(10)
-        val latch = CountDownLatch(1)
+        var latch = CountDownLatch(1)
         var consumedDownPosition: Offset? = null
         rule.runOnUiThread {
             container.setContent {
@@ -199,21 +200,19 @@
         assertThat(latch.await(1, TimeUnit.SECONDS)).isTrue()
 
         rule.runOnUiThread {
-            val androidComposeView = container.getChildAt(0) as AndroidComposeView
-
             // we update size from 10 to 20 pixels
             size.value = 20
             // this call will synchronously mark the LayoutNode as needs remeasure
             Snapshot.sendApplyNotifications()
+            val androidComposeView = container.getChildAt(0) as AndroidComposeView
 
-            val ownerPosition = androidComposeView.calculatePosition()
             val motionEvent = MotionEvent(
                 0,
                 MotionEvent.ACTION_DOWN,
                 1,
                 0,
                 arrayOf(PointerProperties(0)),
-                arrayOf(PointerCoords(ownerPosition.x + 15f, ownerPosition.y + 15f))
+                arrayOf(PointerCoords(15f, 15f))
             )
 
             // we expect it to first remeasure and only then process
@@ -281,7 +280,7 @@
             )
 
             // Act
-            container.dispatchTouchEvent(motionEvent)
+            findRootView(container).dispatchTouchEvent(motionEvent)
 
             // Assert
             assertThat(log).hasSize(1)
@@ -333,10 +332,10 @@
                 arrayOf(PointerCoords(x + 1, y))
             )
 
-            container.dispatchTouchEvent(down)
+            findRootView(container).dispatchTouchEvent(down)
 
             // Act
-            container.dispatchTouchEvent(move)
+            findRootView(container).dispatchTouchEvent(move)
 
             // Assert
             if (callsRequestDisallowInterceptTouchEvent) {
@@ -397,7 +396,7 @@
             )
 
             // Act
-            container.dispatchTouchEvent(motionEvent)
+            findRootView(container).dispatchTouchEvent(motionEvent)
 
             // Assert
             assertThat(log).hasSize(1)
@@ -440,12 +439,12 @@
             container.getLocationInWindow(locationInWindow)
 
             val downEvent = createPointerEventAt(0, MotionEvent.ACTION_DOWN, locationInWindow)
-            container.dispatchTouchEvent(downEvent)
+            findRootView(container).dispatchTouchEvent(downEvent)
         }
 
         rule.runOnUiThread {
             val upEvent = createPointerEventAt(200, MotionEvent.ACTION_UP, locationInWindow)
-            container.dispatchTouchEvent(upEvent)
+            findRootView(container).dispatchTouchEvent(upEvent)
         }
 
         assertTrue(tapLatch.await(1, TimeUnit.SECONDS))
@@ -457,7 +456,7 @@
 
         rule.runOnUiThread {
             val downEvent = createPointerEventAt(1000, MotionEvent.ACTION_DOWN, locationInWindow)
-            container.dispatchTouchEvent(downEvent)
+            findRootView(container).dispatchTouchEvent(downEvent)
         }
         // Need to wait for long press timeout (at least)
         rule.runOnUiThread {
@@ -466,7 +465,7 @@
                 MotionEvent.ACTION_UP,
                 locationInWindow
             )
-            container.dispatchTouchEvent(upEvent)
+            findRootView(container).dispatchTouchEvent(upEvent)
         }
         assertTrue(tapLatch2.await(1, TimeUnit.SECONDS))
 
@@ -476,11 +475,11 @@
 
         rule.runOnUiThread {
             val downEvent = createPointerEventAt(2000, MotionEvent.ACTION_DOWN, locationInWindow)
-            container.dispatchTouchEvent(downEvent)
+            findRootView(container).dispatchTouchEvent(downEvent)
         }
         rule.runOnUiThread {
             val upEvent = createPointerEventAt(2200, MotionEvent.ACTION_UP, locationInWindow)
-            container.dispatchTouchEvent(upEvent)
+            findRootView(container).dispatchTouchEvent(upEvent)
         }
         assertTrue(tapLatch.await(1, TimeUnit.SECONDS))
     }
@@ -621,4 +620,12 @@
     0,
     0,
     0
-)
\ No newline at end of file
+)
+
+internal fun findRootView(view: View): View {
+    val parent = view.parent
+    if (parent is View) {
+        return findRootView(parent)
+    }
+    return view
+}
\ No newline at end of file
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/HitPathTrackerTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/HitPathTrackerTest.kt
index c5b4130..cd96e64 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/HitPathTrackerTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/HitPathTrackerTest.kt
@@ -3160,45 +3160,20 @@
         get() = TODO("not implemented")
 
     override val parentLayoutCoordinates: LayoutCoordinates?
-        get() = TODO("not implemented")
+        get() = null
     override val parentCoordinates: LayoutCoordinates?
-        get() = TODO("Not yet implemented")
+        get() = null
 
-    override fun globalToLocal(global: Offset): Offset {
-        TODO("not implemented")
-    }
+    override fun windowToLocal(relativeToWindow: Offset): Offset = relativeToWindow
 
-    override fun windowToLocal(relativeToWindow: Offset): Offset {
-        TODO("Not yet implemented")
-    }
+    override fun localToWindow(relativeToLocal: Offset): Offset = relativeToLocal
 
-    override fun localToGlobal(local: Offset): Offset {
-        assertThat(isAttached).isTrue()
-        return local + additionalOffset
-    }
-
-    override fun localToWindow(relativeToLocal: Offset): Offset {
-        TODO("Not yet implemented")
-    }
-
-    override fun localToRoot(relativeToLocal: Offset): Offset {
-        TODO("not implemented")
-    }
+    override fun localToRoot(relativeToLocal: Offset): Offset = relativeToLocal
 
     override fun localPositionOf(
         sourceCoordinates: LayoutCoordinates,
         relativeToSource: Offset
-    ): Offset {
-        TODO("Not yet implemented")
-    }
-
-    override fun childToLocal(child: LayoutCoordinates, childLocal: Offset): Offset {
-        TODO("not implemented")
-    }
-
-    override fun childBoundingBox(child: LayoutCoordinates): Rect {
-        TODO("not implemented")
-    }
+    ): Offset = relativeToSource
 
     override fun localBoundingBoxOf(
         sourceCoordinates: LayoutCoordinates,
@@ -3207,7 +3182,7 @@
         TODO("Not yet implemented")
     }
 
-    override fun get(line: AlignmentLine): Int {
+    override fun get(alignmentLine: AlignmentLine): Int {
         TODO("not implemented")
     }
 }
\ No newline at end of file
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/MotionEventAdapterTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/MotionEventAdapterTest.kt
index 34a92d8..90bfb3b 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/MotionEventAdapterTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/MotionEventAdapterTest.kt
@@ -23,6 +23,7 @@
 import android.view.MotionEvent.ACTION_POINTER_DOWN
 import android.view.MotionEvent.ACTION_POINTER_UP
 import android.view.MotionEvent.ACTION_UP
+import androidx.compose.ui.geometry.Offset
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
@@ -35,6 +36,11 @@
 class MotionEventAdapterTest {
 
     private lateinit var motionEventAdapter: MotionEventAdapter
+    private val positionCalculator = object : PositionCalculator {
+        override fun screenToLocal(positionOnScreen: Offset): Offset = positionOnScreen
+
+        override fun localToScreen(localPosition: Offset): Offset = localPosition
+    }
 
     @Before
     fun setup() {
@@ -1519,6 +1525,9 @@
 
         assertThat(pointerInputEvent!!.motionEvent).isSameInstanceAs(motionEvent)
     }
+
+    private fun MotionEventAdapter.convertToPointerInputEvent(motionEvent: MotionEvent) =
+        convertToPointerInputEvent(motionEvent, positionCalculator)
 }
 
 // Private helper functions
@@ -1558,7 +1567,7 @@
 ) {
     assertThat(actual.id).isEqualTo(id)
     assertThat(actual.down).isEqualTo(isDown)
-    assertThat(actual.position.x).isEqualTo(x)
-    assertThat(actual.position.y).isEqualTo(y)
+    assertThat(actual.positionOnScreen.x).isEqualTo(x)
+    assertThat(actual.positionOnScreen.y).isEqualTo(y)
     assertThat(actual.type).isEqualTo(type)
 }
\ No newline at end of file
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessorTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessorTest.kt
index eb20a0d..f3cd0a8 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessorTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessorTest.kt
@@ -16,6 +16,8 @@
 
 package androidx.compose.ui.input.pointer
 
+import android.view.MotionEvent
+import androidx.compose.foundation.layout.offset
 import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.autofill.Autofill
@@ -37,6 +39,7 @@
 import androidx.compose.ui.node.Owner
 import androidx.compose.ui.node.OwnerSnapshotObserver
 import androidx.compose.ui.node.RootForTest
+import androidx.compose.ui.platform.AccessibilityManager
 import androidx.compose.ui.platform.ClipboardManager
 import androidx.compose.ui.platform.TextToolbar
 import androidx.compose.ui.platform.ViewConfiguration
@@ -49,6 +52,7 @@
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.minus
+import androidx.compose.ui.unit.toOffset
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
@@ -85,6 +89,11 @@
 
     private lateinit var pointerInputEventProcessor: PointerInputEventProcessor
     private lateinit var testOwner: TestOwner
+    private val positionCalculator = object : PositionCalculator {
+        override fun screenToLocal(positionOnScreen: Offset): Offset = positionOnScreen
+
+        override fun localToScreen(localPosition: Offset): Offset = localPosition
+    }
 
     @Before
     fun setup() {
@@ -124,6 +133,7 @@
                 id = PointerId(index.toLong()),
                 uptime = index.toLong(),
                 position = Offset(offset.x + index, offset.y + index),
+                positionOnScreen = Offset(offset.x + index, offset.y + index),
                 down = true,
                 type = pointerType
             )
@@ -590,9 +600,15 @@
             insertAt(0, middleLayoutNode)
         }
 
-        testOwner.position = IntOffset(aOX, aOY)
+        val outerLayoutNode = LayoutNode(
+            aOX,
+            aOY,
+            aOX + parentLayoutNode.width,
+            aOY + parentLayoutNode.height
+        )
 
-        addToRoot(parentLayoutNode)
+        outerLayoutNode.insertAt(0, parentLayoutNode)
+        addToRoot(outerLayoutNode)
 
         val additionalOffset = IntOffset(aOX, aOY)
 
@@ -1531,7 +1547,9 @@
                 singlePointerInputFilter
             )
         )
-        addToRoot(layoutNode)
+        val outerLayoutNode = LayoutNode(1, 1, 3, 3)
+        outerLayoutNode.insertAt(0, layoutNode)
+        addToRoot(outerLayoutNode)
         val offsetsThatHit =
             listOf(
                 Offset(2f, 2f),
@@ -1552,7 +1570,6 @@
                     PointerInputEventData(it, 11, allOffsets[it], true)
                 }
             )
-        testOwner.position = IntOffset(1, 1)
 
         // Act
 
@@ -2960,6 +2977,11 @@
         assertThat(processResult1.dispatchedToAPointerInputModifier).isFalse()
         assertThat(processResult1.anyMovementConsumed).isFalse()
     }
+
+    private fun MotionEventAdapter.convertToPointerInputEvent(motionEvent: MotionEvent) =
+        convertToPointerInputEvent(motionEvent, positionCalculator)
+    private fun PointerInputEventProcessor.process(event: PointerInputEvent) =
+        process(event, positionCalculator)
 }
 
 private class PointerInputModifierImpl2(override val pointerInputFilter: PointerInputFilter) :
@@ -2973,9 +2995,8 @@
                 placeable.place(x, y)
             }
         }.then(modifier)
-        measureBlocks = object : LayoutNode.NoIntrinsicsMeasureBlocks("not supported") {
-            override fun measure(
-                measureScope: MeasureScope,
+        measurePolicy = object : LayoutNode.NoIntrinsicsMeasurePolicy("not supported") {
+            override fun MeasureScope.measure(
                 measurables: List<Measurable>,
                 constraints: Constraints
             ): MeasureResult =
@@ -2997,9 +3018,6 @@
         delegate.updateRootConstraints(Constraints(maxWidth = 500, maxHeight = 500))
     }
 
-    override fun calculatePosition(): IntOffset = position
-    override fun calculatePositionInWindow(): IntOffset = position
-
     override fun requestFocus(): Boolean = false
     override val rootForTest: RootForTest
         get() = TODO("Not yet implemented")
@@ -3007,6 +3025,8 @@
         get() = TODO("Not yet implemented")
     override val clipboardManager: ClipboardManager
         get() = TODO("Not yet implemented")
+    override val accessibilityManager: AccessibilityManager
+        get() = TODO("Not yet implemented")
     override val textToolbar: TextToolbar
         get() = TODO("Not yet implemented")
     override val autofillTree: AutofillTree
@@ -3043,6 +3063,12 @@
     override fun onDetach(node: LayoutNode) {
     }
 
+    override fun calculatePositionInWindow(localPosition: Offset): Offset =
+        localPosition + position.toOffset()
+
+    override fun calculateLocalPosition(positionInWindow: Offset): Offset =
+        positionInWindow - position.toOffset()
+
     override fun measureAndLayout() {
         delegate.measureAndLayout()
     }
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInteropFilterTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInteropFilterTest.kt
index 6a6060b..2600605 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInteropFilterTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInteropFilterTest.kt
@@ -4374,10 +4374,8 @@
         override val isAttached: Boolean
             get() = true
 
-        override fun globalToLocal(global: Offset): Offset = Offset.Zero
         override fun windowToLocal(relativeToWindow: Offset): Offset = Offset.Zero
 
-        override fun localToGlobal(local: Offset): Offset = Offset.Zero
         override fun localToWindow(relativeToLocal: Offset): Offset = Offset.Zero
 
         override fun localToRoot(relativeToLocal: Offset): Offset = Offset.Zero
@@ -4386,16 +4384,12 @@
             relativeToSource: Offset
         ): Offset = Offset.Zero
 
-        override fun childToLocal(child: LayoutCoordinates, childLocal: Offset): Offset =
-            Offset.Zero
-
-        override fun childBoundingBox(child: LayoutCoordinates): Rect = Rect.Zero
         override fun localBoundingBoxOf(
             sourceCoordinates: LayoutCoordinates,
             clipBounds: Boolean
         ): Rect = Rect.Zero
 
-        override fun get(line: AlignmentLine): Int = 0
+        override fun get(alignmentLine: AlignmentLine): Int = 0
     }
 }
 
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt
index 7efb18d..9046500 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt
@@ -33,7 +33,7 @@
 import androidx.lifecycle.Lifecycle
 import androidx.test.core.app.ActivityScenario
 import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.MediumTest
+import androidx.test.filters.LargeTest
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CompletableDeferred
@@ -240,7 +240,7 @@
     }
 
     @Test
-    @MediumTest
+    @LargeTest
     fun testRestartPointerInput() = runBlocking {
         var toAdd by mutableStateOf("initial")
         val result = mutableListOf<String>()
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/TestUtils.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/TestUtils.kt
index c7458de..d1874dc 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/TestUtils.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/TestUtils.kt
@@ -40,6 +40,7 @@
         PointerId(id.toLong()),
         uptime,
         position,
+        position,
         down,
         PointerType.Touch
     )
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/Helpers.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/Helpers.kt
index 65a92f9..dd0f380 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/Helpers.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/Helpers.kt
@@ -144,7 +144,7 @@
 
 internal fun node(block: LayoutNode.() -> Unit = {}): LayoutNode {
     return LayoutNode().apply {
-        measureBlocks = MeasureInMeasureBlock()
+        measurePolicy = MeasureInMeasureBlock()
         block.invoke(this)
     }
 }
@@ -152,57 +152,57 @@
 internal fun LayoutNode.add(child: LayoutNode) = insertAt(children.count(), child)
 
 internal fun LayoutNode.measureInLayoutBlock() {
-    measureBlocks = MeasureInLayoutBlock()
+    measurePolicy = MeasureInLayoutBlock()
 }
 
 internal fun LayoutNode.doNotMeasure() {
-    measureBlocks = NoMeasureBlock()
+    measurePolicy = NoMeasure()
 }
 
 internal fun LayoutNode.queryAlignmentLineDuringMeasure() {
-    (measureBlocks as SmartMeasureBlock).queryAlignmentLinesDuringMeasure = true
+    (measurePolicy as SmartMeasurePolicy).queryAlignmentLinesDuringMeasure = true
 }
 
 internal fun LayoutNode.runDuringMeasure(block: () -> Unit) {
-    (measureBlocks as SmartMeasureBlock).preMeasureCallback = block
+    (measurePolicy as SmartMeasurePolicy).preMeasureCallback = block
 }
 
 internal fun LayoutNode.runDuringLayout(block: () -> Unit) {
-    (measureBlocks as SmartMeasureBlock).preLayoutCallback = block
+    (measurePolicy as SmartMeasurePolicy).preLayoutCallback = block
 }
 
 internal val LayoutNode.first: LayoutNode get() = children.first()
 internal val LayoutNode.second: LayoutNode get() = children[1]
 internal val LayoutNode.measuresCount: Int
-    get() = (measureBlocks as SmartMeasureBlock).measuresCount
+    get() = (measurePolicy as SmartMeasurePolicy).measuresCount
 internal val LayoutNode.layoutsCount: Int
-    get() = (measureBlocks as SmartMeasureBlock).layoutsCount
+    get() = (measurePolicy as SmartMeasurePolicy).layoutsCount
 internal var LayoutNode.wrapChildren: Boolean
-    get() = (measureBlocks as SmartMeasureBlock).wrapChildren
+    get() = (measurePolicy as SmartMeasurePolicy).wrapChildren
     set(value) {
-        (measureBlocks as SmartMeasureBlock).wrapChildren = value
+        (measurePolicy as SmartMeasurePolicy).wrapChildren = value
     }
 internal val LayoutNode.measuredWithLayoutDirection: LayoutDirection
-    get() = (measureBlocks as SmartMeasureBlock).measuredLayoutDirection!!
+    get() = (measurePolicy as SmartMeasurePolicy).measuredLayoutDirection!!
 internal var LayoutNode.size: Int?
-    get() = (measureBlocks as SmartMeasureBlock).size
+    get() = (measurePolicy as SmartMeasurePolicy).size
     set(value) {
-        (measureBlocks as SmartMeasureBlock).size = value
+        (measurePolicy as SmartMeasurePolicy).size = value
     }
 internal var LayoutNode.childrenDirection: LayoutDirection?
-    get() = (measureBlocks as SmartMeasureBlock).childrenLayoutDirection
+    get() = (measurePolicy as SmartMeasurePolicy).childrenLayoutDirection
     set(value) {
-        (measureBlocks as SmartMeasureBlock).childrenLayoutDirection = value
+        (measurePolicy as SmartMeasurePolicy).childrenLayoutDirection = value
     }
 internal var LayoutNode.shouldPlaceChildren: Boolean
-    get() = (measureBlocks as SmartMeasureBlock).shouldPlaceChildren
+    get() = (measurePolicy as SmartMeasurePolicy).shouldPlaceChildren
     set(value) {
-        (measureBlocks as SmartMeasureBlock).shouldPlaceChildren = value
+        (measurePolicy as SmartMeasurePolicy).shouldPlaceChildren = value
     }
 
 internal val TestAlignmentLine = HorizontalAlignmentLine(::min)
 
-internal abstract class SmartMeasureBlock : LayoutNode.NoIntrinsicsMeasureBlocks("") {
+internal abstract class SmartMeasurePolicy : LayoutNode.NoIntrinsicsMeasurePolicy("") {
     var measuresCount = 0
         protected set
     var layoutsCount = 0
@@ -219,9 +219,8 @@
     var shouldPlaceChildren = true
 }
 
-internal class MeasureInMeasureBlock : SmartMeasureBlock() {
-    override fun measure(
-        measureScope: MeasureScope,
+internal class MeasureInMeasureBlock : SmartMeasurePolicy() {
+    override fun MeasureScope.measure(
         measurables: List<Measurable>,
         constraints: Constraints
     ): MeasureResult {
@@ -251,7 +250,7 @@
                 maxHeight = max(placeable.height, maxHeight)
             }
         }
-        return measureScope.layout(maxWidth, maxHeight) {
+        return layout(maxWidth, maxHeight) {
             layoutsCount++
             preLayoutCallback?.invoke()
             preLayoutCallback = null
@@ -264,7 +263,7 @@
     }
 }
 
-internal class MeasureInLayoutBlock : SmartMeasureBlock() {
+internal class MeasureInLayoutBlock : SmartMeasurePolicy() {
 
     override var wrapChildren: Boolean
         get() = false
@@ -285,8 +284,7 @@
             }
         }
 
-    override fun measure(
-        measureScope: MeasureScope,
+    override fun MeasureScope.measure(
         measurables: List<Measurable>,
         constraints: Constraints
     ): MeasureResult {
@@ -299,7 +297,7 @@
             val size = size!!
             constraints.copy(maxWidth = size, maxHeight = size)
         }
-        return measureScope.layout(childConstraints.maxWidth, childConstraints.maxHeight) {
+        return layout(childConstraints.maxWidth, childConstraints.maxHeight) {
             preLayoutCallback?.invoke()
             preLayoutCallback = null
             layoutsCount++
@@ -313,7 +311,7 @@
     }
 }
 
-internal class NoMeasureBlock : SmartMeasureBlock() {
+internal class NoMeasure : SmartMeasurePolicy() {
 
     override var queryAlignmentLinesDuringMeasure: Boolean
         get() = false
@@ -326,8 +324,7 @@
             }
         }
 
-    override fun measure(
-        measureScope: MeasureScope,
+    override fun MeasureScope.measure(
         measurables: List<Measurable>,
         constraints: Constraints
     ): MeasureResult {
@@ -337,7 +334,7 @@
 
         val width = size ?: if (!wrapChildren) constraints.maxWidth else constraints.minWidth
         val height = size ?: if (!wrapChildren) constraints.maxHeight else constraints.minHeight
-        return measureScope.layout(width, height) {
+        return layout(width, height) {
             layoutsCount++
             preLayoutCallback?.invoke()
             preLayoutCallback = null
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/OnGloballyPositionedTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/OnGloballyPositionedTest.kt
index e27a680..2554407 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/OnGloballyPositionedTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/OnGloballyPositionedTest.kt
@@ -20,7 +20,7 @@
 import android.view.ViewGroup
 import android.widget.LinearLayout
 import android.widget.ScrollView
-import androidx.activity.compose.setContent
+import androidx.activity.ComponentActivity
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.padding
@@ -30,124 +30,112 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.AtLeastSize
 import androidx.compose.ui.FixedSize
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.SimpleRow
 import androidx.compose.ui.Wrap
+import androidx.compose.ui.background
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Rect
+import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.padding
+import androidx.compose.ui.platform.AndroidComposeView
 import androidx.compose.ui.platform.ComposeView
 import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.runOnUiThreadIR
-import androidx.compose.ui.test.TestActivity
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.test.junit4.createAndroidComposeRule
+import androidx.compose.ui.test.onRoot
 import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.window.Popup
 import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
+import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertNotNull
 import org.junit.Assert.assertTrue
-import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.TimeUnit
 import kotlin.math.min
+import kotlin.math.sqrt
 
-@SmallTest
+@MediumTest
 @RunWith(AndroidJUnit4::class)
 class OnGloballyPositionedTest {
 
-    @Suppress("DEPRECATION")
     @get:Rule
-    val rule = androidx.test.rule.ActivityTestRule<TestActivity>(TestActivity::class.java)
-    private lateinit var activity: TestActivity
-
-    @Before
-    fun setup() {
-        activity = rule.activity
-        activity.hasFocusLatch.await(5, TimeUnit.SECONDS)
-    }
+    val rule = createAndroidComposeRule<ComponentActivity>()
 
     @Test
     fun handlesChildrenNodeMoveCorrectly() {
         val size = 50
         var index by mutableStateOf(0)
-        var latch = CountDownLatch(2)
         var wrap1Position = 0f
         var wrap2Position = 0f
-        rule.runOnUiThread {
-            activity.setContent {
-                SimpleRow {
-                    for (i in 0 until 2) {
-                        if (index == i) {
-                            Wrap(
-                                minWidth = size,
-                                minHeight = size,
-                                modifier = Modifier.onGloballyPositioned { coordinates ->
-                                    wrap1Position = coordinates.positionInWindow().x
-                                    latch.countDown()
-                                }
-                            )
-                        } else {
-                            Wrap(
-                                minWidth = size,
-                                minHeight = size,
-                                modifier = Modifier.onGloballyPositioned { coordinates ->
-                                    wrap2Position = coordinates.positionInWindow().x
-                                    latch.countDown()
-                                }
-                            )
-                        }
+        rule.setContent {
+            SimpleRow {
+                for (i in 0 until 2) {
+                    if (index == i) {
+                        Wrap(
+                            minWidth = size,
+                            minHeight = size,
+                            modifier = Modifier.onGloballyPositioned { coordinates ->
+                                wrap1Position = coordinates.positionInWindow().x
+                            }
+                        )
+                    } else {
+                        Wrap(
+                            minWidth = size,
+                            minHeight = size,
+                            modifier = Modifier.onGloballyPositioned { coordinates ->
+                                wrap2Position = coordinates.positionInWindow().x
+                            }
+                        )
                     }
                 }
             }
         }
-        assertTrue(latch.await(1, TimeUnit.SECONDS))
-        assertEquals(0f, wrap1Position)
-        assertEquals(size.toFloat(), wrap2Position)
-        latch = CountDownLatch(2)
-        rule.runOnUiThread {
+
+        rule.runOnIdle {
+            assertEquals(0f, wrap1Position)
+            assertEquals(size.toFloat(), wrap2Position)
             index = 1
         }
-        assertTrue(latch.await(1, TimeUnit.SECONDS))
-        assertEquals(size.toFloat(), wrap1Position)
-        assertEquals(0f, wrap2Position)
+
+        rule.runOnIdle {
+            assertEquals(size.toFloat(), wrap1Position)
+            assertEquals(0f, wrap2Position)
+        }
     }
 
     @Test
     fun callbacksAreCalledWhenChildResized() {
         var size by mutableStateOf(10)
         var realChildSize = 0
-        var childLatch = CountDownLatch(1)
-        rule.runOnUiThreadIR {
-            activity.setContent {
-                AtLeastSize(size = 20) {
-                    Wrap(
-                        minWidth = size, minHeight = size,
-                        modifier = Modifier.onGloballyPositioned {
-                            realChildSize = it.size.width
-                            childLatch.countDown()
-                        }
-                    )
-                }
+        rule.setContent {
+            AtLeastSize(size = 20) {
+                Wrap(
+                    minWidth = size, minHeight = size,
+                    modifier = Modifier.onGloballyPositioned {
+                        realChildSize = it.size.width
+                    }
+                )
             }
         }
 
-        assertTrue(childLatch.await(1, TimeUnit.SECONDS))
-        assertEquals(10, realChildSize)
-
-        childLatch = CountDownLatch(1)
-        rule.runOnUiThread {
+        rule.runOnIdle {
+            assertEquals(10, realChildSize)
             size = 15
         }
 
-        assertTrue(childLatch.await(1, TimeUnit.SECONDS))
-        assertEquals(15, realChildSize)
+        rule.runOnIdle {
+            assertEquals(15, realChildSize)
+        }
     }
 
     @Test
@@ -155,31 +143,29 @@
         var position by mutableStateOf(0)
         var childGlobalPosition = Offset(0f, 0f)
         var latch = CountDownLatch(1)
-        rule.runOnUiThreadIR {
-            activity.setContent {
-                Layout(
-                    measureBlock = { measurables, constraints ->
-                        layout(10, 10) {
-                            measurables[0].measure(constraints).place(position, 0)
-                        }
-                    },
-                    content = {
+        rule.setContent {
+            Layout(
+                measurePolicy = { measurables, constraints ->
+                    layout(10, 10) {
+                        measurables[0].measure(constraints).place(position, 0)
+                    }
+                },
+                content = {
+                    Wrap(
+                        minWidth = 10,
+                        minHeight = 10
+                    ) {
                         Wrap(
                             minWidth = 10,
-                            minHeight = 10
-                        ) {
-                            Wrap(
-                                minWidth = 10,
-                                minHeight = 10,
-                                modifier = Modifier.onGloballyPositioned { coordinates ->
-                                    childGlobalPosition = coordinates.positionInRoot()
-                                    latch.countDown()
-                                }
-                            )
-                        }
+                            minHeight = 10,
+                            modifier = Modifier.onGloballyPositioned { coordinates ->
+                                childGlobalPosition = coordinates.positionInRoot()
+                                latch.countDown()
+                            }
+                        )
                     }
-                )
-            }
+                }
+            )
         }
 
         assertTrue(latch.await(1, TimeUnit.SECONDS))
@@ -198,40 +184,38 @@
         val latch = CountDownLatch(1)
         var wrap1OnPositionedCalled = false
         var wrap2OnPositionedCalled = false
-        rule.runOnUiThread {
-            activity.setContent {
-                Layout(
-                    measureBlock = { measurables, constraints ->
-                        layout(10, 10) {
-                            measurables[1].measure(constraints).place(0, 0)
+        rule.setContent {
+            Layout(
+                measurePolicy = { measurables, constraints ->
+                    layout(10, 10) {
+                        measurables[1].measure(constraints).place(0, 0)
+                    }
+                },
+                content = {
+                    Wrap(
+                        minWidth = 10,
+                        minHeight = 10,
+                        modifier = Modifier.onGloballyPositioned {
+                            wrap1OnPositionedCalled = true
                         }
-                    },
-                    content = {
+                    )
+                    Wrap(
+                        minWidth = 10,
+                        minHeight = 10,
+                        modifier = Modifier.onGloballyPositioned {
+                            wrap2OnPositionedCalled = true
+                        }
+                    ) {
                         Wrap(
                             minWidth = 10,
                             minHeight = 10,
                             modifier = Modifier.onGloballyPositioned {
-                                wrap1OnPositionedCalled = true
+                                latch.countDown()
                             }
                         )
-                        Wrap(
-                            minWidth = 10,
-                            minHeight = 10,
-                            modifier = Modifier.onGloballyPositioned {
-                                wrap2OnPositionedCalled = true
-                            }
-                        ) {
-                            Wrap(
-                                minWidth = 10,
-                                minHeight = 10,
-                                modifier = Modifier.onGloballyPositioned {
-                                    latch.countDown()
-                                }
-                            )
-                        }
                     }
-                )
-            }
+                }
+            )
         }
 
         assertTrue(latch.await(1, TimeUnit.SECONDS))
@@ -244,31 +228,29 @@
         val positionedLatch = CountDownLatch(1)
         var coordinates: LayoutCoordinates? = null
 
-        rule.runOnUiThread {
-            activity.setContent {
-                FixedSize(
-                    10,
-                    Modifier.padding(5).then(
-                        Modifier.onGloballyPositioned {
-                            coordinates = it
-                            positionedLatch.countDown()
-                        }
-                    )
-                ) {
-                }
+        rule.setContent {
+            FixedSize(
+                10,
+                Modifier.padding(5).then(
+                    Modifier.onGloballyPositioned {
+                        coordinates = it
+                        positionedLatch.countDown()
+                    }
+                )
+            ) {
             }
         }
         assertTrue(positionedLatch.await(1, TimeUnit.SECONDS))
 
         rule.runOnUiThread {
-            assertEquals(Offset(5f, 5f), coordinates!!.positionInParent)
+            assertEquals(Offset(5f, 5f), coordinates!!.positionInParent())
 
             var root = coordinates!!
             while (root.parentLayoutCoordinates != null) {
                 root = root.parentLayoutCoordinates!!
             }
 
-            assertEquals(Offset.Zero, root.positionInParent)
+            assertEquals(Offset.Zero, root.positionInParent())
         }
     }
 
@@ -277,31 +259,29 @@
         val positionedLatch = CountDownLatch(1)
         var coordinates: LayoutCoordinates? = null
 
-        rule.runOnUiThread {
-            activity.setContent {
-                FixedSize(
-                    10,
-                    Modifier.padding(5).then(
-                        Modifier.onGloballyPositioned {
-                            coordinates = it
-                            positionedLatch.countDown()
-                        }
-                    )
-                ) {
-                }
+        rule.setContent {
+            FixedSize(
+                10,
+                Modifier.padding(5).then(
+                    Modifier.onGloballyPositioned {
+                        coordinates = it
+                        positionedLatch.countDown()
+                    }
+                )
+            ) {
             }
         }
         assertTrue(positionedLatch.await(1, TimeUnit.SECONDS))
 
         rule.runOnUiThread {
-            assertEquals(Rect(5f, 5f, 15f, 15f), coordinates!!.boundsInParent)
+            assertEquals(Rect(5f, 5f, 15f, 15f), coordinates!!.boundsInParent())
 
             var root = coordinates!!
             while (root.parentLayoutCoordinates != null) {
                 root = root.parentLayoutCoordinates!!
             }
 
-            assertEquals(Rect(0f, 0f, 20f, 20f), root.boundsInParent)
+            assertEquals(Rect(0f, 0f, 20f, 20f), root.boundsInParent())
         }
     }
 
@@ -310,14 +290,14 @@
         var positionedLatch = CountDownLatch(1)
         var coordinates: LayoutCoordinates? = null
         var scrollView: ScrollView? = null
-        var view: ComposeView? = null
+        lateinit var view: ComposeView
 
         rule.runOnUiThread {
             scrollView = ScrollView(rule.activity)
-            activity.setContentView(scrollView, ViewGroup.LayoutParams(100, 100))
+            rule.activity.setContentView(scrollView, ViewGroup.LayoutParams(100, 100))
             view = ComposeView(rule.activity)
             scrollView!!.addView(view)
-            view?.setContent {
+            view.setContent {
                 Layout(
                     {},
                     modifier = Modifier.onGloballyPositioned {
@@ -340,13 +320,21 @@
             "OnPositioned is not called when the container scrolled",
             positionedLatch.await(1, TimeUnit.SECONDS)
         )
-        // There is a bug on older devices where the location isn't exactly 50
-        // pixels off of the start position, even though we've scrolled by 50 pixels.
-        val position = intArrayOf(0, 0)
-        rule.runOnUiThread {
-            view?.getLocationOnScreen(position)
+        val position = rule.runOnUiThread {
+            view.getYInWindow()
         }
-        assertEquals(position[1].toFloat(), coordinates!!.positionInWindow().y)
+        assertEquals(position, coordinates!!.positionInWindow().y)
+    }
+
+    private fun View.getYInWindow(): Float {
+        var offset = 0f
+        val parentView = parent
+        if (parentView is View) {
+            offset += parentView.getYInWindow()
+            offset -= scrollY.toFloat()
+            offset += top.toFloat()
+        }
+        return offset
     }
 
     @Test
@@ -358,7 +346,7 @@
         rule.runOnUiThread {
             val linearLayout = LinearLayout(rule.activity)
             linearLayout.orientation = LinearLayout.VERTICAL
-            activity.setContentView(linearLayout, ViewGroup.LayoutParams(100, 200))
+            rule.activity.setContentView(linearLayout, ViewGroup.LayoutParams(100, 200))
             topView = View(rule.activity)
             linearLayout.addView(topView!!, ViewGroup.LayoutParams(100, 100))
             val view = ComposeView(rule.activity)
@@ -392,47 +380,45 @@
 
     @Test
     fun onPositionedCalledInDifferentPartsOfHierarchy() {
-        var positionedLatch = CountDownLatch(2)
         var coordinates1: LayoutCoordinates? = null
         var coordinates2: LayoutCoordinates? = null
         var size by mutableStateOf(10f)
 
-        rule.runOnUiThread {
-            activity.setContent {
-                with(LocalDensity.current) {
-                    DelayedMeasure(50) {
-                        Box(Modifier.requiredSize(25.toDp())) {
-                            Box(
-                                Modifier.requiredSize(size.toDp())
-                                    .onGloballyPositioned {
-                                        coordinates1 = it
-                                        positionedLatch.countDown()
-                                    }
-                            )
-                        }
-                        Box(Modifier.requiredSize(25.toDp())) {
-                            Box(
-                                Modifier.requiredSize(size.toDp())
-                                    .onGloballyPositioned {
-                                        coordinates2 = it
-                                        positionedLatch.countDown()
-                                    }
-                            )
-                        }
+        rule.setContent {
+            with(LocalDensity.current) {
+                DelayedMeasure(50) {
+                    Box(Modifier.requiredSize(25.toDp())) {
+                        Box(
+                            Modifier.requiredSize(size.toDp())
+                                .onGloballyPositioned {
+                                    coordinates1 = it
+                                }
+                        )
+                    }
+                    Box(Modifier.requiredSize(25.toDp())) {
+                        Box(
+                            Modifier.requiredSize(size.toDp())
+                                .onGloballyPositioned {
+                                    coordinates2 = it
+                                }
+                        )
                     }
                 }
             }
         }
-        assertTrue(positionedLatch.await(1, TimeUnit.SECONDS))
-        assertNotNull(coordinates1)
-        assertNotNull(coordinates2)
-        positionedLatch = CountDownLatch(2)
 
-        rule.runOnUiThread {
+        rule.runOnIdle {
+            assertNotNull(coordinates1)
+            assertNotNull(coordinates2)
+            coordinates1 = null
+            coordinates2 = null
             size = 15f
         }
 
-        assertTrue(positionedLatch.await(1, TimeUnit.SECONDS))
+        rule.runOnIdle {
+            assertNotNull(coordinates1)
+            assertNotNull(coordinates2)
+        }
     }
 
     @Test
@@ -443,19 +429,17 @@
         var realTop: Float? = null
 
         val positionedLatch = CountDownLatch(1)
-        rule.runOnUiThread {
-            activity.setContent {
-                with(LocalDensity.current) {
-                    Box(
-                        Modifier.fillMaxSize()
-                            .padding(start = paddingLeftPx.toDp(), top = paddingTopPx.toDp())
-                            .onGloballyPositioned {
-                                realLeft = it.positionInParent.x
-                                realTop = it.positionInParent.y
-                                positionedLatch.countDown()
-                            }
-                    )
-                }
+        rule.setContent {
+            with(LocalDensity.current) {
+                Box(
+                    Modifier.fillMaxSize()
+                        .padding(start = paddingLeftPx.toDp(), top = paddingTopPx.toDp())
+                        .onGloballyPositioned {
+                            realLeft = it.positionInParent().x
+                            realTop = it.positionInParent().y
+                            positionedLatch.countDown()
+                        }
+                )
             }
         }
         assertTrue(positionedLatch.await(1, TimeUnit.SECONDS))
@@ -463,6 +447,7 @@
         assertThat(paddingLeftPx).isEqualTo(realLeft)
         assertThat(paddingTopPx).isEqualTo(realTop)
     }
+
     @Test
     fun nestedLayoutCoordinates() {
         val firstPaddingPx = 10f
@@ -472,27 +457,25 @@
         var childCoordinates: LayoutCoordinates? = null
 
         val positionedLatch = CountDownLatch(2)
-        rule.runOnUiThread {
-            activity.setContent {
-                with(LocalDensity.current) {
-                    Box(
-                        Modifier.padding(start = firstPaddingPx.toDp()).then(
-                            Modifier.onGloballyPositioned {
-                                gpCoordinates = it
-                                positionedLatch.countDown()
-                            }
-                        )
-                    ) {
-                        Box(Modifier.padding(start = secondPaddingPx.toDp())) {
-                            Box(
-                                Modifier.fillMaxSize()
-                                    .padding(start = thirdPaddingPx.toDp())
-                                    .onGloballyPositioned {
-                                        childCoordinates = it
-                                        positionedLatch.countDown()
-                                    }
-                            )
+        rule.setContent {
+            with(LocalDensity.current) {
+                Box(
+                    Modifier.padding(start = firstPaddingPx.toDp()).then(
+                        Modifier.onGloballyPositioned {
+                            gpCoordinates = it
+                            positionedLatch.countDown()
                         }
+                    )
+                ) {
+                    Box(Modifier.padding(start = secondPaddingPx.toDp())) {
+                        Box(
+                            Modifier.fillMaxSize()
+                                .padding(start = thirdPaddingPx.toDp())
+                                .onGloballyPositioned {
+                                    childCoordinates = it
+                                    positionedLatch.countDown()
+                                }
+                        )
                     }
                 }
             }
@@ -506,7 +489,7 @@
         val gpPos = gpCoordinates!!.localPositionOf(childCoordinates!!, Offset.Zero).x
         assertThat(gpPos).isEqualTo((secondPaddingPx + thirdPaddingPx))
         // local position
-        assertThat(childCoordinates!!.positionInParent.x).isEqualTo(thirdPaddingPx)
+        assertThat(childCoordinates!!.positionInParent().x).isEqualTo(thirdPaddingPx)
     }
 
     @Test
@@ -520,9 +503,9 @@
 
         val positionedLatch = CountDownLatch(1)
         rule.runOnUiThread {
-            val composeView = ComposeView(activity)
+            val composeView = ComposeView(rule.activity)
             composeView.setPadding(padding, padding, padding, padding)
-            activity.setContentView(composeView)
+            rule.activity.setContentView(composeView)
 
             val position = IntArray(2)
             composeView.getLocationOnScreen(position)
@@ -550,21 +533,21 @@
     fun justAddedOnPositionedCallbackFiredWithoutLayoutChanges() {
         val needCallback = mutableStateOf(false)
 
-        val positionedLatch = CountDownLatch(1)
-        rule.runOnUiThread {
-            activity.setContent {
-                val modifier = if (needCallback.value) {
-                    Modifier.onGloballyPositioned { positionedLatch.countDown() }
-                } else {
-                    Modifier
-                }
-                Box(modifier.fillMaxSize())
+        var positionedCalled = false
+        rule.setContent {
+            val modifier = if (needCallback.value) {
+                Modifier.onGloballyPositioned { positionedCalled = true }
+            } else {
+                Modifier
             }
+            Box(modifier.fillMaxSize())
         }
 
-        rule.runOnUiThread { needCallback.value = true }
+        rule.runOnIdle { needCallback.value = true }
 
-        assertTrue(positionedLatch.await(1, TimeUnit.SECONDS))
+        rule.runOnIdle {
+            assertThat(positionedCalled).isTrue()
+        }
     }
 
     @Test
@@ -572,30 +555,25 @@
         val left = mutableStateOf(30)
         var realLeft: Float? = null
 
-        var positionedLatch = CountDownLatch(1)
-        rule.runOnUiThread {
-            activity.setContent {
-                with(LocalDensity.current) {
-                    Box {
-                        Box(
-                            Modifier.onGloballyPositioned {
-                                realLeft = it.positionInParent.x
-                                positionedLatch.countDown()
-                            }
-                                .fillMaxSize()
-                                .padding(start = left.value.toDp()),
-                        )
-                    }
+        rule.setContent {
+            with(LocalDensity.current) {
+                Box {
+                    Box(
+                        Modifier.onGloballyPositioned {
+                            realLeft = it.positionInParent().x
+                        }
+                            .fillMaxSize()
+                            .padding(start = left.value.toDp()),
+                    )
                 }
             }
         }
-        assertTrue(positionedLatch.await(1, TimeUnit.SECONDS))
 
-        positionedLatch = CountDownLatch(1)
-        rule.runOnUiThread { left.value = 40 }
+        rule.runOnIdle { left.value = 40 }
 
-        assertTrue(positionedLatch.await(1, TimeUnit.SECONDS))
-        assertThat(realLeft).isEqualTo(40)
+        rule.runOnIdle {
+            assertThat(realLeft).isEqualTo(40)
+        }
     }
 
     @Test
@@ -606,20 +584,18 @@
         val left = mutableStateOf(20)
         var realLeft: Float? = null
         var positionedLatch = CountDownLatch(1)
-        rule.runOnUiThread {
-            activity.setContent {
-                with(LocalDensity.current) {
-                    Box {
-                        Offset(left) {
+        rule.setContent {
+            with(LocalDensity.current) {
+                Box {
+                    Offset(left) {
+                        Box(Modifier.requiredSize(10.toDp())) {
                             Box(Modifier.requiredSize(10.toDp())) {
-                                Box(Modifier.requiredSize(10.toDp())) {
-                                    Box(
-                                        Modifier.onGloballyPositioned {
-                                            realLeft = it.positionInRoot().x
-                                            positionedLatch.countDown()
-                                        }.requiredSize(10.toDp())
-                                    )
-                                }
+                                Box(
+                                    Modifier.onGloballyPositioned {
+                                        realLeft = it.positionInRoot().x
+                                        positionedLatch.countDown()
+                                    }.requiredSize(10.toDp())
+                                )
                             }
                         }
                     }
@@ -640,20 +616,103 @@
         val latch = CountDownLatch(1)
         val line = VerticalAlignmentLine(::min)
         val lineValue = 10
-        rule.runOnUiThread {
-            activity.setContent {
-                val onPositioned = Modifier.onGloballyPositioned { coordinates: LayoutCoordinates ->
-                    assertEquals(1, coordinates.providedAlignmentLines.size)
-                    assertEquals(lineValue, coordinates[line])
-                    latch.countDown()
-                }
-                Layout(modifier = onPositioned, content = { }) { _, _ ->
-                    layout(0, 0, mapOf(line to lineValue)) { }
-                }
+        rule.setContent {
+            val onPositioned = Modifier.onGloballyPositioned { coordinates: LayoutCoordinates ->
+                assertEquals(1, coordinates.providedAlignmentLines.size)
+                assertEquals(lineValue, coordinates[line])
+                latch.countDown()
+            }
+            Layout(modifier = onPositioned, content = { }) { _, _ ->
+                layout(0, 0, mapOf(line to lineValue)) { }
             }
         }
         assertTrue(latch.await(1, TimeUnit.SECONDS))
     }
+
+    @Test
+    fun testLayerBoundsPositionInRotatedView() {
+        var coords: LayoutCoordinates? = null
+        var view: View? = null
+        rule.setContent {
+            view = LocalView.current
+            FixedSize(
+                30,
+                Modifier.padding(10).onGloballyPositioned {
+                    coords = it
+                }
+            ) { /* no-op */ }
+        }
+
+        val composeView = view as AndroidComposeView
+        rule.runOnUiThread {
+            // rotate the view so that it no longer aligns squarely
+            composeView.rotation = 45f
+            composeView.pivotX = 0f
+            composeView.pivotY = 0f
+        }
+
+        rule.runOnIdle { } // wait for redraw
+
+        rule.onRoot().apply {
+            val layoutCoordinates = coords!!
+            assertEquals(Offset(10f, 10f), layoutCoordinates.positionInRoot())
+            assertEquals(Rect(10f, 10f, 40f, 40f), layoutCoordinates.boundsInRoot())
+
+            val topLeftInWindow = layoutCoordinates.localToWindow(Offset.Zero)
+            assertEquals(0f, topLeftInWindow.x, 0.1f)
+            assertEquals(10f * sqrt(2f), topLeftInWindow.y, 0.1f)
+
+            val topLeftInLayout = layoutCoordinates.windowToLocal(topLeftInWindow)
+            assertEquals(0f, topLeftInLayout.x, 0.1f)
+            assertEquals(0f, topLeftInLayout.y, 0.1f)
+
+            val bottomRightInWindow = layoutCoordinates.localToWindow(Offset(30f, 30f))
+            assertEquals(0f, bottomRightInWindow.x, 0.1f)
+            assertEquals(40f * sqrt(2f), bottomRightInWindow.y, 0.1f)
+
+            val bottomRightInLayout = layoutCoordinates.windowToLocal(bottomRightInWindow)
+            assertEquals(30f, bottomRightInLayout.x, 0.1f)
+            assertEquals(30f, bottomRightInLayout.y, 0.1f)
+
+            val boundsInWindow = layoutCoordinates.boundsInWindow()
+
+            assertEquals(10f * sqrt(2f), boundsInWindow.top, 0.1f)
+            assertEquals(30f * sqrt(2f) / 2f, boundsInWindow.right, 0.1f)
+            assertEquals(-30f * sqrt(2f) / 2f, boundsInWindow.left, 0.1f)
+            assertEquals(40f * sqrt(2f), boundsInWindow.bottom, 0.1f)
+        }
+    }
+
+    @Test
+    fun testLayerBoundsPositionInMovedWindow() {
+        var coords: LayoutCoordinates? = null
+        var alignment by mutableStateOf(Alignment.Center)
+        rule.setContent {
+            Box(Modifier.fillMaxSize()) {
+                Popup(alignment = alignment) {
+                    FixedSize(
+                        30,
+                        Modifier.padding(10).background(Color.Red).onGloballyPositioned {
+                            coords = it
+                        }
+                    ) { /* no-op */ }
+                }
+            }
+        }
+
+        rule.runOnIdle {
+            val inWindow = coords!!.positionInWindow()
+            assertEquals(10f, inWindow.x)
+            assertEquals(10f, inWindow.y)
+            alignment = Alignment.BottomEnd
+        }
+
+        rule.runOnIdle {
+            val inWindow = coords!!.positionInWindow()
+            assertEquals(10f, inWindow.x)
+            assertEquals(10f, inWindow.y)
+        }
+    }
 }
 
 @Composable
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/PlacedChildTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/PlacedChildTest.kt
index e9af374..27d5a6b 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/PlacedChildTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/PlacedChildTest.kt
@@ -31,7 +31,7 @@
     @Test
     fun remeasureNotPlacedChild() {
         val root = root {
-            measureBlocks = UseChildSizeButNotPlace
+            measurePolicy = UseChildSizeButNotPlace
             add(
                 node {
                     wrapChildren = true
@@ -57,14 +57,13 @@
     }
 }
 
-private val UseChildSizeButNotPlace = object : LayoutNode.NoIntrinsicsMeasureBlocks("") {
-    override fun measure(
-        measureScope: MeasureScope,
+private val UseChildSizeButNotPlace = object : LayoutNode.NoIntrinsicsMeasurePolicy("") {
+    override fun MeasureScope.measure(
         measurables: List<Measurable>,
         constraints: Constraints
     ): MeasureResult {
         val placeable = measurables.first().measure(constraints)
-        return measureScope.layout(placeable.width, placeable.height) {
+        return layout(placeable.width, placeable.height) {
             // do not place
         }
     }
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/RtlLayoutTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/RtlLayoutTest.kt
index 79d086c..197be27 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/RtlLayoutTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/RtlLayoutTest.kt
@@ -18,7 +18,6 @@
 
 import androidx.activity.compose.setContent
 import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.ExperimentalLayout
 import androidx.compose.foundation.layout.IntrinsicSize
 import androidx.compose.foundation.layout.width
 import androidx.compose.runtime.Composable
@@ -31,6 +30,7 @@
 import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.runOnUiThreadIR
 import androidx.compose.ui.test.TestActivity
+import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -224,22 +224,42 @@
 
         activityTestRule.runOnUiThread {
             activity.setContent {
-                @OptIn(ExperimentalLayout::class)
                 CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
+                    val measurePolicy = object : MeasurePolicy {
+                        override fun MeasureScope.measure(
+                            measurables: List<Measurable>,
+                            constraints: Constraints
+                        ) = layout(0, 0) {}
+
+                        override fun IntrinsicMeasureScope.minIntrinsicWidth(
+                            measurables: List<IntrinsicMeasurable>,
+                            height: Int
+                        ) = 0
+
+                        override fun IntrinsicMeasureScope.minIntrinsicHeight(
+                            measurables: List<IntrinsicMeasurable>,
+                            width: Int
+                        ) = 0
+
+                        override fun IntrinsicMeasureScope.maxIntrinsicWidth(
+                            measurables: List<IntrinsicMeasurable>,
+                            height: Int
+                        ): Int {
+                            resultLayoutDirection = this.layoutDirection
+                            latch.countDown()
+                            return 0
+                        }
+
+                        override fun IntrinsicMeasureScope.maxIntrinsicHeight(
+                            measurables: List<IntrinsicMeasurable>,
+                            width: Int
+                        ) = 0
+                    }
                     Layout(
                         content = {},
                         modifier = Modifier.width(IntrinsicSize.Max),
-                        minIntrinsicWidthMeasureBlock = { _, _ -> 0 },
-                        minIntrinsicHeightMeasureBlock = { _, _ -> 0 },
-                        maxIntrinsicWidthMeasureBlock = { _, _ ->
-                            resultLayoutDirection = this.layoutDirection
-                            latch.countDown()
-                            0
-                        },
-                        maxIntrinsicHeightMeasureBlock = { _, _ -> 0 }
-                    ) { _, _ ->
-                        layout(0, 0) {}
-                    }
+                        measurePolicy = measurePolicy
+                    )
                 }
             }
         }
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModelReadsTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModelReadsTest.kt
index c114e78..4b84ece 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModelReadsTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModelReadsTest.kt
@@ -28,7 +28,6 @@
 import androidx.compose.ui.test.TestActivity
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
-import androidx.test.filters.SmallTest
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
@@ -39,7 +38,7 @@
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.TimeUnit
 
-@SmallTest
+@MediumTest
 @RunWith(AndroidJUnit4::class)
 class ModelReadsTest {
 
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidViewCompatTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidViewCompatTest.kt
index 94444f0..bc46b4c 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidViewCompatTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidViewCompatTest.kt
@@ -26,10 +26,12 @@
 import android.view.ViewGroup
 import android.view.ViewGroup.LayoutParams.MATCH_PARENT
 import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import android.widget.FrameLayout
 import android.widget.LinearLayout
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
 import androidx.compose.runtime.Applier
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.ComposeNode
@@ -65,6 +67,7 @@
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.dp
 import androidx.compose.ui.viewinterop.AndroidView
 import androidx.test.espresso.Espresso
 import androidx.test.espresso.assertion.ViewAssertions.matches
@@ -514,7 +517,7 @@
                                 factory = LayoutNode.Constructor,
                                 update = {
                                     init { node = this }
-                                    set(noOpMeasureBlocks, ComposeUiNode.SetMeasureBlocks)
+                                    set(noOpMeasurePolicy, ComposeUiNode.SetMeasurePolicy)
                                 }
                             )
                         }
@@ -560,6 +563,28 @@
         }
     }
 
+    @Test
+    fun testAndroidViewHolder_size() {
+        val size = 100
+
+        rule.runOnUiThread {
+            val root = FrameLayout(rule.activity)
+            val composeView = ComposeView(rule.activity)
+            composeView.layoutParams = FrameLayout.LayoutParams(size, size)
+            root.addView(composeView)
+            rule.activity.setContentView(root)
+            composeView.setContent {
+                AndroidView(::View, Modifier.size(10.dp))
+            }
+        }
+
+        Espresso.onView(withClassName(endsWith("AndroidViewsHandler"))).check { view, exception ->
+            view as AndroidViewsHandler
+            // The views handler should match the size of the ComposeView.
+            if (view.width != size || view.height != size) throw exception
+        }
+    }
+
     class ColoredSquareView(context: Context) : View(context) {
         var size: Int = 100
             set(value) {
@@ -639,9 +664,8 @@
         }
     }
 
-    private val noOpMeasureBlocks = object : LayoutNode.NoIntrinsicsMeasureBlocks("") {
-        override fun measure(
-            measureScope: MeasureScope,
+    private val noOpMeasurePolicy = object : LayoutNode.NoIntrinsicsMeasurePolicy("") {
+        override fun MeasureScope.measure(
             measurables: List<Measurable>,
             constraints: Constraints
         ): MeasureResult {
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt
index 47421fd..479ceb7 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt
@@ -20,8 +20,10 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.layout.MeasurePolicy
 import androidx.compose.ui.platform.InspectableValue
 import androidx.compose.ui.platform.ValueElement
 import androidx.compose.ui.platform.isDebugInspectorInfoEnabled
@@ -713,11 +715,14 @@
 private fun CountingLayout(modifier: Modifier, counter: Counter) {
     Layout(
         modifier = modifier,
-        content = {}
-    ) { _, constraints ->
-        counter.count++
-        layout(constraints.minWidth, constraints.minHeight) {}
-    }
+        content = {},
+        measurePolicy = remember {
+            MeasurePolicy { _, constraints ->
+                counter.count++
+                layout(constraints.minWidth, constraints.minHeight) {}
+            }
+        }
+    )
 }
 
 /**
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/viewinterop/AndroidViewTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/viewinterop/AndroidViewTest.kt
index ff70125..b641278 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/viewinterop/AndroidViewTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/viewinterop/AndroidViewTest.kt
@@ -374,7 +374,7 @@
         rule.setContent {
             CompositionLocalProvider(ambient provides "setByParent") {
                 AndroidView(
-                    viewBlock = {
+                    factory = {
                         ComposeView(it).apply {
                             setContent {
                                 childComposedAmbientValue = ambient.current
@@ -396,7 +396,7 @@
         rule.setContent {
             CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
                 AndroidView(
-                    viewBlock = {
+                    factory = {
                         FrameLayout(it).apply {
                             addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
                                 childViewLayoutDirection = layoutDirection
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupDismissTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupDismissTest.kt
index 2ceab8e..fc01d13 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupDismissTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupDismissTest.kt
@@ -17,7 +17,8 @@
 package androidx.compose.ui.window
 
 import android.os.Build
-import androidx.compose.foundation.ClickableText
+import android.view.View
+import androidx.compose.foundation.text.ClickableText
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.size
@@ -26,6 +27,7 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.layout.onGloballyPositioned
+import androidx.compose.ui.platform.LocalView
 import androidx.compose.ui.test.getUnclippedBoundsInRoot
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithText
@@ -70,8 +72,10 @@
         var btnPos: Offset = Offset.Zero
 
         val latch = CountDownLatch(1)
+        var view: View? = null
 
         rule.setContent {
+            view = LocalView.current
             Box(Modifier.fillMaxSize()) {
                 ClickableText(
                     text = AnnotatedString("Button"),
@@ -79,7 +83,7 @@
                     modifier = Modifier.onGloballyPositioned {
                         // UiDevice needs screen relative coordinates
                         @Suppress("DEPRECATION")
-                        btnPos = it.localToGlobal(Offset.Zero)
+                        btnPos = it.localToRoot(Offset.Zero)
                     }
                 )
 
@@ -105,9 +109,12 @@
 
         with(rule.density) {
             // Need to click via UiDevice as this click has to propagate to multiple windows
+            val viewPos = intArrayOf(0, 0)
+            view!!.getLocationOnScreen(viewPos)
+
             device.click(
-                btnPos.x.toInt() + btnBounds.width.roundToPx() / 2,
-                btnPos.y.toInt() + btnBounds.height.roundToPx() / 2
+                viewPos[0] + btnPos.x.toInt() + btnBounds.width.roundToPx() / 2,
+                viewPos[1] + btnPos.y.toInt() + btnBounds.height.roundToPx() / 2
             )
         }
 
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/AndroidMouse.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/AndroidMouse.android.kt
index e1d091e..e69de29 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/AndroidMouse.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/AndroidMouse.android.kt
@@ -1,20 +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.ui.input.pointer
-
-@MouseTemporaryApi
-actual val isMouseInput = false
\ No newline at end of file
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/AndroidMouse.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/AndroidMouse.kt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/AndroidMouse.kt
@@ -0,0 +1 @@
+
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/MotionEventAdapter.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/MotionEventAdapter.android.kt
index 3478885..90115f7 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/MotionEventAdapter.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/MotionEventAdapter.android.kt
@@ -16,12 +16,15 @@
 
 package androidx.compose.ui.input.pointer
 
+import android.annotation.SuppressLint
+import android.os.Build
 import android.view.MotionEvent
 import android.view.MotionEvent.ACTION_CANCEL
 import android.view.MotionEvent.ACTION_DOWN
 import android.view.MotionEvent.ACTION_POINTER_DOWN
 import android.view.MotionEvent.ACTION_POINTER_UP
 import android.view.MotionEvent.ACTION_UP
+import androidx.annotation.RequiresApi
 import androidx.annotation.VisibleForTesting
 import androidx.compose.ui.geometry.Offset
 
@@ -50,7 +53,10 @@
      *
      * @return The PointerInputEvent or null if the event action was ACTION_CANCEL.
      */
-    internal fun convertToPointerInputEvent(motionEvent: MotionEvent): PointerInputEvent? {
+    internal fun convertToPointerInputEvent(
+        motionEvent: MotionEvent,
+        positionCalculator: PositionCalculator
+    ): PointerInputEvent? {
 
         if (motionEvent.actionMasked == ACTION_CANCEL) {
             motionEventToComposePointerIdMap.clear()
@@ -75,10 +81,16 @@
         // This converts the MotionEvent into a list of PointerInputEventData, and updates
         // internal record keeping.
         @Suppress("NAME_SHADOWING")
-        motionEvent.asOffsetToScreen { motionEvent ->
-            for (i in 0 until motionEvent.pointerCount) {
-                pointers.add(createPointerInputEventData(motionEvent, i, downIndex, upIndex))
-            }
+        for (i in 0 until motionEvent.pointerCount) {
+            pointers.add(
+                createPointerInputEventData(
+                    positionCalculator,
+                    motionEvent,
+                    i,
+                    downIndex,
+                    upIndex
+                )
+            )
         }
 
         return PointerInputEvent(
@@ -92,6 +104,7 @@
      * Creates a new PointerInputEventData.
      */
     private fun createPointerInputEventData(
+        positionCalculator: PositionCalculator,
         motionEvent: MotionEvent,
         index: Int,
         downIndex: Int?,
@@ -117,6 +130,7 @@
             )
 
         return createPointerInputEventData(
+            positionCalculator,
             pointerId,
             motionEvent.eventTime,
             motionEvent,
@@ -130,15 +144,22 @@
  * Creates a new PointerInputData.
  */
 private fun createPointerInputEventData(
+    positionCalculator: PositionCalculator,
     pointerId: PointerId,
     timestamp: Long,
     motionEvent: MotionEvent,
     index: Int,
     upIndex: Int?
 ): PointerInputEventData {
-    val pointerCoords = MotionEvent.PointerCoords()
-    motionEvent.getPointerCoords(index, pointerCoords)
-    val offset = Offset(pointerCoords.x, pointerCoords.y)
+    val position = Offset(motionEvent.getX(index), motionEvent.getY(index))
+    val rawPosition: Offset
+    if (index == 0) {
+        rawPosition = Offset(motionEvent.rawX, motionEvent.rawY)
+    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+        rawPosition = motionEvent.toRawOffset(index)
+    } else {
+        rawPosition = positionCalculator.localToScreen(position)
+    }
     val toolType = when (motionEvent.getToolType(index)) {
         MotionEvent.TOOL_TYPE_UNKNOWN -> PointerType.Unknown
         MotionEvent.TOOL_TYPE_FINGER -> PointerType.Touch
@@ -151,21 +172,15 @@
     return PointerInputEventData(
         pointerId,
         timestamp,
-        offset,
+        rawPosition,
+        position,
         index != upIndex,
         toolType
     )
 }
 
-/**
- * Mutates the MotionEvent to be relative to the screen.
- *
- * This is required to create a valid PointerInputEvent.
- */
-private inline fun MotionEvent.asOffsetToScreen(block: (MotionEvent) -> Unit) {
-    val offsetX = rawX - x
-    val offsetY = rawY - y
-    offsetLocation(offsetX, offsetY)
-    block(this)
-    offsetLocation(-offsetX, -offsetY)
-}
\ No newline at end of file
+@RequiresApi(Build.VERSION_CODES.Q)
+@SuppressLint("UnsafeNewApiCall") // not sure why RequiresApi is not enough
+private fun MotionEvent.toRawOffset(index: Int): Offset {
+    return Offset(getRawX(index), getRawY(index))
+}
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AccessibilityIterators.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AccessibilityIterators.android.kt
index a102b98..98c0c39 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AccessibilityIterators.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AccessibilityIterators.android.kt
@@ -456,10 +456,10 @@
             }
             try {
                 tempRect = Rect(
-                    node.globalBounds.left.toInt(),
-                    node.globalBounds.top.toInt(),
-                    node.globalBounds.right.toInt(),
-                    node.globalBounds.bottom.toInt()
+                    node.boundsInWindow.left.toInt(),
+                    node.boundsInWindow.top.toInt(),
+                    node.boundsInWindow.right.toInt(),
+                    node.boundsInWindow.bottom.toInt()
                 )
                 // TODO(b/153198816): check whether we still get this exception when R is in.
             } catch (e: IllegalStateException) {
@@ -495,10 +495,10 @@
             }
             try {
                 tempRect = Rect(
-                    node.globalBounds.left.toInt(),
-                    node.globalBounds.top.toInt(),
-                    node.globalBounds.right.toInt(),
-                    node.globalBounds.bottom.toInt()
+                    node.boundsInWindow.left.toInt(),
+                    node.boundsInWindow.top.toInt(),
+                    node.boundsInWindow.right.toInt(),
+                    node.boundsInWindow.bottom.toInt()
                 )
                 // TODO(b/153198816): check whether we still get this exception when R is in.
             } catch (e: IllegalStateException) {
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidAccessibilityManager.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidAccessibilityManager.kt
new file mode 100644
index 0000000..494b57f
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidAccessibilityManager.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.ui.platform
+
+import android.content.Context
+import android.os.Build
+import androidx.annotation.RequiresApi
+
+/**
+ * Android implementation for [AccessibilityManager].
+ */
+internal class AndroidAccessibilityManager(context: Context) : AccessibilityManager {
+    private companion object {
+        const val FlagContentIcons = 1
+        const val FlagContentText = 2
+        const val FlagContentControls = 4
+    }
+    private val accessibilityManager = context.getSystemService(Context.ACCESSIBILITY_SERVICE) as
+        android.view.accessibility.AccessibilityManager
+
+    override fun calculateRecommendedTimeoutMillis(
+        originalTimeoutMillis: Long,
+        containsIcons: Boolean,
+        containsText: Boolean,
+        containsControls: Boolean
+    ): Long {
+        if (originalTimeoutMillis >= Int.MAX_VALUE) {
+            return originalTimeoutMillis
+        }
+        var uiContentFlags = 0
+        if (containsIcons) {
+            uiContentFlags = uiContentFlags or FlagContentIcons
+        }
+        if (containsText) {
+            uiContentFlags = uiContentFlags or FlagContentText
+        }
+        if (containsControls) {
+            uiContentFlags = uiContentFlags or FlagContentControls
+        }
+        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            val recommended = Api29Impl().getRecommendedTimeoutMillis(
+                originalTimeoutMillis.toInt(),
+                uiContentFlags
+            )
+            if (recommended == Int.MAX_VALUE) {
+                Long.MAX_VALUE
+            } else {
+                recommended.toLong()
+            }
+        } else if (containsControls && accessibilityManager.isTouchExplorationEnabled) {
+            Long.MAX_VALUE
+        } else {
+            originalTimeoutMillis
+        }
+    }
+
+    @RequiresApi(Build.VERSION_CODES.Q)
+    inner class Api29Impl {
+        fun getRecommendedTimeoutMillis(originalTimeout: Int, uiContentFlags: Int): Int {
+            return accessibilityManager.getRecommendedTimeoutMillis(originalTimeout, uiContentFlags)
+        }
+    }
+}
\ No newline at end of file
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
index 469cccd..1b15c47 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
@@ -19,6 +19,7 @@
 import android.annotation.SuppressLint
 import android.content.Context
 import android.content.res.Configuration
+import android.graphics.Matrix
 import android.graphics.Rect
 import android.os.Build
 import android.os.Looper
@@ -57,6 +58,7 @@
 import androidx.compose.ui.focus.FocusDirection.Up
 import androidx.compose.ui.focus.FocusManager
 import androidx.compose.ui.focus.FocusManagerImpl
+import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Canvas
 import androidx.compose.ui.graphics.CanvasHolder
 import androidx.compose.ui.hapticfeedback.AndroidHapticFeedback
@@ -74,8 +76,9 @@
 import androidx.compose.ui.input.key.type
 import androidx.compose.ui.input.pointer.MotionEventAdapter
 import androidx.compose.ui.input.pointer.PointerInputEventProcessor
+import androidx.compose.ui.input.pointer.PositionCalculator
 import androidx.compose.ui.input.pointer.ProcessResult
-import androidx.compose.ui.layout.RootMeasureBlocks
+import androidx.compose.ui.layout.RootMeasurePolicy
 import androidx.compose.ui.node.InternalCoreApi
 import androidx.compose.ui.node.LayoutNode
 import androidx.compose.ui.node.LayoutNode.UsageByParent
@@ -109,7 +112,7 @@
 @OptIn(ExperimentalComposeUiApi::class)
 @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
 internal class AndroidComposeView(context: Context) :
-    ViewGroup(context), Owner, ViewRootForTest {
+    ViewGroup(context), Owner, ViewRootForTest, PositionCalculator {
 
     override val view: View = this
 
@@ -149,7 +152,7 @@
     private val canvasHolder = CanvasHolder()
 
     override val root = LayoutNode().also {
-        it.measureBlocks = RootMeasureBlocks
+        it.measurePolicy = RootMeasurePolicy
         it.modifier = Modifier
             .then(semanticsModifier)
             .then(_focusManager.modifier)
@@ -195,6 +198,11 @@
      */
     override val clipboardManager = AndroidClipboardManager(context)
 
+    /**
+     * Provide accessibility manager to the user. Use the Android version of accessibility manager.
+     */
+    override val accessibilityManager = AndroidAccessibilityManager(context)
+
     override val snapshotObserver = OwnerSnapshotObserver { command ->
         if (handler?.looper === Looper.myLooper()) {
             command()
@@ -240,6 +248,8 @@
     private var globalPosition: IntOffset = IntOffset.Zero
 
     private val tmpPositionArray = intArrayOf(0, 0)
+    private val tmpOffsetArray = floatArrayOf(0f, 0f)
+    private val tmpMatrix = Matrix()
 
     // Used to track whether or not there was an exception while creating an MRenderNode
     // so that we don't have to continue using try/catch after fails once.
@@ -481,10 +491,15 @@
         // are currently wrong if you try to get the global(activity) coordinates -
         // View is not yet laid out.
         updatePositionCacheAndDispatch()
-        if (_androidViewsHandler != null && androidViewsHandler.isLayoutRequested) {
-            // Even if we laid out during onMeasure, this can happen when the Views hierarchy
-            // receives forceLayout(). We need to relayout to clear the isLayoutRequested info
-            // on the Views, as otherwise further layout requests will be discarded.
+        if (_androidViewsHandler != null) {
+            // Even if we laid out during onMeasure, we want to set the bounds of the
+            // AndroidViewsHandler for accessibility and for Views making assumptions based on
+            // the size of their ancestors. Usually the Views in the hierarchy will not
+            // be relaid out, as they have not requested layout in the meantime.
+            // However, there is also chance for the AndroidViewsHandler to be isLayoutRequested
+            // at this point, in case the Views hierarchy receives forceLayout().
+            // In this case, calling layout here will relayout to clear the isLayoutRequested
+            // info on the Views, as otherwise further layout requests will be discarded.
             androidViewsHandler.layout(0, 0, r - l, b - t)
         }
     }
@@ -662,19 +677,10 @@
     // TODO(shepshapard): Test this method.
     override fun dispatchTouchEvent(motionEvent: MotionEvent): Boolean {
         measureAndLayout()
-        // TODO(b/166848812): Calling updatePositionCacheAndDispatch here seems necessary because
-        //  if the soft keyboard being displayed causes the AndroidComposeView to be offset from
-        //  the screen, we don't seem to have any timely callback that updates our globalPosition
-        //  cache. ViewTreeObserver.OnGlobalLayoutListener gets called, but not when the keyboard
-        //  opens. And when it gets called as the keyboard is closing, it is called before the
-        //  keyboard actually closes causing the globalPosition to be wrong.
-        // TODO(shepshapard): There is no test to garuntee that this method is called here as doing
-        //  so proved to be very difficult. A test should be added.
-        updatePositionCacheAndDispatch()
         val processResult = trace("AndroidOwner:onTouch") {
-            val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
+            val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent, this)
             if (pointerInputEvent != null) {
-                pointerInputEventProcessor.process(pointerInputEvent)
+                pointerInputEventProcessor.process(pointerInputEvent, this)
             } else {
                 pointerInputEventProcessor.processCancel()
                 ProcessResult(
@@ -691,16 +697,65 @@
         return processResult.dispatchedToAPointerInputModifier
     }
 
+    override fun localToScreen(localPosition: Offset): Offset {
+        tmpMatrix.reset()
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            TransformMatrixApi29.transformMatrixToScreen(this, tmpMatrix)
+        } else {
+            TransformMatrixApi28.transformMatrixToScreen(this, tmpMatrix, tmpPositionArray)
+        }
+        val points = tmpOffsetArray
+        points[0] = localPosition.x
+        points[1] = localPosition.y
+        tmpMatrix.mapPoints(points)
+        return Offset(points[0], points[1])
+    }
+
+    override fun screenToLocal(positionOnScreen: Offset): Offset {
+        tmpMatrix.reset()
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            TransformMatrixApi29.transformMatrixFromScreen(this, tmpMatrix)
+        } else {
+            TransformMatrixApi28.transformMatrixFromScreen(this, tmpMatrix, tmpPositionArray)
+        }
+        val points = tmpOffsetArray
+        points[0] = positionOnScreen.x
+        points[1] = positionOnScreen.y
+        tmpMatrix.mapPoints(points)
+        return Offset(points[0], points[1])
+    }
+
     override fun onCheckIsTextEditor(): Boolean = textInputServiceAndroid.isEditorFocused()
 
     override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection? =
         textInputServiceAndroid.createInputConnection(outAttrs)
 
-    override fun calculatePosition(): IntOffset = globalPosition
+    override fun calculateLocalPosition(positionInWindow: Offset): Offset {
+        tmpMatrix.reset()
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            TransformMatrixApi29.transformMatrixFromWindow(this, tmpMatrix, tmpPositionArray)
+        } else {
+            TransformMatrixApi28.transformMatrixFromWindow(this, tmpMatrix)
+        }
+        val points = tmpOffsetArray
+        points[0] = positionInWindow.x
+        points[1] = positionInWindow.y
+        tmpMatrix.mapPoints(points)
+        return Offset(points[0], points[1])
+    }
 
-    override fun calculatePositionInWindow(): IntOffset {
-        getLocationInWindow(tmpPositionArray)
-        return IntOffset(tmpPositionArray[0], tmpPositionArray[1])
+    override fun calculatePositionInWindow(localPosition: Offset): Offset {
+        tmpMatrix.reset()
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            TransformMatrixApi29.transformMatrixToWindow(this, tmpMatrix, tmpPositionArray)
+        } else {
+            TransformMatrixApi28.transformMatrixToWindow(this, tmpMatrix)
+        }
+        val points = tmpOffsetArray
+        points[0] = localPosition.x
+        points[1] = localPosition.y
+        tmpMatrix.mapPoints(points)
+        return Offset(points[0], points[1])
     }
 
     override fun onConfigurationChanged(newConfig: Configuration) {
@@ -778,6 +833,94 @@
     else -> LayoutDirection.Ltr
 }
 
+private fun View.findRootView(): View {
+    var contentView: View = this
+    var parent = contentView.parent
+    while (parent is View) {
+        contentView = parent
+        parent = contentView.parent
+    }
+    return contentView
+}
+
+private class TransformMatrixApi28 {
+    companion object {
+        fun transformMatrixToWindow(view: View, matrix: Matrix) =
+            transformFromLocal(view, matrix, null)
+
+        fun transformMatrixToScreen(view: View, matrix: Matrix, tmpPositionArray: IntArray) =
+            transformFromLocal(view, matrix, tmpPositionArray)
+
+        fun transformMatrixFromWindow(view: View, matrix: Matrix) =
+            transformToLocal(view, matrix, null)
+
+        fun transformMatrixFromScreen(view: View, matrix: Matrix, tmpPositionArray: IntArray) =
+            transformToLocal(view, matrix, tmpPositionArray)
+
+        private fun transformFromLocal(view: View, transform: Matrix, tmpPositionArray: IntArray?) {
+            val parentView = view.parent
+            if (parentView is View) {
+                transformFromLocal(parentView, transform, tmpPositionArray)
+                transform.preTranslate(-view.scrollX.toFloat(), -view.scrollY.toFloat())
+                transform.preTranslate(view.left.toFloat(), view.top.toFloat())
+            } else if (tmpPositionArray != null) {
+                view.getLocationOnScreen(tmpPositionArray)
+                transform.preTranslate(tmpPositionArray[0].toFloat(), tmpPositionArray[1].toFloat())
+            }
+
+            val matrix = view.matrix
+            if (!matrix.isIdentity) {
+                transform.preConcat(matrix)
+            }
+        }
+
+        private fun transformToLocal(view: View, transform: Matrix, tmpPositionArray: IntArray?) {
+            val parentView = view.parent
+            if (parentView is View) {
+                transformToLocal(parentView, transform, tmpPositionArray)
+                transform.postTranslate(view.scrollX.toFloat(), view.scrollY.toFloat())
+                transform.postTranslate(-view.left.toFloat(), -view.top.toFloat())
+            } else if (tmpPositionArray != null) {
+                view.getLocationOnScreen(tmpPositionArray)
+                transform.postTranslate(
+                    -tmpPositionArray[0].toFloat(),
+                    -tmpPositionArray[1].toFloat()
+                )
+            }
+
+            val matrix = view.matrix
+            if (!matrix.isIdentity) {
+                matrix.invert(matrix)
+                transform.postConcat(matrix)
+            }
+        }
+    }
+}
+
+private class TransformMatrixApi29 {
+    @RequiresApi(Build.VERSION_CODES.Q)
+    companion object {
+        fun transformMatrixToScreen(view: View, matrix: Matrix) =
+            view.transformMatrixToGlobal(matrix)
+
+        fun transformMatrixToWindow(view: View, matrix: Matrix, tmpPositionArray: IntArray) {
+            val rootView = view.findRootView()
+            rootView.getLocationOnScreen(tmpPositionArray)
+            matrix.preTranslate(-tmpPositionArray[0].toFloat(), -tmpPositionArray[1].toFloat())
+            view.transformMatrixToGlobal(matrix)
+        }
+        fun transformMatrixFromScreen(view: View, matrix: Matrix) =
+            view.transformMatrixToLocal(matrix)
+
+        fun transformMatrixFromWindow(view: View, matrix: Matrix, tmpPositionArray: IntArray) {
+            val rootView = view.findRootView()
+            rootView.getLocationOnScreen(tmpPositionArray)
+            matrix.postTranslate(tmpPositionArray[0].toFloat(), tmpPositionArray[1].toFloat())
+            view.transformMatrixToLocal(matrix)
+        }
+    }
+}
+
 /** @suppress */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @InternalComposeUiApi // used by testing infra
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
index 35eb63b..cfa7cd7 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
@@ -56,8 +56,10 @@
 import androidx.compose.ui.text.platform.toAccessibilitySpannableString
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.semantics.ProgressBarRangeInfo
 import androidx.compose.ui.text.InternalTextApi
+import androidx.compose.ui.util.fastForEachIndexed
 import androidx.core.view.AccessibilityDelegateCompat
 import androidx.core.view.ViewCompat
 import androidx.core.view.accessibility.AccessibilityEventCompat
@@ -65,6 +67,7 @@
 import androidx.core.view.accessibility.AccessibilityNodeProviderCompat
 import kotlinx.coroutines.channels.Channel
 import kotlinx.coroutines.delay
+import kotlin.math.abs
 
 private fun LayoutNode.findClosestParentNode(selector: (LayoutNode) -> Boolean): LayoutNode? {
     var currentParent = this.parent
@@ -267,10 +270,10 @@
         try {
             info.setBoundsInScreen(
                 android.graphics.Rect(
-                    semanticsNode.globalBounds.left.toInt(),
-                    semanticsNode.globalBounds.top.toInt(),
-                    semanticsNode.globalBounds.right.toInt(),
-                    semanticsNode.globalBounds.bottom.toInt()
+                    semanticsNode.boundsInWindow.left.toInt(),
+                    semanticsNode.boundsInWindow.top.toInt(),
+                    semanticsNode.boundsInWindow.right.toInt(),
+                    semanticsNode.boundsInWindow.bottom.toInt()
                 )
             )
         } catch (e: IllegalStateException) {
@@ -320,8 +323,10 @@
             (semanticsNode.config.getOrNull(SemanticsProperties.InvisibleToUser) == null)
         info.isClickable = false
         semanticsNode.config.getOrNull(SemanticsActions.OnClick)?.let {
-            info.isClickable = true
-            if (semanticsNode.enabled()) {
+            // Selectable items that are already selected should not announce it again
+            val isSelected = semanticsNode.config.getOrNull(SemanticsProperties.Selected) == true
+            info.isClickable = !isSelected
+            if (semanticsNode.enabled() && !isSelected) {
                 info.addAction(
                     AccessibilityNodeInfoCompat.AccessibilityActionCompat(
                         AccessibilityNodeInfoCompat.ACTION_CLICK,
@@ -462,6 +467,9 @@
             Api24Impl.addSetProgressAction(info, semanticsNode)
         }
 
+        setCollectionInfo(semanticsNode, info)
+        setCollectionItemInfo(semanticsNode, info)
+
         val xScrollState =
             semanticsNode.config.getOrNull(SemanticsProperties.HorizontalScrollAxisRange)
         val scrollAction = semanticsNode.config.getOrNull(SemanticsActions.ScrollBy)
@@ -935,7 +943,7 @@
                         xScrollState.value() < xScrollState.maxValue()
                     ) {
                         return scrollAction.action?.invoke(
-                            node.globalBounds.right - node.globalBounds.left,
+                            node.boundsInWindow.right - node.boundsInWindow.left,
                             0f
                         ) ?: false
                     }
@@ -953,7 +961,7 @@
                         xScrollState.value() > 0
                     ) {
                         return scrollAction.action?.invoke(
-                            -(node.globalBounds.right - node.globalBounds.left),
+                            -(node.boundsInWindow.right - node.boundsInWindow.left),
                             0f
                         ) ?: false
                     }
@@ -976,7 +984,7 @@
                     ) {
                         return scrollAction.action?.invoke(
                             0f,
-                            node.globalBounds.bottom - node.globalBounds.top
+                            node.boundsInWindow.bottom - node.boundsInWindow.top
                         ) ?: false
                     }
                     if ((
@@ -994,7 +1002,7 @@
                     ) {
                         return scrollAction.action?.invoke(
                             0f,
-                            -(node.globalBounds.bottom - node.globalBounds.top)
+                            -(node.boundsInWindow.bottom - node.boundsInWindow.top)
                         ) ?: false
                     }
                 }
@@ -1116,8 +1124,8 @@
     }
 
     private fun toScreenCoords(textNode: SemanticsNode, bounds: Rect): Rect? {
-        val screenBounds = bounds.translate(textNode.globalPosition)
-        val globalBounds = textNode.globalBounds
+        val screenBounds = bounds.translate(textNode.positionInWindow)
+        val globalBounds = textNode.boundsInWindow
         if (screenBounds.overlaps(globalBounds)) {
             return screenBounds.intersect(globalBounds)
         }
@@ -1187,8 +1195,8 @@
     internal fun getVirtualViewAt(x: Float, y: Float): Int {
         val node = view.semanticsOwner.rootSemanticsNode
         val id = findVirtualViewAt(
-            x + node.globalBounds.left,
-            y + node.globalBounds.top, node
+            x + node.boundsInWindow.left,
+            y + node.boundsInWindow.top, node
         )
         if (id == node.id) {
             return AccessibilityNodeProviderCompat.HOST_VIEW_ID
@@ -1206,8 +1214,8 @@
             }
         }
 
-        if (node.globalBounds.left < x && node.globalBounds.right > x && node
-            .globalBounds.top < y && node.globalBounds.bottom > y
+        if (node.boundsInWindow.left < x && node.boundsInWindow.right > x && node
+            .boundsInWindow.top < y && node.boundsInWindow.bottom > y
         ) {
             return node.id
         }
@@ -1876,6 +1884,104 @@
         }
     }
 
+    private fun setCollectionInfo(node: SemanticsNode, info: AccessibilityNodeInfoCompat) {
+        val groupedChildren = mutableListOf<SemanticsNode>()
+
+        if (node.config.getOrNull(SemanticsProperties.SelectableGroup) != null) {
+            node.children.fastForEach { childNode ->
+                // we assume that Tabs and RadioButtons are not mixed under a single group
+                if (childNode.config.contains(SemanticsProperties.Selected)) {
+                    groupedChildren.add(childNode)
+                }
+            }
+        }
+
+        if (groupedChildren.isNotEmpty()) {
+            /* When we provide a more complex CollectionInfo object, we will use it to determine
+            the number of rows, columns, and selection mode. Currently we assume mutual
+            exclusivity and liner layout (aka Column or Row). We determine if the layout is
+            horizontal or vertical by checking the bounds of the children
+            */
+            val isHorizontal = calculateIfHorizontallyStacked(groupedChildren)
+            info.setCollectionInfo(
+                AccessibilityNodeInfoCompat.CollectionInfoCompat.obtain(
+                    if (isHorizontal) 1 else groupedChildren.count(),
+                    if (isHorizontal) groupedChildren.count() else 1,
+                    false,
+                    getSelectionMode(groupedChildren)
+                )
+            )
+        }
+    }
+
+    private fun setCollectionItemInfo(node: SemanticsNode, info: AccessibilityNodeInfoCompat) {
+        if (!node.config.contains(SemanticsProperties.Selected)) return
+
+        val groupedChildren = mutableListOf<SemanticsNode>()
+
+        // for "tab" item find all siblings to calculate the index
+        val parentNode = node.parent ?: return
+        if (parentNode.config.getOrNull(SemanticsProperties.SelectableGroup) != null) {
+            // find all siblings to calculate the index
+            parentNode.children.fastForEach { childNode ->
+                if (childNode.config.contains(SemanticsProperties.Selected)) {
+                    groupedChildren.add(childNode)
+                }
+            }
+        }
+
+        if (groupedChildren.isNotEmpty()) {
+            val isHorizontal = calculateIfHorizontallyStacked(groupedChildren)
+
+            groupedChildren.fastForEachIndexed { index, tabNode ->
+                if (tabNode.id == node.id) {
+                    val itemInfo = AccessibilityNodeInfoCompat.CollectionItemInfoCompat.obtain(
+                        if (isHorizontal) 0 else index,
+                        1,
+                        if (isHorizontal) index else 0,
+                        1,
+                        false,
+                        tabNode.config.getOrElse(SemanticsProperties.Selected) { false }
+                    )
+                    if (itemInfo != null) {
+                        info.setCollectionItemInfo(itemInfo)
+                    }
+                }
+            }
+        }
+    }
+
+    /** A naïve algorithm to determine if elements are stacked vertically or horizontally */
+    private fun calculateIfHorizontallyStacked(items: List<SemanticsNode>): Boolean {
+        if (items.count() < 2) return true
+
+        val deltas = items.zipWithNext { el1, el2 ->
+            Offset(
+                abs(el1.boundsInRoot.center.x - el2.boundsInRoot.center.x),
+                abs(el1.boundsInRoot.center.y - el2.boundsInRoot.center.y)
+            )
+        }
+        val (deltaX, deltaY) = when (deltas.count()) {
+            1 -> deltas.first()
+            else -> deltas.reduce { result, element -> result + element }
+        }
+        return deltaY < deltaX
+    }
+
+    private fun getSelectionMode(items: List<SemanticsNode>): Int {
+        var numberOfSelectedItems = 0
+        items.fastForEach {
+            if (it.config.getOrElse(SemanticsProperties.Selected) { false }) {
+                numberOfSelectedItems += 1
+            }
+        }
+        return when (numberOfSelectedItems) {
+            0 -> AccessibilityNodeInfoCompat.CollectionInfoCompat.SELECTION_MODE_NONE
+            1 -> AccessibilityNodeInfoCompat.CollectionInfoCompat.SELECTION_MODE_SINGLE
+            else -> AccessibilityNodeInfoCompat.CollectionInfoCompat.SELECTION_MODE_MULTIPLE
+        }
+    }
+
     // TODO(b/160820721): use AccessibilityNodeProviderCompat instead of AccessibilityNodeProvider
     inner class MyNodeProvider : AccessibilityNodeProvider() {
         override fun createAccessibilityNodeInfo(virtualViewId: Int):
@@ -1960,13 +2066,13 @@
 ): Map<Int, SemanticsNode> {
     val root = if (useUnmergedTree) unmergedRootSemanticsNode else rootSemanticsNode
     val nodes = mutableMapOf<Int, SemanticsNode>()
-    val unaccountedSpace = Region().also { it.set(root.globalBounds.toAndroidRect()) }
+    val unaccountedSpace = Region().also { it.set(root.boundsInWindow.toAndroidRect()) }
 
     fun findAllSemanticNodesRecursive(currentNode: SemanticsNode) {
         if (unaccountedSpace.isEmpty) {
             return
         }
-        val rect = currentNode.globalBounds.toAndroidRect()
+        val rect = currentNode.boundsInWindow.toAndroidRect()
 
         if (Region(unaccountedSpace).op(rect, Region.Op.INTERSECT)) {
             nodes[currentNode.id] = currentNode
@@ -1984,4 +2090,4 @@
 
     findAllSemanticNodesRecursive(root)
     return nodes
-}
+}
\ No newline at end of file
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidView.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidView.android.kt
index 0312731..2d74294 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidView.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidView.android.kt
@@ -35,24 +35,24 @@
 import androidx.compose.ui.unit.LayoutDirection
 
 /**
- * Composes an Android [View] obtained from [viewBlock]. The [viewBlock] block will be called
+ * Composes an Android [View] obtained from [factory]. The [factory] block will be called
  * exactly once to obtain the [View] to be composed, and it is also guaranteed to be invoked on
- * the UI thread. Therefore, in addition to creating the [viewBlock], the block can also be used
+ * the UI thread. Therefore, in addition to creating the [factory], the block can also be used
  * to perform one-off initializations and [View] constant properties' setting.
  * The [update] block can be run multiple times (on the UI thread as well) due to recomposition,
  * and it is the right place to set [View] properties depending on state. When state changes,
  * the block will be reexecuted to set the new properties. Note the block will also be ran once
- * right after the [viewBlock] block completes.
+ * right after the [factory] block completes.
  *
  * @sample androidx.compose.ui.samples.AndroidViewSample
  *
- * @param viewBlock The block creating the [View] to be composed.
+ * @param factory The block creating the [View] to be composed.
  * @param modifier The modifier to be applied to the layout.
  * @param update The callback to be invoked after the layout is inflated.
  */
 @Composable
 fun <T : View> AndroidView(
-    viewBlock: (Context) -> T,
+    factory: (Context) -> T,
     modifier: Modifier = Modifier,
     update: (T) -> Unit = NoOpUpdate
 ) {
@@ -61,13 +61,13 @@
     val density = LocalDensity.current
     val layoutDirection = LocalLayoutDirection.current
     val parentReference = rememberCompositionContext()
-    val viewBlockHolderRef = remember { Ref<ViewBlockHolder<T>>() }
+    val viewBlockHolderRef = remember { Ref<ViewFactoryHolder<T>>() }
     ComposeNode<LayoutNode, UiApplier>(
         factory = {
-            val viewBlockHolder = ViewBlockHolder<T>(context, parentReference)
-            viewBlockHolder.viewBlock = viewBlock
-            viewBlockHolderRef.value = viewBlockHolder
-            viewBlockHolder.toLayoutNode()
+            val viewFactoryHolder = ViewFactoryHolder<T>(context, parentReference)
+            viewFactoryHolder.factory = factory
+            viewBlockHolderRef.value = viewFactoryHolder
+            viewFactoryHolder.toLayoutNode()
         },
         update = {
             set(materialized) { viewBlockHolderRef.value!!.modifier = it }
@@ -88,14 +88,14 @@
  */
 val NoOpUpdate: View.() -> Unit = {}
 
-internal class ViewBlockHolder<T : View>(
+internal class ViewFactoryHolder<T : View>(
     context: Context,
     parentContext: CompositionContext? = null
 ) : AndroidViewHolder(context, parentContext) {
 
     private var typedView: T? = null
 
-    var viewBlock: ((Context) -> T)? = null
+    var factory: ((Context) -> T)? = null
         set(value) {
             field = value
             if (value != null) {
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidViewHolder.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidViewHolder.android.kt
index ae128b0..e402d80 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidViewHolder.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidViewHolder.android.kt
@@ -201,11 +201,10 @@
             view = null
         }
 
-        layoutNode.measureBlocks = object : LayoutNode.NoIntrinsicsMeasureBlocks(
+        layoutNode.measurePolicy = object : LayoutNode.NoIntrinsicsMeasurePolicy(
             "Intrinsics not supported for Android views"
         ) {
-            override fun measure(
-                measureScope: MeasureScope,
+            override fun MeasureScope.measure(
                 measurables: List<Measurable>,
                 constraints: Constraints
             ): MeasureResult {
@@ -230,7 +229,7 @@
                         layoutParams!!.height
                     )
                 )
-                return measureScope.layout(measuredWidth, measuredHeight) {
+                return layout(measuredWidth, measuredHeight) {
                     layoutAccordingTo(layoutNode)
                 }
             }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/TransformOrigin.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/TransformOrigin.kt
index ede35c6..4656ae1 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/TransformOrigin.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/TransformOrigin.kt
@@ -26,8 +26,7 @@
  * Constructs a [TransformOrigin] from the given fractional values from the Layer's
  * width and height
  */
-@Suppress("NOTHING_TO_INLINE")
-inline fun TransformOrigin(pivotFractionX: Float, pivotFractionY: Float): TransformOrigin =
+fun TransformOrigin(pivotFractionX: Float, pivotFractionY: Float): TransformOrigin =
     TransformOrigin(packFloats(pivotFractionX, pivotFractionY))
 
 /**
@@ -36,7 +35,7 @@
 @Suppress("EXPERIMENTAL_FEATURE_WARNING")
 @OptIn(ExperimentalUnsignedTypes::class)
 @Immutable
-inline class TransformOrigin(@PublishedApi internal val packedValue: Long) {
+inline class TransformOrigin internal constructor(@PublishedApi internal val packedValue: Long) {
 
     /**
      * Return the position along the x-axis that should be used as the
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/HitPathTracker.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/HitPathTracker.kt
index 9ea0b0b..adb330a 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/HitPathTracker.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/HitPathTracker.kt
@@ -16,9 +16,9 @@
 
 package androidx.compose.ui.input.pointer
 
+import androidx.compose.ui.layout.LayoutCoordinates
+import androidx.compose.ui.layout.findRoot
 import androidx.compose.ui.node.InternalCoreApi
-import androidx.compose.ui.unit.IntOffset
-import androidx.compose.ui.unit.plus
 
 /**
  * Organizes pointers and the [PointerInputFilter]s that they hit into a hierarchy such that
@@ -353,40 +353,25 @@
         // dispatch or could have moved in some synchronous way (an Android parent may have moved
         // for example) and we actually want to add back whatever position was previously
         // subtracted.
-        val position = pointerInputFilter.position
-        val size = pointerInputFilter.size
+        val coordinates = filter.layoutCoordinates!!
+        val root = coordinates.findRoot()
 
-        // TODO(shepshapard): Subtracting offsets and adding offsets is currently expensive because
-        //  PointerInputChanges are copied during the operation. Should be better when
-        //  PointerInputChanges are privately mutable.
-        subtractOffset(position)
-        val pointerEvent = PointerEvent(this.changes.values.toList(), this)
-        filter.onPointerEvent(pointerEvent, pass, size)
-        addOffset(position)
+        val pointerEvent = PointerEvent(changesInLocal(root, coordinates), this)
+        filter.onPointerEvent(pointerEvent, pass, coordinates.size)
     }
 
-    private fun InternalPointerEvent.addOffset(position: IntOffset) {
-        // TODO(shepshapard): Replace everything is costly, we should be able to simply change
-        //  data in place here and prevent it from being changed when dispatched to
-        //  PointerInputFilters.
-        if (position != IntOffset.Zero) {
-            changes.replaceEverything {
-                it.copy(
-                    currentPosition = it.position + position,
-                    previousPosition = it.previousPosition + position
-                )
-            }
+    private fun InternalPointerEvent.changesInLocal(
+        root: LayoutCoordinates,
+        local: LayoutCoordinates
+    ): List<PointerInputChange> {
+        val list = mutableListOf<PointerInputChange>()
+        changes.values.forEach { change ->
+            list += change.copy(
+                previousPosition = local.localPositionOf(root, change.previousPosition),
+                currentPosition = local.localPositionOf(root, change.position)
+            )
         }
-    }
-
-    private fun InternalPointerEvent.subtractOffset(position: IntOffset) {
-        addOffset(-position)
-    }
-
-    private inline fun <K, V> MutableMap<K, V>.replaceEverything(f: (V) -> V) {
-        for (entry in this) {
-            entry.setValue(f(entry.value))
-        }
+        return list
     }
 }
 
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/InternalPointerInput.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/InternalPointerInput.kt
index bdd25b4..b1107e1 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/InternalPointerInput.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/InternalPointerInput.kt
@@ -34,11 +34,12 @@
 /**
  * Data that describes a particular pointer
  *
- * All pointer locations are relative to the device screen.
+ * [positionOnScreen] is relative to the device screen. [position] is relative to the owner.
  */
 internal data class PointerInputEventData(
     val id: PointerId,
     val uptime: Long,
+    val positionOnScreen: Offset,
     val position: Offset,
     val down: Boolean,
     val type: PointerType
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/MouseTemporaryApi.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/MouseTemporaryApi.kt
deleted file mode 100644
index d3cadbe..0000000
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/MouseTemporaryApi.kt
+++ /dev/null
@@ -1,29 +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.ui.input.pointer
-
-@RequiresOptIn(
-    level = RequiresOptIn.Level.ERROR,
-    message = "This is a temporary API and should be removed after proper mouse handling is " +
-        "settled (b/171402426)."
-)
-@Target(
-    AnnotationTarget.CLASS,
-    AnnotationTarget.FUNCTION,
-    AnnotationTarget.PROPERTY
-)
-annotation class MouseTemporaryApi
\ No newline at end of file
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/PointerEvent.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/PointerEvent.kt
index d282ff9..38ac86a 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/PointerEvent.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/PointerEvent.kt
@@ -26,9 +26,7 @@
 import androidx.compose.ui.input.pointer.PointerEventPass.Main
 import androidx.compose.ui.layout.LayoutCoordinates
 import androidx.compose.ui.node.InternalCoreApi
-import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.IntSize
-import androidx.compose.ui.unit.round
 
 /**
  * A [Modifier.Element] that can interact with pointer input.
@@ -78,10 +76,6 @@
      */
     val size: IntSize
         get() = layoutCoordinates?.size ?: IntSize.Zero
-
-    @Suppress("DEPRECATION")
-    internal val position: IntOffset
-        get() = layoutCoordinates?.run { localToGlobal(Offset.Zero).round() } ?: IntOffset.Zero
     internal val isAttached: Boolean
         get() = layoutCoordinates?.isAttached == true
 }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessor.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessor.kt
index f7d7bf0..aa6be16 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessor.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessor.kt
@@ -21,6 +21,11 @@
 import androidx.compose.ui.node.LayoutNode
 import androidx.compose.ui.util.fastForEach
 
+internal interface PositionCalculator {
+    fun screenToLocal(positionOnScreen: Offset): Offset
+    fun localToScreen(localPosition: Offset): Offset
+}
+
 /**
  * The core element that receives [PointerInputEvent]s and process them in Compose UI.
  */
@@ -40,11 +45,14 @@
      * @see ProcessResult
      * @see PointerInputEvent
      */
-    fun process(pointerEvent: PointerInputEvent): ProcessResult {
+    fun process(
+        pointerEvent: PointerInputEvent,
+        positionCalculator: PositionCalculator
+    ): ProcessResult {
 
         // Gets a new PointerInputChangeEvent with the PointerInputEvent.
         val internalPointerEvent =
-            pointerInputChangeEventProducer.produce(pointerEvent)
+            pointerInputChangeEventProducer.produce(pointerEvent, positionCalculator)
 
         // TODO(shepshapard): Create fast forEach for maps?
 
@@ -110,32 +118,42 @@
     /**
      * Produces [InternalPointerEvent]s by tracking changes between [PointerInputEvent]s
      */
-    internal fun produce(pointerInputEvent: PointerInputEvent):
+    fun produce(pointerInputEvent: PointerInputEvent, positionCalculator: PositionCalculator):
         InternalPointerEvent {
             val changes: MutableMap<PointerId, PointerInputChange> = mutableMapOf()
             pointerInputEvent.pointers.fastForEach {
-                val previous = previousPointerInputData[it.id] ?: PointerInputData(
-                    it.uptime,
-                    it.position,
-                    false,
-                    it.type
-                )
+                val previousTime: Long
+                val previousPosition: Offset
+                val previousDown: Boolean
+
+                val previousData = previousPointerInputData[it.id]
+                if (previousData == null) {
+                    previousTime = it.uptime
+                    previousPosition = it.position
+                    previousDown = false
+                } else {
+                    previousTime = previousData.uptime
+                    previousDown = previousData.down
+                    previousPosition =
+                        positionCalculator.screenToLocal(previousData.positionOnScreen)
+                }
+
                 changes[it.id] =
                     PointerInputChange(
                         it.id,
                         it.uptime,
                         it.position,
                         it.down,
-                        previous.uptime,
-                        previous.position,
-                        previous.down,
+                        previousTime,
+                        previousPosition,
+                        previousDown,
                         ConsumedData(),
                         it.type
                     )
                 if (it.down) {
                     previousPointerInputData[it.id] = PointerInputData(
                         it.uptime,
-                        it.position,
+                        it.positionOnScreen,
                         it.down,
                         it.type
                     )
@@ -155,7 +173,7 @@
 
     private class PointerInputData(
         val uptime: Long,
-        val position: Offset,
+        val positionOnScreen: Offset,
         val down: Boolean,
         val type: PointerType
     )
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilter.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilter.kt
index cb9aa21..ee04406 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilter.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilter.kt
@@ -117,18 +117,23 @@
     ): R
 }
 
+private const val PointerInputModifierNoParamError =
+    "Modifier.pointerInput must provide one or more 'key' parameters that define the identity of " +
+        "the modifier and determine when its previous input processing coroutine should be " +
+        "cancelled and a new effect launched for the new key."
+
 /**
  * Create a modifier for processing pointer input within the region of the modified element.
  *
- * [pointerInput] [block]s may call [PointerInputScope.awaitPointerEventScope] to install a pointer
- * input handler that can [AwaitPointerEventScope.awaitPointerEvent] to receive and consume
- * pointer input events. Extension functions on [PointerInputScope] or [AwaitPointerEventScope]
- * may be defined to perform higher-level gesture detection.
+ * It is an error to call [pointerInput] without at least one `key` parameter.
  */
-@Deprecated("Effect keys are now required parameters", ReplaceWith("pointerInput(Unit, block)"))
+// This deprecated-error function shadows the varargs overload so that the varargs version
+// is not used without key parameters.
+@Suppress("DeprecatedCallableAddReplaceWith", "UNUSED_PARAMETER", "unused")
+@Deprecated(PointerInputModifierNoParamError, level = DeprecationLevel.ERROR)
 fun Modifier.pointerInput(
     block: suspend PointerInputScope.() -> Unit
-): Modifier = pointerInput(Unit, block)
+): Modifier = error(PointerInputModifierNoParamError)
 
 /**
  * Create a modifier for processing pointer input within the region of the modified element.
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/IntrinsicMeasurable.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/IntrinsicMeasurable.kt
index dd87658..c9efdf6 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/IntrinsicMeasurable.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/IntrinsicMeasurable.kt
@@ -54,5 +54,8 @@
 /**
  * A function for performing intrinsic measurement.
  */
-typealias IntrinsicMeasureBlock =
+@Deprecated(
+    "IntrinsicMeasureBlock was deprecated. See MeasurePolicy and the new Layout overloads."
+)
+internal typealias IntrinsicMeasureBlock =
     IntrinsicMeasureScope.(List<IntrinsicMeasurable>, Int) -> Int
\ No newline at end of file
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 b0b33fd..d6f45c5 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
@@ -23,7 +23,6 @@
 import androidx.compose.runtime.ComposeNode
 import androidx.compose.runtime.SkippableUpdater
 import androidx.compose.runtime.currentComposer
-import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.GraphicsLayerScope
 import androidx.compose.ui.materialize
@@ -41,40 +40,54 @@
 
 /**
  * [Layout] is the main core component for layout. It can be used to measure and position
- * zero or more children.
+ * zero or more layout children.
  *
- * Intrinsic measurement blocks define the intrinsic sizes of the current layout. These
- * can be queried by the parent in order to understand, in specific cases, what constraints
- * should the layout be measured with:
- * - [minIntrinsicWidthMeasureBlock] defines the minimum width this layout can take, given
- *   a specific height, such that the content of the layout will be painted correctly
- * - [minIntrinsicHeightMeasureBlock] defines the minimum height this layout can take, given
- *   a specific width, such that the content of the layout will be painted correctly
- * - [maxIntrinsicWidthMeasureBlock] defines the minimum width such that increasing it further
- *   will not decrease the minimum intrinsic height
- * - [maxIntrinsicHeightMeasureBlock] defines the minimum height such that increasing it further
- *   will not decrease the minimum intrinsic width
+ * The measurement, layout and intrinsic measurement behaviours of this layout will be defined
+ * by the [measurePolicy] instance. See [MeasurePolicy] for more details.
  *
  * For a composable able to define its content according to the incoming constraints,
- * see [WithConstraints].
+ * see [androidx.compose.foundation.layout.BoxWithConstraints].
  *
  * Example usage:
+ * @sample androidx.compose.ui.samples.LayoutUsage
+ *
+ * Example usage with custom intrinsic measurements:
  * @sample androidx.compose.ui.samples.LayoutWithProvidedIntrinsicsUsage
  *
  * @param content The children composable to be laid out.
  * @param modifier Modifiers to be applied to the layout.
- * @param minIntrinsicWidthMeasureBlock The minimum intrinsic width of the layout.
- * @param minIntrinsicHeightMeasureBlock The minimum intrinsic height of the layout.
- * @param maxIntrinsicWidthMeasureBlock The maximum intrinsic width of the layout.
- * @param maxIntrinsicHeightMeasureBlock The maximum intrinsic height of the layout.
- * @param measureBlock The block defining the measurement and positioning of the layout.
+ * @param measurePolicy The policy defining the measurement and positioning of the layout.
  *
  * @see Layout
- * @see WithConstraints
+ * @see MeasurePolicy
+ * @see androidx.compose.foundation.layout.BoxWithConstraints
  */
 @Suppress("ComposableLambdaParameterPosition")
+@Composable inline fun Layout(
+    content: @Composable () -> Unit,
+    modifier: Modifier = Modifier,
+    measurePolicy: MeasurePolicy
+) {
+    val density = LocalDensity.current
+    val layoutDirection = LocalLayoutDirection.current
+    ComposeNode<ComposeUiNode, Applier<Any>>(
+        factory = ComposeUiNode.Constructor,
+        update = {
+            set(measurePolicy, ComposeUiNode.SetMeasurePolicy)
+            set(density, ComposeUiNode.SetDensity)
+            set(layoutDirection, ComposeUiNode.SetLayoutDirection)
+        },
+        skippableUpdate = materializerOf(modifier),
+        content = content
+    )
+}
+
+@Suppress("ComposableLambdaParameterPosition")
 @Composable
-fun Layout(
+@Deprecated(
+    "This composable was deprecated. Please use the alternative Layout overloads instead."
+)
+internal fun Layout(
     content: @Composable () -> Unit,
     minIntrinsicWidthMeasureBlock: IntrinsicMeasureBlock,
     minIntrinsicHeightMeasureBlock: IntrinsicMeasureBlock,
@@ -83,47 +96,41 @@
     modifier: Modifier = Modifier,
     measureBlock: MeasureBlock
 ) {
-    val measureBlocks = measureBlocksOf(
-        minIntrinsicWidthMeasureBlock,
-        minIntrinsicHeightMeasureBlock,
-        maxIntrinsicWidthMeasureBlock,
-        maxIntrinsicHeightMeasureBlock,
-        measureBlock
-    )
-    Layout(content, measureBlocks, modifier)
+    val measurePolicy = object : MeasurePolicy {
+        override fun MeasureScope.measure(
+            measurables: List<Measurable>,
+            constraints: Constraints
+        ) = measureBlock(this, measurables, constraints)
+
+        override fun IntrinsicMeasureScope.minIntrinsicWidth(
+            measurables: List<IntrinsicMeasurable>,
+            height: Int
+        ) = minIntrinsicWidthMeasureBlock(this, measurables, height)
+
+        override fun IntrinsicMeasureScope.minIntrinsicHeight(
+            measurables: List<IntrinsicMeasurable>,
+            width: Int
+        ) = minIntrinsicHeightMeasureBlock(this, measurables, width)
+
+        override fun IntrinsicMeasureScope.maxIntrinsicWidth(
+            measurables: List<IntrinsicMeasurable>,
+            height: Int
+        ) = maxIntrinsicWidthMeasureBlock(this, measurables, height)
+
+        override fun IntrinsicMeasureScope.maxIntrinsicHeight(
+            measurables: List<IntrinsicMeasurable>,
+            width: Int
+        ) = maxIntrinsicHeightMeasureBlock(this, measurables, width)
+    }
+
+    Layout(content, modifier, measurePolicy)
 }
 
-/**
- * Creates an instance of [MeasureBlocks] to pass to [Layout] given
- * intrinsic measures and a measure block.
- *
- * @sample androidx.compose.ui.samples.LayoutWithMeasureBlocksWithIntrinsicUsage
- *
- * Intrinsic measurement blocks define the intrinsic sizes of the current layout. These
- * can be queried by the parent in order to understand, in specific cases, what constraints
- * should the layout be measured with:
- * - [minIntrinsicWidthMeasureBlock] defines the minimum width this layout can take, given
- *   a specific height, such that the content of the layout will be painted correctly
- * - [minIntrinsicHeightMeasureBlock] defines the minimum height this layout can take, given
- *   a specific width, such that the content of the layout will be painted correctly
- * - [maxIntrinsicWidthMeasureBlock] defines the minimum width such that increasing it further
- *   will not decrease the minimum intrinsic height
- * - [maxIntrinsicHeightMeasureBlock] defines the minimum height such that increasing it further
- *   will not decrease the minimum intrinsic width
- *
- * For a composable able to define its content according to the incoming constraints,
- * see [WithConstraints].
- *
- * @param minIntrinsicWidthMeasureBlock The minimum intrinsic width of the layout.
- * @param minIntrinsicHeightMeasureBlock The minimum intrinsic height of the layout.
- * @param maxIntrinsicWidthMeasureBlock The maximum intrinsic width of the layout.
- * @param maxIntrinsicHeightMeasureBlock The maximum intrinsic height of the layout.
- * @param measureBlock The block defining the measurement and positioning of the layout.
- *
- * @see Layout
- * @see WithConstraints
- */
-fun measureBlocksOf(
+@Deprecated(
+    "MeasureBlocks was deprecated. Please use MeasurePolicy and the Layout overloads using " +
+        "it instead."
+)
+internal fun measureBlocksOf(
     minIntrinsicWidthMeasureBlock: IntrinsicMeasureBlock,
     minIntrinsicHeightMeasureBlock: IntrinsicMeasureBlock,
     maxIntrinsicWidthMeasureBlock: IntrinsicMeasureBlock,
@@ -159,84 +166,6 @@
     }
 }
 
-/**
- * [Layout] is the main core component for layout. It can be used to measure and position
- * zero or more children.
- *
- * The intrinsic measurements of this layout will be calculated by running the measureBlock,
- * while swapping measure calls with appropriate intrinsic measurements. Note that these
- * provided implementations will not be accurate in all cases - when this happens, the other
- * overload of [Layout] should be used to provide correct measurements.
- *
- * For a composable able to define its content according to the incoming constraints,
- * see [WithConstraints].
- *
- * Example usage:
- * @sample androidx.compose.ui.samples.LayoutUsage
- *
- * @param content The children composable to be laid out.
- * @param modifier Modifiers to be applied to the layout.
- * @param measureBlock The block defining the measurement and positioning of the layout.
- *
- * @see Layout
- * @see WithConstraints
- */
-@Suppress("ComposableLambdaParameterPosition")
-@Composable
-/*inline*/ fun Layout(
-    /*crossinline*/
-    content: @Composable () -> Unit,
-    modifier: Modifier = Modifier,
-    /*noinline*/
-    measureBlock: MeasureBlock
-) {
-    val measureBlocks = remember(measureBlock) { MeasuringIntrinsicsMeasureBlocks(measureBlock) }
-    Layout(content, measureBlocks, modifier)
-}
-
-/**
- * [Layout] is the main core component for layout. It can be used to measure and position
- * zero or more children.
- *
- * The intrinsic measurements of this layout will be calculated by using the [measureBlocks]
- * instance.
- *
- * For a composable able to define its content according to the incoming constraints,
- * see [WithConstraints].
- *
- * Example usage:
- * @sample androidx.compose.ui.samples.LayoutWithMeasureBlocksWithIntrinsicUsage
- *
- * @param content The children composable to be laid out.
- * @param modifier Modifiers to be applied to the layout.
- * @param measureBlocks An [MeasureBlocks] instance defining the measurement and
- * positioning of the layout.
- *
- * @see Layout
- * @see measureBlocksOf
- * @see WithConstraints
- */
-
-@Suppress("ComposableLambdaParameterPosition")
-@Composable inline fun Layout(
-    content: @Composable () -> Unit,
-    measureBlocks: MeasureBlocks,
-    modifier: Modifier = Modifier
-) {
-    val density = LocalDensity.current
-    val layoutDirection = LocalLayoutDirection.current
-    ComposeNode<ComposeUiNode, Applier<Any>>(
-        factory = ComposeUiNode.Constructor,
-        update = {
-            set(measureBlocks, ComposeUiNode.SetMeasureBlocks)
-            set(density, ComposeUiNode.SetDensity)
-            set(layoutDirection, ComposeUiNode.SetLayoutDirection)
-        },
-        skippableUpdate = materializerOf(modifier),
-        content = content
-    )
-}
-
 @PublishedApi
 internal fun materializerOf(
     modifier: Modifier
@@ -247,18 +176,17 @@
     }
 }
 
-@Suppress("ComposableLambdaParameterNaming", "ComposableLambdaParameterPosition")
+@Suppress("ComposableLambdaParameterPosition")
 @Composable
 @Deprecated(
-    "This composable is temporary to enable quicker prototyping in ConstraintLayout. " +
-        "It should not be used in app code directly."
+    "This API is unsafe for UI performance at scale - using it incorrectly will lead " +
+        "to exponential performance issues. This API should be avoided whenever possible."
 )
 fun MultiMeasureLayout(
     modifier: Modifier = Modifier,
-    children: @Composable () -> Unit,
-    measureBlock: MeasureBlock
+    content: @Composable () -> Unit,
+    measurePolicy: MeasurePolicy
 ) {
-    val measureBlocks = remember(measureBlock) { MeasuringIntrinsicsMeasureBlocks(measureBlock) }
     val materialized = currentComposer.materialize(modifier)
     val density = LocalDensity.current
     val layoutDirection = LocalLayoutDirection.current
@@ -267,13 +195,13 @@
         factory = LayoutNode.Constructor,
         update = {
             set(materialized, ComposeUiNode.SetModifier)
-            set(measureBlocks, ComposeUiNode.SetMeasureBlocks)
+            set(measurePolicy, ComposeUiNode.SetMeasurePolicy)
             set(density, ComposeUiNode.SetDensity)
             set(layoutDirection, ComposeUiNode.SetLayoutDirection)
             @Suppress("DEPRECATION")
             init { this.canMultiMeasure = true }
         },
-        content = children
+        content = content
     )
 }
 
@@ -285,7 +213,7 @@
         measuredSize = IntSize(width, height)
     }
 
-    override fun get(line: AlignmentLine): Int = AlignmentLine.Unspecified
+    override fun get(alignmentLine: AlignmentLine): Int = AlignmentLine.Unspecified
     override fun placeAt(
         position: IntOffset,
         zIndex: Float,
@@ -297,7 +225,6 @@
 /**
  * Identifies an [IntrinsicMeasurable] as a min or max intrinsic measurement.
  */
-@PublishedApi
 internal enum class IntrinsicMinMax {
     Min, Max
 }
@@ -305,7 +232,6 @@
 /**
  * Identifies an [IntrinsicMeasurable] as a width or height intrinsic measurement.
  */
-@PublishedApi
 internal enum class IntrinsicWidthHeight {
     Width, Height
 }
@@ -316,7 +242,6 @@
  * by using their [measure], substituting the intrinsics gathering method
  * for the [Measurable.measure] call.
  */
-@PublishedApi
 internal class DefaultIntrinsicMeasurable(
     val measurable: IntrinsicMeasurable,
     val minMax: IntrinsicMinMax,
@@ -363,7 +288,6 @@
  * Receiver scope for [Layout]'s and [LayoutModifier]'s layout lambda when used in an intrinsics
  * call.
  */
-@PublishedApi
 internal class IntrinsicsMeasureScope(
     density: Density,
     override val layoutDirection: LayoutDirection
@@ -373,7 +297,8 @@
  * Default [MeasureBlocks] object implementation, providing intrinsic measurements
  * that use the measure block replacing the measure calls with intrinsic measurement calls.
  */
-fun MeasuringIntrinsicsMeasureBlocks(measureBlock: MeasureBlock) =
+@Deprecated("MeasuringIntrinsicsMeasureBlocks was deprecated. Please use MeasurePolicy instead.")
+internal fun MeasuringIntrinsicsMeasureBlocks(measureBlock: MeasureBlock) =
     object : MeasureBlocks {
         override fun measure(
             measureScope: MeasureScope,
@@ -435,8 +360,8 @@
  * Default implementation for the min intrinsic width of a layout. This works by running the
  * measure block with measure calls replaced with intrinsic measurement calls.
  */
-private inline fun Density.MeasuringMinIntrinsicWidth(
-    measureBlock: MeasureBlock,
+private fun Density.MeasuringMinIntrinsicWidth(
+    measureBlock: MeasureScope.(List<Measurable>, Constraints) -> MeasureResult,
     measurables: List<IntrinsicMeasurable>,
     h: Int,
     layoutDirection: LayoutDirection
@@ -454,8 +379,8 @@
  * Default implementation for the min intrinsic width of a layout. This works by running the
  * measure block with measure calls replaced with intrinsic measurement calls.
  */
-private inline fun Density.MeasuringMinIntrinsicHeight(
-    measureBlock: MeasureBlock /*TODO: crossinline*/,
+private fun Density.MeasuringMinIntrinsicHeight(
+    measureBlock: MeasureScope.(List<Measurable>, Constraints) -> MeasureResult,
     measurables: List<IntrinsicMeasurable>,
     w: Int,
     layoutDirection: LayoutDirection
@@ -473,8 +398,8 @@
  * Default implementation for the max intrinsic width of a layout. This works by running the
  * measure block with measure calls replaced with intrinsic measurement calls.
  */
-private inline fun Density.MeasuringMaxIntrinsicWidth(
-    measureBlock: MeasureBlock /*TODO: crossinline*/,
+private fun Density.MeasuringMaxIntrinsicWidth(
+    measureBlock: MeasureScope.(List<Measurable>, Constraints) -> MeasureResult,
     measurables: List<IntrinsicMeasurable>,
     h: Int,
     layoutDirection: LayoutDirection
@@ -492,8 +417,8 @@
  * Default implementation for the max intrinsic height of a layout. This works by running the
  * measure block with measure calls replaced with intrinsic measurement calls.
  */
-private inline fun Density.MeasuringMaxIntrinsicHeight(
-    measureBlock: MeasureBlock /*TODO: crossinline*/,
+private fun Density.MeasuringMaxIntrinsicHeight(
+    measureBlock: MeasureScope.(List<Measurable>, Constraints) -> MeasureResult,
     measurables: List<IntrinsicMeasurable>,
     w: Int,
     layoutDirection: LayoutDirection
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/LayoutCoordinates.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/LayoutCoordinates.kt
index d6256ff..c4a7e1a 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/LayoutCoordinates.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/LayoutCoordinates.kt
@@ -24,7 +24,6 @@
 /**
  * A holder of the measured bounds for the layout (MeasureBox).
  */
-// TODO(Andrey): Add Matrix transformation here when we would have this logic.
 interface LayoutCoordinates {
     /**
      * The size of this layout in the local coordinates space.
@@ -53,27 +52,12 @@
     val isAttached: Boolean
 
     /**
-     * Converts a global position into a local position within this layout.
-     */
-    @Deprecated(
-        "Use windowToLocal instead",
-        replaceWith = ReplaceWith("windowToLocal(global)")
-    )
-    fun globalToLocal(global: Offset): Offset
-
-    /**
      * Converts [relativeToWindow] relative to the window's origin into an [Offset] relative to
      * this layout.
      */
     fun windowToLocal(relativeToWindow: Offset): Offset
 
     /**
-     * Converts a local position within this layout into a global one.
-     */
-    @Deprecated("Use localToWindow instead", ReplaceWith("localToWindow(local)"))
-    fun localToGlobal(local: Offset): Offset
-
-    /**
      * Converts [relativeToLocal] position within this layout into an [Offset] relative to the
      * window's origin.
      */
@@ -92,23 +76,6 @@
     fun localPositionOf(sourceCoordinates: LayoutCoordinates, relativeToSource: Offset): Offset
 
     /**
-     * Converts a child layout position into a local position within this layout.
-     */
-    @Deprecated("Use localPositionOf instead", ReplaceWith("localPositionOf(child, childLocal)"))
-    fun childToLocal(child: LayoutCoordinates, childLocal: Offset): Offset
-
-    /**
-     * Returns the child bounding box, in local coordinates. A child that is rotated or scaled
-     * will have the bounding box of rotated or scaled content in local coordinates. If a child
-     * is clipped, the clipped rectangle will be returned.
-     */
-    @Deprecated(
-        message = "Use localBoundingBoxOf instead",
-        replaceWith = ReplaceWith("localBoundingBoxOf(child)")
-    )
-    fun childBoundingBox(child: LayoutCoordinates): Rect
-
-    /**
      * Returns the bounding box of [sourceCoordinates] in the local coordinates.
      * If [clipBounds] is `true`, any clipping that occurs between [sourceCoordinates] and
      * this layout will affect the returned bounds, and can even result in an empty rectangle
@@ -127,24 +94,14 @@
      * Returns the position in pixels of an [alignment line][AlignmentLine],
      * or [AlignmentLine.Unspecified] if the line is not provided.
      */
-    operator fun get(line: AlignmentLine): Int
+    operator fun get(alignmentLine: AlignmentLine): Int
 }
 
 /**
- * The global position of this layout.
- */
-@Suppress("DEPRECATION")
-@Deprecated("Use positionInWindow() instead", ReplaceWith("positionInWindow()"))
-inline val LayoutCoordinates.globalPosition: Offset get() = localToGlobal(Offset.Zero)
-
-/**
  * The position of this layout inside the root composable.
  */
 fun LayoutCoordinates.positionInRoot(): Offset = localToRoot(Offset.Zero)
 
-@Deprecated("Use positionInRoot() instead", ReplaceWith("positionInRoot()"))
-inline val LayoutCoordinates.positionInRoot: Offset get() = localToRoot(Offset.Zero)
-
 /**
  * The position of this layout relative to the window.
  */
@@ -156,59 +113,40 @@
 fun LayoutCoordinates.boundsInRoot(): Rect =
     findRoot().localBoundingBoxOf(this)
 
-@Deprecated("Use boundsInRoot()", ReplaceWith("boundsInRoot()"))
-val LayoutCoordinates.boundsInRoot: Rect get() = boundsInRoot()
-
 /**
  * The boundaries of this layout relative to the window's origin.
  */
 fun LayoutCoordinates.boundsInWindow(): Rect {
     val root = findRoot()
     val bounds = boundsInRoot()
-    val windowPosition = root.positionInWindow()
-    return Rect(
-        left = bounds.left + windowPosition.x,
-        top = bounds.top + windowPosition.y,
-        right = bounds.right + windowPosition.x,
-        bottom = bounds.bottom + windowPosition.y
-    )
+    val topLeft = root.localToWindow(Offset(bounds.left, bounds.top))
+    val topRight = root.localToWindow(Offset(bounds.right, bounds.top))
+    val bottomRight = root.localToWindow(Offset(bounds.right, bounds.bottom))
+    val bottomLeft = root.localToWindow(Offset(bounds.left, bounds.bottom))
+    val left = minOf(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x)
+    val top = minOf(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y)
+    val right = maxOf(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x)
+    val bottom = maxOf(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y)
+    return Rect(left, top, right, bottom)
 }
 
 /**
  * Returns the position of the top-left in the parent's content area or (0, 0)
  * for the root.
  */
-val LayoutCoordinates.positionInParent: Offset
-    get() = parentLayoutCoordinates?.localPositionOf(this, Offset.Zero) ?: Offset.Zero
+fun LayoutCoordinates.positionInParent(): Offset =
+    parentLayoutCoordinates?.localPositionOf(this, Offset.Zero) ?: Offset.Zero
 
 /**
  * Returns the bounding box of the child in the parent's content area, including any clipping
  * done with respect to the parent. For the root, the bounds is positioned at (0, 0) and sized
  * to the size of the root.
  */
-val LayoutCoordinates.boundsInParent: Rect
-    get() = parentLayoutCoordinates?.localBoundingBoxOf(this)
+fun LayoutCoordinates.boundsInParent(): Rect =
+    parentLayoutCoordinates?.localBoundingBoxOf(this)
         ?: Rect(0f, 0f, size.width.toFloat(), size.height.toFloat())
 
 /**
- * The global boundaries of this layout inside.
- */
-@Deprecated("Use boundsInWindow instead", ReplaceWith("boundsInWindow"))
-val LayoutCoordinates.globalBounds: Rect
-    get() {
-        val root = findRoot()
-        @Suppress("DEPRECATION")
-        val rootPosition = root.localToGlobal(Offset.Zero)
-        val bounds = root.localBoundingBoxOf(this)
-        return Rect(
-            left = bounds.left + rootPosition.x,
-            top = bounds.top + rootPosition.y,
-            right = bounds.right + rootPosition.x,
-            bottom = bounds.bottom + rootPosition.y
-        )
-    }
-
-/**
  * Returns the [LayoutCoordinates] of the root layout element in the hierarchy. This will have
  * the size of the entire compose UI.
  */
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/LayoutModifier.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/LayoutModifier.kt
index 4b37b72..a57fce3 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/LayoutModifier.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/LayoutModifier.kt
@@ -229,7 +229,7 @@
             measuredSize = IntSize(width, height)
         }
 
-        override fun get(line: AlignmentLine): Int = AlignmentLine.Unspecified
+        override fun get(alignmentLine: AlignmentLine): Int = AlignmentLine.Unspecified
         override fun placeAt(
             position: IntOffset,
             zIndex: Float,
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/MeasurePolicy.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/MeasurePolicy.kt
new file mode 100644
index 0000000..b6cc8e1
--- /dev/null
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/MeasurePolicy.kt
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.ui.layout
+
+import androidx.compose.runtime.Stable
+import androidx.compose.ui.unit.Constraints
+
+/**
+ * Defines the measure and layout behavior of a [Layout]. [Layout] and [MeasurePolicy] are the way
+ * Compose layouts (such as `Box`, `Column`, etc.) are built, and they can also be used to achieve
+ * custom layouts.
+ *
+ * See [Layout] samples for examples of how to use [MeasurePolicy].
+ *
+ * Intrinsic measurement methods define the intrinsic size of the layout. These can be queried
+ * by the layout's parent in order to obtain, in specific cases, more information about
+ * the size of the layout in the absence of specific constraints:
+ * - [minIntrinsicWidthMeasureBlock] defines the minimum width this layout can take, given
+ *   a specific height, such that the content of the layout will be painted correctly
+ * - [minIntrinsicHeightMeasureBlock] defines the minimum height this layout can take, given
+ *   a specific width, such that the content of the layout will be painted correctly
+ * - [maxIntrinsicWidthMeasureBlock] defines the minimum width such that increasing it further
+ *   will not decrease the minimum intrinsic height
+ * - [maxIntrinsicHeightMeasureBlock] defines the minimum height such that increasing it further
+ *   will not decrease the minimum intrinsic width
+ * Most layout scenarios do not require querying intrinsic measurements. Therefore, when writing
+ * a custom layout, it is common to only define the actual measurement, as most of the times
+ * the intrinsic measurements of the layout will not be queried. Moreover, intrinsic measurement
+ * methods have default implementations that make a best effort attempt to calculate the intrinsic
+ * measurements by reusing the [measure] method. Note this will not be correct for all layouts,
+ * but can be a convenient approximation.
+ * Intrinsic measurements can be useful when the layout system enforcement of no more than one
+ * measurement per child is limiting. Layouts that use them are the `preferredWidth(IntrinsicSize)`
+ * and `preferredHeight(IntrinsicSize)` modifiers. See their samples for when they can be useful.
+ *
+ * @see Layout
+ */
+@Stable
+fun interface MeasurePolicy {
+    /**
+     * The function that defines the measurement and layout. Each [Measurable] in the [measurables]
+     * list corresponds to a layout child of the layout, and children can be measured using the
+     * [Measurable.measure] method. Measuring a child returns a [Placeable], which can then
+     * be positioned in the [MeasureResult.placeChildren] of the returned [MeasureResult].
+     * Usually [MeasureResult] objects are created using the [MeasureScope.layout] factory, which
+     * takes the calculated size of this layout, its alignment lines, and a block defining
+     * the positioning of the children layouts.
+     */
+    fun MeasureScope.measure(
+        measurables: List<Measurable>,
+        constraints: Constraints
+    ): MeasureResult
+
+    /**
+     * The function used to calculate [IntrinsicMeasurable.minIntrinsicWidth]. It represents
+     * the minimum width this layout can take, given a specific height, such that the content
+     * of the layout can be painted correctly.
+     */
+    fun IntrinsicMeasureScope.minIntrinsicWidth(
+        measurables: List<IntrinsicMeasurable>,
+        height: Int
+    ): Int {
+        val mapped = measurables.map {
+            DefaultIntrinsicMeasurable(it, IntrinsicMinMax.Min, IntrinsicWidthHeight.Width)
+        }
+        val constraints = Constraints(maxHeight = height)
+        val layoutReceiver = IntrinsicsMeasureScope(this, layoutDirection)
+        val layoutResult = layoutReceiver.measure(mapped, constraints)
+        return layoutResult.width
+    }
+
+    /**
+     * The function used to calculate [IntrinsicMeasurable.minIntrinsicHeight]. It represents
+     * defines the minimum height this layout can take, given  a specific width, such
+     * that the content of the layout will be painted correctly.
+     */
+    fun IntrinsicMeasureScope.minIntrinsicHeight(
+        measurables: List<IntrinsicMeasurable>,
+        width: Int
+    ): Int {
+        val mapped = measurables.map {
+            DefaultIntrinsicMeasurable(it, IntrinsicMinMax.Min, IntrinsicWidthHeight.Height)
+        }
+        val constraints = Constraints(maxWidth = width)
+        val layoutReceiver = IntrinsicsMeasureScope(this, layoutDirection)
+        val layoutResult = layoutReceiver.measure(mapped, constraints)
+        return layoutResult.height
+    }
+
+    /**
+     * The function used to calculate [IntrinsicMeasurable.maxIntrinsicWidth]. It represents the
+     * minimum width such that increasing it further will not decrease the minimum intrinsic height.
+     */
+    fun IntrinsicMeasureScope.maxIntrinsicWidth(
+        measurables: List<IntrinsicMeasurable>,
+        height: Int
+    ): Int {
+        val mapped = measurables.map {
+            DefaultIntrinsicMeasurable(it, IntrinsicMinMax.Max, IntrinsicWidthHeight.Width)
+        }
+        val constraints = Constraints(maxHeight = height)
+        val layoutReceiver = IntrinsicsMeasureScope(this, layoutDirection)
+        val layoutResult = layoutReceiver.measure(mapped, constraints)
+        return layoutResult.width
+    }
+
+    /**
+     * The function used to calculate [IntrinsicMeasurable.maxIntrinsicHeight]. It represents the
+     * minimum height such that increasing it further will not decrease the minimum intrinsic width.
+     */
+    fun IntrinsicMeasureScope.maxIntrinsicHeight(
+        measurables: List<IntrinsicMeasurable>,
+        width: Int
+    ): Int {
+        val mapped = measurables.map {
+            DefaultIntrinsicMeasurable(it, IntrinsicMinMax.Max, IntrinsicWidthHeight.Height)
+        }
+        val constraints = Constraints(maxWidth = width)
+        val layoutReceiver = IntrinsicsMeasureScope(this, layoutDirection)
+        val layoutResult = layoutReceiver.measure(mapped, constraints)
+        return layoutResult.height
+    }
+}
\ No newline at end of file
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/MeasureScope.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/MeasureScope.kt
index 4a399cf..fab606e 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/MeasureScope.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/MeasureScope.kt
@@ -59,4 +59,5 @@
 /**
  * A function for performing layout measurement.
  */
-typealias MeasureBlock = MeasureScope.(List<Measurable>, Constraints) -> MeasureResult
\ No newline at end of file
+@Deprecated("MeasureBlock was deprecated. See MeasurePolicy and the new Layout overloads.")
+internal typealias MeasureBlock = MeasureScope.(List<Measurable>, Constraints) -> MeasureResult
\ No newline at end of file
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Measured.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Measured.kt
index a434ef2..85dd793 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Measured.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Measured.kt
@@ -17,22 +17,22 @@
 package androidx.compose.ui.layout
 
 /**
- * Read-only wrapper over [Placeable] that exposes the measurement result with no placing ability.
+ * A [Measured] corresponds to a layout that has been measured by its parent layout.
  */
-inline class Measured(internal val placeable: Placeable) {
+interface Measured {
     /**
-     * The measured width of the layout.
+     * The measured width of the layout. This might not respect the measurement constraints.
      */
-    val width: Int get() = placeable.measuredWidth
+    val measuredWidth: Int
 
     /**
-     * The measured height of the layout.
+     * The measured height of the layout. This might not respect the measurement constraints.
      */
-    val height: Int get() = placeable.measuredHeight
+    val measuredHeight: Int
 
     /**
      * Returns the position of an [alignment line][AlignmentLine],
-     * or `null` if the line is not provided.
+     * or [AlignmentLine.Unspecified] if the line is not provided.
      */
-    operator fun get(alignmentLine: AlignmentLine): Int = placeable[alignmentLine]
-}
\ No newline at end of file
+    operator fun get(alignmentLine: AlignmentLine): Int
+}
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Placeable.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Placeable.kt
index 1224f97..2897c48 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Placeable.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Placeable.kt
@@ -28,30 +28,38 @@
  *
  * A `Placeable` should never be stored between measure calls.
  */
-abstract class Placeable {
+abstract class Placeable : Measured {
     /**
-     * The width, in pixels, of the measured layout, as seen by the parent. This is usually the
-     * `width` value passed into [MeasureScope.layout], but will be different if the layout does
-     * not respect its incoming constraints, so the width will be coerced inside the min and
-     * max width.
+     * The width, in pixels, of the measured layout, as seen by the parent. This will usually
+     * coincide with the measured width of the layout (aka the `width` value passed into
+     * [MeasureScope.layout]), but can be different if the layout does not respect its
+     * incoming constraints: in these cases the width will be coerced inside the min and
+     * max width constraints - to access the actual width that the layout measured itself to,
+     * use [measuredWidth].
      */
     var width: Int = 0
         private set
 
     /**
-     * The height, in pixels, of the measured layout, as seen by the parent. This is usually the
-     * `height` value passed into [MeasureScope.layout], but can be different if the layout does
-     * not respect its incoming constraints, so the height will be coerced inside the min and
-     * max height.
+     * The height, in pixels, of the measured layout, as seen by the parent. This will usually
+     * coincide with the measured height of the layout (aka the `height` value passed
+     * into [MeasureScope.layout]), but can be different if the layout does not respect its
+     * incoming constraints: in these cases the height will be coerced inside the min and
+     * max height constraints - to access the actual height that the layout measured itself to,
+     * use [measuredHeight].
      */
     var height: Int = 0
         private set
 
     /**
-     * Returns the position of an [alignment line][AlignmentLine],
-     * or [AlignmentLine.Unspecified] if the line is not provided.
+     * The measured width of the layout. This might not respect the measurement constraints.
      */
-    abstract operator fun get(line: AlignmentLine): Int
+    override val measuredWidth: Int get() = measuredSize.width
+
+    /**
+     * The measured height of the layout. This might not respect the measurement constraints.
+     */
+    override val measuredHeight: Int get() = measuredSize.height
 
     /**
      * The measured size of this Placeable. This might not respect [measurementConstraints].
@@ -69,10 +77,6 @@
             )
         }
 
-    internal val measuredWidth get() = measuredSize.width
-
-    internal val measuredHeight get() = measuredSize.height
-
     /**
      * Positions the [Placeable] at [position] in its parent's coordinate system.
      *
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/RootMeasureBlocks.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/RootMeasurePolicy.kt
similarity index 87%
rename from compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/RootMeasureBlocks.kt
rename to compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/RootMeasurePolicy.kt
index 6a74225..d861c46 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/RootMeasureBlocks.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/RootMeasurePolicy.kt
@@ -22,21 +22,20 @@
 import androidx.compose.ui.unit.constrainWidth
 import androidx.compose.ui.util.fastForEach
 
-internal object RootMeasureBlocks : LayoutNode.NoIntrinsicsMeasureBlocks(
+internal object RootMeasurePolicy : LayoutNode.NoIntrinsicsMeasurePolicy(
     "Undefined intrinsics block and it is required"
 ) {
-    override fun measure(
-        measureScope: MeasureScope,
+    override fun MeasureScope.measure(
         measurables: List<Measurable>,
         constraints: Constraints
     ): MeasureResult {
         return when {
             measurables.isEmpty() -> {
-                measureScope.layout(constraints.minWidth, constraints.minHeight) {}
+                layout(constraints.minWidth, constraints.minHeight) {}
             }
             measurables.size == 1 -> {
                 val placeable = measurables[0].measure(constraints)
-                measureScope.layout(
+                layout(
                     constraints.constrainWidth(placeable.width),
                     constraints.constrainHeight(placeable.height)
                 ) {
@@ -53,7 +52,7 @@
                     maxWidth = maxOf(placeable.width, maxWidth)
                     maxHeight = maxOf(placeable.height, maxHeight)
                 }
-                measureScope.layout(
+                layout(
                     constraints.constrainWidth(maxWidth),
                     constraints.constrainHeight(maxHeight)
                 ) {
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/ScaleFactor.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/ScaleFactor.kt
index 1b351f4..f242669 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/ScaleFactor.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/ScaleFactor.kt
@@ -35,7 +35,7 @@
  */
 @Suppress("EXPERIMENTAL_FEATURE_WARNING")
 @Immutable
-inline class ScaleFactor(@PublishedApi internal val packedValue: Long) {
+inline class ScaleFactor internal constructor(@PublishedApi internal val packedValue: Long) {
 
     /**
      * Returns the scale factor to apply along the horizontal axis
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/SubcomposeLayout.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/SubcomposeLayout.kt
index 2ce132f..273d498 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/SubcomposeLayout.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/SubcomposeLayout.kt
@@ -30,7 +30,6 @@
 import androidx.compose.ui.node.ComposeUiNode
 import androidx.compose.ui.node.LayoutNode
 import androidx.compose.ui.node.LayoutNode.LayoutState
-import androidx.compose.ui.node.MeasureBlocks
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.platform.createSubcomposition
@@ -54,12 +53,12 @@
  * @sample androidx.compose.ui.samples.SubcomposeLayoutSample
  *
  * @param modifier [Modifier] to apply for the layout.
- * @param measureBlock Measure block which provides ability to subcompose during the measuring.
+ * @param measurePolicy Measure policy which provides ability to subcompose during the measuring.
  */
 @Composable
 fun SubcomposeLayout(
     modifier: Modifier = Modifier,
-    measureBlock: SubcomposeMeasureScope.(Constraints) -> MeasureResult
+    measurePolicy: SubcomposeMeasureScope.(Constraints) -> MeasureResult
 ) {
     val state = remember { SubcomposeLayoutState() }
     state.compositionContext = rememberCompositionContext()
@@ -72,7 +71,7 @@
         update = {
             init(state.setRoot)
             set(materialized, ComposeUiNode.SetModifier)
-            set(measureBlock, state.setMeasureBlock)
+            set(measurePolicy, state.setMeasurePolicy)
             set(density, ComposeUiNode.SetDensity)
             set(layoutDirection, ComposeUiNode.SetLayoutDirection)
         }
@@ -110,9 +109,9 @@
 
     // Pre-allocated lambdas to update LayoutNode
     val setRoot: LayoutNode.() -> Unit = { root = this }
-    val setMeasureBlock:
+    val setMeasurePolicy:
         LayoutNode.(SubcomposeMeasureScope.(Constraints) -> MeasureResult) -> Unit =
-            { measureBlocks = createMeasureBlocks(it) }
+            { measurePolicy = createMeasurePolicy(it) }
 
     // inner state
     private var root: LayoutNode? = null
@@ -197,19 +196,18 @@
         root.removeAt(currentIndex, root.foldedChildren.size - currentIndex)
     }
 
-    private fun createMeasureBlocks(
+    private fun createMeasurePolicy(
         block: SubcomposeMeasureScope.(Constraints) -> MeasureResult
-    ): MeasureBlocks = object : LayoutNode.NoIntrinsicsMeasureBlocks(
+    ): MeasurePolicy = object : LayoutNode.NoIntrinsicsMeasurePolicy(
         error = "Intrinsic measurements are not currently supported by SubcomposeLayout"
     ) {
-        override fun measure(
-            measureScope: MeasureScope,
+        override fun MeasureScope.measure(
             measurables: List<Measurable>,
             constraints: Constraints
         ): MeasureResult {
-            this@SubcomposeLayoutState.layoutDirection = measureScope.layoutDirection
-            this@SubcomposeLayoutState.density = measureScope.density
-            this@SubcomposeLayoutState.fontScale = measureScope.fontScale
+            this@SubcomposeLayoutState.layoutDirection = layoutDirection
+            this@SubcomposeLayoutState.density = density
+            this@SubcomposeLayoutState.fontScale = fontScale
             currentIndex = 0
             val result = block(constraints)
             val indexAfterMeasure = currentIndex
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/TestModifierUpdater.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/TestModifierUpdater.kt
index 036c5fd..d065d02 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/TestModifierUpdater.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/TestModifierUpdater.kt
@@ -44,13 +44,13 @@
 @Composable
 @Suppress("DEPRECATION_ERROR")
 fun TestModifierUpdaterLayout(onAttached: (TestModifierUpdater) -> Unit) {
-    val measureBlocks = MeasuringIntrinsicsMeasureBlocks { _, constraints ->
+    val measurePolicy = MeasurePolicy { _, constraints ->
         layout(constraints.maxWidth, constraints.maxHeight) {}
     }
     ComposeNode<LayoutNode, Applier<Any>>(
         factory = LayoutNode.Constructor,
         update = {
-            set(measureBlocks, ComposeUiNode.SetMeasureBlocks)
+            set(measurePolicy, ComposeUiNode.SetMeasurePolicy)
             init { onAttached(TestModifierUpdater(this)) }
         }
     )
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/ComposeUiNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/ComposeUiNode.kt
index 63352fc..57f6b75 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/ComposeUiNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/ComposeUiNode.kt
@@ -17,6 +17,7 @@
 package androidx.compose.ui.node
 
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.MeasurePolicy
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.LayoutDirection
 
@@ -25,7 +26,7 @@
  */
 @PublishedApi
 internal interface ComposeUiNode {
-    var measureBlocks: MeasureBlocks
+    var measurePolicy: MeasurePolicy
     var layoutDirection: LayoutDirection
     var density: Density
     var modifier: Modifier
@@ -37,8 +38,8 @@
         val Constructor: () -> ComposeUiNode = LayoutNode.Constructor
         val SetModifier: ComposeUiNode.(Modifier) -> Unit = { this.modifier = it }
         val SetDensity: ComposeUiNode.(Density) -> Unit = { this.density = it }
-        val SetMeasureBlocks: ComposeUiNode.(MeasureBlocks) -> Unit =
-            { this.measureBlocks = it }
+        val SetMeasurePolicy: ComposeUiNode.(MeasurePolicy) -> Unit =
+            { this.measurePolicy = it }
         val SetLayoutDirection: ComposeUiNode.(LayoutDirection) -> Unit =
             { this.layoutDirection = it }
     }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DelegatingLayoutNodeWrapper.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DelegatingLayoutNodeWrapper.kt
index 764f286..63529ac 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DelegatingLayoutNodeWrapper.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DelegatingLayoutNodeWrapper.kt
@@ -71,15 +71,16 @@
     }
 
     override fun hitTest(
-        pointerPositionRelativeToScreen: Offset,
+        pointerPosition: Offset,
         hitPointerInputFilters: MutableList<PointerInputFilter>
     ) {
-        if (withinLayerBounds(pointerPositionRelativeToScreen)) {
-            wrapped.hitTest(pointerPositionRelativeToScreen, hitPointerInputFilters)
+        if (withinLayerBounds(pointerPosition)) {
+            val positionInWrapped = wrapped.fromParentPosition(pointerPosition)
+            wrapped.hitTest(positionInWrapped, hitPointerInputFilters)
         }
     }
 
-    override fun get(line: AlignmentLine): Int = wrapped[line]
+    override fun get(alignmentLine: AlignmentLine): Int = wrapped[alignmentLine]
 
     override fun placeAt(
         position: IntOffset,
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/InnerPlaceable.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/InnerPlaceable.kt
index dee6bcb..0093059 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/InnerPlaceable.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/InnerPlaceable.kt
@@ -41,11 +41,9 @@
     override val measureScope get() = layoutNode.measureScope
 
     override fun performMeasure(constraints: Constraints): Placeable {
-        val measureResult = layoutNode.measureBlocks.measure(
-            layoutNode.measureScope,
-            layoutNode.children,
-            constraints
-        )
+        val measureResult = with(layoutNode.measurePolicy) {
+            layoutNode.measureScope.measure(layoutNode.children, constraints)
+        }
         layoutNode.handleMeasureResult(measureResult)
         return this
     }
@@ -70,35 +68,27 @@
     override fun findLastKeyInputWrapper(): ModifiedKeyInputNode? = findPreviousKeyInputWrapper()
 
     override fun minIntrinsicWidth(height: Int): Int {
-        return layoutNode.measureBlocks.minIntrinsicWidth(
-            measureScope,
-            layoutNode.children,
-            height
-        )
+        return with(layoutNode.measurePolicy) {
+            measureScope.minIntrinsicWidth(layoutNode.children, height)
+        }
     }
 
     override fun minIntrinsicHeight(width: Int): Int {
-        return layoutNode.measureBlocks.minIntrinsicHeight(
-            measureScope,
-            layoutNode.children,
-            width
-        )
+        return with(layoutNode.measurePolicy) {
+            measureScope.minIntrinsicHeight(layoutNode.children, width)
+        }
     }
 
     override fun maxIntrinsicWidth(height: Int): Int {
-        return layoutNode.measureBlocks.maxIntrinsicWidth(
-            measureScope,
-            layoutNode.children,
-            height
-        )
+        return with(layoutNode.measurePolicy) {
+            measureScope.maxIntrinsicWidth(layoutNode.children, height)
+        }
     }
 
     override fun maxIntrinsicHeight(width: Int): Int {
-        return layoutNode.measureBlocks.maxIntrinsicHeight(
-            measureScope,
-            layoutNode.children,
-            width
-        )
+        return with(layoutNode.measurePolicy) {
+            measureScope.maxIntrinsicHeight(layoutNode.children, width)
+        }
     }
 
     override fun placeAt(
@@ -118,8 +108,8 @@
         layoutNode.onNodePlaced()
     }
 
-    override operator fun get(line: AlignmentLine): Int {
-        return layoutNode.calculateAlignmentLines()[line] ?: AlignmentLine.Unspecified
+    override operator fun get(alignmentLine: AlignmentLine): Int {
+        return layoutNode.calculateAlignmentLines()[alignmentLine] ?: AlignmentLine.Unspecified
     }
 
     override fun performDraw(canvas: Canvas) {
@@ -138,16 +128,16 @@
     }
 
     override fun hitTest(
-        pointerPositionRelativeToScreen: Offset,
+        pointerPosition: Offset,
         hitPointerInputFilters: MutableList<PointerInputFilter>
     ) {
-        if (withinLayerBounds(pointerPositionRelativeToScreen)) {
+        if (withinLayerBounds(pointerPosition)) {
             // Any because as soon as true is returned, we know we have found a hit path and we must
             // not add PointerInputFilters on different paths so we should not even go looking.
             val originalSize = hitPointerInputFilters.size
             layoutNode.zSortedChildren.reversedAny { child ->
                 if (child.isPlaced) {
-                    callHitTest(child, pointerPositionRelativeToScreen, hitPointerInputFilters)
+                    callHitTest(child, pointerPosition, hitPointerInputFilters)
                     hitPointerInputFilters.size > originalSize
                 } else {
                     false
@@ -169,10 +159,10 @@
 
         private fun callHitTest(
             node: LayoutNode,
-            globalPoint: Offset,
+            pointerPosition: Offset,
             hitPointerInputFilters: MutableList<PointerInputFilter>
         ) {
-            node.hitTest(globalPoint, hitPointerInputFilters)
+            node.hitTest(pointerPosition, hitPointerInputFilters)
         }
     }
 }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt
index d17698b..8f2a4e3 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt
@@ -38,6 +38,7 @@
 import androidx.compose.ui.layout.LayoutInfo
 import androidx.compose.ui.layout.LayoutModifier
 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.ModifierInfo
@@ -389,7 +390,7 @@
 
     override fun toString(): String {
         return "${simpleIdentityToString(this, null)} children: ${children.size} " +
-            "measureBlocks: $measureBlocks"
+            "measurePolicy: $measurePolicy"
     }
 
     /**
@@ -418,36 +419,32 @@
         return treeString
     }
 
-    internal abstract class NoIntrinsicsMeasureBlocks(private val error: String) : MeasureBlocks {
-        override fun minIntrinsicWidth(
-            intrinsicMeasureScope: IntrinsicMeasureScope,
+    internal abstract class NoIntrinsicsMeasurePolicy(private val error: String) : MeasurePolicy {
+        override fun IntrinsicMeasureScope.minIntrinsicWidth(
             measurables: List<IntrinsicMeasurable>,
-            h: Int
+            height: Int
         ) = error(error)
 
-        override fun minIntrinsicHeight(
-            intrinsicMeasureScope: IntrinsicMeasureScope,
+        override fun IntrinsicMeasureScope.minIntrinsicHeight(
             measurables: List<IntrinsicMeasurable>,
-            w: Int
+            width: Int
         ) = error(error)
 
-        override fun maxIntrinsicWidth(
-            intrinsicMeasureScope: IntrinsicMeasureScope,
+        override fun IntrinsicMeasureScope.maxIntrinsicWidth(
             measurables: List<IntrinsicMeasurable>,
-            h: Int
+            height: Int
         ) = error(error)
 
-        override fun maxIntrinsicHeight(
-            intrinsicMeasureScope: IntrinsicMeasureScope,
+        override fun IntrinsicMeasureScope.maxIntrinsicHeight(
             measurables: List<IntrinsicMeasurable>,
-            w: Int
+            width: Int
         ) = error(error)
     }
 
     /**
      * Blocks that define the measurement and intrinsic measurement of the layout.
      */
-    override var measureBlocks: MeasureBlocks = ErrorMeasureBlocks
+    override var measurePolicy: MeasurePolicy = ErrorMeasurePolicy
         set(value) {
             if (field != value) {
                 field = value
@@ -461,8 +458,7 @@
     override var density: Density = Density(1f)
 
     /**
-     * The scope used to run the [MeasureBlocks.measure]
-     * [MeasureBlock][androidx.compose.ui.layout.MeasureBlock].
+     * The scope used to [measure][MeasurePolicy.measure] children.
      */
     internal val measureScope: MeasureScope = object : MeasureScope, Density {
         override val density: Float get() = this@LayoutNode.density.density
@@ -797,28 +793,29 @@
      * Carries out a hit test on the [PointerInputModifier]s associated with this [LayoutNode] and
      * all [PointerInputModifier]s on all descendant [LayoutNode]s.
      *
-     * If [pointerPositionRelativeToScreen] is within the bounds of any tested
+     * If [pointerPosition] is within the bounds of any tested
      * [PointerInputModifier]s, the [PointerInputModifier] is added to [hitPointerInputFilters]
      * and true is returned.
      *
-     * @param pointerPositionRelativeToScreen The tested pointer position, which is relative to
-     * the device screen.
+     * @param pointerPosition The tested pointer position, which is relative to
+     * the LayoutNode.
      * @param hitPointerInputFilters The collection that the hit [PointerInputFilter]s will be
      * added to if hit.
      */
     internal fun hitTest(
-        pointerPositionRelativeToScreen: Offset,
+        pointerPosition: Offset,
         hitPointerInputFilters: MutableList<PointerInputFilter>
     ) {
-        outerLayoutNodeWrapper.hitTest(pointerPositionRelativeToScreen, hitPointerInputFilters)
+        val positionInWrapped = outerLayoutNodeWrapper.fromParentPosition(pointerPosition)
+        outerLayoutNodeWrapper.hitTest(positionInWrapped, hitPointerInputFilters)
     }
 
     /**
      * Returns the alignment line value for a given alignment line without affecting whether
      * the flag for whether the alignment line was read.
      */
-    internal fun getAlignmentLine(line: AlignmentLine): Int? {
-        val linePos = alignmentLines[line] ?: return null
+    internal fun getAlignmentLine(alignmentLine: AlignmentLine): Int? {
+        val linePos = alignmentLines[alignmentLine] ?: return null
         var pos = Offset(linePos.toFloat(), linePos.toFloat())
         var wrapper = innerLayoutNodeWrapper
         while (wrapper != outerLayoutNodeWrapper) {
@@ -826,7 +823,7 @@
             wrapper = wrapper.wrappedBy!!
         }
         pos = wrapper.toParentPosition(pos)
-        return if (line is HorizontalAlignmentLine) {
+        return if (alignmentLine is HorizontalAlignmentLine) {
             pos.y.roundToInt()
         } else {
             pos.x.roundToInt()
@@ -1273,12 +1270,11 @@
         get() = parent
 
     internal companion object {
-        private val ErrorMeasureBlocks: NoIntrinsicsMeasureBlocks =
-            object : NoIntrinsicsMeasureBlocks(
+        private val ErrorMeasurePolicy: NoIntrinsicsMeasurePolicy =
+            object : NoIntrinsicsMeasurePolicy(
                 error = "Undefined intrinsics block and it is required"
             ) {
-                override fun measure(
-                    measureScope: MeasureScope,
+                override fun MeasureScope.measure(
                     measurables: List<Measurable>,
                     constraints: Constraints
                 ) = error("Undefined measure and it is required")
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNodeWrapper.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNodeWrapper.kt
index e547508..844d0a6 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNodeWrapper.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNodeWrapper.kt
@@ -37,13 +37,12 @@
 import androidx.compose.ui.layout.MeasureScope
 import androidx.compose.ui.layout.Placeable
 import androidx.compose.ui.layout.findRoot
-import androidx.compose.ui.layout.globalPosition
+import androidx.compose.ui.layout.positionInRoot
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.minus
 import androidx.compose.ui.unit.plus
-import androidx.compose.ui.unit.toOffset
 
 /**
  * Measurable and Placeable type that has a position.
@@ -135,18 +134,13 @@
         get() = _matrixCache ?: Matrix().also { _matrixCache = it }
 
     /**
-     * Whether a pointer that is relative to the device screen is in the bounds of this
+     * Whether a pointer that is relative to the [LayoutNodeWrapper] is in the bounds of this
      * LayoutNodeWrapper.
      */
-    fun isGlobalPointerInBounds(globalPointerPosition: Offset): Boolean {
-        // TODO(shepshapard): Right now globalToLocal has to traverse the tree all the way back up
-        //  so calling this is expensive.  Would be nice to cache data such that this is cheap.
-        @Suppress("DEPRECATION")
-        val localPointerPosition = globalToLocal(globalPointerPosition)
-        return localPointerPosition.x >= 0 &&
-            localPointerPosition.x < measuredSize.width &&
-            localPointerPosition.y >= 0 &&
-            localPointerPosition.y < measuredSize.height
+    fun isPointerInBounds(pointerPosition: Offset): Boolean {
+        val x = pointerPosition.x
+        val y = pointerPosition.y
+        return x >= 0f && y >= 0f && x < measuredWidth && y < measuredHeight
     }
 
     /**
@@ -305,57 +299,28 @@
      * Override appropriately to either add a [PointerInputFilter] to [hitPointerInputFilters] or
      * to pass the execution on.
      *
-     * @param pointerPositionRelativeToScreen The tested pointer position, which is relative to
-     * the device screen.
+     * @param pointerPosition The tested pointer position, which is relative to
+     * the [LayoutNodeWrapper].
      * @param hitPointerInputFilters The collection that the hit [PointerInputFilter]s will be
      * added to if hit.
      */
     abstract fun hitTest(
-        pointerPositionRelativeToScreen: Offset,
+        pointerPosition: Offset,
         hitPointerInputFilters: MutableList<PointerInputFilter>
     )
 
-    override fun childToLocal(child: LayoutCoordinates, childLocal: Offset): Offset {
-        check(isAttached) { ExpectAttachedLayoutCoordinates }
-        check(child.isAttached) { "Child $child is not attached!" }
-        var wrapper = child as LayoutNodeWrapper
-        var position = childLocal
-        while (wrapper !== this) {
-            position = wrapper.toParentPosition(position)
-
-            val parent = wrapper.wrappedBy
-            check(parent != null) {
-                "childToLocal: child parameter is not a child of the LayoutCoordinates"
-            }
-            wrapper = parent
-        }
-        return position
-    }
-
-    override fun globalToLocal(global: Offset): Offset {
-        check(isAttached) { ExpectAttachedLayoutCoordinates }
-        val positionOnScreen = layoutNode.requireOwner().calculatePosition()
-        val root = findRoot()
-        val rootPosition = (root as LayoutNodeWrapper).position.toOffset()
-        return localPositionOf(root, global - positionOnScreen - rootPosition)
-    }
-
     override fun windowToLocal(relativeToWindow: Offset): Offset {
         check(isAttached) { ExpectAttachedLayoutCoordinates }
         val root = findRoot()
-        val rootPosition = (root as LayoutNodeWrapper).position.toOffset()
-        val positionInRoot =
-            relativeToWindow - layoutNode.requireOwner().calculatePositionInWindow().toOffset() -
-                rootPosition
+        val positionInRoot = layoutNode.requireOwner()
+            .calculateLocalPosition(relativeToWindow) - root.positionInRoot()
         return localPositionOf(root, positionInRoot)
     }
 
-    override fun localToGlobal(local: Offset): Offset {
-        return localToRoot(local) + layoutNode.requireOwner().calculatePosition()
-    }
-
     override fun localToWindow(relativeToLocal: Offset): Offset {
-        return localToRoot(relativeToLocal) + layoutNode.requireOwner().calculatePositionInWindow()
+        val positionInRoot = localToRoot(relativeToLocal)
+        val owner = layoutNode.requireOwner()
+        return owner.calculatePositionInWindow(positionInRoot)
     }
 
     override fun localPositionOf(
@@ -581,45 +546,9 @@
         }
     }
 
-    override fun childBoundingBox(child: LayoutCoordinates): Rect {
-        check(isAttached) { ExpectAttachedLayoutCoordinates }
-        check(child.isAttached) { "Child $child is not attached!" }
-        val bounds = rectCache
-        bounds.left = 0f
-        bounds.top = 0f
-        bounds.right = child.size.width.toFloat()
-        bounds.bottom = child.size.height.toFloat()
-        var wrapper = child as LayoutNodeWrapper
-        while (wrapper !== this) {
-            wrapper.rectInParent(bounds, clipBounds = true)
-            if (bounds.isEmpty) {
-                return Rect.Zero
-            }
-
-            val parent = wrapper.wrappedBy
-            check(parent != null) {
-                "childToLocal: child parameter is not a child of the LayoutCoordinates"
-            }
-            wrapper = parent
-        }
-        return bounds.toRect()
-    }
-
-    protected fun withinLayerBounds(pointerPositionRelativeToScreen: Offset): Boolean {
+    protected fun withinLayerBounds(pointerPosition: Offset): Boolean {
         if (layer != null && isClipping) {
-            @Suppress("DEPRECATION")
-            val l = globalPosition.x
-            @Suppress("DEPRECATION")
-            val t = globalPosition.y
-            val r = l + width
-            val b = t + height
-
-            val localBoundsRelativeToScreen = Rect(l, t, r, b)
-            if (!localBoundsRelativeToScreen.contains(pointerPositionRelativeToScreen)) {
-                // If we should clip pointer input hit testing to our bounds, and the pointer is
-                // not in our bounds, then return false now.
-                return false
-            }
+            return isPointerInBounds(pointerPosition)
         }
 
         // If we are here, either we aren't clipping to bounds or we are and the pointer was in
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/MeasureBlocks.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/MeasureBlocks.kt
index d70ab9b..f813b01 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/MeasureBlocks.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/MeasureBlocks.kt
@@ -23,7 +23,8 @@
 import androidx.compose.ui.layout.MeasureScope
 import androidx.compose.ui.unit.Constraints
 
-interface MeasureBlocks {
+@Deprecated("MeasureBlocks was deprecated. Please use MeasurePolicy instead.")
+internal interface MeasureBlocks {
     /**
      * The function used to measure the child. It must call [MeasureScope.layout] before
      * completing.
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/ModifiedLayoutNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/ModifiedLayoutNode.kt
index 7ac55e2..ec54573 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/ModifiedLayoutNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/ModifiedLayoutNode.kt
@@ -57,11 +57,11 @@
             measureScope.maxIntrinsicHeight(wrapped, width)
         }
 
-    override operator fun get(line: AlignmentLine): Int {
-        if (measureResult.alignmentLines.containsKey(line)) {
-            return measureResult.alignmentLines[line] ?: AlignmentLine.Unspecified
+    override operator fun get(alignmentLine: AlignmentLine): Int {
+        if (measureResult.alignmentLines.containsKey(alignmentLine)) {
+            return measureResult.alignmentLines[alignmentLine] ?: AlignmentLine.Unspecified
         }
-        val positionInWrapped = wrapped[line]
+        val positionInWrapped = wrapped[alignmentLine]
         if (positionInWrapped == AlignmentLine.Unspecified) {
             return AlignmentLine.Unspecified
         }
@@ -69,7 +69,7 @@
         isShallowPlacing = true
         placeAt(this.position, this.zIndex, this.layerBlock)
         isShallowPlacing = false
-        return if (line is HorizontalAlignmentLine) {
+        return if (alignmentLine is HorizontalAlignmentLine) {
             positionInWrapped + wrapped.position.y
         } else {
             positionInWrapped + wrapped.position.x
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/OuterMeasurablePlaceable.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/OuterMeasurablePlaceable.kt
index 243173d9..f4ab498 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/OuterMeasurablePlaceable.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/OuterMeasurablePlaceable.kt
@@ -89,6 +89,7 @@
             measurementConstraints = constraints
             lastProvidedAlignmentLines.clear()
             lastProvidedAlignmentLines.putAll(layoutNode.providedAlignmentLines)
+            val outerWrapperPreviousMeasuredSize = outerWrapper.size
             owner.snapshotObserver.observeMeasureSnapshotReads(layoutNode) {
                 outerWrapper.measure(constraints)
             }
@@ -96,20 +97,24 @@
             if (layoutNode.providedAlignmentLines != lastProvidedAlignmentLines) {
                 layoutNode.onAlignmentsChanged()
             }
-            val previousSize = measuredSize
-            val newWidth = outerWrapper.width
-            val newHeight = outerWrapper.height
-            if (newWidth != previousSize.width ||
-                newHeight != previousSize.height
-            ) {
-                measuredSize = IntSize(newWidth, newHeight)
-                return true
-            }
+            val sizeChanged = outerWrapper.size != outerWrapperPreviousMeasuredSize ||
+                outerWrapper.width != width ||
+                outerWrapper.height != height
+            // We are using the coerced wrapper size here to avoid double offset in layout coop.
+            measuredSize = IntSize(outerWrapper.width, outerWrapper.height)
+            return sizeChanged
         }
         return false
     }
 
-    override fun get(line: AlignmentLine): Int = outerWrapper[line]
+    // We are setting our measuredSize to match the coerced outerWrapper size, to prevent
+    // double offseting for layout cooperation. However, this means that here we need
+    // to override these getters to make the measured values correct in Measured.
+    // TODO(popam): clean this up
+    override val measuredWidth: Int get() = outerWrapper.measuredWidth
+    override val measuredHeight: Int get() = outerWrapper.measuredHeight
+
+    override fun get(alignmentLine: AlignmentLine): Int = outerWrapper[alignmentLine]
 
     override fun placeAt(
         position: IntOffset,
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/Owner.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/Owner.kt
index eebbda9..5a70959 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/Owner.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/Owner.kt
@@ -20,9 +20,11 @@
 import androidx.compose.ui.autofill.AutofillTree
 import androidx.compose.ui.focus.FocusDirection
 import androidx.compose.ui.focus.FocusManager
+import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Canvas
 import androidx.compose.ui.hapticfeedback.HapticFeedback
 import androidx.compose.ui.input.key.KeyEvent
+import androidx.compose.ui.platform.AccessibilityManager
 import androidx.compose.ui.platform.ClipboardManager
 import androidx.compose.ui.platform.TextToolbar
 import androidx.compose.ui.platform.ViewConfiguration
@@ -30,7 +32,6 @@
 import androidx.compose.ui.text.font.Font
 import androidx.compose.ui.text.input.TextInputService
 import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.LayoutDirection
 
 /**
@@ -58,6 +59,11 @@
     val clipboardManager: ClipboardManager
 
     /**
+     * Provide accessibility manager to the user. Use the Android version of accessibility manager.
+     */
+    val accessibilityManager: AccessibilityManager
+
+    /**
      * Provide toolbar for text-related actions, such as copy, paste, cut etc.
      */
     val textToolbar: TextToolbar
@@ -131,15 +137,18 @@
     fun onDetach(node: LayoutNode)
 
     /**
-     * Returns the most global position of the owner that Compose can access (such as the device
-     * screen).
+     * Returns the position relative to the containing window of the [localPosition],
+     * the position relative to the [Owner]. If the [Owner] is rotated, scaled, or otherwise
+     * transformed relative to the window, this will not be a simple translation.
      */
-    fun calculatePosition(): IntOffset
+    fun calculatePositionInWindow(localPosition: Offset): Offset
 
     /**
-     * Returns the most position of the owner relative to the window.
+     * Returns the position relative to the [Owner] of the [positionInWindow],
+     * the position relative to the window. If the [Owner] is rotated, scaled, or otherwise
+     * transformed relative to the window, this will not be a simple translation.
      */
-    fun calculatePositionInWindow(): IntOffset
+    fun calculateLocalPosition(positionInWindow: Offset): Offset
 
     /**
      * Ask the system to provide focus to this owner.
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/PointerInputDelegatingWrapper.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/PointerInputDelegatingWrapper.kt
index ae8308c..2370c49 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/PointerInputDelegatingWrapper.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/PointerInputDelegatingWrapper.kt
@@ -37,17 +37,17 @@
         }
 
     override fun hitTest(
-        pointerPositionRelativeToScreen: Offset,
+        pointerPosition: Offset,
         hitPointerInputFilters: MutableList<PointerInputFilter>
     ) {
-        if (isGlobalPointerInBounds(pointerPositionRelativeToScreen)) {
+        if (isPointerInBounds(pointerPosition)) {
             // If the pointer is in bounds, we hit the pointer input filter, so add it!
             hitPointerInputFilters.add(modifier.pointerInputFilter)
         }
 
         // Also, keep looking to see if we also might hit any children.
         super.hitTest(
-            pointerPositionRelativeToScreen,
+            pointerPosition,
             hitPointerInputFilters
         )
     }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/AccessibilityManager.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/AccessibilityManager.kt
new file mode 100644
index 0000000..8590cb0
--- /dev/null
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/AccessibilityManager.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.ui.platform
+
+/**
+ * Interface for managing accessibility.
+ */
+interface AccessibilityManager {
+    /**
+     * Calculate the recommended timeout for changes to the UI needed by this user. Controls should
+     * remain on the screen for at least this long to give users time to react. Some users may need
+     * extra time to review the controls, or to reach them, or to activate assistive technology
+     * to activate the controls automatically.
+     * <p>
+     * Use the boolean parameters to indicate contents of UI. For example, set [containsIcons]
+     * and [containsText] to true for message notification which contains icons and text, or set
+     * [containsText] and [containsControls] to true for button dialog which contains text and
+     * button controls.
+     * <p/>
+     *
+     * @param originalTimeoutMillis The timeout appropriate for users with no accessibility needs
+     * in milliseconds.
+     * @param containsIcons The contents of UI contain icons.
+     * @param containsText The contents of UI contain text.
+     * @param containsControls The contents of UI contain controls.
+     * @return The recommended UI timeout for the current user in milliseconds.
+     */
+    fun calculateRecommendedTimeoutMillis(
+        originalTimeoutMillis: Long,
+        containsIcons: Boolean = false,
+        containsText: Boolean = false,
+        containsControls: Boolean = false
+    ): Long
+}
\ No newline at end of file
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/CompositionLocals.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/CompositionLocals.kt
index de61532..700c7cb 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/CompositionLocals.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/CompositionLocals.kt
@@ -31,6 +31,11 @@
 import androidx.compose.ui.unit.LayoutDirection
 
 /**
+ * The CompositionLocal to provide communication with platform accessibility service.
+ */
+val LocalAccessibilityManager = staticCompositionLocalOf<AccessibilityManager?> { null }
+
+/**
  * The CompositionLocal that can be used to trigger autofill actions.
  * Eg. [Autofill.requestAutofillForNode].
  */
@@ -141,6 +146,7 @@
     content: @Composable () -> Unit
 ) {
     CompositionLocalProvider(
+        LocalAccessibilityManager provides owner.accessibilityManager,
         LocalAutofill provides owner.autofill,
         LocalAutofillTree provides owner.autofillTree,
         LocalClipboardManager provides owner.clipboardManager,
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsNode.kt
index 87b4899b2..e4836c2 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsNode.kt
@@ -20,10 +20,10 @@
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.layout.AlignmentLine
 import androidx.compose.ui.layout.boundsInRoot
-import androidx.compose.ui.layout.globalBounds
 import androidx.compose.ui.layout.positionInRoot
 import androidx.compose.ui.layout.LayoutInfo
-import androidx.compose.ui.layout.globalPosition
+import androidx.compose.ui.layout.boundsInWindow
+import androidx.compose.ui.layout.positionInWindow
 import androidx.compose.ui.node.LayoutNode
 import androidx.compose.ui.node.LayoutNodeWrapper
 import androidx.compose.ui.node.RootForTest
@@ -113,29 +113,27 @@
 
     /**
      * The bounding box for this node relative to the screen, with clipping applied. To get the
-     * bounds with no clipping applied, use PxBounds([globalPosition], [size].toSize())
+     * bounds with no clipping applied, use PxBounds([positionInWindow], [size].toSize())
      */
-    val globalBounds: Rect
+    val boundsInWindow: Rect
         get() {
-            @Suppress("DEPRECATION")
-            return this.layoutNode.coordinates.globalBounds
+            return this.layoutNode.coordinates.boundsInWindow()
         }
 
     /**
      * The position of this node relative to the screen, with no clipping applied
      */
-    val globalPosition: Offset
+    val positionInWindow: Offset
         get() {
-            @Suppress("DEPRECATION")
-            return this.layoutNode.coordinates.globalPosition
+            return this.layoutNode.coordinates.positionInWindow()
         }
 
     /**
      * Returns the position of an [alignment line][AlignmentLine], or [AlignmentLine.Unspecified]
      * if the line is not provided.
      */
-    fun getAlignmentLinePosition(line: AlignmentLine): Int {
-        return this.layoutNode.coordinates[line]
+    fun getAlignmentLinePosition(alignmentLine: AlignmentLine): Int {
+        return this.layoutNode.coordinates[alignmentLine]
     }
 
     // CHILDREN
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt
index b738043..bd1d34d 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt
@@ -70,6 +70,9 @@
         }
     )
 
+    /** @see SemanticsPropertyReceiver.selectableGroup */
+    val SelectableGroup = SemanticsPropertyKey<Unit>("SelectableGroup")
+
     /**
      * The node is marked as heading for accessibility.
      *
@@ -705,6 +708,15 @@
 }
 
 /**
+ * The node is marked as a collection of horizontally or vertically stacked selectable elements.
+ *
+ * @see SemanticsPropertyReceiver.selected
+*/
+fun SemanticsPropertyReceiver.selectableGroup() {
+    this[SemanticsProperties.SelectableGroup] = Unit
+}
+
+/**
  * Custom actions which are defined by app developers.
  */
 var SemanticsPropertyReceiver.customActions by SemanticsActions.CustomActions
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/AppFrame.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/AppFrame.desktop.kt
index 18cb05a..a24a204 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/AppFrame.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/AppFrame.desktop.kt
@@ -112,7 +112,7 @@
      * Sets the menu bar of the window. The menu bar can be displayed inside a window (Windows,
      * Linux) or at the top of the screen (Mac OS).
      *
-     * @param manuBar Window menu bar.
+     * @param menuBar Window menu bar.
      */
     abstract fun setMenuBar(menuBar: MenuBar)
 
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/AppWindow.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/AppWindow.desktop.kt
index a79b1e0..dcfd076 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/AppWindow.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/AppWindow.desktop.kt
@@ -287,7 +287,7 @@
      * Sets the menu bar of the window. The menu bar can be displayed inside a window (Windows,
      * Linux) or at the top of the screen (Mac OS).
      *
-     * @param manuBar Window menu bar.
+     * @param menuBar Window menu bar.
      */
     override fun setMenuBar(menuBar: MenuBar) {
         this.menuBar = menuBar
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/SwingPanel.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/SwingPanel.desktop.kt
index 9a5ac4e..a8780d3 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/SwingPanel.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/desktop/SwingPanel.desktop.kt
@@ -37,21 +37,21 @@
 val NoOpUpdate: Component.() -> Unit = {}
 
 /**
- * Composes an AWT/Swing component obtained from [componentBlock]. The [componentBlock]
+ * Composes an AWT/Swing component obtained from [factory]. The [factory]
  * block will be called to obtain the [Component] to be composed. The Swing component is
  * placed on top of the Compose layer.
  * The [update] block runs due to recomposition, this is the place to set [Component] properties
  * depending on state. When state changes, the block will be reexecuted to set the new properties.
  *
  * @param background Background color of SwingPanel
- * @param componentBlock The block creating the [Component] to be composed.
+ * @param factory The block creating the [Component] to be composed.
  * @param modifier The modifier to be applied to the layout.
  * @param update The callback to be invoked after the layout is inflated.
  */
 @Composable
 public fun <T : Component> SwingPanel(
     background: Color = Color.White,
-    componentBlock: () -> T,
+    factory: () -> T,
     modifier: Modifier = Modifier,
     update: (T) -> Unit = NoOpUpdate
 ) {
@@ -75,18 +75,18 @@
             componentInfo.layout.validate()
             componentInfo.layout.repaint()
         },
-        measureBlock = { _, _ ->
+        measurePolicy = { _, _ ->
             layout(0, 0) {}
         }
     )
 
-    DisposableEffect(componentBlock) {
-        componentInfo.component = componentBlock()
+    DisposableEffect(factory) {
+        componentInfo.factory = factory()
         componentInfo.layout = JPanel().apply {
             setLayout(BorderLayout(0, 0))
-            add(componentInfo.component)
+            add(componentInfo.factory)
         }
-        componentInfo.updater = Updater(componentInfo.component, update)
+        componentInfo.updater = Updater(componentInfo.factory, update)
         container.add(componentInfo.layout)
         onDispose {
             container.remove(componentInfo.layout)
@@ -111,7 +111,7 @@
 
 private class ComponentInfo<T : Component> {
     lateinit var layout: Container
-    lateinit var component: T
+    lateinit var factory: T
     lateinit var updater: Updater<T>
 }
 
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/input/pointer/DesktopMouse.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/input/pointer/DesktopMouse.desktop.kt
deleted file mode 100644
index 7c4a27a..0000000
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/input/pointer/DesktopMouse.desktop.kt
+++ /dev/null
@@ -1,20 +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.ui.input.pointer
-
-@MouseTemporaryApi
-actual val isMouseInput = true
\ No newline at end of file
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/input/pointer/DesktopMouse.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/input/pointer/DesktopMouse.kt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/input/pointer/DesktopMouse.kt
@@ -0,0 +1 @@
+
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/input/pointer/PointerInputEvent.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/input/pointer/PointerInputEvent.desktop.kt
index f8155ff..860f20f 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/input/pointer/PointerInputEvent.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/input/pointer/PointerInputEvent.desktop.kt
@@ -35,5 +35,5 @@
     val down: Boolean
 ) {
     internal fun toPointerInputEventData() =
-        PointerInputEventData(id, uptime, position, down, PointerType.Mouse)
+        PointerInputEventData(id, uptime, position, position, down, PointerType.Mouse)
 }
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopAccessibilityManager.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopAccessibilityManager.kt
new file mode 100644
index 0000000..c007938
--- /dev/null
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopAccessibilityManager.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.ui.platform
+
+internal class DesktopAccessibilityManager : AccessibilityManager {
+    override fun calculateRecommendedTimeoutMillis(
+        originalTimeoutMillis: Long,
+        containsIcons: Boolean,
+        containsText: Boolean,
+        containsControls: Boolean
+    ): Long {
+        return originalTimeoutMillis
+    }
+}
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopOwner.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopOwner.desktop.kt
index 78eab18..badabc6 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopOwner.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopOwner.desktop.kt
@@ -53,9 +53,10 @@
 import androidx.compose.ui.input.pointer.PointerInputEventProcessor
 import androidx.compose.ui.input.pointer.PointerInputFilter
 import androidx.compose.ui.input.pointer.PointerMoveEventFilter
+import androidx.compose.ui.input.pointer.PositionCalculator
 import androidx.compose.ui.input.pointer.TestPointerInputEventData
-import androidx.compose.ui.layout.RootMeasureBlocks
-import androidx.compose.ui.layout.globalBounds
+import androidx.compose.ui.layout.RootMeasurePolicy
+import androidx.compose.ui.layout.boundsInWindow
 import androidx.compose.ui.node.InternalCoreApi
 import androidx.compose.ui.node.LayoutNode
 import androidx.compose.ui.node.MeasureAndLayoutDelegate
@@ -68,7 +69,6 @@
 import androidx.compose.ui.text.platform.FontLoader
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.LayoutDirection
 
@@ -79,7 +79,7 @@
 internal class DesktopOwner(
     val container: DesktopOwners,
     density: Density = Density(1f, 1f)
-) : Owner, RootForTest, DesktopRootForTest {
+) : Owner, RootForTest, DesktopRootForTest, PositionCalculator {
     internal var size by mutableStateOf(IntSize(0, 0))
 
     override var density by mutableStateOf(density)
@@ -119,7 +119,7 @@
     )
 
     override val root = LayoutNode().also {
-        it.measureBlocks = RootMeasureBlocks
+        it.measurePolicy = RootMeasurePolicy
         it.modifier = semanticsModifier
             .then(_focusManager.modifier)
             .then(keyInputModifier)
@@ -154,7 +154,7 @@
 
     override val clipboardManager = DesktopClipboardManager()
 
-    internal val selectionTracker = SelectionTracker()
+    override val accessibilityManager = DesktopAccessibilityManager()
 
     override val textToolbar = DesktopTextToolbar()
 
@@ -231,9 +231,13 @@
         else -> null
     }
 
-    override fun calculatePosition() = IntOffset.Zero
+    override fun calculatePositionInWindow(localPosition: Offset): Offset = localPosition
 
-    override fun calculatePositionInWindow() = IntOffset.Zero
+    override fun calculateLocalPosition(positionInWindow: Offset): Offset = positionInWindow
+
+    override fun localToScreen(localPosition: Offset): Offset = localPosition
+
+    override fun screenToLocal(positionOnScreen: Offset): Offset = positionOnScreen
 
     fun setSize(width: Int, height: Int) {
         val constraints = Constraints(0, width, 0, height)
@@ -247,7 +251,7 @@
 
     internal fun processPointerInput(event: PointerInputEvent) {
         measureAndLayout()
-        pointerInputEventProcessor.process(event)
+        pointerInputEventProcessor.process(event, this)
     }
 
     override fun processPointerInput(nanoTime: Long, pointers: List<TestPointerInputEventData>) {
@@ -304,7 +308,7 @@
                 .filterIsInstance<PointerMoveEventFilter>()
         ) {
             if (!onMoveConsumed) {
-                val relative = position - filter.layoutCoordinates!!.globalBounds.topLeft
+                val relative = position - filter.layoutCoordinates!!.boundsInWindow().topLeft
                 onMoveConsumed = filter.onMoveHandler(relative)
             }
             if (!onEnterConsumed && !oldMoveFilters.contains(filter))
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopOwners.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopOwners.desktop.kt
index 8dab0e2..41baeb8 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopOwners.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopOwners.desktop.kt
@@ -199,13 +199,15 @@
         down: Boolean
     ): PointerInputEvent {
         val time = System.nanoTime() / 1_000_000L
+        val position = Offset(x.toFloat(), y.toFloat())
         return PointerInputEvent(
             time,
             listOf(
                 PointerInputEventData(
                     PointerId(pointerId),
                     time,
-                    Offset(x.toFloat(), y.toFloat()),
+                    position,
+                    position,
                     down,
                     PointerType.Mouse
                 )
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopSelectionClipboard.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopSelectionClipboard.desktop.kt
index 2dec323..e69de29 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopSelectionClipboard.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopSelectionClipboard.desktop.kt
@@ -1,37 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.ui.platform
-
-import androidx.compose.runtime.staticCompositionLocalOf
-import androidx.compose.ui.input.key.Key
-import androidx.compose.ui.input.key.plus
-import androidx.compose.ui.text.AnnotatedString
-
-val SelectionTrackerAmbient = staticCompositionLocalOf<SelectionTracker> {
-    error("CompositionLocal SelectionTrackerAmbient not provided")
-}
-
-class SelectionTracker {
-    var getSelectedText: (() -> AnnotatedString?)? = null
-}
-
-val copyToClipboardKeySet by lazy {
-    when (DesktopPlatform.Current) {
-        DesktopPlatform.MacOS -> Key.MetaLeft + Key.C
-        else -> Key.CtrlLeft + Key.C
-    }
-}
\ No newline at end of file
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/Wrapper.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/Wrapper.desktop.kt
index 06aab2e..5ea7190 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/Wrapper.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/Wrapper.desktop.kt
@@ -37,15 +37,7 @@
 
     val composition = Composition(DesktopUiApplier(root), parent ?: container.recomposer)
     composition.setContent {
-        ProvideDesktopAmbients(this) {
-            content()
-        }
-    }
-
-    keyboard?.setShortcut(copyToClipboardKeySet) {
-        selectionTracker.getSelectedText?.invoke()?.let {
-            clipboardManager.setText(it)
-        }
+        ProvideDesktopAmbients(this, content)
     }
 
     return composition
@@ -54,8 +46,7 @@
 @Composable
 private fun ProvideDesktopAmbients(owner: DesktopOwner, content: @Composable () -> Unit) {
     CompositionLocalProvider(
-        DesktopOwnersAmbient provides owner.container,
-        SelectionTrackerAmbient provides owner.selectionTracker
+        DesktopOwnersAmbient provides owner.container
     ) {
         ProvideCommonCompositionLocals(
             owner = owner,
@@ -71,4 +62,4 @@
 ): Composition = Composition(
     DesktopUiApplier(container),
     parent
-)
\ No newline at end of file
+)
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/vector/DesktopXmlVectorParser.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/vector/DesktopXmlVectorParser.desktop.kt
index 70253a7..9340c9e 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/vector/DesktopXmlVectorParser.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/vector/DesktopXmlVectorParser.desktop.kt
@@ -18,7 +18,6 @@
 
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.ColorStop
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.PathFillType
 import androidx.compose.ui.graphics.SolidColor
@@ -203,7 +202,7 @@
     )
 )
 
-private fun Element.parseColorStops(): Array<ColorStop> {
+private fun Element.parseColorStops(): Array<Pair<Float, Color>> {
     val items = childrenSequence
         .filterIsInstance<Element>()
         .filter { it.nodeName == "item" }
@@ -232,7 +231,7 @@
     return colorStops.toTypedArray()
 }
 
-private fun Element.parseColorStop(defaultOffset: Float): ColorStop? {
+private fun Element.parseColorStop(defaultOffset: Float): Pair<Float, Color>? {
     val offset = attributeOrNull(ANDROID_NS, "offset")?.toFloat() ?: defaultOffset
     val color = attributeOrNull(ANDROID_NS, "color")?.let(::parseColorValue) ?: return null
     return offset to Color(color)
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/DesktopPopup.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/DesktopPopup.desktop.kt
index ddacfbf..49624b0 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/DesktopPopup.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/DesktopPopup.desktop.kt
@@ -133,7 +133,7 @@
                 coordinates.size
             )
         },
-        measureBlock = { _, _ ->
+        measurePolicy = { _, _ ->
             layout(0, 0) {}
         }
     )
@@ -149,7 +149,7 @@
                         onDismissRequest?.invoke()
                     }
                 },
-                measureBlock = { measurables, constraints ->
+                measurePolicy = { measurables, constraints ->
                     val width = constraints.maxWidth
                     val height = constraints.maxHeight
 
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/DesktopInputComponentTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/DesktopInputComponentTest.kt
index e7e98ab..06417a3 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/DesktopInputComponentTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/DesktopInputComponentTest.kt
@@ -42,14 +42,14 @@
         val input = DesktopPlatformInput(DummyDesktopComponent)
         val inputService = TextInputService(input)
 
-        val token = inputService.startInput(
+        val session = inputService.startInput(
             TextFieldValue(),
             ImeOptions.Default,
-            processor::onEditCommands,
+            processor::apply,
             {}
         )
 
-        processor.onNewState(TextFieldValue("h"), inputService, token)
+        processor.reset(TextFieldValue("h"), session)
 
         val familyEmoji = "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66"
 
@@ -64,7 +64,7 @@
             )
         )
 
-        val buffer = processor.mBufferState
+        val buffer = processor.toTextFieldValue()
 
         Assert.assertEquals("${familyEmoji}h", buffer.text)
         Assert.assertEquals(TextRange(11), buffer.selection)
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt
index e31400b8..5b0bf3d 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt
@@ -16,12 +16,10 @@
 package androidx.compose.ui.node
 
 import androidx.compose.ui.ExperimentalComposeUiApi
-import androidx.compose.ui.graphics.drawscope.ContentDrawScope
-import androidx.compose.ui.draw.DrawModifier
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.TransformOrigin
 import androidx.compose.ui.autofill.Autofill
 import androidx.compose.ui.autofill.AutofillTree
+import androidx.compose.ui.draw.DrawModifier
 import androidx.compose.ui.draw.drawBehind
 import androidx.compose.ui.focus.FocusDirection
 import androidx.compose.ui.focus.FocusManager
@@ -29,6 +27,8 @@
 import androidx.compose.ui.graphics.Canvas
 import androidx.compose.ui.graphics.Matrix
 import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.graphics.TransformOrigin
+import androidx.compose.ui.graphics.drawscope.ContentDrawScope
 import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.hapticfeedback.HapticFeedback
 import androidx.compose.ui.input.key.KeyEvent
@@ -36,13 +36,14 @@
 import androidx.compose.ui.input.pointer.PointerEventPass
 import androidx.compose.ui.input.pointer.PointerInputFilter
 import androidx.compose.ui.input.pointer.PointerInputModifier
-import androidx.compose.ui.layout.LayoutModifier
 import androidx.compose.ui.layout.AlignmentLine
+import androidx.compose.ui.layout.LayoutModifier
 import androidx.compose.ui.layout.Measurable
 import androidx.compose.ui.layout.MeasureResult
 import androidx.compose.ui.layout.MeasureScope
 import androidx.compose.ui.layout.layout
 import androidx.compose.ui.layout.positionInRoot
+import androidx.compose.ui.platform.AccessibilityManager
 import androidx.compose.ui.platform.ClipboardManager
 import androidx.compose.ui.platform.TextToolbar
 import androidx.compose.ui.platform.ViewConfiguration
@@ -54,6 +55,7 @@
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.unit.toOffset
 import androidx.compose.ui.zIndex
 import com.google.common.truth.Truth.assertThat
 import org.junit.Assert.assertEquals
@@ -1337,76 +1339,6 @@
         }
     }
 
-    /**
-     * This test creates a layout of this shape:
-     *
-     *   |---|
-     *   |tt |
-     *   |t  |
-     *   |---|t
-     *       tt
-     *
-     *   But where the additional offset suggest something more like this shape.
-     *
-     *   tt
-     *   t|---|
-     *    |  t|
-     *    | tt|
-     *    |---|
-     *
-     *   Without the additional offset, it would be expected that only the top left 3 pointers would
-     *   hit, but with the additional offset, only the bottom right 3 hit.
-     */
-    @Test
-    fun hitTest_ownerIsOffset_onlyCorrectPointersHit() {
-
-        // Arrange
-
-        val pointerInputFilter: PointerInputFilter = mockPointerInputFilter()
-
-        val layoutNode = LayoutNode(
-            0, 0, 2, 2,
-            PointerInputModifierImpl(
-                pointerInputFilter
-            )
-        ).apply {
-            attach(MockOwner(IntOffset(1, 1)))
-        }
-
-        val offsetThatHits1 = Offset(2f, 2f)
-        val offsetThatHits2 = Offset(2f, 1f)
-        val offsetThatHits3 = Offset(1f, 2f)
-        val offsetsThatMiss =
-            listOf(
-                Offset(0f, 0f),
-                Offset(0f, 1f),
-                Offset(1f, 0f)
-            )
-
-        val hit1 = mutableListOf<PointerInputFilter>()
-        val hit2 = mutableListOf<PointerInputFilter>()
-        val hit3 = mutableListOf<PointerInputFilter>()
-
-        val miss = mutableListOf<PointerInputFilter>()
-
-        // Act.
-
-        layoutNode.hitTest(offsetThatHits1, hit1)
-        layoutNode.hitTest(offsetThatHits2, hit2)
-        layoutNode.hitTest(offsetThatHits3, hit3)
-
-        offsetsThatMiss.forEach {
-            layoutNode.hitTest(it, miss)
-        }
-
-        // Assert.
-
-        assertThat(hit1).isEqualTo(listOf(pointerInputFilter))
-        assertThat(hit2).isEqualTo(listOf(pointerInputFilter))
-        assertThat(hit3).isEqualTo(listOf(pointerInputFilter))
-        assertThat(miss).isEmpty()
-    }
-
     @Test
     fun hitTest_pointerOn3NestedPointerInputModifiers_allPimsHitInCorrectOrder() {
 
@@ -1780,6 +1712,8 @@
         get() = TODO("Not yet implemented")
     override val clipboardManager: ClipboardManager
         get() = TODO("Not yet implemented")
+    override val accessibilityManager: AccessibilityManager
+        get() = TODO("Not yet implemented")
     override val textToolbar: TextToolbar
         get() = TODO("Not yet implemented")
     @OptIn(ExperimentalComposeUiApi::class)
@@ -1820,8 +1754,11 @@
         onDetachParams += node
     }
 
-    override fun calculatePosition(): IntOffset = position
-    override fun calculatePositionInWindow(): IntOffset = position
+    override fun calculatePositionInWindow(localPosition: Offset): Offset =
+        localPosition + position.toOffset()
+
+    override fun calculateLocalPosition(positionInWindow: Offset): Offset =
+        positionInWindow - position.toOffset()
 
     override fun requestFocus(): Boolean = false
 
@@ -1897,13 +1834,12 @@
 private fun LayoutNode(x: Int, y: Int, x2: Int, y2: Int, modifier: Modifier = Modifier) =
     LayoutNode().apply {
         this.modifier = modifier
-        measureBlocks = object : LayoutNode.NoIntrinsicsMeasureBlocks("not supported") {
-            override fun measure(
-                measureScope: MeasureScope,
+        measurePolicy = object : LayoutNode.NoIntrinsicsMeasurePolicy("not supported") {
+            override fun MeasureScope.measure(
                 measurables: List<Measurable>,
                 constraints: Constraints
             ): MeasureResult =
-                measureScope.layout(x2 - x, y2 - y) {
+                layout(x2 - x, y2 - y) {
                     measurables.forEach { it.measure(constraints).place(0, 0) }
                 }
         }
diff --git a/core/core-animation/src/main/java/androidx/core/animation/PathKeyframes.java b/core/core-animation/src/main/java/androidx/core/animation/PathKeyframes.java
index e1fe40a..fe6cb0e 100644
--- a/core/core-animation/src/main/java/androidx/core/animation/PathKeyframes.java
+++ b/core/core-animation/src/main/java/androidx/core/animation/PathKeyframes.java
@@ -220,7 +220,7 @@
 
         @NonNull
         @Override
-        @SuppressWarnings("unchecked")
+        @SuppressWarnings({"unchecked", "CatchAndPrintStackTrace"})
         public Keyframes<T> clone() {
             Keyframes<T> clone = null;
             try {
diff --git a/core/core-animation/src/main/java/androidx/core/animation/PropertyValuesHolder.java b/core/core-animation/src/main/java/androidx/core/animation/PropertyValuesHolder.java
index 28ecb23..27e973a 100644
--- a/core/core-animation/src/main/java/androidx/core/animation/PropertyValuesHolder.java
+++ b/core/core-animation/src/main/java/androidx/core/animation/PropertyValuesHolder.java
@@ -1404,6 +1404,7 @@
         }
 
         @Override
+        @SuppressWarnings("CatchAndPrintStackTrace")
         void setupSetter(Class<?> targetClass) {
             synchronized (sSetterPropertyMap) {
                 // Have to lock property map prior to reading it, to guard against
@@ -1503,6 +1504,7 @@
         }
 
         @Override
+        @SuppressWarnings("CatchAndPrintStackTrace")
         void setupSetter(Class<?> targetClass) {
             synchronized (sSetterPropertyMap) {
                 // Have to lock property map prior to reading it, to guard against
diff --git a/core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateFromResumeTestCase.kt b/core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateFromLifecycleStatesTestCase.kt
similarity index 91%
rename from core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateFromResumeTestCase.kt
rename to core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateFromLifecycleStatesTestCase.kt
index 59a897b..7f2a7de 100644
--- a/core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateFromResumeTestCase.kt
+++ b/core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateFromLifecycleStatesTestCase.kt
@@ -33,16 +33,13 @@
 
 @LargeTest
 @RunWith(AndroidJUnit4::class)
-class ActivityCompatRecreateFromLifecycleStatesTestCase {
+public class ActivityCompatRecreateFromLifecycleStatesTestCase {
     @get:Rule
-    val activityTestRule = ActivityTestRule(
-        ActivityCompatRecreateLifecycleTestActivity::class.java,
-        false,
-        false
-    )
+    public val activityTestRule: ActivityTestRule<ActivityCompatRecreateLifecycleTestActivity> =
+        ActivityTestRule(ActivityCompatRecreateLifecycleTestActivity::class.java, false, false)
 
     @Test
-    fun testRecreateFromOnResume() {
+    public fun testRecreateFromOnResume() {
         val calledRecreate = CountDownLatch(1)
         lateinit var firstActivity: Activity
 
@@ -76,7 +73,7 @@
     }
 
     @Test
-    fun testRecreateFromOnStart() {
+    public fun testRecreateFromOnStart() {
         val calledRecreate = CountDownLatch(1)
         lateinit var firstActivity: Activity
 
@@ -110,7 +107,7 @@
     }
 
     @Test
-    fun testRecreateFromOnStop() {
+    public fun testRecreateFromOnStop() {
         val calledRecreate = CountDownLatch(1)
         lateinit var firstActivity: Activity
 
@@ -136,10 +133,4 @@
         // Make sure that we didn't start a new activity.
         assertEquals(firstActivity, activityTestRule.activity)
     }
-}
-
-fun runnable(body: Runnable.(Runnable) -> Unit) = object : Runnable {
-    override fun run() {
-        this.body(this)
-    }
 }
\ No newline at end of file
diff --git a/core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateLifecycleTestActivity.kt b/core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateLifecycleTestActivity.kt
index 2dce783..704c045 100644
--- a/core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateLifecycleTestActivity.kt
+++ b/core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateLifecycleTestActivity.kt
@@ -20,7 +20,7 @@
 import androidx.activity.ComponentActivity
 import androidx.core.test.R
 
-class ActivityCompatRecreateLifecycleTestActivity : ComponentActivity() {
+public class ActivityCompatRecreateLifecycleTestActivity : ComponentActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
 
@@ -46,7 +46,7 @@
         onStopHandler?.invoke(this)
     }
 
-    companion object {
+    internal companion object {
         var onResumeHandler: ((ActivityCompatRecreateLifecycleTestActivity) -> Unit)? = null
         var onStartHandler: ((ActivityCompatRecreateLifecycleTestActivity) -> Unit)? = null
         var onStopHandler: ((ActivityCompatRecreateLifecycleTestActivity) -> Unit)? = null
diff --git a/core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateTestCase.java b/core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateTestCase.java
index 2d4f778..4b88d70 100644
--- a/core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateTestCase.java
+++ b/core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateTestCase.java
@@ -28,21 +28,22 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
 import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.rule.ActivityTestRule;
 import androidx.testutils.PollingCheck;
 
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+@SuppressWarnings("deprecation")
 @LargeTest
 @RunWith(AndroidJUnit4.class)
 public class ActivityCompatRecreateTestCase {
     @Rule
-    public final ActivityTestRule<TestActivityWithLifecycle> mActivityTestRule;
+    public final androidx.test.rule.ActivityTestRule<TestActivityWithLifecycle> mActivityTestRule;
 
     public ActivityCompatRecreateTestCase() {
-        mActivityTestRule = new ActivityTestRule<>(TestActivityWithLifecycle.class);
+        mActivityTestRule = new androidx.test.rule.ActivityTestRule<>(
+                TestActivityWithLifecycle.class);
     }
 
     @Test
diff --git a/core/core/src/androidTest/java/androidx/core/view/WindowInsetsCompatActivityTest.kt b/core/core/src/androidTest/java/androidx/core/view/WindowInsetsCompatActivityTest.kt
index 6331c51..c704ef9 100644
--- a/core/core/src/androidTest/java/androidx/core/view/WindowInsetsCompatActivityTest.kt
+++ b/core/core/src/androidTest/java/androidx/core/view/WindowInsetsCompatActivityTest.kt
@@ -44,6 +44,7 @@
 import org.junit.After
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertNotEquals
+import org.junit.Assert.assertNotNull
 import org.junit.Assume.assumeFalse
 import org.junit.Assume.assumeThat
 import org.junit.Before
@@ -322,6 +323,15 @@
         assertEquals(originalInsets, convertedInsets)
     }
 
+    @Test
+    @SdkSuppress(minSdkVersion = 21)
+    public fun root_insets_not_null() {
+        val container: View = scenario.withActivity { findViewById(R.id.container) }
+        val rootWindowInsets = ViewCompat.getRootWindowInsets(container)
+        assertNotNull(rootWindowInsets)
+        assertNotEquals(WindowInsetsCompat.CONSUMED, rootWindowInsets)
+    }
+
     public companion object {
         @JvmStatic
         @Parameterized.Parameters
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 6130b91..de76c7f 100644
--- a/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java
@@ -587,6 +587,7 @@
      * or an empty list on older SDKs which don't support Notification Channels.
      */
     @NonNull
+    @SuppressWarnings("MixedMutabilityReturnType")
     public List<NotificationChannelCompat> getNotificationChannelsCompat() {
         if (Build.VERSION.SDK_INT >= 26) {
             List<NotificationChannel> channels = getNotificationChannels();
@@ -618,6 +619,7 @@
      * or an empty list on older SDKs which don't support Notification Channels.
      */
     @NonNull
+    @SuppressWarnings("MixedMutabilityReturnType")
     public List<NotificationChannelGroupCompat> getNotificationChannelGroupsCompat() {
         if (Build.VERSION.SDK_INT >= 26) {
             List<NotificationChannelGroup> groups = getNotificationChannelGroups();
diff --git a/core/core/src/main/java/androidx/core/content/res/FontResourcesParserCompat.java b/core/core/src/main/java/androidx/core/content/res/FontResourcesParserCompat.java
index 04ec6b1..35ef6f2 100644
--- a/core/core/src/main/java/androidx/core/content/res/FontResourcesParserCompat.java
+++ b/core/core/src/main/java/androidx/core/content/res/FontResourcesParserCompat.java
@@ -265,6 +265,7 @@
      *
      * Provider cert entry must be cert string array or array of cert string array.
      */
+    @SuppressWarnings("MixedMutabilityReturnType")
     public static List<List<byte[]>> readCerts(Resources resources, @ArrayRes int certsId) {
         if (certsId == 0) {
             return Collections.<List<byte[]>>emptyList();
diff --git a/core/core/src/main/java/androidx/core/os/ProcessCompat.java b/core/core/src/main/java/androidx/core/os/ProcessCompat.java
index 9c8ad10..272d429 100644
--- a/core/core/src/main/java/androidx/core/os/ProcessCompat.java
+++ b/core/core/src/main/java/androidx/core/os/ProcessCompat.java
@@ -87,7 +87,7 @@
             // This class is non-instantiable.
         }
 
-        @SuppressWarnings("JavaReflectionMemberAccess")
+        @SuppressWarnings({"JavaReflectionMemberAccess", "CatchAndPrintStackTrace"})
         @SuppressLint("DiscouragedPrivateApi")
         static boolean isApplicationUid(int uid) {
             // In JELLY_BEAN_MR2, the equivalent isApp(int) hidden method moved to public class
@@ -126,6 +126,7 @@
         }
 
         @SuppressLint("PrivateApi")
+        @SuppressWarnings("CatchAndPrintStackTrace")
         static boolean isApplicationUid(int uid) {
             // In JELLY_BEAN_MR1, the equivalent isApp(int) hidden method was available on hidden
             // class android.os.UserId.
diff --git a/core/core/src/main/java/androidx/core/view/ViewCompat.java b/core/core/src/main/java/androidx/core/view/ViewCompat.java
index ea3306d..a9f9e59 100644
--- a/core/core/src/main/java/androidx/core/view/ViewCompat.java
+++ b/core/core/src/main/java/androidx/core/view/ViewCompat.java
@@ -4717,7 +4717,7 @@
 
         @Nullable
         public static WindowInsetsCompat getRootWindowInsets(@NonNull View v) {
-            return WindowInsetsCompat.getRootInsets(v);
+            return WindowInsetsCompat.Api21ReflectionHolder.getRootWindowInsets(v);
         }
 
         static WindowInsetsCompat computeSystemWindowInsets(@NonNull View v,
diff --git a/core/core/src/main/java/androidx/core/view/WindowInsetsCompat.java b/core/core/src/main/java/androidx/core/view/WindowInsetsCompat.java
index 156f261..d306de7 100644
--- a/core/core/src/main/java/androidx/core/view/WindowInsetsCompat.java
+++ b/core/core/src/main/java/androidx/core/view/WindowInsetsCompat.java
@@ -869,16 +869,6 @@
         }
     }
 
-    @Nullable
-    static WindowInsetsCompat getRootInsets(@NonNull View v) {
-        if (SDK_INT >= 23) {
-            return ViewCompat.getRootWindowInsets(v);
-        } else if (SDK_INT >= 21) {
-            return Impl21.getRootWindowInsets(v);
-        }
-        return null;
-    }
-
     @RequiresApi(20)
     private static class Impl20 extends Impl {
 
@@ -1236,53 +1226,7 @@
             return mStableInsets;
         }
 
-        private static Field sViewAttachInfoField;
-        private static Field sStableInsets;
-        private static Field sVisibleInsets;
 
-        static {
-            try {
-                sViewAttachInfoField = View.class.getDeclaredField("mAttachInfo");
-                sViewAttachInfoField.setAccessible(true);
-                Class<?> sAttachInfoClass = Class.forName("android.view.View$AttachInfo");
-                sStableInsets = sAttachInfoClass.getDeclaredField("mStableInsets");
-                sStableInsets.setAccessible(true);
-                sVisibleInsets = sAttachInfoClass.getDeclaredField("mVisibleInsets");
-                sVisibleInsets.setAccessible(true);
-            } catch (ReflectiveOperationException e) {
-                Log.e(TAG, "Failed to get visible insets from AttachInfo " + e.getMessage(), e);
-            }
-        }
-
-        @SuppressWarnings("deprecation")
-        @Nullable
-        public static WindowInsetsCompat getRootWindowInsets(@NonNull View v) {
-            if (!v.isAttachedToWindow()) {
-                return null;
-            }
-
-            if (sViewAttachInfoField == null || sStableInsets == null || sVisibleInsets == null) {
-                return null;
-            }
-
-            View rootView = v.getRootView();
-            try {
-                Object attachInfo = sViewAttachInfoField.get(rootView);
-                if (attachInfo != null) {
-                    Rect stableInsets = (Rect) sStableInsets.get(attachInfo);
-                    Rect visibleInsets = (Rect) sVisibleInsets.get(attachInfo);
-                    if (stableInsets != null && visibleInsets != null) {
-                        return new WindowInsetsCompat.Builder()
-                                .setStableInsets(Insets.of(stableInsets))
-                                .setSystemWindowInsets(Insets.of(visibleInsets))
-                                .build();
-                    }
-                }
-            } catch (IllegalAccessException e) {
-                Log.e(TAG, "Failed to get insets from AttachInfo. " + e.getMessage(), e);
-            }
-            return null;
-        }
     }
 
     @RequiresApi(28)
@@ -2135,4 +2079,58 @@
     void copyRootViewBounds(@NonNull View rootView) {
         mImpl.copyRootViewBounds(rootView);
     }
+
+    @RequiresApi(21)
+    static class Api21ReflectionHolder {
+
+        private Api21ReflectionHolder() {
+            // privatex
+        }
+
+        private static Field sViewAttachInfoField;
+        private static Field sStableInsets;
+        private static Field sContentInsets;
+        private static boolean sReflectionSucceeded;
+
+        static {
+            try {
+                sViewAttachInfoField = View.class.getDeclaredField("mAttachInfo");
+                sViewAttachInfoField.setAccessible(true);
+                Class<?> sAttachInfoClass = Class.forName("android.view.View$AttachInfo");
+                sStableInsets = sAttachInfoClass.getDeclaredField("mStableInsets");
+                sStableInsets.setAccessible(true);
+                sContentInsets = sAttachInfoClass.getDeclaredField("mContentInsets");
+                sContentInsets.setAccessible(true);
+                sReflectionSucceeded = true;
+            } catch (ReflectiveOperationException e) {
+                Log.w(TAG, "Failed to get visible insets from AttachInfo " + e.getMessage(), e);
+            }
+        }
+
+        @SuppressWarnings("deprecation")
+        @Nullable
+        public static WindowInsetsCompat getRootWindowInsets(@NonNull View v) {
+            if (!sReflectionSucceeded || !v.isAttachedToWindow()) {
+                return null;
+            }
+
+            View rootView = v.getRootView();
+            try {
+                Object attachInfo = sViewAttachInfoField.get(rootView);
+                if (attachInfo != null) {
+                    Rect stableInsets = (Rect) sStableInsets.get(attachInfo);
+                    Rect visibleInsets = (Rect) sContentInsets.get(attachInfo);
+                    if (stableInsets != null && visibleInsets != null) {
+                        return new WindowInsetsCompat.Builder()
+                                .setStableInsets(Insets.of(stableInsets))
+                                .setSystemWindowInsets(Insets.of(visibleInsets))
+                                .build();
+                    }
+                }
+            } catch (IllegalAccessException e) {
+                Log.w(TAG, "Failed to get insets from AttachInfo. " + e.getMessage(), e);
+            }
+            return null;
+        }
+    }
 }
diff --git a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
index 6b35ae0..2feab6c 100644
--- a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
+++ b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
@@ -3069,7 +3069,7 @@
      *     <li>API &lt; 21: Always returns {@code null}</li>
      * </ul>
      */
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings({"unchecked", "MixedMutabilityReturnType"})
     public List<AccessibilityActionCompat> getActionList() {
         List<Object> actions = null;
         if (Build.VERSION.SDK_INT >= 21) {
@@ -3374,6 +3374,7 @@
      * @param viewId The fully qualified resource name of the view id to find.
      * @return A list of node info.
      */
+    @SuppressWarnings("MixedMutabilityReturnType")
     public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByViewId(String viewId) {
         if (Build.VERSION.SDK_INT >= 18) {
             List<AccessibilityNodeInfo> nodes = mInfo.findAccessibilityNodeInfosByViewId(viewId);
diff --git a/customview/customview/src/main/java/androidx/customview/widget/ViewDragHelper.java b/customview/customview/src/main/java/androidx/customview/widget/ViewDragHelper.java
index fb1dc4c..dbaa3e0 100644
--- a/customview/customview/src/main/java/androidx/customview/widget/ViewDragHelper.java
+++ b/customview/customview/src/main/java/androidx/customview/widget/ViewDragHelper.java
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 package androidx.customview.widget;
 
 import android.content.Context;
@@ -68,6 +67,7 @@
     /**
      * Edge flag indicating that the left edge should be affected.
      */
+    @SuppressWarnings("PointlessBitwiseExpression")
     public static final int EDGE_LEFT = 1 << 0;
 
     /**
@@ -93,6 +93,7 @@
     /**
      * Indicates that a check should occur along the horizontal axis
      */
+    @SuppressWarnings("PointlessBitwiseExpression")
     public static final int DIRECTION_HORIZONTAL = 1 << 0;
 
     /**
@@ -130,20 +131,23 @@
     private int mPointersDown;
 
     private VelocityTracker mVelocityTracker;
-    private float mMaxVelocity;
+    private final float mMaxVelocity;
     private float mMinVelocity;
 
     private int mEdgeSize;
     private final int mDefaultEdgeSize;
     private int mTrackingEdges;
 
-    private OverScroller mScroller;
+    @NonNull
+    private final OverScroller mScroller;
 
+    @NonNull
     private final Callback mCallback;
 
     private View mCapturedView;
     private boolean mReleaseInProgress;
 
+    @NonNull
     private final ViewGroup mParentView;
 
     /**
@@ -277,6 +281,7 @@
          * @param child Child view to check
          * @return range of vertical motion in pixels
          */
+        @SuppressWarnings("unused")
         public int getViewVerticalDragRange(@NonNull View child) {
             return 0;
         }
@@ -385,12 +390,8 @@
      */
     private ViewDragHelper(@NonNull Context context, @NonNull ViewGroup forParent,
             @NonNull Callback cb) {
-        if (forParent == null) {
-            throw new IllegalArgumentException("Parent view may not be null");
-        }
-        if (cb == null) {
-            throw new IllegalArgumentException("Callback may not be null");
-        }
+        requireNonNull(forParent, "Parent view may not be null");
+        requireNonNull(cb, "Callback may not be null");
 
         mParentView = forParent;
         mCallback = cb;
@@ -1066,7 +1067,7 @@
                     final float dy = y - mInitialMotionY[pointerId];
 
                     final View toCapture = findTopChildUnder((int) x, (int) y);
-                    final boolean pastSlop = toCapture != null && checkTouchSlop(toCapture, dx, dy);
+                    final boolean pastSlop = checkTouchSlop(toCapture, dx, dy);
                     if (pastSlop) {
                         // check the callback's
                         // getView[Horizontal|Vertical]DragRange methods to know
@@ -1210,8 +1211,6 @@
                     final int idy = (int) (y - mLastMotionY[mActivePointerId]);
 
                     dragTo(mCapturedView.getLeft() + idx, mCapturedView.getTop() + idy, idx, idy);
-
-                    saveLastMotion(ev);
                 } else {
                     // Check to see if any pointer is now over a draggable view.
                     final int pointerCount = ev.getPointerCount();
@@ -1238,8 +1237,9 @@
                             break;
                         }
                     }
-                    saveLastMotion(ev);
                 }
+
+                saveLastMotion(ev);
                 break;
             }
 
@@ -1338,12 +1338,14 @@
      * @param child Child to check
      * @param dx Motion since initial position along X axis
      * @param dy Motion since initial position along Y axis
-     * @return true if the touch slop has been crossed
+     * @return {@code true} if the touch slop has been crossed, {@code false} otherwise or if
+     *         child is {@code null}
      */
-    private boolean checkTouchSlop(View child, float dx, float dy) {
+    private boolean checkTouchSlop(@Nullable View child, float dx, float dy) {
         if (child == null) {
             return false;
         }
+
         final boolean checkHorizontal = mCallback.getViewHorizontalDragRange(child) > 0;
         final boolean checkVertical = mCallback.getViewVerticalDragRange(child) > 0;
 
@@ -1372,6 +1374,10 @@
      * @return true if the slop threshold has been crossed, false otherwise
      */
     public boolean checkTouchSlop(int directions) {
+        if (mInitialMotionX == null) {
+            return false;
+        }
+
         final int count = mInitialMotionX.length;
         for (int i = 0; i < count; i++) {
             if (checkTouchSlop(directions, i)) {
@@ -1404,6 +1410,15 @@
         final boolean checkHorizontal = (directions & DIRECTION_HORIZONTAL) == DIRECTION_HORIZONTAL;
         final boolean checkVertical = (directions & DIRECTION_VERTICAL) == DIRECTION_VERTICAL;
 
+        if (mInitialMotionX == null || mInitialMotionY == null
+                || mLastMotionX == null || mLastMotionY == null) {
+            // We should never reach this point, because if the pointer is down then there ought
+            // to be an initial motion event; however, isPointerDown is not a guarantee of this.
+            Log.w(TAG, "Inconsistent pointer event stream: pointer is down, but there is no "
+                    + "initial motion recorded. Is something intercepting or modifying events?");
+            return false;
+        }
+
         final float dx = mLastMotionX[pointerId] - mInitialMotionX[pointerId];
         final float dy = mLastMotionY[pointerId] - mInitialMotionY[pointerId];
 
@@ -1427,6 +1442,10 @@
      * @return true if any of the edges specified were initially touched in the current gesture
      */
     public boolean isEdgeTouched(int edges) {
+        if (mInitialEdgesTouched == null) {
+            return false;
+        }
+
         final int count = mInitialEdgesTouched.length;
         for (int i = 0; i < count; i++) {
             if (isEdgeTouched(edges, i)) {
@@ -1447,7 +1466,8 @@
      * @return true if any of the edges specified were initially touched in the current gesture
      */
     public boolean isEdgeTouched(int edges, int pointerId) {
-        return isPointerDown(pointerId) && (mInitialEdgesTouched[pointerId] & edges) != 0;
+        return isPointerDown(pointerId) && mInitialEdgesTouched != null
+                && (mInitialEdgesTouched[pointerId] & edges) != 0;
     }
 
     private void releaseViewForPointerUp() {
@@ -1547,6 +1567,7 @@
         return result;
     }
 
+    @SuppressWarnings("BooleanMethodIsAlwaysInverted")
     private boolean isValidPointerForActionMove(int pointerId) {
         if (!isPointerDown(pointerId)) {
             if (DEBUG) {
@@ -1559,4 +1580,11 @@
         }
         return true;
     }
+
+    // Temporary backport of Objects.requireNonNull() until we can port it to core (b/179904366).
+    @Nullable
+    private static <T> T requireNonNull(@Nullable T obj, @NonNull String message) {
+        if (obj == null) throw new NullPointerException(message);
+        return obj;
+    }
 }
diff --git a/datastore/datastore-preferences-core/api/restricted_current.txt b/datastore/datastore-preferences-core/api/restricted_current.txt
index c8be158..1b3e2d0 100644
--- a/datastore/datastore-preferences-core/api/restricted_current.txt
+++ b/datastore/datastore-preferences-core/api/restricted_current.txt
@@ -31,7 +31,6 @@
   }
 
   public static final class Preferences.Key<T> {
-    ctor @kotlin.PublishedApi internal Preferences.Key(String name);
     method public String getName();
     method public infix androidx.datastore.preferences.core.Preferences.Pair<T> to(T? value);
     property public final String name;
diff --git a/datastore/datastore-preferences-core/src/main/java/androidx/datastore/preferences/core/Preferences.kt b/datastore/datastore-preferences-core/src/main/java/androidx/datastore/preferences/core/Preferences.kt
index 0448adf..c540667 100644
--- a/datastore/datastore-preferences-core/src/main/java/androidx/datastore/preferences/core/Preferences.kt
+++ b/datastore/datastore-preferences-core/src/main/java/androidx/datastore/preferences/core/Preferences.kt
@@ -31,10 +31,10 @@
      *
      * T must be one of the following: Boolean, Int, Long, Float, String, Set<String>.
      *
-     * Construct Keys for your data type using: [preferencesKey], [preferencesSetKey].
+     * Construct Keys for your data type using: [booleanPreferencesKey], [intPreferencesKey],
+     * [longPreferencesKey], [floatPreferencesKey], [stringPreferencesKey], [stringSetPreferencesKey]
      */
     public class Key<T>
-    @PublishedApi // necessary to use this in the public inline function preferencesKey().
     internal constructor(public val name: String) {
         /**
          * Infix function to create a Preferences.Pair.
@@ -53,6 +53,8 @@
         override fun hashCode(): Int {
             return name.hashCode()
         }
+
+        override fun toString(): String = name
     }
 
     /**
diff --git a/datastore/datastore-preferences-rxjava2/api/current.txt b/datastore/datastore-preferences-rxjava2/api/current.txt
index 8235e24..f92d774 100644
--- a/datastore/datastore-preferences-rxjava2/api/current.txt
+++ b/datastore/datastore-preferences-rxjava2/api/current.txt
@@ -6,7 +6,7 @@
     ctor public RxPreferenceDataStoreBuilder(android.content.Context context, String name);
     method public androidx.datastore.preferences.rxjava2.RxPreferenceDataStoreBuilder addDataMigration(androidx.datastore.core.DataMigration<androidx.datastore.preferences.core.Preferences> dataMigration);
     method public androidx.datastore.preferences.rxjava2.RxPreferenceDataStoreBuilder addRxDataMigration(androidx.datastore.rxjava2.RxDataMigration<androidx.datastore.preferences.core.Preferences> rxDataMigration);
-    method public androidx.datastore.core.DataStore<androidx.datastore.preferences.core.Preferences> build();
+    method public androidx.datastore.rxjava2.RxDataStore<androidx.datastore.preferences.core.Preferences> build();
     method public androidx.datastore.preferences.rxjava2.RxPreferenceDataStoreBuilder setCorruptionHandler(androidx.datastore.core.handlers.ReplaceFileCorruptionHandler<androidx.datastore.preferences.core.Preferences> corruptionHandler);
     method public androidx.datastore.preferences.rxjava2.RxPreferenceDataStoreBuilder setIoScheduler(io.reactivex.Scheduler ioScheduler);
   }
diff --git a/datastore/datastore-preferences-rxjava2/api/public_plus_experimental_current.txt b/datastore/datastore-preferences-rxjava2/api/public_plus_experimental_current.txt
index 8235e24..f92d774 100644
--- a/datastore/datastore-preferences-rxjava2/api/public_plus_experimental_current.txt
+++ b/datastore/datastore-preferences-rxjava2/api/public_plus_experimental_current.txt
@@ -6,7 +6,7 @@
     ctor public RxPreferenceDataStoreBuilder(android.content.Context context, String name);
     method public androidx.datastore.preferences.rxjava2.RxPreferenceDataStoreBuilder addDataMigration(androidx.datastore.core.DataMigration<androidx.datastore.preferences.core.Preferences> dataMigration);
     method public androidx.datastore.preferences.rxjava2.RxPreferenceDataStoreBuilder addRxDataMigration(androidx.datastore.rxjava2.RxDataMigration<androidx.datastore.preferences.core.Preferences> rxDataMigration);
-    method public androidx.datastore.core.DataStore<androidx.datastore.preferences.core.Preferences> build();
+    method public androidx.datastore.rxjava2.RxDataStore<androidx.datastore.preferences.core.Preferences> build();
     method public androidx.datastore.preferences.rxjava2.RxPreferenceDataStoreBuilder setCorruptionHandler(androidx.datastore.core.handlers.ReplaceFileCorruptionHandler<androidx.datastore.preferences.core.Preferences> corruptionHandler);
     method public androidx.datastore.preferences.rxjava2.RxPreferenceDataStoreBuilder setIoScheduler(io.reactivex.Scheduler ioScheduler);
   }
diff --git a/datastore/datastore-preferences-rxjava2/api/restricted_current.txt b/datastore/datastore-preferences-rxjava2/api/restricted_current.txt
index 8235e24..f92d774 100644
--- a/datastore/datastore-preferences-rxjava2/api/restricted_current.txt
+++ b/datastore/datastore-preferences-rxjava2/api/restricted_current.txt
@@ -6,7 +6,7 @@
     ctor public RxPreferenceDataStoreBuilder(android.content.Context context, String name);
     method public androidx.datastore.preferences.rxjava2.RxPreferenceDataStoreBuilder addDataMigration(androidx.datastore.core.DataMigration<androidx.datastore.preferences.core.Preferences> dataMigration);
     method public androidx.datastore.preferences.rxjava2.RxPreferenceDataStoreBuilder addRxDataMigration(androidx.datastore.rxjava2.RxDataMigration<androidx.datastore.preferences.core.Preferences> rxDataMigration);
-    method public androidx.datastore.core.DataStore<androidx.datastore.preferences.core.Preferences> build();
+    method public androidx.datastore.rxjava2.RxDataStore<androidx.datastore.preferences.core.Preferences> build();
     method public androidx.datastore.preferences.rxjava2.RxPreferenceDataStoreBuilder setCorruptionHandler(androidx.datastore.core.handlers.ReplaceFileCorruptionHandler<androidx.datastore.preferences.core.Preferences> corruptionHandler);
     method public androidx.datastore.preferences.rxjava2.RxPreferenceDataStoreBuilder setIoScheduler(io.reactivex.Scheduler ioScheduler);
   }
diff --git a/datastore/datastore-preferences-rxjava2/src/androidTest/java/androidx/datastore/preferences/rxjava2/RxPreferencesDataStoreBuilderTest.java b/datastore/datastore-preferences-rxjava2/src/androidTest/java/androidx/datastore/preferences/rxjava2/RxPreferencesDataStoreBuilderTest.java
index ba1ae8f..bfc6473 100644
--- a/datastore/datastore-preferences-rxjava2/src/androidTest/java/androidx/datastore/preferences/rxjava2/RxPreferencesDataStoreBuilderTest.java
+++ b/datastore/datastore-preferences-rxjava2/src/androidTest/java/androidx/datastore/preferences/rxjava2/RxPreferencesDataStoreBuilderTest.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 
 import androidx.annotation.NonNull;
-import androidx.datastore.core.DataStore;
 import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler;
 import androidx.datastore.preferences.core.MutablePreferences;
 import androidx.datastore.preferences.core.Preferences;
@@ -59,17 +58,19 @@
     public void testConstructWithProduceFile() throws Exception {
         File file = tempFolder.newFile("temp.preferences_pb");
 
-        DataStore<Preferences> dataStore =
+        RxDataStore<Preferences> dataStore =
                 new RxPreferenceDataStoreBuilder(() -> file).build();
 
-        Single<Preferences> incrementInt = RxDataStore.updateDataAsync(dataStore,
+        Single<Preferences> incrementInt = dataStore.updateDataAsync(
                 RxPreferencesDataStoreBuilderTest::incrementInteger);
         assertThat(incrementInt.blockingGet().get(INTEGER_KEY)).isEqualTo(1);
+        dataStore.dispose();
+        dataStore.shutdownComplete().blockingAwait();
 
         // Construct it again and confirm that the data is still there:
         dataStore = new RxPreferenceDataStoreBuilder(() -> file).build();
 
-        assertThat(RxDataStore.data(dataStore).blockingFirst().get(INTEGER_KEY))
+        assertThat(dataStore.data().blockingFirst().get(INTEGER_KEY))
                 .isEqualTo(1);
     }
 
@@ -86,16 +87,21 @@
             prefsFile.delete();
         }
 
-        DataStore<Preferences> dataStore =
+        RxDataStore<Preferences> dataStore =
                 new RxPreferenceDataStoreBuilder(context, name).build();
 
-        Single<Preferences> set1 = RxDataStore.updateDataAsync(dataStore,
+        Single<Preferences> set1 = dataStore.updateDataAsync(
                 RxPreferencesDataStoreBuilderTest::incrementInteger);
         assertThat(set1.blockingGet().get(INTEGER_KEY)).isEqualTo(1);
+        dataStore.dispose();
+        dataStore.shutdownComplete().blockingAwait();
 
         // Construct it again and confirm that the data is still there:
         dataStore = new RxPreferenceDataStoreBuilder(context, name).build();
-        assertThat(RxDataStore.data(dataStore).blockingFirst().get(INTEGER_KEY)).isEqualTo(1);
+        assertThat(dataStore.data().blockingFirst().get(INTEGER_KEY)).isEqualTo(1);
+        dataStore.dispose();
+        dataStore.shutdownComplete().blockingAwait();
+
 
         // Construct it again with the expected file path and confirm that the data is there:
         dataStore =
@@ -105,7 +111,7 @@
                                         + "/datastore/" + name + ".preferences_pb")
                 ).build();
 
-        assertThat(RxDataStore.data(dataStore).blockingFirst().get(INTEGER_KEY)).isEqualTo(1);
+        assertThat(dataStore.data().blockingFirst().get(INTEGER_KEY)).isEqualTo(1);
     }
 
     @Test
@@ -130,19 +136,19 @@
             }
         };
 
-        DataStore<Preferences> dataStore =
+        RxDataStore<Preferences> dataStore =
                 new RxPreferenceDataStoreBuilder(() ->
                         tempFolder.newFile("temp.preferences_pb"))
                         .addRxDataMigration(plusOneMigration)
                         .build();
 
-        assertThat(RxDataStore.data(dataStore).blockingFirst().get(INTEGER_KEY))
+        assertThat(dataStore.data().blockingFirst().get(INTEGER_KEY))
                 .isEqualTo(1);
     }
 
 
     @Test
-    public void testCorruptionHandlerIsUser() throws Exception {
+    public void testCorruptionHandlerIsUsed() throws Exception {
 
         File file = tempFolder.newFile("temp.preferences_pb");
 
@@ -159,12 +165,12 @@
                 });
 
 
-        DataStore<Preferences> dataStore =
+        RxDataStore<Preferences> dataStore =
                 new RxPreferenceDataStoreBuilder(() -> file)
                         .setCorruptionHandler(replaceFileCorruptionHandler)
                         .build();
 
-        assertThat(RxDataStore.data(dataStore).blockingFirst().get(INTEGER_KEY))
+        assertThat(dataStore.data().blockingFirst().get(INTEGER_KEY))
                 .isEqualTo(99);
     }
 }
diff --git a/datastore/datastore-preferences-rxjava2/src/main/java/androidx/datastore/preferences/rxjava2/RxPreferenceDataStoreBuilder.kt b/datastore/datastore-preferences-rxjava2/src/main/java/androidx/datastore/preferences/rxjava2/RxPreferenceDataStoreBuilder.kt
index 2075576..dc3f40d 100644
--- a/datastore/datastore-preferences-rxjava2/src/main/java/androidx/datastore/preferences/rxjava2/RxPreferenceDataStoreBuilder.kt
+++ b/datastore/datastore-preferences-rxjava2/src/main/java/androidx/datastore/preferences/rxjava2/RxPreferenceDataStoreBuilder.kt
@@ -19,15 +19,16 @@
 import android.annotation.SuppressLint
 import android.content.Context
 import androidx.datastore.core.DataMigration
-import androidx.datastore.core.DataStore
 import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
 import androidx.datastore.preferences.core.PreferenceDataStoreFactory
 import androidx.datastore.preferences.core.Preferences
 import androidx.datastore.preferences.createDataStore
 import androidx.datastore.rxjava2.RxDataMigration
+import androidx.datastore.rxjava2.RxDataStore
 import io.reactivex.Scheduler
 import io.reactivex.schedulers.Schedulers
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
 import kotlinx.coroutines.rx2.asCoroutineDispatcher
 import kotlinx.coroutines.rx2.await
 import java.io.File
@@ -135,24 +136,22 @@
      * context and name are set.
      * @return the DataStore with the provided parameters
      */
-    public fun build(): DataStore<Preferences> {
-        val scope = CoroutineScope(ioScheduler.asCoroutineDispatcher())
+    public fun build(): RxDataStore<Preferences> {
+        val scope = CoroutineScope(ioScheduler.asCoroutineDispatcher() + Job())
 
         val produceFile: Callable<File>? = this.produceFile
         val context: Context? = this.context
         val name: String? = this.name
 
-        return if (produceFile != null) {
+        val delegate = if (produceFile != null) {
             PreferenceDataStoreFactory.create(
                 produceFile = { produceFile.call() },
-                scope = CoroutineScope(
-                    ioScheduler.asCoroutineDispatcher()
-                ),
+                scope = scope,
                 corruptionHandler = corruptionHandler,
                 migrations = dataMigrations
             )
         } else if (context != null && name != null) {
-            return context.createDataStore(
+            context.createDataStore(
                 name = name,
                 scope = scope,
                 corruptionHandler = corruptionHandler,
@@ -161,6 +160,8 @@
         } else {
             error("Either produceFile or context and name must be set. This should never happen.")
         }
+
+        return RxDataStore.create(delegate, scope)
     }
 }
 
diff --git a/datastore/datastore-rxjava2/api/current.txt b/datastore/datastore-rxjava2/api/current.txt
index b52a1fc..4878ed3 100644
--- a/datastore/datastore-rxjava2/api/current.txt
+++ b/datastore/datastore-rxjava2/api/current.txt
@@ -7,9 +7,12 @@
     method public io.reactivex.Single<java.lang.Boolean!> shouldMigrate(T?);
   }
 
-  public final class RxDataStore {
-    method @kotlinx.coroutines.ExperimentalCoroutinesApi public static <T> io.reactivex.Flowable<T> data(androidx.datastore.core.DataStore<T>);
-    method @kotlinx.coroutines.ExperimentalCoroutinesApi public static <T> io.reactivex.Single<T> updateDataAsync(androidx.datastore.core.DataStore<T>, io.reactivex.functions.Function<T,io.reactivex.Single<T>> transform);
+  public final class RxDataStore<T> implements io.reactivex.disposables.Disposable {
+    method @kotlinx.coroutines.ExperimentalCoroutinesApi public io.reactivex.Flowable<T> data();
+    method public void dispose();
+    method public boolean isDisposed();
+    method public io.reactivex.Completable shutdownComplete();
+    method @kotlinx.coroutines.ExperimentalCoroutinesApi public io.reactivex.Single<T> updateDataAsync(io.reactivex.functions.Function<T,io.reactivex.Single<T>> transform);
   }
 
   public final class RxDataStoreBuilder<T> {
@@ -17,7 +20,7 @@
     ctor public RxDataStoreBuilder(android.content.Context context, String fileName, androidx.datastore.core.Serializer<T> serializer);
     method public androidx.datastore.rxjava2.RxDataStoreBuilder<T> addDataMigration(androidx.datastore.core.DataMigration<T> dataMigration);
     method public androidx.datastore.rxjava2.RxDataStoreBuilder<T> addRxDataMigration(androidx.datastore.rxjava2.RxDataMigration<T> rxDataMigration);
-    method public androidx.datastore.core.DataStore<T> build();
+    method public androidx.datastore.rxjava2.RxDataStore<T> build();
     method public androidx.datastore.rxjava2.RxDataStoreBuilder<T> setCorruptionHandler(androidx.datastore.core.handlers.ReplaceFileCorruptionHandler<T> corruptionHandler);
     method public androidx.datastore.rxjava2.RxDataStoreBuilder<T> setIoScheduler(io.reactivex.Scheduler ioScheduler);
   }
diff --git a/datastore/datastore-rxjava2/api/public_plus_experimental_current.txt b/datastore/datastore-rxjava2/api/public_plus_experimental_current.txt
index b52a1fc..4878ed3 100644
--- a/datastore/datastore-rxjava2/api/public_plus_experimental_current.txt
+++ b/datastore/datastore-rxjava2/api/public_plus_experimental_current.txt
@@ -7,9 +7,12 @@
     method public io.reactivex.Single<java.lang.Boolean!> shouldMigrate(T?);
   }
 
-  public final class RxDataStore {
-    method @kotlinx.coroutines.ExperimentalCoroutinesApi public static <T> io.reactivex.Flowable<T> data(androidx.datastore.core.DataStore<T>);
-    method @kotlinx.coroutines.ExperimentalCoroutinesApi public static <T> io.reactivex.Single<T> updateDataAsync(androidx.datastore.core.DataStore<T>, io.reactivex.functions.Function<T,io.reactivex.Single<T>> transform);
+  public final class RxDataStore<T> implements io.reactivex.disposables.Disposable {
+    method @kotlinx.coroutines.ExperimentalCoroutinesApi public io.reactivex.Flowable<T> data();
+    method public void dispose();
+    method public boolean isDisposed();
+    method public io.reactivex.Completable shutdownComplete();
+    method @kotlinx.coroutines.ExperimentalCoroutinesApi public io.reactivex.Single<T> updateDataAsync(io.reactivex.functions.Function<T,io.reactivex.Single<T>> transform);
   }
 
   public final class RxDataStoreBuilder<T> {
@@ -17,7 +20,7 @@
     ctor public RxDataStoreBuilder(android.content.Context context, String fileName, androidx.datastore.core.Serializer<T> serializer);
     method public androidx.datastore.rxjava2.RxDataStoreBuilder<T> addDataMigration(androidx.datastore.core.DataMigration<T> dataMigration);
     method public androidx.datastore.rxjava2.RxDataStoreBuilder<T> addRxDataMigration(androidx.datastore.rxjava2.RxDataMigration<T> rxDataMigration);
-    method public androidx.datastore.core.DataStore<T> build();
+    method public androidx.datastore.rxjava2.RxDataStore<T> build();
     method public androidx.datastore.rxjava2.RxDataStoreBuilder<T> setCorruptionHandler(androidx.datastore.core.handlers.ReplaceFileCorruptionHandler<T> corruptionHandler);
     method public androidx.datastore.rxjava2.RxDataStoreBuilder<T> setIoScheduler(io.reactivex.Scheduler ioScheduler);
   }
diff --git a/datastore/datastore-rxjava2/api/restricted_current.txt b/datastore/datastore-rxjava2/api/restricted_current.txt
index b52a1fc..4878ed3 100644
--- a/datastore/datastore-rxjava2/api/restricted_current.txt
+++ b/datastore/datastore-rxjava2/api/restricted_current.txt
@@ -7,9 +7,12 @@
     method public io.reactivex.Single<java.lang.Boolean!> shouldMigrate(T?);
   }
 
-  public final class RxDataStore {
-    method @kotlinx.coroutines.ExperimentalCoroutinesApi public static <T> io.reactivex.Flowable<T> data(androidx.datastore.core.DataStore<T>);
-    method @kotlinx.coroutines.ExperimentalCoroutinesApi public static <T> io.reactivex.Single<T> updateDataAsync(androidx.datastore.core.DataStore<T>, io.reactivex.functions.Function<T,io.reactivex.Single<T>> transform);
+  public final class RxDataStore<T> implements io.reactivex.disposables.Disposable {
+    method @kotlinx.coroutines.ExperimentalCoroutinesApi public io.reactivex.Flowable<T> data();
+    method public void dispose();
+    method public boolean isDisposed();
+    method public io.reactivex.Completable shutdownComplete();
+    method @kotlinx.coroutines.ExperimentalCoroutinesApi public io.reactivex.Single<T> updateDataAsync(io.reactivex.functions.Function<T,io.reactivex.Single<T>> transform);
   }
 
   public final class RxDataStoreBuilder<T> {
@@ -17,7 +20,7 @@
     ctor public RxDataStoreBuilder(android.content.Context context, String fileName, androidx.datastore.core.Serializer<T> serializer);
     method public androidx.datastore.rxjava2.RxDataStoreBuilder<T> addDataMigration(androidx.datastore.core.DataMigration<T> dataMigration);
     method public androidx.datastore.rxjava2.RxDataStoreBuilder<T> addRxDataMigration(androidx.datastore.rxjava2.RxDataMigration<T> rxDataMigration);
-    method public androidx.datastore.core.DataStore<T> build();
+    method public androidx.datastore.rxjava2.RxDataStore<T> build();
     method public androidx.datastore.rxjava2.RxDataStoreBuilder<T> setCorruptionHandler(androidx.datastore.core.handlers.ReplaceFileCorruptionHandler<T> corruptionHandler);
     method public androidx.datastore.rxjava2.RxDataStoreBuilder<T> setIoScheduler(io.reactivex.Scheduler ioScheduler);
   }
diff --git a/datastore/datastore-rxjava2/src/androidTest/java/androidx/datastore/rxjava2/RxDataStoreBuilderTest.java b/datastore/datastore-rxjava2/src/androidTest/java/androidx/datastore/rxjava2/RxDataStoreBuilderTest.java
index 2d3a0ae..6986576 100644
--- a/datastore/datastore-rxjava2/src/androidTest/java/androidx/datastore/rxjava2/RxDataStoreBuilderTest.java
+++ b/datastore/datastore-rxjava2/src/androidTest/java/androidx/datastore/rxjava2/RxDataStoreBuilderTest.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 
 import androidx.annotation.NonNull;
-import androidx.datastore.core.DataStore;
 import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler;
 import androidx.test.core.app.ApplicationProvider;
 
@@ -48,40 +47,50 @@
     @Test
     public void testConstructWithProduceFile() throws Exception {
         File file = tempFolder.newFile();
-        DataStore<Byte> dataStore =
+        RxDataStore<Byte> dataStore =
                 new RxDataStoreBuilder<Byte>(() -> file, new TestingSerializer())
                         .build();
-        Single<Byte> incrementByte = RxDataStore.updateDataAsync(dataStore,
+        Single<Byte> incrementByte = dataStore.updateDataAsync(
                 RxDataStoreBuilderTest::incrementByte);
         assertThat(incrementByte.blockingGet()).isEqualTo(1);
+        dataStore.dispose();
+        dataStore.shutdownComplete().blockingAwait();
+
         // Construct it again and confirm that the data is still there:
         dataStore =
                 new RxDataStoreBuilder<Byte>(() -> file, new TestingSerializer())
                         .build();
-        assertThat(RxDataStore.data(dataStore).blockingFirst()).isEqualTo(1);
+        assertThat(dataStore.data().blockingFirst()).isEqualTo(1);
     }
 
     @Test
     public void testConstructWithContextAndName() throws Exception {
         Context context = ApplicationProvider.getApplicationContext();
         String name = "my_data_store";
-        DataStore<Byte> dataStore =
+        RxDataStore<Byte> dataStore =
                 new RxDataStoreBuilder<Byte>(context, name, new TestingSerializer())
                         .build();
-        Single<Byte> set1 = RxDataStore.updateDataAsync(dataStore, input -> Single.just((byte) 1));
+        Single<Byte> set1 = dataStore.updateDataAsync(input -> Single.just((byte) 1));
         assertThat(set1.blockingGet()).isEqualTo(1);
+        dataStore.dispose();
+        dataStore.shutdownComplete().blockingAwait();
+
         // Construct it again and confirm that the data is still there:
         dataStore =
                 new RxDataStoreBuilder<Byte>(context, name, new TestingSerializer())
                         .build();
-        assertThat(RxDataStore.data(dataStore).blockingFirst()).isEqualTo(1);
+        assertThat(dataStore.data().blockingFirst()).isEqualTo(1);
+        dataStore.dispose();
+        dataStore.shutdownComplete().blockingAwait();
+
+
         // Construct it again with the expected file path and confirm that the data is there:
         dataStore =
                 new RxDataStoreBuilder<Byte>(() -> new File(context.getFilesDir().getPath()
                         + "/datastore/" + name), new TestingSerializer()
                 )
                         .build();
-        assertThat(RxDataStore.data(dataStore).blockingFirst()).isEqualTo(1);
+        assertThat(dataStore.data().blockingFirst()).isEqualTo(1);
     }
 
     @Test
@@ -106,12 +115,12 @@
             }
         };
 
-        DataStore<Byte> dataStore = new RxDataStoreBuilder<Byte>(
+        RxDataStore<Byte> dataStore = new RxDataStoreBuilder<Byte>(
                 () -> tempFolder.newFile(), new TestingSerializer())
                 .addRxDataMigration(plusOneMigration)
                 .build();
 
-        assertThat(RxDataStore.data(dataStore).blockingFirst()).isEqualTo(1);
+        assertThat(dataStore.data().blockingFirst()).isEqualTo(1);
     }
 
     @Test
@@ -125,17 +134,17 @@
                 }));
 
 
-        DataStore<Byte> dataStore = new RxDataStoreBuilder<Byte>(() -> tempFolder.newFile(),
+        RxDataStore<Byte> dataStore = new RxDataStoreBuilder<Byte>(() -> tempFolder.newFile(),
                 new TestingSerializer())
                 .setIoScheduler(singleThreadedScheduler)
                 .build();
-        Single<Byte> update = RxDataStore.updateDataAsync(dataStore, input -> {
+        Single<Byte> update = dataStore.updateDataAsync(input -> {
             Thread currentThread = Thread.currentThread();
             assertThat(currentThread.getName()).isEqualTo("TestingThread");
             return Single.just(input);
         });
         assertThat(update.blockingGet()).isEqualTo((byte) 0);
-        Single<Byte> subsequentUpdate = RxDataStore.updateDataAsync(dataStore, input -> {
+        Single<Byte> subsequentUpdate = dataStore.updateDataAsync(input -> {
             Thread currentThread = Thread.currentThread();
             assertThat(currentThread.getName()).isEqualTo("TestingThread");
             return Single.just(input);
@@ -151,11 +160,11 @@
                 new ReplaceFileCorruptionHandler<Byte>(exception -> (byte) 99);
 
 
-        DataStore<Byte> dataStore = new RxDataStoreBuilder<Byte>(
+        RxDataStore<Byte> dataStore = new RxDataStoreBuilder<Byte>(
                 () -> tempFolder.newFile(),
                 testingSerializer)
                 .setCorruptionHandler(replaceFileCorruptionHandler)
                 .build();
-        assertThat(RxDataStore.data(dataStore).blockingFirst()).isEqualTo(99);
+        assertThat(dataStore.data().blockingFirst()).isEqualTo(99);
     }
 }
diff --git a/datastore/datastore-rxjava2/src/androidTest/java/androidx/datastore/rxjava2/RxSharedPreferencesMigrationTest.java b/datastore/datastore-rxjava2/src/androidTest/java/androidx/datastore/rxjava2/RxSharedPreferencesMigrationTest.java
index c8e0b79..d97261b 100644
--- a/datastore/datastore-rxjava2/src/androidTest/java/androidx/datastore/rxjava2/RxSharedPreferencesMigrationTest.java
+++ b/datastore/datastore-rxjava2/src/androidTest/java/androidx/datastore/rxjava2/RxSharedPreferencesMigrationTest.java
@@ -24,7 +24,6 @@
 import android.content.SharedPreferences;
 
 import androidx.datastore.core.DataMigration;
-import androidx.datastore.core.DataStore;
 import androidx.datastore.migrations.SharedPreferencesView;
 import androidx.test.core.app.ApplicationProvider;
 
@@ -82,9 +81,9 @@
         DataMigration<Byte> spMigration =
                 getSpMigrationBuilder(skippedMigration).build();
 
-        DataStore<Byte> dataStoreWithMigrations = getDataStoreWithMigration(spMigration);
+        RxDataStore<Byte> dataStoreWithMigrations = getDataStoreWithMigration(spMigration);
 
-        assertThat(RxDataStore.data(dataStoreWithMigrations).blockingFirst()).isEqualTo(0);
+        assertThat(dataStoreWithMigrations.data().blockingFirst()).isEqualTo(0);
     }
 
     @Test
@@ -114,9 +113,9 @@
                         }
                 ).setKeysToMigrate(includedKey).build();
 
-        DataStore<Byte> byteStore = getDataStoreWithMigration(dataMigration);
+        RxDataStore<Byte> byteStore = getDataStoreWithMigration(dataMigration);
 
-        assertThat(RxDataStore.data(byteStore).blockingFirst()).isEqualTo(50);
+        assertThat(byteStore.data().blockingFirst()).isEqualTo(50);
 
         assertThat(mSharedPrefs.contains(includedKey)).isFalse();
         assertThat(mSharedPrefs.contains(notMigratedKey)).isTrue();
@@ -149,9 +148,9 @@
                         }
                 ).build();
 
-        DataStore<Byte> byteStore = getDataStoreWithMigration(dataMigration);
+        RxDataStore<Byte> byteStore = getDataStoreWithMigration(dataMigration);
 
-        assertThat(RxDataStore.data(byteStore).blockingFirst()).isEqualTo(50);
+        assertThat(byteStore.data().blockingFirst()).isEqualTo(50);
 
         assertThat(mSharedPrefs.contains(includedKey)).isFalse();
         assertThat(mSharedPrefs.contains(includedKey2)).isFalse();
@@ -166,8 +165,8 @@
         DataMigration<Byte> dataMigration =
                 getSpMigrationBuilder(new DefaultMigration()).setDeleteEmptyPreferences(
                         true).build();
-        DataStore<Byte> byteStore = getDataStoreWithMigration(dataMigration);
-        assertThat(RxDataStore.data(byteStore).blockingFirst()).isEqualTo(0);
+        RxDataStore<Byte> byteStore = getDataStoreWithMigration(dataMigration);
+        assertThat(byteStore.data().blockingFirst()).isEqualTo(0);
 
         // Check that the shared preferences files are deleted
         File prefsDir = new File(mContext.getApplicationInfo().dataDir, "shared_prefs");
@@ -183,7 +182,7 @@
                 rxSharedPreferencesMigration);
     }
 
-    private DataStore<Byte> getDataStoreWithMigration(DataMigration<Byte> dataMigration) {
+    private RxDataStore<Byte> getDataStoreWithMigration(DataMigration<Byte> dataMigration) {
         return new RxDataStoreBuilder<Byte>(() -> mDatastoreFile, new TestingSerializer())
                 .addDataMigration(dataMigration).build();
     }
diff --git a/datastore/datastore-rxjava2/src/main/java/androidx/datastore/rxjava2/RxDataStore.kt b/datastore/datastore-rxjava2/src/main/java/androidx/datastore/rxjava2/RxDataStore.kt
index 6f49f41..dfe8026 100644
--- a/datastore/datastore-rxjava2/src/main/java/androidx/datastore/rxjava2/RxDataStore.kt
+++ b/datastore/datastore-rxjava2/src/main/java/androidx/datastore/rxjava2/RxDataStore.kt
@@ -13,64 +13,115 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@file:JvmName("RxDataStore")
-
 package androidx.datastore.rxjava2
 
+import androidx.annotation.RestrictTo
 import androidx.datastore.core.DataStore
+import io.reactivex.Completable
 import io.reactivex.Flowable
 import io.reactivex.Single
+import io.reactivex.disposables.Disposable
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.async
 import kotlinx.coroutines.rx2.asFlowable
 import kotlinx.coroutines.rx2.asSingle
 import kotlinx.coroutines.rx2.await
 import io.reactivex.functions.Function
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.SupervisorJob
+import kotlinx.coroutines.job
+import kotlinx.coroutines.rx2.rxCompletable
 
 /**
- * Gets a reactivex.Flowable of the data from DataStore. See [DataStore.data] for more information.
- *
- * Provides efficient, cached (when possible) access to the latest durably persisted state.
- * The flow will always either emit a value or throw an exception encountered when attempting
- * to read from disk. If an exception is encountered, collecting again will attempt to read the
- * data again.
- *
- * Do not layer a cache on top of this API: it will be be impossible to guarantee consistency.
- * Instead, use data.first() to access a single snapshot.
- *
- * The Flowable will complete with an IOException when an exception is encountered when reading
- * data.
- *
- * @return a flow representing the current state of the data
+ * A DataStore that supports RxJava operations on DataStore.
  */
-@ExperimentalCoroutinesApi
-public fun <T : Any> DataStore<T>.data(): Flowable<T> {
-    return this.data.asFlowable()
-}
+public class RxDataStore<T : Any> private constructor(
+    /**
+     * The delegate DataStore.
+     */
+    private val delegateDs: DataStore<T>,
+    /**
+     * The CoroutineScope that the DataStore is created with. Must contain a Job to allow for
+     * cancellation.
+     */
+    private val scope: CoroutineScope
+) : Disposable {
 
-/**
- * See [DataStore.updateData]
- *
- * Updates the data transactionally in an atomic read-modify-write operation. All operations
- * are serialized, and the transform itself is a async so it can perform heavy work
- * such as RPCs.
- *
- * The Single completes when the data has been persisted durably to disk (after which
- * [data] will reflect the update). If the transform or write to disk fails, the
- * transaction is aborted and the returned Single is completed with the error.
- *
- * The transform will be run on the scheduler that DataStore was constructed with.
- *
- * @return the snapshot returned by the transform
- * @throws Exception when thrown by the transform function
- */
-@ExperimentalCoroutinesApi
-public fun <T : Any> DataStore<T>.updateDataAsync(transform: Function<T, Single<T>>): Single<T> {
-    return CoroutineScope(Dispatchers.Unconfined).async {
-        this@updateDataAsync.updateData {
-            transform.apply(it).await()
+    /**
+     * @hide for datastore-preferences-rxjava2 artifact only
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    companion object {
+        public fun <T : Any> create(delegateDs: DataStore<T>, scope: CoroutineScope):
+            RxDataStore<T> {
+                return RxDataStore<T>(delegateDs, scope)
+            }
+    }
+
+    /**
+     * Dispose of the DataStore. Wait for the Completable returned by [shutdownComplete] to
+     * confirm that the DataStore has been shut down.
+     */
+    override fun dispose() = scope.coroutineContext.job.cancel()
+
+    /**
+     * Returns whether this DataStore is closed
+     */
+    override fun isDisposed(): Boolean = scope.coroutineContext.job.isActive
+
+    /**
+     * Returns a completable that completes when the DataStore is completed. It is not safe to
+     * create a new DataStore with the same file name until this has completed.
+     */
+    public fun shutdownComplete(): Completable =
+        rxCompletable(scope.coroutineContext.minusKey(Job)) {
+            scope.coroutineContext.job.join()
         }
-    }.asSingle(Dispatchers.Unconfined)
+
+    /**
+     * Gets a reactivex.Flowable of the data from DataStore. See [DataStore.data] for more information.
+     *
+     * Provides efficient, cached (when possible) access to the latest durably persisted state.
+     * The flow will always either emit a value or throw an exception encountered when attempting
+     * to read from disk. If an exception is encountered, collecting again will attempt to read the
+     * data again.
+     *
+     * Do not layer a cache on top of this API: it will be be impossible to guarantee consistency.
+     * Instead, use data.first() to access a single snapshot.
+     *
+     * The Flowable will complete with an IOException when an exception is encountered when reading
+     * data.
+     *
+     * @return a flow representing the current state of the data
+     */
+    @ExperimentalCoroutinesApi
+    public fun data(): Flowable<T> {
+        return delegateDs.data.asFlowable(scope.coroutineContext)
+    }
+
+    /**
+     * See [DataStore.updateData]
+     *
+     * Updates the data transactionally in an atomic read-modify-write operation. All operations
+     * are serialized, and the transform itself is a async so it can perform heavy work
+     * such as RPCs.
+     *
+     * The Single completes when the data has been persisted durably to disk (after which
+     * [data] will reflect the update). If the transform or write to disk fails, the
+     * transaction is aborted and the returned Single is completed with the error.
+     *
+     * The transform will be run on the scheduler that DataStore was constructed with.
+     *
+     * @return the snapshot returned by the transform
+     * @throws Exception when thrown by the transform function
+     */
+    @ExperimentalCoroutinesApi
+    public fun updateDataAsync(transform: Function<T, Single<T>>): Single<T> {
+        return scope.async(SupervisorJob()) {
+            delegateDs.updateData {
+                transform.apply(it).await()
+            }
+        }.asSingle(scope.coroutineContext.minusKey(Job))
+    }
 }
diff --git a/datastore/datastore-rxjava2/src/main/java/androidx/datastore/rxjava2/RxDataStoreBuilder.kt b/datastore/datastore-rxjava2/src/main/java/androidx/datastore/rxjava2/RxDataStoreBuilder.kt
index 43b1fcc..ab51853 100644
--- a/datastore/datastore-rxjava2/src/main/java/androidx/datastore/rxjava2/RxDataStoreBuilder.kt
+++ b/datastore/datastore-rxjava2/src/main/java/androidx/datastore/rxjava2/RxDataStoreBuilder.kt
@@ -19,7 +19,6 @@
 import android.annotation.SuppressLint
 import android.content.Context
 import androidx.datastore.core.DataMigration
-import androidx.datastore.core.DataStore
 import androidx.datastore.core.DataStoreFactory
 import androidx.datastore.core.Serializer
 import androidx.datastore.createDataStore
@@ -27,16 +26,17 @@
 import io.reactivex.Scheduler
 import io.reactivex.schedulers.Schedulers
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
 import kotlinx.coroutines.rx2.asCoroutineDispatcher
 import kotlinx.coroutines.rx2.await
 import java.io.File
 import java.util.concurrent.Callable
 
 /**
- * RxSharedPreferencesMigrationBuilder class for a DataStore that works on a single process.
+ * RxDataStoreBuilder class for a DataStore that works on a single process.
  */
 @SuppressLint("TopLevelBuilder")
-public class RxDataStoreBuilder<T> {
+public class RxDataStoreBuilder<T : Any> {
 
     /**
      * Create a RxDataStoreBuilder with the callable which returns the File that DataStore acts on.
@@ -139,21 +139,19 @@
      *
      * @return the DataStore with the provided parameters
      */
-    public fun build(): DataStore<T> {
-        val scope = CoroutineScope(ioScheduler.asCoroutineDispatcher())
+    public fun build(): RxDataStore<T> {
+        val scope = CoroutineScope(ioScheduler.asCoroutineDispatcher() + Job())
 
-        return if (produceFile != null) {
+        val delegateDs = if (produceFile != null) {
             DataStoreFactory.create(
                 produceFile = { produceFile!!.call() },
                 serializer = serializer!!,
-                scope = CoroutineScope(
-                    ioScheduler.asCoroutineDispatcher()
-                ),
+                scope = scope,
                 corruptionHandler = corruptionHandler,
                 migrations = dataMigrations
             )
         } else if (context != null && name != null) {
-            return context!!.createDataStore(
+            context!!.createDataStore(
                 fileName = name!!,
                 serializer = serializer!!,
                 scope = scope,
@@ -161,10 +159,10 @@
                 migrations = dataMigrations
             )
         } else {
-            error(
-                "Either produceFile or context and name must be set. This should never happen."
-            )
+            error("Either produceFile or context and name must be set. This should never happen.")
         }
+
+        return RxDataStore.create(delegateDs, scope)
     }
 }
 
diff --git a/datastore/datastore-rxjava2/src/test/java/androidx/datastore/rxjava2/RxDataStoreTest.java b/datastore/datastore-rxjava2/src/test/java/androidx/datastore/rxjava2/RxDataStoreTest.java
index 992d3648..d66267f 100644
--- a/datastore/datastore-rxjava2/src/test/java/androidx/datastore/rxjava2/RxDataStoreTest.java
+++ b/datastore/datastore-rxjava2/src/test/java/androidx/datastore/rxjava2/RxDataStoreTest.java
@@ -18,22 +18,18 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import androidx.datastore.core.DataStore;
-import androidx.datastore.core.DataStoreFactory;
-
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 
 import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
+import java.util.concurrent.CancellationException;
 import java.util.concurrent.TimeUnit;
 
 import io.reactivex.Single;
+import io.reactivex.observers.TestObserver;
 import io.reactivex.subscribers.TestSubscriber;
-import kotlinx.coroutines.CoroutineScopeKt;
-import kotlinx.coroutines.Dispatchers;
 
 public class RxDataStoreTest {
     @Rule
@@ -47,22 +43,19 @@
     public void testGetSingleValue() throws Exception {
         File newFile = tempFolder.newFile();
 
-        DataStore<Byte> byteStore = DataStoreFactory.INSTANCE.create(
-                new TestingSerializer(),
-                null,
-                new ArrayList<>(),
-                CoroutineScopeKt.CoroutineScope(Dispatchers.getIO()),
-                () -> newFile);
+        RxDataStore<Byte> byteStore =
+                new RxDataStoreBuilder<Byte>(() -> newFile, new TestingSerializer()).build();
 
-        Byte firstByte = RxDataStore.data(byteStore).blockingFirst();
+
+        Byte firstByte = byteStore.data().blockingFirst();
         assertThat(firstByte).isEqualTo(0);
 
-        Single<Byte> incrementByte = RxDataStore.updateDataAsync(byteStore,
+        Single<Byte> incrementByte = byteStore.updateDataAsync(
                 RxDataStoreTest::incrementByte);
 
         assertThat(incrementByte.blockingGet()).isEqualTo(1);
 
-        firstByte = RxDataStore.data(byteStore).blockingFirst();
+        firstByte = byteStore.data().blockingFirst();
         assertThat(firstByte).isEqualTo(1);
     }
 
@@ -70,17 +63,14 @@
     public void testTake3() throws Exception {
         File newFile = tempFolder.newFile();
 
-        DataStore<Byte> byteStore = DataStoreFactory.INSTANCE.create(
-                new TestingSerializer(),
-                null,
-                new ArrayList<>(),
-                CoroutineScopeKt.CoroutineScope(Dispatchers.getIO()),
-                () -> newFile);
+        RxDataStore<Byte> byteStore =
+                new RxDataStoreBuilder<Byte>(() -> newFile, new TestingSerializer())
+                        .build();
 
-        TestSubscriber<Byte> testSubscriber = RxDataStore.data(byteStore).test();
+        TestSubscriber<Byte> testSubscriber = byteStore.data().test();
 
-        RxDataStore.updateDataAsync(byteStore, RxDataStoreTest::incrementByte);
-        RxDataStore.updateDataAsync(byteStore, RxDataStoreTest::incrementByte);
+        byteStore.updateDataAsync(RxDataStoreTest::incrementByte);
+        byteStore.updateDataAsync(RxDataStoreTest::incrementByte);
 
         testSubscriber.awaitCount(3).assertValues((byte) 0, (byte) 1, (byte) 2);
     }
@@ -91,16 +81,13 @@
         File newFile = tempFolder.newFile();
         TestingSerializer testingSerializer = new TestingSerializer();
 
-        DataStore<Byte> byteStore = DataStoreFactory.INSTANCE.create(
-                testingSerializer,
-                null,
-                new ArrayList<>(),
-                CoroutineScopeKt.CoroutineScope(Dispatchers.getIO()),
-                () -> newFile);
+        RxDataStore<Byte> byteStore =
+                new RxDataStoreBuilder<Byte>(() -> newFile, testingSerializer).build();
+
 
         testingSerializer.setFailingRead(true);
 
-        TestSubscriber<Byte> testSubscriber = RxDataStore.data(byteStore).test();
+        TestSubscriber<Byte> testSubscriber = byteStore.data().test();
 
         assertThat(testSubscriber.awaitTerminalEvent(5, TimeUnit.SECONDS)).isTrue();
 
@@ -108,7 +95,7 @@
 
         testingSerializer.setFailingRead(false);
 
-        testSubscriber = RxDataStore.data(byteStore).test();
+        testSubscriber = byteStore.data().test();
         testSubscriber.awaitCount(1).assertValues((byte) 0);
     }
 
@@ -117,28 +104,63 @@
         File newFile = tempFolder.newFile();
         TestingSerializer testingSerializer = new TestingSerializer();
 
-        DataStore<Byte> byteStore = DataStoreFactory.INSTANCE.create(
-                testingSerializer,
-                null,
-                new ArrayList<>(),
-                CoroutineScopeKt.CoroutineScope(Dispatchers.getIO()),
-                () -> newFile);
+        RxDataStore<Byte> byteStore =
+                new RxDataStoreBuilder<Byte>(() -> newFile, testingSerializer).build();
 
-        TestSubscriber<Byte> testSubscriber = RxDataStore.data(byteStore).test();
+        TestSubscriber<Byte> testSubscriber = byteStore.data().test();
 
         testingSerializer.setFailingWrite(true);
-        Single<Byte> incrementByte = RxDataStore.updateDataAsync(byteStore,
-                RxDataStoreTest::incrementByte);
+        Single<Byte> incrementByte = byteStore.updateDataAsync(RxDataStoreTest::incrementByte);
 
         incrementByte.cache().test().await().assertError(IOException.class);
 
         testSubscriber.awaitCount(1).assertNoErrors().assertValues((byte) 0);
         testingSerializer.setFailingWrite(false);
 
-        Single<Byte> incrementByte2 = RxDataStore.updateDataAsync(byteStore,
-                RxDataStoreTest::incrementByte);
+        Single<Byte> incrementByte2 = byteStore.updateDataAsync(RxDataStoreTest::incrementByte);
         assertThat(incrementByte2.blockingGet()).isEqualTo((byte) 1);
 
         testSubscriber.awaitCount(2).assertValues((byte) 0, (byte) 1);
     }
+
+    @Test
+    public void canCloseDataStore() throws Exception {
+        File newFile = tempFolder.newFile();
+        TestingSerializer testingSerializer = new TestingSerializer();
+
+        RxDataStore<Byte> byteRxDataStore = new RxDataStoreBuilder<Byte>(() -> newFile,
+                testingSerializer).build();
+
+        assertThat(byteRxDataStore.data().blockingFirst()).isEqualTo((byte) 0);
+
+        byteRxDataStore.dispose();
+        byteRxDataStore.shutdownComplete().blockingAwait();
+
+
+        TestSubscriber<Byte> testSubscriber = byteRxDataStore.data().test();
+
+        assertThat(testSubscriber.awaitTerminalEvent()).isTrue();
+        testSubscriber.assertTerminated()
+                // Note(rohitsat): this is different from coroutines bc asFlowable converts the
+                // CancellationException to onComplete.
+                .assertNoErrors()
+                .assertComplete()
+                .assertValueCount(0);
+
+
+        // NOTE(rohitsat): this is different from data()
+        TestObserver<Byte> testObserver = byteRxDataStore.updateDataAsync(Single::just).test();
+        testObserver.awaitTerminalEvent();
+
+        testObserver.assertTerminated()
+                .assertError(CancellationException.class)
+                .assertNoValues();
+
+
+        RxDataStore<Byte> byteRxDataStore2 = new RxDataStoreBuilder<Byte>(() -> newFile,
+                testingSerializer).build();
+
+        // Should not throw
+        assertThat(byteRxDataStore2.data().blockingFirst()).isEqualTo((byte) 0);
+    }
 }
diff --git a/datastore/datastore-rxjava3/src/main/java/androidx/datastore/rxjava3/RxDataStoreBuilder.kt b/datastore/datastore-rxjava3/src/main/java/androidx/datastore/rxjava3/RxDataStoreBuilder.kt
index e24ac29..7823ba3 100644
--- a/datastore/datastore-rxjava3/src/main/java/androidx/datastore/rxjava3/RxDataStoreBuilder.kt
+++ b/datastore/datastore-rxjava3/src/main/java/androidx/datastore/rxjava3/RxDataStoreBuilder.kt
@@ -33,7 +33,7 @@
 import java.util.concurrent.Callable
 
 /**
- * RxSharedPreferencesMigrationBuilder class for a DataStore that works on a single process.
+ * Builder for an RxDataStore that works on a single process.
  */
 @SuppressLint("TopLevelBuilder")
 public class RxDataStoreBuilder<T> {
diff --git a/datastore/datastore-sampleapp/build.gradle b/datastore/datastore-sampleapp/build.gradle
index 8c521df..5e6e422 100644
--- a/datastore/datastore-sampleapp/build.gradle
+++ b/datastore/datastore-sampleapp/build.gradle
@@ -40,7 +40,7 @@
     implementation(PROTOBUF_LITE)
     implementation(KOTLIN_STDLIB)
     implementation("androidx.appcompat:appcompat:1.2.0")
-    implementation("androidx.activity:activity-ktx:1.2.0-rc01")
+    implementation("androidx.activity:activity-ktx:1.2.0")
 
     // For settings fragment
     implementation("androidx.preference:preference:1.1.1")
diff --git a/development/build_log_processor.sh b/development/build_log_processor.sh
index 58cc023..ccfd33e 100755
--- a/development/build_log_processor.sh
+++ b/development/build_log_processor.sh
@@ -93,18 +93,20 @@
     fi
   fi
 else
-  echo >&2
-  echo "############################################################################" >&2
-  echo "Attempting to locate the relevant error messages via build_log_simplifier.py" >&2
-  echo "############################################################################" >&2
-  echo >&2
-  # Try to identify the most relevant lines of output, and put them at the bottom of the
-  # output where they will also be placed into the build failure email.
-  # TODO: We may be able to stop cleaning up Gradle's output after Gradle can do this on its own:
-  # https://github.com/gradle/gradle/issues/1005
-  # and https://github.com/gradle/gradle/issues/13090
-  summaryLog="$LOG_DIR/error_summary.log"
-  $SCRIPT_PATH/build_log_simplifier.py $logFile | tee "$summaryLog" >&2
+  if [ "$summarizeOnFailure" == "true" ]; then
+    echo >&2
+    echo "############################################################################" >&2
+    echo "Attempting to locate the relevant error messages via build_log_simplifier.py" >&2
+    echo "############################################################################" >&2
+    echo >&2
+    # Try to identify the most relevant lines of output, and put them at the bottom of the
+    # output where they will also be placed into the build failure email.
+    # TODO: We may be able to stop cleaning up Gradle's output after Gradle can do this on its own:
+    # https://github.com/gradle/gradle/issues/1005
+    # and https://github.com/gradle/gradle/issues/13090
+    summaryLog="$LOG_DIR/error_summary.log"
+    $SCRIPT_PATH/build_log_simplifier.py $logFile | tee "$summaryLog" >&2
+  fi
   exit 1
 fi
 
diff --git a/development/build_log_simplifier/gc.sh b/development/build_log_simplifier/gc.sh
index 5e34af4..4eaef24 100755
--- a/development/build_log_simplifier/gc.sh
+++ b/development/build_log_simplifier/gc.sh
@@ -53,7 +53,7 @@
 BUILD_SCRIPTS_DIR="$SUPPORT_ROOT/busytown"
 
 # find the .sh files that enable build log validation
-target_scripts="$(cd $BUILD_SCRIPTS_DIR && find -name "*.sh" -type f | xargs grep -l androidx.validateNoUnrecognizedMessages | sed 's|^./||')"
+target_scripts="$(cd $BUILD_SCRIPTS_DIR && find -name "*.sh" -type f | xargs grep -l "impl/build.sh" | sed 's|^./||')"
 
 # find the target names that enable build log validation
 targets="$(echo $target_scripts | sed 's/\.sh//g')"
diff --git a/development/build_log_simplifier/message-flakes.ignore b/development/build_log_simplifier/message-flakes.ignore
index dea9966..12395f5 100644
--- a/development/build_log_simplifier/message-flakes.ignore
+++ b/development/build_log_simplifier/message-flakes.ignore
@@ -18,3 +18,13 @@
 # > Task :compose:compiler:compiler-hosted:integration-tests:testDebugUnitTest
 # If a test fails, we don't want the build to fail, we want to pass the test output to the tests server and for the tests server to report the failure
 [0-9]+ test.*failed.*
+# Some status messages
+Starting a Gradle Daemon, [0-9]+ busy and [0-9]+ incompatible Daemons could not be reused, use \-\-status for details
+Starting a Gradle Daemon, [0-9]+ busy and [0-9]+ incompatible and [0-9]+ stopped Daemons could not be reused, use \-\-status for details
+Remote build cache is disabled when running with \-\-offline\.
+[0-9]+ actionable tasks: [0-9]+ up\-to\-date
+[0-9]+ actionable tasks: [0-9]+ executed
+[0-9]+ actionable tasks: [0-9]+ executed, [0-9]+ from cache, [0-9]+ up\-to\-date
+# Some messages that encode the number of a certain type of other error
+[0-9]+ errors, [0-9]+ warnings \([0-9]+ warnings filtered by baseline lint\-baseline\.xml\)
+[0-9]+ errors, [0-9]+ warnings \([0-9]+ warning filtered by baseline lint\-baseline\.xml\)
diff --git a/development/build_log_simplifier/messages.ignore b/development/build_log_simplifier/messages.ignore
index 33e76a2..60b7547 100644
--- a/development/build_log_simplifier/messages.ignore
+++ b/development/build_log_simplifier/messages.ignore
@@ -1,4 +1,4 @@
-ould not perform incremental compilation: Could not connect to Kot# This file is a list of regexes of messages that are expected to appear in stdout/stderr.
+# This file is a list of regexes of messages that are expected to appear in stdout/stderr.
 # Comments and blank lines are ignored.
 # Before adding a suppression to this file, please attempt to suppress the output inside the generating tool instead.
 # Messages that only sometimes appear in stdout/stderr should be exempted in message-flakes.ignore, because this file (messages.ignore) may be automatically garbage collected whereas that one will not be.
@@ -164,7 +164,6 @@
 at org\.jetbrains\.dokka\.Formats\.DevsiteLayoutHtmlFormatOutputBuilder\$fullMemberDocs\$[0-9]+\$[0-9]+\$[0-9]+\$\$special\$\$inlined\$forEach\$lambda\$[0-9]+\.invoke\(DacHtmlFormat\.kt:[0-9]+\)
 at org\.jetbrains\.dokka\.Formats\.DevsiteLayoutHtmlFormatOutputBuilder\$fullMemberDocs\$[0-9]+\$[0-9]+\$[0-9]+\.invoke\(DacHtmlFormat\.kt:[0-9]+\)
 at org\.jetbrains\.dokka\.Formats\.DevsiteLayoutHtmlFormatOutputBuilder\$fullMemberDocs\$[0-9]+\$[0-9]+\.invoke\(DacHtmlFormat\.kt:[0-9]+\)
-Exception while resolving link to Module: Package:androidx\.compose\.animation\.core Class:TransitionSpec Function:using Receiver:<this>
 at org\.jetbrains\.dokka\.Formats\.DevsiteLayoutHtmlFormatOutputBuilder\$summaryNodeGroupForExtensions\$[0-9]+\$\$special\$\$inlined\$forEach\$lambda\$[0-9]+\$[0-9]+\$[0-9]+\.invoke\(DacHtmlFormat\.kt:[0-9]+\)
 at org\.jetbrains\.dokka\.Formats\.DevsiteLayoutHtmlFormatOutputBuilder\$summaryNodeGroupForExtensions\$[0-9]+\$\$special\$\$inlined\$forEach\$lambda\$[0-9]+\$[0-9]+\.invoke\(DacHtmlFormat\.kt:[0-9]+\)
 at org\.jetbrains\.dokka\.Formats\.DevsiteLayoutHtmlFormatOutputBuilder\$summaryNodeGroupForExtensions\$[0-9]+\$\$special\$\$inlined\$forEach\$lambda\$[0-9]+\.invoke\(DacHtmlFormat\.kt:[0-9]+\)
@@ -196,7 +195,6 @@
 Exception while resolving link to Module: Package:androidx\.compose\.ui\.graphics GroupNode:NativeCanvas
 at kotlinx\.html\.Gen_tag_groupsKt\.pre\(gen\-tag\-groups\.kt:[0-9]+\)
 Exception while resolving link to Module: Package:androidx\.compose\.ui\.graphics GroupNode:NativePaint
-Exception while resolving link to Module: Package:androidx\.compose\.ui\.graphics GroupNode:NativePathEffect
 at org\.jetbrains\.dokka\.Formats\.JavaLayoutHtmlFormatOutputBuilder\$propertyLikeSummaryRow\$[0-9]+\$[0-9]+\.invoke\(JavaLayoutHtmlFormatOutputBuilder\.kt:[0-9]+\)
 at org\.jetbrains\.dokka\.Formats\.JavaLayoutHtmlFormatOutputBuilder\$propertyLikeSummaryRow\$[0-9]+\.invoke\(JavaLayoutHtmlFormatOutputBuilder\.kt:[0-9]+\)
 at org\.jetbrains\.dokka\.Formats\.JavaLayoutHtmlFormatOutputBuilder\.propertyLikeSummaryRow\(JavaLayoutHtmlFormatOutputBuilder\.kt:[0-9]+\)
@@ -216,39 +214,23 @@
 DIST_DIR=\$DIST_DIR
 CHECKOUT=\$CHECKOUT
 GRADLE_USER_HOME=\$GRADLE_USER_HOME
-Starting a Gradle Daemon, [0-9]+ busy and [0-9]+ incompatible Daemons could not be reused, use \-\-status for details
-Starting a Gradle Daemon, [0-9]+ busy and [0-9]+ incompatible and [0-9]+ stopped Daemons could not be reused, use \-\-status for details
 Downloading file\:\$SUPPORT\/gradle\/wrapper\/\.\.\/\.\.\/\.\.\/\.\.\/tools\/external\/gradle\/gradle\-[0-9]+\.[0-9]+\.[0-9]+\-bin\.zip
 \.\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.[0-9]+%
-Downloading file:\$SUPPORT/gradle/wrapper/\.\./\.\./\.\./\.\./tools/external/gradle/gradle\-[0-9]+\.[0-9]+\-bin\.zip
-\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.[0-9]+%\.\.\.\.\.\.\.\.\.\.[0-9]+%
 Welcome to Gradle [0-9]+\.[0-9]+\.[0-9]+\!
-Welcome to Gradle [0-9]+\.[0-9]+!
 Here are the highlights of this release:
 \- Faster Kotlin DSL script compilation
 \- Vendor selection for Java toolchains
 \- Convenient execution of tasks in composite builds
 \- Consistent dependency resolution
-\- File system watching is ready for production use
-\- Declare the version of Java your build requires
-\- Java [0-9]+ support
 For more details see https\:\/\/docs\.gradle\.org\/[0-9]+\.[0-9]+\.[0-9]+\/release\-notes\.html
 To honour the JVM settings for this build a single\-use Daemon process will be forked\. See https://docs\.gradle\.org/[0-9]+\.[0-9]+\.[0-9]+/userguide/gradle_daemon\.html\#sec:disabling_the_daemon\.
 Daemon will be stopped at the end of the build
-Remote build cache is disabled when running with \-\-offline\.
-To honour the JVM settings for this build a new JVM will be forked\. Please consider using the daemon\: https\:\/\/docs\.gradle\.org\/[0-9]+\.[0-9]+\.[0-9]+\/userguide\/gradle_daemon\.html\.
-For more details see https://docs\.gradle\.org/[0-9]+\.[0-9]+/release\-notes\.html
-To honour the JVM settings for this build a new JVM will be forked\. Please consider using the daemon: https://docs\.gradle\.org/[0-9]+\.[0-9]+/userguide/gradle_daemon\.html\.
-Daemon will be stopped at the end of the build stopping after processing
 # > Task :buildSrc:build
 # > Configure project :appsearch:appsearch\-local\-backend
-WARNING: NDK was located by using ndk\.dir property\. This method is deprecated and will be removed in a future release\. Please use android\.ndkVersion or android\.ndkPath in build\.gradle to specify the NDK to use\. https://developer\.android\.com/r/studio\-ui/ndk\-dir
-NDK was located by using ndk\.dir property\. This method is deprecated and will be removed in a future release\. Please use android\.ndkVersion or android\.ndkPath in build\.gradle to specify the NDK to use\. https://developer\.android\.com/r/studio\-ui/ndk\-dir
 Configuration on demand is an incubating feature\.
 # > Configure project :
 updated local\.properties
 # > Configure project :compose:test\-utils
-Kotlin Multiplatform Projects are an Alpha feature\.
 The following Kotlin source sets were configured but not added to any Kotlin compilation:
 \* androidAndroidTestRelease
 \* androidTestRelease
@@ -261,11 +243,7 @@
 Deprecated Gradle features were used in this build, making it incompatible with Gradle [0-9]+\.[0-9]+\.
 Use '\-\-warning\-mode all' to show the individual deprecation warnings\.
 See https\:\/\/docs\.gradle\.org\/[0-9]+\.[0-9]+\.[0-9]+\/userguide\/command_line_interface\.html\#sec\:command_line_warnings
-See https://docs\.gradle\.org/[0-9]+\.[0-9]+/userguide/command_line_interface\.html\#sec:command_line_warnings
 BUILD SUCCESSFUL in .*
-[0-9]+ actionable tasks: [0-9]+ up\-to\-date
-[0-9]+ actionable tasks: [0-9]+ executed
-[0-9]+ actionable tasks: [0-9]+ executed, [0-9]+ from cache, [0-9]+ up\-to\-date
 [0-9]+ actionable task: [0-9]+ executed
 # > Task :doclava:compileJava
 Note\: Some input files use or override a deprecated API\.
@@ -278,12 +256,6 @@
 # > Task :tracing:tracing:compileDebugAndroidTestJavaWithJavac
 # > Task :ui:ui-tooling:processDebugAndroidTestManifest
 application@android:debuggable was tagged at manifestMerger[0-9]+\.xml:[0-9]+ to replace other declarations but no other declaration present
-# > Task :generateSdkApi
-javadoc: warning \- The old Doclet and Taglet APIs in the packages
-com\.sun\.javadoc, com\.sun\.tools\.doclets and their implementations
-are planned to be removed in a future JDK release\. These
-components have been superseded by the new APIs in jdk\.javadoc\.doclet\.
-Users are strongly recommended to migrate to the new APIs\.
 # > Task :compose:foundation:foundation-layout:processDebugAndroidTestManifest
 \$OUT_DIR/androidx/compose/foundation/foundation\-layout/build/intermediates/tmp/manifest/androidTest/debug/manifestMerger[0-9]+\.xml:[0-9]+:[0-9]+\-[0-9]+:[0-9]+ Warning:
 # > Task :compose:integration-tests:benchmark:processReleaseAndroidTestManifest
@@ -304,42 +276,12 @@
 \$CHECKOUT/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin\-stdlib/[0-9]+\.[0-9]+\.[0-9]+/kotlin\-stdlib\-[0-9]+\.[0-9]+\.[0-9]+\.jar \(version [0-9]+\.[0-9]+\)
 \$CHECKOUT/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin\-stdlib\-common/[0-9]+\.[0-9]+\.[0-9]+/kotlin\-stdlib\-common\-[0-9]+\.[0-9]+\.[0-9]+\.jar \(version [0-9]+\.[0-9]+\)
 w: Some runtime JAR files in the classpath have an incompatible version\. Consider removing them from the classpath
-w: \$SUPPORT/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/TransformOrigin\.kt: \([0-9]+, [0-9]+\): The feature "inline classes" is experimental
-w: \$SUPPORT/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/VectorAssetBuilder\.kt: \([0-9]+, [0-9]+\): The feature "inline classes" is experimental
 w: \$SUPPORT/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/key/Key\.kt: \([0-9]+, [0-9]+\): The feature "inline classes" is experimental
 w: \$SUPPORT/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Measured\.kt: \([0-9]+, [0-9]+\): The feature "inline classes" is experimental
 w: \$SUPPORT/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DepthSortedSet\.kt: \([0-9]+, [0-9]+\): The corresponding parameter in the supertype 'Comparator' is named 'a'\. This may cause problems when calling this function with named arguments\.
 w: \$SUPPORT/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DepthSortedSet\.kt: \([0-9]+, [0-9]+\): The corresponding parameter in the supertype 'Comparator' is named 'b'\. This may cause problems when calling this function with named arguments\.
 # > Task :benchmark:benchmark-common:runErrorProne
 \^
-cast to Object for a varargs call
-cast to Object\[\] for a non\-varargs call and to suppress this warning
-\$SUPPORT\/lint\-checks\/src\/main\/java\/androidx\/build\/lint\/BanInappropriateExperimentalUsage\.kt\:[0-9]+\: Warning\: \"RequiresOptIn\" looks like a code reference\; surround with backtics in string to display as symbol\, e\.g\. \`RequiresOptIn\` \[LintImplTextFormat\]
-\"\@RequiresOptIn and \@Experimental APIs are considered alpha\, and we do not allow \" \+
-\~\~\~\~\~\~\~\~\~\~\~\~\~
-Explanation for issues of type \"LintImplTextFormat\"\:
-Lint supports various markdown like formatting directives in all of its
-strings \(issue explanations\, reported error messages\, etc\)\.
-This lint check looks for strings that look like they may benefit from
-additional formatting\. For example\, if a snippet looks like code it should
-be surrounded with backticks\.
-Note\: Be careful changing existing strings\; this may stop baseline file
-matching from working\, so consider suppressing existing violations of this
-check if this is an error many users may be filtering in baselines\. \(This
-is only an issue for strings used in report calls\; for issue registration
-strings like summaries and explanations there\'s no risk changing the text
-contents\.\)
-[0-9]+ warning
-# > Task :compose:runtime:runtime:generateApi
-src/commonMain/kotlin/androidx/compose/runtime/Composer\.kt:[0-9]+: warning: Field ComposerKt\.ambientMap references hidden type androidx\.compose\.runtime\.OpaqueKey\. \[HiddenTypeParameter\]
-src/commonMain/kotlin/androidx/compose/runtime/Composer\.kt:[0-9]+: warning: Field ComposerKt\.invocation references hidden type androidx\.compose\.runtime\.OpaqueKey\. \[HiddenTypeParameter\]
-src/commonMain/kotlin/androidx/compose/runtime/Composer\.kt:[0-9]+: warning: Field ComposerKt\.provider references hidden type androidx\.compose\.runtime\.OpaqueKey\. \[HiddenTypeParameter\]
-src/commonMain/kotlin/androidx/compose/runtime/Composer\.kt:[0-9]+: warning: Field ComposerKt\.providerMaps references hidden type androidx\.compose\.runtime\.OpaqueKey\. \[HiddenTypeParameter\]
-src/commonMain/kotlin/androidx/compose/runtime/Composer\.kt:[0-9]+: warning: Field ComposerKt\.providerValues references hidden type androidx\.compose\.runtime\.OpaqueKey\. \[HiddenTypeParameter\]
-src/commonMain/kotlin/androidx/compose/runtime/Composer\.kt:[0-9]+: warning: Field ComposerKt\.reference references hidden type androidx\.compose\.runtime\.OpaqueKey\. \[HiddenTypeParameter\]
-# > Task :compose:foundation:foundation-layout:generateApi
-src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl\.kt:[0-9]+: warning: Parameter orientation references hidden type androidx\.compose\.foundation\.layout\.LayoutOrientation\. \[HiddenTypeParameter\]
-src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl\.kt:[0-9]+: warning: Parameter crossAxisAlignment references hidden type androidx\.compose\.foundation\.layout\.CrossAxisAlignment\. \[HiddenTypeParameter\]
 # > Task :buildOnServer
 [0-9]+ actionable tasks: [0-9]+ executed, [0-9]+ up\-to\-date
 [0-9]+ actionable tasks: [0-9]+ executed, [0-9]+ from cache
@@ -390,7 +332,6 @@
 # > Task :camera:integration-tests:camera-testapp-core:compileDebugJavaWithJavac
 # > Task :room:integration-tests:room-testapp:processDebugMainManifest
 \[androidx\.vectordrawable:vectordrawable\-animated:[0-9]+\.[0-9]+\.[0-9]+\] \$GRADLE_USER_HOME/caches/transforms\-[0-9]+/[0-9a-f]{32}/transformed/vectordrawable\-animated\-[0-9]+\.[0-9]+\.[0-9]+/AndroidManifest\.xml Warning:
-\[androidx\.vectordrawable:vectordrawable\-animated:[0-9]+\.[0-9]+\.[0-9]+\] \$GRADLE_USER_HOME/caches/transforms\-[0-9]+/files\-[0-9]+\.[0-9]+/[0-9a-f]{32}/vectordrawable\-animated\-[0-9]+\.[0-9]+\.[0-9]+/AndroidManifest\.xml Warning:
 Package name 'androidx\.vectordrawable' used in: androidx\.vectordrawable:vectordrawable\-animated:[0-9]+\.[0-9]+\.[0-9]+, androidx\.vectordrawable:vectordrawable:[0-9]+\.[0-9]+\.[0-9]+\.
 # > Task :lifecycle:integration-tests:lifecycle-testapp:compileDebugJavaWithJavac
 # > Task :support-slices-demos:compileDebugJavaWithJavac
@@ -404,15 +345,6 @@
 # > Task :internal-testutils-runtime:processDebugAndroidTestManifest
 # > Task :slice-benchmark:processReleaseAndroidTestManifest
 \$OUT_DIR/androidx/slice\-benchmark/build/intermediates/tmp/manifest/androidTest/release/manifestMerger[0-9]+\.xml:[0-9]+:[0-9]+\-[0-9]+:[0-9]+ Warning:
-# > Task :slice-builders-ktx:processDebugAndroidTestManifest
-# > Task :slice-core:processDebugAndroidTestManifest
-# > Task :slice-remotecallback:processDebugAndroidTestManifest
-# > Task :slice-view:processDebugAndroidTestManifest
-# > Task :slice-benchmark:compileReleaseAndroidTestJavaWithJavac
-# > Task :support-media2-test-service:compileDebugAndroidTestJavaWithJavac
-Note: \$SUPPORT/media[0-9]+/session/version\-compat\-tests/current/service/src/androidTest/java/androidx/media[0-9]+/test/service/MockPlayer\.java uses unchecked or unsafe operations\.
-# > Task :support-media2-test-service-previous:compileDebugAndroidTestJavaWithJavac
-Note: \$SUPPORT/media[0-9]+/session/version\-compat\-tests/previous/service/src/androidTest/java/androidx/media[0-9]+/test/service/MockPlayer\.java uses unchecked or unsafe operations\.
 # > Task :activity:activity:processDebugAndroidTestManifest
 # > Task :appcompat:appcompat:processDebugAndroidTestManifest
 Package name 'androidx\.testutils' used in: :internal\-testutils\-appcompat, :internal\-testutils\-runtime\.
@@ -429,16 +361,6 @@
 Build testing_surface_format_.*
 # > Task :collection:collection-benchmark:processReleaseAndroidTestManifest
 \$OUT_DIR/androidx/collection/collection\-benchmark/build/intermediates/tmp/manifest/androidTest/release/manifestMerger[0-9]+\.xml:[0-9]+:[0-9]+\-[0-9]+:[0-9]+ Warning:
-# > Task :camera:camera-extensions:compileDebugAndroidTestJavaWithJavac
-Note: \$SUPPORT/camera/camera\-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderTest\.java uses unchecked or unsafe operations\.
-# > Task :customview:customview:processDebugAndroidTestManifest
-# > Task :core:core-ktx:processDebugAndroidTestManifest
-# > Task :appsearch:appsearch:processDebugAndroidTestManifest
-# > Task :customview:customview:compileDebugAndroidTestJavaWithJavac
-# > Task :core:core:compileDebugAndroidTestJavaWithJavac
-Note: \$SUPPORT/core/core/src/androidTest/java/androidx/core/content/pm/ShortcutManagerCompatTest\.java uses unchecked or unsafe operations\.
-# > Task :exifinterface:exifinterface:compileDebugAndroidTestJavaWithJavac
-Note: \$SUPPORT/exifinterface/exifinterface/src/androidTest/java/androidx/exifinterface/media/ExifInterfaceTest\.java uses unchecked or unsafe operations\.
 # > Task :gridlayout:gridlayout:compileDebugAndroidTestJavaWithJavac
 # > Task :leanback:leanback:processDebugAndroidTestManifest
 Package name 'androidx\.testutils' used in: :internal\-testutils\-runtime, :internal\-testutils\-espresso\.
@@ -456,7 +378,6 @@
 warning: unknown enum constant AnnotationTarget\.PROPERTY_SETTER
 warning: unknown enum constant AnnotationTarget\.FILE
 warning: unknown enum constant AnnotationTarget\.TYPEALIAS
-warning: unknown enum constant AnnotationRetention\.RUNTIME
 reason: class file for kotlin\.annotation\.AnnotationRetention not found
 warning: unknown enum constant AnnotationTarget\.ANNOTATION_CLASS
 # > Task :lifecycle:lifecycle-service:processDebugAndroidTestManifest
@@ -477,21 +398,14 @@
 # > Task :preference:preference-ktx:processDebugAndroidTestManifest
 # > Task :recyclerview:recyclerview-benchmark:processReleaseAndroidTestManifest
 \$OUT_DIR/androidx/recyclerview/recyclerview\-benchmark/build/intermediates/tmp/manifest/androidTest/release/manifestMerger[0-9]+\.xml:[0-9]+:[0-9]+\-[0-9]+:[0-9]+ Warning:
-# > Task :recyclerview:recyclerview-selection:processDebugAndroidTestManifest
-# > Task :preference:preference:compileDebugAndroidTestJavaWithJavac
-Note: \$SUPPORT/preference/preference/src/androidTest/java/androidx/preference/tests/PreferenceDataStoreTest\.java uses unchecked or unsafe operations\.
 # > Task :remotecallback:remotecallback:processDebugAndroidTestManifest
 # > Task :recyclerview:recyclerview-selection:compileDebugAndroidTestJavaWithJavac
 # > Task :savedstate:savedstate:processDebugAndroidTestManifest
 # > Task :room:room-benchmark:processReleaseAndroidTestManifest
 \$OUT_DIR/androidx/room/room\-benchmark/build/intermediates/tmp/manifest/androidTest/release/manifestMerger[0-9]+\.xml:[0-9]+:[0-9]+\-[0-9]+:[0-9]+ Warning:
-# > Task :room:room-runtime:compileDebugAndroidTestJavaWithJavac
-Note: \$SUPPORT/room/runtime/src/androidTest/java/androidx/room/migration/TableInfoTest\.java uses unchecked or unsafe operations\.
 # > Task :room:room-benchmark:kaptReleaseAndroidTestKotlin
 \$OUT_DIR/androidx/room/room\-benchmark/build/tmp/kapt[0-9]+/stubs/releaseAndroidTest/androidx/room/benchmark/RelationBenchmark\.java:[0-9]+: warning: The return value includes a POJO with a @Relation\. It is usually desired to annotate this method with @Transaction to avoid possibility of inconsistent results between the POJO and its relations\. See https://developer\.android\.com/reference/androidx/room/Transaction\.html for details\.
 public abstract java\.util\.List<androidx\.room\.benchmark\.RelationBenchmark\.UserWithItems> getUserWithItems\(\);
-# > Task :sharetarget:sharetarget:compileDebugAndroidTestJavaWithJavac
-Note: \$SUPPORT/sharetarget/sharetarget/src/androidTest/java/androidx/sharetarget/ChooserTargetServiceCompatTest\.java uses unchecked or unsafe operations\.
 # > Task :viewpager2:viewpager2:processDebugAndroidTestManifest
 Package name 'androidx\.testutils' used in: :internal\-testutils\-appcompat, :internal\-testutils\-runtime, :internal\-testutils\-espresso\.
 # > Task :wear:wear-watchface:processDebugAndroidTestManifest
@@ -505,10 +419,6 @@
 \$OUT_DIR/androidx/benchmark/integration\-tests/startup\-benchmark/build/intermediates/tmp/manifest/androidTest/release/manifestMerger[0-9]+\.xml:[0-9]+:[0-9]+\-[0-9]+:[0-9]+ Warning:
 # > Task :camera:integration-tests:camera-testapp-core:externalNativeBuildDebug
 Build opengl_renderer_jni_.*
-# > Task :camera:integration-tests:camera-testapp-extensions:compileDebugAndroidTestJavaWithJavac
-# > Task :camera:integration-tests:camera-testapp-camera2-pipe:minifyReleaseWithR8
-R[0-9]+: Missing class: java\.lang\.instrument\.ClassFileTransformer
-R[0-9]+: Missing class: sun\.misc\.SignalHandler
 # > Task :camera:integration-tests:camera-testapp-view:minifyReleaseWithR8
 R[0-9]+: Missing class: java\.lang\.ClassValue
 # > Task :room:integration-tests:room-testapp-noappcompat:compileDebugAndroidTestJavaWithJavac
@@ -520,127 +430,8 @@
 Note: \$SUPPORT/room/integration\-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/TestUtil\.java uses unchecked or unsafe operations\.
 # > Task :hilt:integration-tests:hilt-testapp-worker:kaptDebugAndroidTestKotlin
 warning: The following options were not recognized by any processor: '\[dagger\.hilt\.android\.internal\.disableAndroidSuperclassValidation, kapt\.kotlin\.generated\]'
-# > Task :hilt:integration-tests:hilt-testapp-viewmodel:compileReleaseJavaWithJavac
-# > Task :slice-core:generateApi
-class androidx\.activity\.ComponentActivity with androidx\.core\.app\.ComponentActivity
-androidx\.core\.app\.ComponentActivity\#dispatchKeyShortcutEvent
-androidx\.core\.app\.ComponentActivity\#dispatchKeyEvent
-androidx\.core\.app\.ComponentActivity\#superDispatchKeyEvent
-class androidx\.appcompat\.app\.AppCompatActivity with androidx\.core\.app\.ComponentActivity
-class androidx\.fragment\.app\.FragmentActivity with androidx\.core\.app\.ComponentActivity
-class androidx\.slice\.Slice with androidx\.versionedparcelable\.CustomVersionedParcelable
-class androidx\.slice\.SliceItem with androidx\.versionedparcelable\.CustomVersionedParcelable
-src/main/java/androidx/slice/compat/SliceProviderCompat\.java:[0-9]+: warning: Parameter permissionManager references hidden type androidx\.slice\.compat\.CompatPermissionManager\. \[HiddenTypeParameter\]
 # > Task :appsearch:appsearch-compiler:lint
-[0-9]+ errors, [0-9]+ warnings \([0-9]+ warnings filtered by baseline lint\-baseline\.xml\)
-[0-9]+ errors, [0-9]+ warnings \([0-9]+ warning filtered by baseline lint\-baseline\.xml\)
 [0-9]+ errors, [0-9]+ warnings \([0-9]+ error filtered by baseline lint\-baseline\.xml\)
-# > Task :slice-view:generateApi
-src/main/java/androidx/slice/widget/ListContent\.java:[0-9]+: warning: Parameter of hidden type SliceContent in androidx\.slice\.widget\.ListContent\.getListHeight\(\) \[UnavailableSymbol\]
-src/main/java/androidx/slice/widget/ListContent\.java:[0-9]+: warning: Parameter of unavailable type androidx\.slice\.widget\.SliceStyle in androidx\.slice\.widget\.ListContent\.getHeight\(\) \[UnavailableSymbol\]
-src/main/java/androidx/slice/widget/ListContent\.java:[0-9]+: warning: Parameter of unavailable type androidx\.slice\.widget\.SliceViewPolicy in androidx\.slice\.widget\.ListContent\.getHeight\(\) \[UnavailableSymbol\]
-src/main/java/androidx/slice/widget/ListContent\.java:[0-9]+: warning: Parameter of unavailable type androidx\.slice\.widget\.SliceStyle in androidx\.slice\.widget\.ListContent\.getRowItems\(\) \[UnavailableSymbol\]
-src/main/java/androidx/slice/widget/ListContent\.java:[0-9]+: warning: Parameter of unavailable type androidx\.slice\.widget\.SliceViewPolicy in androidx\.slice\.widget\.ListContent\.getRowItems\(\) \[UnavailableSymbol\]
-src/main/java/androidx/slice/widget/ListContent\.java:[0-9]+: warning: Method androidx\.slice\.widget\.ListContent\.getSeeMoreItem returns unavailable type SliceContent \[UnavailableSymbol\]
-src/main/java/androidx/slice/widget/ListContent\.java:[0-9]+: warning: Parameter of unavailable type androidx\.slice\.widget\.SliceContent in androidx\.slice\.widget\.ListContent\.getRowType\(\) \[UnavailableSymbol\]
-src/main/java/androidx/slice/widget/ListContent\.java:[0-9]+: warning: Parameter of unavailable type androidx\.slice\.widget\.SliceStyle in androidx\.slice\.widget\.ListContent\.getListHeight\(\) \[UnavailableSymbol\]
-src/main/java/androidx/slice/widget/ListContent\.java:[0-9]+: warning: Parameter of unavailable type androidx\.slice\.widget\.SliceViewPolicy in androidx\.slice\.widget\.ListContent\.getListHeight\(\) \[UnavailableSymbol\]
-src/main/java/androidx/slice/widget/ListContent\.java:[0-9]+: warning: Method androidx\.slice\.widget\.ListContent\.getRowItems\(int, androidx\.slice\.widget\.SliceStyle, androidx\.slice\.widget\.SliceViewPolicy\) references hidden type androidx\.slice\.widget\.DisplayedListItems\. \[HiddenTypeParameter\]
-src/main/java/androidx/slice/widget/GridContent\.java:[0-9]+: warning: Parameter of unavailable type androidx\.slice\.widget\.SliceStyle in androidx\.slice\.widget\.GridContent\.getHeight\(\) \[UnavailableSymbol\]
-src/main/java/androidx/slice/widget/GridContent\.java:[0-9]+: warning: Parameter of unavailable type androidx\.slice\.widget\.SliceViewPolicy in androidx\.slice\.widget\.GridContent\.getHeight\(\) \[UnavailableSymbol\]
-src/main/java/androidx/slice/widget/RowContent\.java:[0-9]+: warning: Parameter of unavailable type androidx\.slice\.widget\.SliceStyle in androidx\.slice\.widget\.RowContent\.getHeight\(\) \[UnavailableSymbol\]
-src/main/java/androidx/slice/widget/RowContent\.java:[0-9]+: warning: Parameter of unavailable type androidx\.slice\.widget\.SliceViewPolicy in androidx\.slice\.widget\.RowContent\.getHeight\(\) \[UnavailableSymbol\]
-src/main/java/androidx/slice/widget/GridContent\.java:[0-9]+: warning: Parameter style references hidden type androidx\.slice\.widget\.SliceStyle\. \[HiddenTypeParameter\]
-src/main/java/androidx/slice/widget/GridContent\.java:[0-9]+: warning: Parameter policy references hidden type androidx\.slice\.widget\.SliceViewPolicy\. \[HiddenTypeParameter\]
-src/main/java/androidx/slice/widget/ListContent\.java:[0-9]+: warning: Parameter style references hidden type androidx\.slice\.widget\.SliceStyle\. \[HiddenTypeParameter\]
-src/main/java/androidx/slice/widget/ListContent\.java:[0-9]+: warning: Parameter policy references hidden type androidx\.slice\.widget\.SliceViewPolicy\. \[HiddenTypeParameter\]
-src/main/java/androidx/slice/widget/ListContent\.java:[0-9]+: warning: Parameter listItems references hidden type class androidx\.slice\.widget\.SliceContent\. \[HiddenTypeParameter\]
-src/main/java/androidx/slice/widget/ListContent\.java:[0-9]+: warning: Method androidx\.slice\.widget\.ListContent\.getRowItems\(\) references hidden type class androidx\.slice\.widget\.SliceContent\. \[HiddenTypeParameter\]
-src/main/java/androidx/slice/widget/ListContent\.java:[0-9]+: warning: Parameter content references hidden type androidx\.slice\.widget\.SliceContent\. \[HiddenTypeParameter\]
-src/main/java/androidx/slice/widget/ListContent\.java:[0-9]+: warning: Method androidx\.slice\.widget\.ListContent\.getSeeMoreItem\(\) references hidden type androidx\.slice\.widget\.SliceContent\. \[HiddenTypeParameter\]
-src/main/java/androidx/slice/widget/RowContent\.java:[0-9]+: warning: Parameter style references hidden type androidx\.slice\.widget\.SliceStyle\. \[HiddenTypeParameter\]
-src/main/java/androidx/slice/widget/RowContent\.java:[0-9]+: warning: Parameter policy references hidden type androidx\.slice\.widget\.SliceViewPolicy\. \[HiddenTypeParameter\]
-# > Task :appcompat:appcompat-resources:generateApi
-class androidx\.appcompat\.graphics\.drawable\.AnimatedStateListDrawableCompat with androidx\.appcompat\.graphics\.drawable\.StateListDrawable , androidx\.appcompat\.graphics\.drawable\.DrawableContainer
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#setColorFilter
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#getMinimumHeight
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#setHotspot
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#setTintMode
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#getChangingConfigurations
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#setDither
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#getConstantState
-androidx\.appcompat\.graphics\.drawable\.StateListDrawable\#applyTheme
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#setHotspotBounds
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#getIntrinsicWidth
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#getAlpha
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#getOpacity
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#getOutline
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#invalidateDrawable
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#getIntrinsicHeight
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#getMinimumWidth
-androidx\.appcompat\.graphics\.drawable\.StateListDrawable\#addState
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#setAutoMirrored
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#isAutoMirrored
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#getPadding
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#setAlpha
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#draw
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#setExitFadeDuration
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#setEnterFadeDuration
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#canApplyTheme
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#getHotspotBounds
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#getCurrent
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#unscheduleDrawable
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#scheduleDrawable
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#setTintList
-androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#onLayoutDirectionChanged
-src/main/java/androidx/appcompat/widget/ResourceManagerInternal\.java:[0-9]+: warning: Parameter hooks references hidden type androidx\.appcompat\.widget\.ResourceManagerInternal\.ResourceManagerHooks\. \[HiddenTypeParameter\]androidx\.appcompat\.graphics\.drawable\.DrawableContainer\#getHotspotBounds
-src/main/java/androidx/appcompat/widget/ResourceManagerInternal\.java:[0-9]+: warning: Parameter hooks references hidden type androidx\.appcompat\.widget\.ResourceManagerInternal\.ResourceManagerHooks\. \[HiddenTypeParameter\]
-# > Task :arch:core:core-common:generateApi
-class androidx\.arch\.core\.internal\.SafeIterableMap\.IteratorWithAdditions with androidx\.arch\.core\.internal\.SafeIterableMap\.SupportRemove
-src/main/java/androidx/arch/core/internal/FastSafeIterableMap\.java:[0-9]+: warning: Method androidx\.arch\.core\.internal\.FastSafeIterableMap\.get\(K\) references hidden type androidx\.arch\.core\.internal\.SafeIterableMap\.Entry<K,V>\. \[HiddenTypeParameter\]
-src/main/java/androidx/arch/core/internal/SafeIterableMap\.java:[0-9]+: warning: Method androidx\.arch\.core\.internal\.SafeIterableMap\.get\(K\) references hidden type androidx\.arch\.core\.internal\.SafeIterableMap\.Entry<K,V>\. \[HiddenTypeParameter\]
-# > Task :appcompat:appcompat:generateApi
-class androidx\.appcompat\.view\.menu\.MenuItemWrapperICS with androidx\.appcompat\.view\.menu\.BaseMenuWrapper
-class androidx\.appcompat\.view\.menu\.MenuWrapperICS with androidx\.appcompat\.view\.menu\.BaseMenuWrapper
-class androidx\.appcompat\.widget\.ActionBarContextView with androidx\.appcompat\.widget\.AbsActionBarView
-androidx\.appcompat\.widget\.AbsActionBarView\#canShowOverflowMenu
-androidx\.appcompat\.widget\.AbsActionBarView\#onTouchEvent
-androidx\.appcompat\.widget\.AbsActionBarView\#getContentHeight
-androidx\.appcompat\.widget\.AbsActionBarView\#setupAnimatorToVisibility
-androidx\.appcompat\.widget\.AbsActionBarView\#postShowOverflowMenu
-androidx\.appcompat\.widget\.AbsActionBarView\#setVisibility
-androidx\.appcompat\.widget\.AbsActionBarView\#dismissPopupMenus
-androidx\.appcompat\.widget\.AbsActionBarView\#isOverflowMenuShowPending
-androidx\.appcompat\.widget\.AbsActionBarView\#isOverflowReserved
-androidx\.appcompat\.widget\.AbsActionBarView\#onHoverEvent
-androidx\.appcompat\.widget\.AbsActionBarView\#getAnimatedVisibility
-androidx\.appcompat\.widget\.AbsActionBarView\#animateToVisibility
-class androidx\.appcompat\.widget\.MenuPopupWindow\.MenuDropDownListView with androidx\.appcompat\.widget\.DropDownListView
-androidx\.appcompat\.widget\.DropDownListView\#onForwardedEvent
-androidx\.appcompat\.widget\.DropDownListView\#onTouchEvent
-androidx\.appcompat\.widget\.DropDownListView\#measureHeightOfChildrenCompat
-androidx\.appcompat\.widget\.DropDownListView\#setSelector
-androidx\.appcompat\.widget\.DropDownListView\#hasWindowFocus
-androidx\.appcompat\.widget\.DropDownListView\#hasFocus
-androidx\.appcompat\.widget\.DropDownListView\#isInTouchMode
-androidx\.appcompat\.widget\.DropDownListView\#isFocused
-androidx\.appcompat\.widget\.DropDownListView\#lookForSelectablePosition
-src/main/java/androidx/appcompat/view/menu/MenuPopupHelper\.java:[0-9]+: warning: Method androidx\.appcompat\.view\.menu\.MenuPopupHelper\.getPopup\(\) references hidden type androidx\.appcompat\.view\.menu\.MenuPopup\. \[HiddenTypeParameter\]
-src/main/java/androidx/appcompat/widget/ActionMenuView\.java:[0-9]+: warning: Parameter presenter references hidden type androidx\.appcompat\.widget\.ActionMenuPresenter\. \[HiddenTypeParameter\]
-src/main/java/androidx/appcompat/widget/ActivityChooserView\.java:[0-9]+: warning: Method androidx\.appcompat\.widget\.ActivityChooserView\.getDataModel\(\) references hidden type androidx\.appcompat\.widget\.ActivityChooserModel\. \[HiddenTypeParameter\]
-src/main/java/androidx/appcompat/widget/ActivityChooserView\.java:[0-9]+: warning: Parameter dataModel references hidden type androidx\.appcompat\.widget\.ActivityChooserModel\. \[HiddenTypeParameter\]
-src/main/java/androidx/appcompat/widget/Toolbar\.java:[0-9]+: warning: Parameter outerPresenter references hidden type androidx\.appcompat\.widget\.ActionMenuPresenter\. \[HiddenTypeParameter\]
-# > Task :cursoradapter:cursoradapter:generateApi
-src/main/java/androidx/cursoradapter/widget/CursorAdapter\.java:[0-9]+: warning: Field CursorAdapter\.mChangeObserver references hidden type androidx\.cursoradapter\.widget\.CursorAdapter\.ChangeObserver\. \[HiddenTypeParameter\]
-src/main/java/androidx/cursoradapter/widget/CursorAdapter\.java:[0-9]+: warning: Field CursorAdapter\.mCursorFilter references hidden type androidx\.cursoradapter\.widget\.CursorFilter\. \[HiddenTypeParameter\]
-# > Task :media:media:generateApi
-src/main/java/android/support/v[0-9]+/media/session/MediaControllerCompat\.java:[0-9]+: warning: Method android\.support\.v[0-9]+\.media\.session\.MediaControllerCompat\.Callback\.getIControllerCallback returns unavailable type IMediaControllerCallback \[UnavailableSymbol\]
-src/main/java/android/support/v[0-9]+/media/session/MediaControllerCompat\.java:[0-9]+: warning: Method android\.support\.v[0-9]+\.media\.session\.MediaControllerCompat\.Callback\.getIControllerCallback\(\) references hidden type android\.support\.v[0-9]+\.media\.session\.IMediaControllerCallback\. \[HiddenTypeParameter\]
-# > Task :transition:transition:generateApi
-src/main/java/androidx/transition/Transition\.java:[0-9]+: warning: Parameter startValues references hidden type androidx\.transition\.TransitionValuesMaps\. \[HiddenTypeParameter\]
-src/main/java/androidx/transition/Transition\.java:[0-9]+: warning: Parameter endValues references hidden type androidx\.transition\.TransitionValuesMaps\. \[HiddenTypeParameter\]
-src/main/java/androidx/transition/TransitionSet\.java:[0-9]+: warning: Parameter startValues references hidden type androidx\.transition\.TransitionValuesMaps\. \[HiddenTypeParameter\]
-src/main/java/androidx/transition/TransitionSet\.java:[0-9]+: warning: Parameter endValues references hidden type androidx\.transition\.TransitionValuesMaps\. \[HiddenTypeParameter\]
 # > Task :activity:integration-tests:testapp:processDebugAndroidTestManifest
 # b/166471969
 .*androidTest.*AndroidManifest.*xml Warning.*:
@@ -651,16 +442,13 @@
 \[:internal\-testutils\-runtime\] \$OUT_DIR/androidx/internal\-testutils\-runtime/build/intermediates/merged_manifest/debug/AndroidManifest\.xml Warning:
 # > Task :leanback:leanback-paging:generateApi
 w\: Runtime JAR files in the classpath have the version [0-9]+\.[0-9]+\, which is older than the API version [0-9]+\.[0-9]+\. Consider using the runtime of version [0-9]+\.[0-9]+\, or pass \'\-api\-version [0-9]+\.[0-9]+\' explicitly to restrict the available APIs to the runtime of version [0-9]+\.[0-9]+\. You can also pass \'\-language\-version [0-9]+\.[0-9]+\' instead\, which will restrict not only the APIs to the specified version\, but also the language features
-w: \$GRADLE_USER_HOME/wrapper/dists/gradle\-[^/]*\-bin/[^/]*/gradle\-[^/]*/lib/kotlin\-stdlib\-[0-9]+\.[0-9]+\.[0-9]+\.jar: Runtime JAR file has version [0-9]+\.[0-9]+ which is older than required for API version [0-9]+\.[0-9]+
-w: \$GRADLE_USER_HOME/wrapper/dists/gradle\-[^/]*\-bin/[^/]*/gradle\-[^/]*/lib/kotlin\-stdlib\-common\-[0-9]+\.[0-9]+\.[0-9]+\.jar: Runtime JAR file has version [0-9]+\.[0-9]+ which is older than required for API version [0-9]+\.[0-9]+
-w: \$GRADLE_USER_HOME/wrapper/dists/gradle\-[^/]*\-bin/[^/]*/gradle\-[^/]*/lib/kotlin\-stdlib\-jdk[0-9]+\-[0-9]+\.[0-9]+\.[0-9]+\.jar: Runtime JAR file has version [0-9]+\.[0-9]+ which is older than required for API version [0-9]+\.[0-9]+
-w: \$GRADLE_USER_HOME/wrapper/dists/gradle\-[^/]*\-bin/[^/]*/gradle\-[^/]*/lib/kotlin\-reflect\-[0-9]+\.[0-9]+\.[0-9]+\.jar: Runtime JAR file has version [0-9]+\.[0-9]+ which is older than required for API version [0-9]+\.[0-9]+
 w\: \$CHECKOUT\/prebuilts\/androidx\/external\/org\/jetbrains\/kotlin\/kotlin\-stdlib\/[0-9]+\.[0-9]+\.[0-9]+\/kotlin\-stdlib\-[0-9]+\.[0-9]+\.[0-9]+\.jar\: Runtime JAR file has version [0-9]+\.[0-9]+ which is older than required for API version [0-9]+\.[0-9]+
 w\: \$CHECKOUT\/prebuilts\/androidx\/external\/org\/jetbrains\/kotlin\/kotlin\-stdlib\-common\/[0-9]+\.[0-9]+\.[0-9]+\/kotlin\-stdlib\-common\-[0-9]+\.[0-9]+\.[0-9]+\.jar\: Runtime JAR file has version [0-9]+\.[0-9]+ which is older than required for API version [0-9]+\.[0-9]+
 # > Task :compose:material:material:icons:generator:zipHtmlResultsOfTest
 Html results of .* zipped into.*\.zip
 # > Task :annotation:annotation-experimental-lint:test
 WARNING: An illegal reflective access operation has occurred
+WARNING: Illegal reflective access by com\.intellij\.util\.ReflectionUtil \(file:\$OUT_DIR/androidx/compose/compiler/compiler\-hosted/integration\-tests/kotlin\-compiler\-repackaged/build/repackaged/kotlin\-compiler\-repackaged\.jar\) to method java\.util\.ResourceBundle\.setParent\(java\.util\.ResourceBundle\)
 WARNING\: Illegal reflective access using Lookup on org\.gradle\.internal\.classloader\.ClassLoaderUtils\$AbstractClassLoaderLookuper \(file\:\$GRADLE_USER_HOME\/caches\/[0-9]+\.[0-9]+\.[0-9]+\/generated\-gradle\-jars\/gradle\-api\-[0-9]+\.[0-9]+\.[0-9]+\.jar\) to class java\.lang\.ClassLoader
 WARNING\: Please consider reporting this to the maintainers of org\.gradle\.internal\.classloader\.ClassLoaderUtils\$AbstractClassLoaderLookuper
 WARNING\: Illegal reflective access by org\.robolectric\.util\.ReflectionHelpers\$[0-9]+ \(file\:\$CHECKOUT\/prebuilts\/androidx\/external\/org\/robolectric\/shadowapi\/[0-9]+\.[0-9]+\-alpha\-[0-9]+\/shadowapi\-[0-9]+\.[0-9]+\-alpha\-[0-9]+\.jar\) to method java\.lang\.ClassLoader\.getPackage\(java\.lang\.String\)
@@ -669,31 +457,18 @@
 WARNING\: Illegal reflective access by org\.jetbrains\.kotlin\.com\.intellij\.util\.ReflectionUtil \(file\:\$CHECKOUT\/prebuilts\/androidx\/external\/org\/jetbrains\/kotlin\/kotlin\-compiler\-embeddable\/[0-9]+\.[0-9]+\.[0-9]+\/kotlin\-compiler\-embeddable\-[0-9]+\.[0-9]+\.[0-9]+\.jar\) to method java\.util\.ResourceBundle\.setParent\(java\.util\.ResourceBundle\)
 WARNING\: Please consider reporting this to the maintainers of org\.jetbrains\.kotlin\.com\.intellij\.util\.ReflectionUtil
 WARNING: Illegal reflective access by com\.intellij\.util\.ReflectionUtil \(file:\$CHECKOUT/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin\-compiler/[0-9]+\.[0-9]+\.[0-9]+/kotlin\-compiler\-[0-9]+\.[0-9]+\.[0-9]+\.jar\) to method java\.util\.ResourceBundle\.setParent\(java\.util\.ResourceBundle\)
-WARNING: Illegal reflective access by androidx\.room\.compiler\.processing\.javac\.JavacProcessingEnvMessager\$Companion\$isFromCompiledClass\$[0-9]+ \(file:\$OUT_DIR/androidx/room/room\-compiler\-processing/build/libs/room\-compiler\-processing\-[0-9]+\.[0-9]+\.[0-9]+(\-(alpha|beta|rc)[0-9]+)?\.jar\) to field com\.sun\.tools\.javac\.code\.Symbol\.owner
-WARNING: Illegal reflective access by com\.intellij\.util\.ReflectionUtil \(file:\$CHECKOUT/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin\-compiler/[0-9]+\.[0-9]+\.[0-9]+\-M[0-9]+/kotlin\-compiler\-[0-9]+\.[0-9]+\.[0-9]+\-M[0-9]+\.jar\) to method java\.util\.ResourceBundle\.setParent\(java\.util\.ResourceBundle\)
-WARNING: Illegal reflective access by com\.intellij\.util\.ReflectionUtil \(file:\$CHECKOUT/prebuilts/androidx/external/com/android/tools/external/com\-intellij/intellij\-core/[0-9]+\.[0-9]+\.[0-9]+\-alpha[0-9]+/intellij\-core\-[0-9]+\.[0-9]+\.[0-9]+\-alpha[0-9]+\.jar\) to method java\.util\.ResourceBundle\.setParent\(java\.util\.ResourceBundle\)
 WARNING: Please consider reporting this to the maintainers of com\.intellij\.util\.ReflectionUtil
 WARNING: Use \-\-illegal\-access=warn to enable warnings of further illegal reflective access operations
 WARNING: All illegal access operations will be denied in a future release
 # > Task :compose:compiler:compiler-hosted:integration-tests:testDebugUnitTest
 WARNING: Illegal reflective access by org\.robolectric\.util\.ReflectionHelpers \(file:\$CHECKOUT/prebuilts/androidx/external/org/robolectric/shadowapi/[0-9]+\.[0-9]+\-alpha\-[0-9]+/shadowapi\-[0-9]+\.[0-9]+\-alpha\-[0-9]+\.jar\) to field java\.lang\.reflect\.Field\.modifiers
-WARNING: Illegal reflective access by org\.jetbrains\.kotlin\.com\.intellij\.util\.ReflectionUtil \(file:\$CHECKOUT/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin\-compiler\-embeddable/[0-9]+\.[0-9]+\.[0-9]+\-[0-9]+/kotlin\-compiler\-embeddable\-[0-9]+\.[0-9]+\.[0-9]+\-[0-9]+\.jar\) to method java\.util\.ResourceBundle\.setParent\(java\.util\.ResourceBundle\)
-WARNING: Illegal reflective access by com\.intellij\.util\.ReflectionUtil \(file:\$CHECKOUT/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin\-compiler/[0-9]+\.[0-9]+\.[0-9]+\-[0-9]+/kotlin\-compiler\-[0-9]+\.[0-9]+\.[0-9]+\-[0-9]+\.jar\) to method java\.util\.ResourceBundle\.setParent\(java\.util\.ResourceBundle\)
 WARNING: Please consider reporting this to the maintainers of org\.robolectric\.util\.ReflectionHelpers
 # > Task :compose:compiler:compiler-hosted:integration-tests:test
 wrote dependency log to \$DIST_DIR/affected_module_detector_log\.txt
-# > Task :enterprise-feedback-testing:compileDebugUnitTestJavaWithJavac
-# > Task :biometric:biometric:compileDebugUnitTestJavaWithJavac
-Note: \$SUPPORT/biometric/biometric/src/test/java/androidx/biometric/KeyguardUtilsTest\.java uses unchecked or unsafe operations\.
-# > Task :lifecycle:lifecycle-process:compileDebugUnitTestJavaWithJavac
-# > Task :lifecycle:lifecycle-viewmodel:compileDebugUnitTestJavaWithJavac
-Note: \$SUPPORT/lifecycle/lifecycle\-viewmodel/src/test/java/androidx/lifecycle/ViewModelProviderTest\.java uses unchecked or unsafe operations\.
 # > Task :ipc:ipc-compiler:kaptTestKotlin
 Annotation processors discovery from compile classpath is deprecated\.
 Set 'kapt\.includeCompileClasspath = false' to disable discovery\.
 Run the build with '\-\-info' for more details\.
-# > Task :camera:camera-core:compileDebugUnitTestJavaWithJavac
-Note: \$SUPPORT/camera/camera\-core/src/test/java/androidx/camera/core/impl/DeferrableSurfaceTest\.java uses unchecked or unsafe operations\.
 # > Task :wear:wear-input:compileDebugUnitTestJavaWithJavac
 # > Task :lifecycle:integration-tests:incrementality:compileTestKotlin
 \$GRADLE_USER_HOME\/wrapper\/dists\/gradle\-[^/]*-bin\/[0-9a-z]+\/gradle\-[^/]*/lib\/kotlin\-stdlib\-[0-9.]*.jar \(version [^/]*\)
@@ -701,9 +476,6 @@
 \$GRADLE_USER_HOME\/wrapper\/dists\/gradle\-[^/]*-bin\/[0-9a-z]+\/gradle\-[^/]*/lib\/kotlin\-stdlib\-jdk[0-9]*-[0-9.]*.jar \(version [^/]*\)
 \$GRADLE_USER_HOME\/wrapper\/dists\/gradle\-[^/]*-bin\/[0-9a-z]+\/gradle\-[^/]*/lib\/kotlin\-reflect\-[0-9.]*.jar \(version [^/]*\)
 w: Consider providing an explicit dependency on kotlin\-reflect [^/]* to prevent strange errors
-# > Task :contentaccess:contentaccess-compiler:test
-WARNING: Illegal reflective access by org\.jetbrains\.kotlin\.kapt[0-9]+\.base\.javac\.KaptJavaFileManager \(file:\$CHECKOUT/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin\-annotation\-processing\-embeddable/[0-9]+\.[0-9]+\.[0-9]+/kotlin\-annotation\-processing\-embeddable\-[0-9]+\.[0-9]+\.[0-9]+\.jar\) to method com\.sun\.tools\.javac\.file\.BaseFileManager\.handleOption\(com\.sun\.tools\.javac\.main\.Option,java\.lang\.String\)
-WARNING: Please consider reporting this to the maintainers of org\.jetbrains\.kotlin\.kapt[0-9]+\.base\.javac\.KaptJavaFileManager
 # > Task :room:room-compiler:test
 WARNING: Illegal reflective access by androidx\.room\.compiler\.processing\.javac\.JavacProcessingEnvMessager\$Companion\$isFromCompiledClass\$[0-9]+ \(file:\$OUT_DIR/androidx/room/room\-compiler\-processing/build/libs/room\-compiler\-processing\-[0-9]+\.[0-9]+\.[0-9]+(\-(alpha|beta|rc)[0-9]+)?\.jar\) to field com\.sun\.tools\.javac\.code\.Symbol\$ClassSymbol\.classfile
 WARNING: Please consider reporting this to the maintainers of androidx\.room\.compiler\.processing\.javac\.JavacProcessingEnvMessager\$Companion\$isFromCompiledClass\$[0-9]+
@@ -716,12 +488,6 @@
 # > Task :docs-runner:dokkaJavaTipOfTreeDocs
 \$CHECKOUT\/prebuilts\/androidx\/external\/org\/jetbrains\/kotlin\/kotlin\-reflect\/[0-9]+\.[0-9]+\.[0-9]+\/kotlin\-reflect\-[0-9]+\.[0-9]+\.[0-9]+\.jar \(version [0-9]+\.[0-9]+\)
 \$CHECKOUT/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin\-stdlib\-jdk[0-9]+/[0-9]+\.[0-9]+\.[0-9]+/kotlin\-stdlib\-jdk[0-9]+\-[0-9]+\.[0-9]+\.[0-9]+\.jar \(version [0-9]+\.[0-9]+\)
-\$CHECKOUT/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin\-stdlib/[0-9]+\.[0-9]+\.[0-9]+\-[0-9]+/kotlin\-stdlib\-[0-9]+\.[0-9]+\.[0-9]+\-[0-9]+\.jar \(version [0-9]+\.[0-9]+\)
-\$CHECKOUT/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin\-stdlib\-common/[0-9]+\.[0-9]+\.[0-9]+\-[0-9]+/kotlin\-stdlib\-common\-[0-9]+\.[0-9]+\.[0-9]+\-[0-9]+\.jar \(version [0-9]+\.[0-9]+\)
-\$CHECKOUT/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin\-stdlib/[0-9]+\.[0-9]+\.[0-9]+\-M[0-9]+/kotlin\-stdlib\-[0-9]+\.[0-9]+\.[0-9]+\-M[0-9]+\.jar \(version [0-9]+\.[0-9]+\)
-\$CHECKOUT/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin\-stdlib\-common/[0-9]+\.[0-9]+\.[0-9]+\-M[0-9]+/kotlin\-stdlib\-common\-[0-9]+\.[0-9]+\.[0-9]+\-M[0-9]+\.jar \(version [0-9]+\.[0-9]+\)
-\$CHECKOUT/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin\-stdlib/[0-9]+\.[0-9]+\.[0-9]+\-rc/kotlin\-stdlib\-[0-9]+\.[0-9]+\.[0-9]+\-rc\.jar \(version [0-9]+\.[0-9]+\)
-\$CHECKOUT/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin\-stdlib\-common/[0-9]+\.[0-9]+\.[0-9]+\-rc/kotlin\-stdlib\-common\-[0-9]+\.[0-9]+\.[0-9]+\-rc\.jar \(version [0-9]+\.[0-9]+\)
 # > Task :compose:ui:ui:processDebugAndroidTestManifest
 \$OUT_DIR\/androidx\/compose\/ui\/ui\/build\/intermediates\/tmp\/manifest\/androidTest\/debug\/manifestMerger[0-9]+\.xml Warning\:
 Package name \'androidx\.compose\.ui\.test\' used in\: manifestMerger[0-9]+\.xml\, \:compose\:ui\:ui\-test\.
@@ -746,124 +512,11 @@
 # > Task :camera:integration-tests:camera-testapp-camera2-pipe:dexBuilderDebug
 \$OUT_DIR/androidx/camera/integration\-tests/camera\-testapp\-camera[0-9]+\-pipe/build/intermediates/jacoco_instrumented_classes/debug/out/androidx/camera/integration/camera[0-9]+/pipe/DebugKt\.class: D[0-9]+: Invalid stack map table at [0-9]+: aload [0-9]+, error: The expected type Initialized\(double\) is not assignable to java\.lang\.Object\.
 # > Task :support-remotecallback-demos:lintDebug
-\$GRADLE_USER_HOME/caches/transforms\-[0-9]+/files\-[0-9]+\.[0-9]+/[0-9a-f]{32}/annotation\-experimental\-[0-9]+\.[0-9]+\.[0-9]+/jars/lint\.jar: Warning: Lint found an issue registry \(androidx\.annotation\.experimental\.lint\.ExperimentalIssueRegistry\) which did not specify the Lint API version it was compiled with\.
-This means that the lint checks are likely not compatible\.
-If you are the author of this lint check, make your lint IssueRegistry class contain
-override val api: Int = com\.android\.tools\.lint\.detector\.api\.CURRENT_API
-or from Java,
-@Override public int getApi\(\) \{ return com\.android\.tools\.lint\.detector\.api\.ApiKt\.CURRENT_API; \}
-If you are just using lint checks from a third party library you have no control over, you can disable these lint checks \(if they misbehave\) like this:
-android \{
-lintOptions \{
-disable "UnsafeExperimentalUsageError",
-"UnsafeExperimentalUsageWarning"
-\}
-\[ObsoleteLintCustomCheck\]
-Explanation for issues of type "ObsoleteLintCustomCheck":
-Lint can be extended with "custom checks": additional checks implemented by
-developers and libraries to for example enforce specific API usages
-required by a library or a company coding style guideline\.
-The Lint APIs are not yet stable, so these checks may either cause a
-performance degradation, or stop working, or provide wrong results\.
-This warning flags custom lint checks that are found to be using obsolete
-APIs and will need to be updated to run in the current lint environment\.
-It may also flag issues found to be using a newer version of the API,
-meaning that you need to use a newer version of lint \(or Android Studio or
-Gradle plugin etc\) to work with these checks\.
-[0-9]+ errors\, [0-9]+ warnings \([0-9]+ errors\, [0-9]+ warning filtered by baseline lint\-baseline\.xml\)
 [0-9]+ errors\, [0-9]+ warnings \([0-9]+ errors filtered by baseline lint\-baseline\.xml\)
-[0-9]+ errors, [0-9]+ warnings \([0-9]+ errors, [0-9]+ warnings filtered by baseline lint\-baseline\.xml\)
 # > Task :camera:camera-camera2-pipe-integration:lintDebug
-\$GRADLE_USER_HOME/caches/transforms\-[0-9]+/files\-[0-9]+\.[0-9]+/[0-9a-f]{32}/annotation\-experimental\-[0-9]+\.[0-9]+\.[0-9]+\-rc[0-9]+/jars/lint\.jar: Warning: Lint found an issue registry \(androidx\.annotation\.experimental\.lint\.ExperimentalIssueRegistry\) which did not specify the Lint API version it was compiled with\.
 [0-9]+ errors, [0-9]+ warnings
-# > Task :support-leanback-demos:lintDebug
-\$GRADLE_USER_HOME/caches/transforms\-[0-9]+/files\-[0-9]+\.[0-9]+/[0-9a-f]{32}/appcompat\-[0-9]+\.[0-9]+\.[0-9]+/jars/lint\.jar: Warning: Lint found an issue registry \(androidx\.appcompat\.AppCompatIssueRegistry\) which is older than the current API level; these checks may not work correctly\.
-Recompile the checks against the latest version\. Custom check API version is [0-9]+ \([0-9]+\.[0-9]+\), current lint API level is [0-9]+ \([0-9]+\.[0-9]+\) \[ObsoleteLintCustomCheck\]
-\$GRADLE_USER_HOME/caches/transforms\-[0-9]+/files\-[0-9]+\.[0-9]+/[0-9a-f]{32}/fragment\-[0-9]+\.[0-9]+\.[0-9]+/jars/lint\.jar: Warning: Lint found an issue registry \(androidx\.fragment\.lint\.FragmentIssueRegistry\) which is older than the current API level; these checks may not work correctly\.
-\$GRADLE_USER_HOME/caches/transforms\-[0-9]+/files\-[0-9]+\.[0-9]+/[0-9a-f]{32}/lifecycle\-runtime\-ktx\-[0-9]+\.[0-9]+\.[0-9]+/jars/lint\.jar: Warning: Lint found an issue registry \(androidx\.lifecycle\.lint\.LifecycleRuntimeIssueRegistry\) which is older than the current API level; these checks may not work correctly\.
-# > Task :hilt:hilt-lifecycle-viewmodel:lintDebug
-\$GRADLE_USER_HOME/caches/transforms\-[0-9]+/files\-[0-9]+\.[0-9]+/[0-9a-f]{32}/dagger\-lint\-aar\-[0-9]+\.[0-9]+\.[0-9]+/jars/lint\.jar: Warning: Lint found an issue registry \(dagger\.lint\.DaggerIssueRegistry\) which is older than the current API level; these checks may not work correctly\.
-# > Task :hilt:hilt-work:lintDebug
-\$GRADLE_USER_HOME/caches/transforms\-[0-9]+/files\-[0-9]+\.[0-9]+/[0-9a-f]{32}/work\-runtime\-[0-9]+\.[0-9]+\.[0-9]+/jars/lint\.jar: Warning: Lint found an issue registry \(androidx\.work\.lint\.WorkManagerIssueRegistry\) which is older than the current API level; these checks may not work correctly\.
-# > Task :camera:integration-tests:camera-testapp-view:lintDebug
-\$GRADLE_USER_HOME/caches/transforms\-[0-9]+/files\-[0-9]+\.[0-9]+/[0-9a-f]{32}/fragment\-testing\-[0-9]+\.[0-9]+\.[0-9]+/jars/lint\.jar: Warning: Lint found an issue registry \(androidx\.fragment\.testing\.lint\.FragmentTestingIssueRegistry\) which is older than the current API level; these checks may not work correctly\.
-# > Task :camera:integration-tests:camera-testapp-uiwidgets:lintDebug
-[0-9]+ errors, [0-9]+ warnings \([0-9]+ error, [0-9]+ warnings filtered by baseline lint\-baseline\.xml\)
-# > Task :lint-checks:lint
-\$SUPPORT\/lint\-checks\/src\/main\/java\/androidx\/build\/lint\/BanInappropriateExperimentalUsage\.kt\:[0-9]+\: Warning\: \"OptIn\" looks like a code reference\; surround with backtics in string to display as symbol\, e\.g\. \`OptIn\` \[LintImplTextFormat\]
-\"Experimental\/OptIn APIs should only be used from within the same library or \" \+
-\~\~\~\~\~
-\$SUPPORT\/lint\-checks\/src\/main\/java\/androidx\/build\/lint\/BanInappropriateExperimentalUsage\.kt\:[0-9]+\: Warning\: The issue summary should be shorter\; typically just a [0-9]+\-[0-9]+ words\; it\'s used as a topic header in HTML reports and in the IDE inspections window \[LintImplTextFormat\]
-\"Experimental apis can only be used from within the same library or from libraries \" \+
-# > Task :compose:ui:ui-text:lintDebug
-\$SUPPORT\/text\/text\/src\/main\/java\/androidx\/compose\/ui\/text\/android\/style\/FontSpan\.kt\:[0-9]+\: Warning\: Field requires API level [0-9]+ \(current min is [0-9]+\)\: android\.graphics\.fonts\.FontStyle\#FONT_WEIGHT_NORMAL \[InlinedApi\]
-textPaint\.typeface \= getTypeface\(FontStyle\.FONT_WEIGHT_NORMAL\, false\)
-\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~
-\$SUPPORT\/text\/text\/src\/main\/java\/androidx\/compose\/ui\/text\/android\/style\/FontSpan\.kt\:[0-9]+\: Warning\: Field requires API level [0-9]+ \(current min is [0-9]+\)\: android\.graphics\.fonts\.FontStyle\#FONT_WEIGHT_BOLD \[InlinedApi\]
-FontStyle\.FONT_WEIGHT_BOLD
-\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~
-FontStyle\.FONT_WEIGHT_NORMAL
-\$SUPPORT\/text\/text\/src\/main\/java\/androidx\/compose\/ui\/text\/android\/style\/FontWeightStyleSpan\.kt\:[0-9]+\: Warning\: Field requires API level [0-9]+ \(current min is [0-9]+\)\: android\.graphics\.fonts\.FontStyle\#FONT_WEIGHT_NORMAL \[InlinedApi\]
-oldTypeface\?\.weight \?\: FontStyle\.FONT_WEIGHT_NORMAL
-\$SUPPORT\/text\/text\/src\/main\/java\/androidx\/compose\/ui\/text\/android\/LayoutCompat\.kt\:[0-9]+\: Warning\: Field requires API level [0-9]+ \(current min is [0-9]+\)\: android\.graphics\.text\.LineBreaker\#JUSTIFICATION_MODE_NONE \[InlinedApi\]
-const val JUSTIFICATION_MODE_NONE \= LineBreaker\.JUSTIFICATION_MODE_NONE
-\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~
-\$SUPPORT\/text\/text\/src\/main\/java\/androidx\/compose\/ui\/text\/android\/LayoutCompat\.kt\:[0-9]+\: Warning\: Field requires API level [0-9]+ \(current min is [0-9]+\)\: android\.graphics\.text\.LineBreaker\#JUSTIFICATION_MODE_INTER_WORD \[InlinedApi\]
-const val JUSTIFICATION_MODE_INTER_WORD \= LineBreaker\.JUSTIFICATION_MODE_INTER_WORD
-\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~
-\$SUPPORT\/text\/text\/src\/main\/java\/androidx\/compose\/ui\/text\/android\/LayoutCompat\.kt\:[0-9]+\: Warning\: Field requires API level [0-9]+ \(current min is [0-9]+\)\: android\.text\.Layout\#HYPHENATION_FREQUENCY_NORMAL \[InlinedApi\]
-const val HYPHENATION_FREQUENCY_NORMAL \= Layout\.HYPHENATION_FREQUENCY_NORMAL
-\$SUPPORT\/text\/text\/src\/main\/java\/androidx\/compose\/ui\/text\/android\/LayoutCompat\.kt\:[0-9]+\: Warning\: Field requires API level [0-9]+ \(current min is [0-9]+\)\: android\.text\.Layout\#HYPHENATION_FREQUENCY_FULL \[InlinedApi\]
-const val HYPHENATION_FREQUENCY_FULL \= Layout\.HYPHENATION_FREQUENCY_FULL
-\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~
-\$SUPPORT\/text\/text\/src\/main\/java\/androidx\/compose\/ui\/text\/android\/LayoutCompat\.kt\:[0-9]+\: Warning\: Field requires API level [0-9]+ \(current min is [0-9]+\)\: android\.text\.Layout\#HYPHENATION_FREQUENCY_NONE \[InlinedApi\]
-const val HYPHENATION_FREQUENCY_NONE \= Layout\.HYPHENATION_FREQUENCY_NONE
-\$SUPPORT\/text\/text\/src\/main\/java\/androidx\/compose\/ui\/text\/android\/LayoutCompat\.kt\:[0-9]+\: Warning\: Field requires API level [0-9]+ \(current min is [0-9]+\)\: android\.graphics\.text\.LineBreaker\#BREAK_STRATEGY_SIMPLE \[InlinedApi\]
-const val BREAK_STRATEGY_SIMPLE \= LineBreaker\.BREAK_STRATEGY_SIMPLE
-\$SUPPORT\/text\/text\/src\/main\/java\/androidx\/compose\/ui\/text\/android\/LayoutCompat\.kt\:[0-9]+\: Warning\: Field requires API level [0-9]+ \(current min is [0-9]+\)\: android\.graphics\.text\.LineBreaker\#BREAK_STRATEGY_HIGH_QUALITY \[InlinedApi\]
-const val BREAK_STRATEGY_HIGH_QUALITY \= LineBreaker\.BREAK_STRATEGY_HIGH_QUALITY
-\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~
-\$SUPPORT\/text\/text\/src\/main\/java\/androidx\/compose\/ui\/text\/android\/LayoutCompat\.kt\:[0-9]+\: Warning\: Field requires API level [0-9]+ \(current min is [0-9]+\)\: android\.graphics\.text\.LineBreaker\#BREAK_STRATEGY_BALANCED \[InlinedApi\]
-const val BREAK_STRATEGY_BALANCED \= LineBreaker\.BREAK_STRATEGY_BALANCED
-Explanation for issues of type \"InlinedApi\"\:
-This check scans through all the Android API field references in the
-application and flags certain constants\, such as static final integers and
-Strings\, which were introduced in later versions\. These will actually be
-copied into the class files rather than being referenced\, which means that
-the value is available even when running on older devices\. In some cases
-that\'s fine\, and in other cases it can result in a runtime crash or
-incorrect behavior\. It depends on the context\, so consider the code
-carefully and decide whether it\'s safe and can be suppressed or whether the
-code needs to be guarded\.
-If you really want to use this API and don\'t need to support older devices
-just set the minSdkVersion in your build\.gradle or AndroidManifest\.xml
-files\.
-If your code is deliberately accessing newer APIs\, and you have ensured
-\(e\.g\. with conditional execution\) that this code will only ever be called
-on a supported platform\, then you can annotate your class or method with
-the \@TargetApi annotation specifying the local minimum SDK to apply\, such
-as \@TargetApi\([0-9]+\)\, such that this check considers [0-9]+ rather than your
-manifest file\'s minimum SDK as the required API level\.
-# > Task :camera:camera-video:lintDebug
-\$SUPPORT\/camera\/camera\-video\/src\/main\/java\/androidx\/camera\/video\/VideoCaptureLegacy\.java\:[0-9]+\: Warning\: Switch statement on an int with known associated constant missing case MediaCodec\.INFO_OUTPUT_BUFFERS_CHANGED \[SwitchIntDef\]
-switch \(outputBufferId\) \{
-\~\~\~\~\~\~
-Explanation for issues of type \"SwitchIntDef\"\:
-This check warns if a switch statement does not explicitly include all the
-values declared by the typedef \@IntDef declaration\.
-# > Task :car:app:app:lintDebug
-\$SUPPORT\/car\/app\/app\/src\/main\/java\/androidx\/car\/app\/model\/Action\.java\:[0-9]+\: Warning\: Switch statement on an int with known associated constant missing case TYPE_UNKNOWN \[SwitchIntDef\]
-switch \(type\) \{
 # > Task :camera:camera-core:compileDebugJavaWithJavac
 warning: unknown enum constant AnnotationRetention\.BINARY
-# > Task :drawerlayout:drawerlayout:compileDebugJavaWithJavac
-# > Task :viewpager:viewpager:compileDebugJavaWithJavac
-# > Task :fragment:fragment:compileDebugJavaWithJavac
-# > Task :core:core-animation:compileDebugJavaWithJavac
-# > Task :biometric:biometric:compileDebugJavaWithJavac
-# > Task :camera:camera-camera2:compileDebugUnitTestJavaWithJavac
-\$SUPPORT/camera/camera\-camera[0-9]+/src/test/java/androidx/camera/camera[0-9]+/internal/compat/workaround/ExcludedSupportedSizesContainerTest\.java:[0-9]+: warning: non\-varargs call of varargs method with inexact argument type for last parameter;
-assertThat\(excludedSizes\)\.containsExactly\(mConfig\.mExcludedSizes\);
 # > Task :navigation:navigation-dynamic-features-fragment:compileDebugKotlin
 w: \$SUPPORT/navigation/navigation\-dynamic\-features\-fragment/src/main/java/androidx/navigation/dynamicfeatures/fragment/ui/AbstractProgressFragment\.kt: \([0-9]+, [0-9]+\): 'startIntentSenderForResult\(IntentSender!, Int, Intent\?, Int, Int, Int, Bundle\?\): Unit' is deprecated\. Deprecated in Java
 w: \$SUPPORT/navigation/navigation\-dynamic\-features\-fragment/src/main/java/androidx/navigation/dynamicfeatures/fragment/ui/AbstractProgressFragment\.kt: \([0-9]+, [0-9]+\): 'onActivityResult\(Int, Int, Intent\?\): Unit' is deprecated\. Deprecated in Java
@@ -871,14 +524,6 @@
 There were failing tests\. See the report at: .*.html
 # > Task :compose:ui:ui:processDebugUnitTestManifest
 \$OUT_DIR/androidx/compose/ui/ui/build/intermediates/tmp/manifest/test/debug/manifestMerger[0-9]+\.xml Warning:
-# > Task :wear:wear-watchface:compileDebugKotlin
-w: \$SUPPORT/wear/wear\-watchface/src/main/java/androidx/wear/watchface/ui/ConfigFragment\.kt: \([0-9]+, [0-9]+\): 'onActivityCreated\(Bundle\?\): Unit' is deprecated\. Deprecated in Java
-w: \$SUPPORT/wear/wear\-watchface/src/main/java/androidx/wear/watchface/ui/StyleConfigFragment\.kt: \([0-9]+, [0-9]+\): 'onActivityCreated\(Bundle\?\): Unit' is deprecated\. Deprecated in Java
-w: \$SUPPORT/wear/wear\-watchface/src/main/java/androidx/wear/watchface/ui/WatchFaceConfigActivity\.kt: \([0-9]+, [0-9]+\): 'startActivityForResult\(Intent!, Int\): Unit' is deprecated\. Deprecated in Java
-# > Task :compose:ui:ui-tooling:lintDebug
-\$SUPPORT/compose/ui/ui\-tooling/src/main/java/androidx/compose/ui/tooling/preview/UiMode\.kt:[0-9]+: Warning: Field requires API level [0-9]+ \(current min is [0-9]+\): android\.content\.res\.Configuration\#UI_MODE_TYPE_VR_HEADSET \[InlinedApi\]
-UI_MODE_TYPE_VR_HEADSET,
-\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~
 # > Task *:lintDebug
 \$SUPPORT/.*/build\.gradle: Ignore: Unknown issue id "ComposableNaming" \[UnknownIssueId\]
 \$SUPPORT/.*/build\.gradle: Ignore: Unknown issue id "ComposableLambdaParameterNaming" \[UnknownIssueId\]
@@ -887,41 +532,22 @@
 Explanation for issues of type "UnknownIssueId":
 Lint will report this issue if it is configured with an issue id it does
 not recognize in for example Gradle files or lint\.xml configuration files\.
-# > Task :room:room-compiler:compileTestKotlin
-w: \$SUPPORT/room/compiler/src/test/kotlin/androidx/room/ext/ElementExtTest\.kt: \([0-9]+, [0-9]+\): Arguments execution order is going to be changed in a future release\.The expression for named vararg argument will be executed in the order in which it was listed, not at the end\.See KT\-[0-9]+ for more details\.
-w: \$SUPPORT/room/compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest\.kt: \([0-9]+, [0-9]+\): Arguments execution order is going to be changed in a future release\.The expression for named vararg argument will be executed in the order in which it was listed, not at the end\.See KT\-[0-9]+ for more details\.
-w: \$SUPPORT/room/compiler/src/test/kotlin/androidx/room/processor/ProjectionExpanderTest\.kt: \([0-9]+, [0-9]+\): Arguments execution order is going to be changed in a future release\.The expression for named vararg argument will be executed in the order in which it was listed, not at the end\.See KT\-[0-9]+ for more details\.
-w: \$SUPPORT/room/compiler/src/test/kotlin/androidx/room/processor/autovalue/AutoValuePojoProcessorDelegateTest\.kt: \([0-9]+, [0-9]+\): Arguments execution order is going to be changed in a future release\.The expression for named vararg argument will be executed in the order in which it was listed, not at the end\.See KT\-[0-9]+ for more details\.
-w: \$SUPPORT/room/compiler/src/test/kotlin/androidx/room/solver/TypeAdapterStoreTest\.kt: \([0-9]+, [0-9]+\): Arguments execution order is going to be changed in a future release\.The expression for named vararg argument will be executed in the order in which it was listed, not at the end\.See KT\-[0-9]+ for more details\.
-# > Configure project :window:window-samples
-Warning: The 'kotlin\-android\-extensions' Gradle plugin is deprecated\. Please use this migration guide \(https://goo\.gle/kotlin\-android\-extensions\-deprecation\) to start working with View Binding \(https://developer\.android\.com/topic/libraries/view\-binding\) and the 'kotlin\-parcelize' plugin\.
-'kotlin\-android\-extensions' plugin is deprecated\. Use 'kotlin\-parcelize' for the @Parcelize functionality, and View Binding \(https://developer\.android\.com/topic/libraries/view\-binding\) instead of synthetic view accessors\.
-# > Task :room:integration-tests:room-testapp-kotlin:compileDebugAndroidTestKotlin
-w: \$SUPPORT/room/integration\-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/migration/MigrationDbKotlin\.kt: \([0-9]+, [0-9]+\): Arguments execution order is going to be changed in a future release\.The expression for named vararg argument will be executed in the order in which it was listed, not at the end\.See KT\-[0-9]+ for more details\.
 # > Task :compose:foundation:foundation:reportLibraryMetrics
-Stripped invalid locals information from [0-9]+ method\.
 Stripped invalid locals information from [0-9]+ methods\.
 Methods with invalid locals information:
 java\.lang\.Object androidx\.compose\.foundation\.gestures\.ZoomableKt\$detectZoom\$[0-9]+\.invokeSuspend\(java\.lang\.Object\)
 Type information in locals\-table is inconsistent\. Cannot constrain type: @Nullable java\.util\.List \{\} for value: v[0-9]+\(\$this\$fastAny\$iv\) by constraint FLOAT\.
 java\.lang\.Object androidx\.compose\.foundation\.gestures\.DragGestureDetectorKt\$awaitLongPressOrCancellation\$[0-9]+\$[0-9]+\.invokeSuspend\(java\.lang\.Object\)
 java\.lang\.Object androidx\.compose\.foundation\.gestures\.DragGestureDetectorKt\.awaitVerticalTouchSlopOrCancellation\-jO[0-9]+t[0-9]+\(androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope, long, kotlin\.jvm\.functions\.Function[0-9]+, kotlin\.coroutines\.Continuation\)
-java\.lang\.Object androidx\.compose\.foundation\.gestures\.DragGestureDetectorKt\.awaitVerticalTouchSlopOrCancellation\-qFc19kk\(androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope, long, kotlin\.jvm\.functions\.Function[0-9]+, kotlin\.coroutines\.Continuation\)
-java\.lang\.Object androidx\.compose\.foundation\.gestures\.TapGestureDetectorKt\.waitForUpOrCancel\(androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope, kotlin\.coroutines\.Continuation\)
 Type information in locals\-table is inconsistent\. Cannot constrain type: BOTTOM \(empty\) for value: v[0-9]+ by constraint INT\.
 java\.lang\.Object androidx\.compose\.foundation\.gestures\.TransformableKt\$detectZoom\$[0-9]+\$[0-9]+\.invokeSuspend\(java\.lang\.Object\)
 Type information in locals\-table is inconsistent\. Cannot constrain type: BOTTOM \(empty\) for value: v[0-9]+\(\$this\$fastAny\$iv\) by constraint FLOAT\.
 Some warnings are typically a sign of using an outdated Java toolchain\. To fix, recompile the source with an updated toolchain\.
 Type information in locals\-table is inconsistent\. Cannot constrain type: BOTTOM \(empty\) for value: v[0-9]+ by constraint FLOAT\.
 java\.lang\.Object androidx\.compose\.foundation\.gestures\.DragGestureDetectorKt\.awaitHorizontalTouchSlopOrCancellation\-jO[0-9]+t[0-9]+\(androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope, long, kotlin\.jvm\.functions\.Function[0-9]+, kotlin\.coroutines\.Continuation\)
-java\.lang\.Object androidx\.compose\.foundation\.gestures\.DragGestureDetectorKt\.awaitHorizontalTouchSlopOrCancellation\-qFc19kk\(androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope, long, kotlin\.jvm\.functions\.Function[0-9]+, kotlin\.coroutines\.Continuation\)
 java\.lang\.Object androidx\.compose\.foundation\.gestures\.TransformGestureDetectorKt\$detectTransformGestures\$[0-9]+\$[0-9]+\.invokeSuspend\(java\.lang\.Object\)
 Type information in locals\-table is inconsistent\. Cannot constrain type: INT for value: v[0-9]+\(index\$iv\$iv\) by constraint FLOAT\.
-Attempt to define local of type int as it\$iv:java\.lang\.Object
-Type information in locals\-table is inconsistent\. Cannot constrain type: INT for value: v379\(index\$iv\$iv\) by constraint FLOAT\.
 java\.lang\.Object androidx\.compose\.foundation\.gestures\.TapGestureDetectorKt\.waitForUpOrCancellation\(androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope, kotlin\.coroutines\.Continuation\)
-# > Task :hilt:integration-tests:hilt-testapp-viewmodel:kaptDebugKotlin
-warning: The following options were not recognized by any processor: '\[dagger\.fastInit, dagger\.hilt\.android\.internal\.disableAndroidSuperclassValidation, kapt\.kotlin\.generated\]'
 # > Task :preference:preference:compileDebugAndroidTestKotlin
 w\: \$SUPPORT\/preference\/preference\/src\/androidTest\/java\/androidx\/preference\/tests\/PreferenceDialogFragmentCompatTest\.kt\: \([0-9]+\, [0-9]+\)\: \'setTargetFragment\(Fragment\?\, Int\)\: Unit\' is deprecated\. Deprecated in Java
 # > Task :viewpager2:viewpager2:compileDebugAndroidTestKotlin
@@ -939,268 +565,23 @@
 w\: \$SUPPORT\/viewpager[0-9]+\/viewpager[0-9]+\/src\/androidTest\/java\/androidx\/viewpager[0-9]+\/widget\/OnApplyWindowInsetsListenerTest\.kt\: \([0-9]+\, [0-9]+\)\: \'consumeDisplayCutout\(\)\: WindowInsetsCompat\' is deprecated\. Deprecated in Java
 # > Task :contentpager:contentpager:compileDebugAndroidTestJavaWithJavac
 # > Task :annotation:annotation-experimental-lint-integration-tests:lintDebug
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin\-stdlib/[0-9]+\.[0-9]+\.[0-9]+\-[0-9]+/kotlin\-stdlib\-[0-9]+\.[0-9]+\.[0-9]+\-[0-9]+\.jar:META\-INF/versions/[0-9]+/module\-info\.class: broken class file\? \(This feature requires ASM[0-9]+\)
 Error processing \$CHECKOUT/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin\-stdlib/[0-9]+\.[0-9]+\.[0-9]+/kotlin\-stdlib\-[0-9]+\.[0-9]+\.[0-9]+\.jar:META\-INF/versions/[0-9]+/module\-info\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-# > Task :text:text:lintDebug
-# > Task :compose:ui:ui-test-font:lintDebug
-# > Task :camera:camera-camera2-pipe-testing:lintDebug
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/bouncycastle/bcprov\-jdk[0-9]+on/[0-9]+\.[0-9]+/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar:META\-INF/versions/[0-9]+/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/bouncycastle/bcprov\-jdk[0-9]+on/[0-9]+\.[0-9]+/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar:META\-INF/versions/[0-9]+/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi\$Ed[0-9]+\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/bouncycastle/bcprov\-jdk[0-9]+on/[0-9]+\.[0-9]+/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar:META\-INF/versions/[0-9]+/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi\$EdDSA\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/bouncycastle/bcprov\-jdk[0-9]+on/[0-9]+\.[0-9]+/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar:META\-INF/versions/[0-9]+/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi\$X[0-9]+\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/bouncycastle/bcprov\-jdk[0-9]+on/[0-9]+\.[0-9]+/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar:META\-INF/versions/[0-9]+/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi\$XDH\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/bouncycastle/bcprov\-jdk[0-9]+on/[0-9]+\.[0-9]+/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar:META\-INF/versions/[0-9]+/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/bouncycastle/bcprov\-jdk[0-9]+on/[0-9]+\.[0-9]+/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar:META\-INF/versions/[0-9]+/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi\$Ed[0-9]+\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/bouncycastle/bcprov\-jdk[0-9]+on/[0-9]+\.[0-9]+/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar:META\-INF/versions/[0-9]+/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi\$EdDSA\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/bouncycastle/bcprov\-jdk[0-9]+on/[0-9]+\.[0-9]+/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar:META\-INF/versions/[0-9]+/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi\$X[0-9]+\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/bouncycastle/bcprov\-jdk[0-9]+on/[0-9]+\.[0-9]+/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar:META\-INF/versions/[0-9]+/org/bouncycastle/jcajce/provider/asymmetric/edec/KeyPairGeneratorSpi\$XDH\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/bouncycastle/bcprov\-jdk[0-9]+on/[0-9]+\.[0-9]+/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar:META\-INF/versions/[0-9]+/module\-info\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/ow[0-9]+/asm/asm\-commons/[0-9]+\.[0-9]+/asm\-commons\-[0-9]+\.[0-9]+\.jar:module\-info\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/ow[0-9]+/asm/asm\-util/[0-9]+\.[0-9]+/asm\-util\-[0-9]+\.[0-9]+\.jar:module\-info\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/ow[0-9]+/asm/asm\-analysis/[0-9]+\.[0-9]+/asm\-analysis\-[0-9]+\.[0-9]+\.jar:module\-info\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/ow[0-9]+/asm/asm\-tree/[0-9]+\.[0-9]+/asm\-tree\-[0-9]+\.[0-9]+\.jar:module\-info\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-Error processing \$CHECKOUT/prebuilts/androidx/external/org/ow[0-9]+/asm/asm/[0-9]+\.[0-9]+/asm\-[0-9]+\.[0-9]+\.jar:module\-info\.class: broken class file\? \(This feature requires ASM[0-9]+\)
-# > Task :compose:runtime:runtime:benchmark:lintDebug
-# > Task :compose:runtime:runtime:integration-tests:lintDebug
-# > Task :internal-testutils-paging:lint
-WARN: Could not read file: \$OUT_DIR/androidx/paging/paging\-common/build/libs/paging\-common\-[0-9]+\.[0-9]+\.[0-9]+\-alpha[0-9]+\.jar!/androidx/paging/DataSource\$InvalidatedCallback\.class; size in bytes: [0-9]+; file type: CLASS
-WARN: Could not read file: \$OUT_DIR/androidx/paging/paging\-common/build/libs/paging\-common\-[0-9]+\.[0-9]+\.[0-9]+\-alpha[0-9]+\.jar!/androidx/paging/DataSource\$KeyType\.class; size in bytes: [0-9]+; file type: CLASS
-WARN: Could not read file: \$OUT_DIR/androidx/paging/paging\-common/build/libs/paging\-common\-[0-9]+\.[0-9]+\.[0-9]+\-alpha[0-9]+\.jar!/androidx/paging/DataSource\$Params\.class; size in bytes: [0-9]+; file type: CLASS
-# > Task :activity:activity-compose:lintDebug
-# > Task :activity:activity-compose:activity-compose-samples:lintDebug
-# > Task :activity:activity-compose:integration-tests:activity-demos:lintDebug
-# > Task :compose:runtime:runtime:lintDebug
-# > Task :compose:integration-tests:demos:common:lintDebug
-# > Task :compose:runtime:runtime-rxjava2:lintDebug
-# > Task :compose:ui:ui-util:lintDebug
-# > Task :compose:ui:ui-geometry:lintDebug
-# > Task :compose:runtime:runtime-saveable:lintDebug
-# > Task :compose:ui:ui-unit:lintDebug
-# > Task :compose:ui:ui-graphics:lintDebug
-# > Task :compose:ui:ui:lintDebug
-# > Task :compose:runtime:runtime-livedata:lintDebug
-# > Task :compose:ui:ui-viewbinding:lintDebug
-# > Task :navigation:navigation-compose:lintDebug
-# > Task :compose:ui:ui-unit:ui-unit-samples:lintDebug
-# > Task :compose:ui:ui-viewbinding:ui-viewbinding-samples:lintDebug
-# > Task :compose:material:material-icons-core:lintDebug
-# > Task :compose:foundation:foundation-layout:lintDebug
-# > Task :compose:animation:animation:lintDebug
-# > Task :compose:foundation:foundation:lintDebug
-# > Task :paging:paging-compose:lintDebug
-# > Task :compose:ui:ui-graphics:ui-graphics-samples:lintDebug
-# > Task :compose:ui:ui-test-junit4:lintDebug
-# > Task :compose:androidview:androidview:lintDebug
-# > Task :compose:test-utils:lintDebug
-# > Task :compose:material:material:lintDebug
-# > Task :compose:runtime:runtime-livedata:runtime-livedata-samples:lintDebug
-# > Task :paging:paging-compose:paging-compose-samples:lintDebug
-# > Task :navigation:navigation-compose:navigation-compose-samples:lintDebug
-# > Task :compose:runtime:runtime-rxjava2:runtime-rxjava2-samples:lintDebug
-# > Task :compose:runtime:runtime-saveable:runtime-saveable-samples:lintDebug
-# > Task :compose:animation:animation:animation-samples:lintDebug
-# > Task :compose:material:material-icons-core:material-icons-core-samples:lintDebug
-# > Task :compose:animation:animation-core:animation-core-samples:lintDebug
-# > Task :compose:ui:ui-text:ui-text-samples:lintDebug
-# > Task :navigation:navigation-compose:integration-tests:navigation-demos:lintDebug
-# > Task :compose:runtime:runtime:runtime-samples:lintDebug
-# > Task :compose:foundation:foundation-layout:foundation-layout-samples:lintDebug
-# > Task :compose:material:material:integration-tests:material-studies:lintDebug
-# > Task :compose:integration-tests:lintDebug
-# > Task :paging:paging-compose:integration-tests:paging-demos:lintDebug
-# > Task :compose:ui:ui:ui-samples:lintDebug
-# > Task :compose:androidview:androidview:integration-tests:androidview-demos:lintDebug
-# > Task :compose:foundation:foundation:foundation-samples:lintDebug
-# > Task :compose:integration-tests:benchmark:lintDebug
-# > Task :compose:material:material:material-samples:lintDebug
-# > Task :compose:foundation:foundation-layout:integration-tests:foundation-layout-demos:lintDebug
-# > Task :compose:animation:animation:integration-tests:animation-demos:lintDebug
-# > Task :compose:integration-tests:macrobenchmark-target:lintDebug
-# > Task :compose:material:material:integration-tests:material-demos:lintDebug
-# > Task :compose:ui:ui:integration-tests:ui-demos:lintDebug
-# > Task :compose:foundation:foundation:integration-tests:foundation-demos:lintDebug
-# > Task :compose:integration-tests:demos:lintDebug
-# > Task :compose:integration-tests:docs-snippets:lintDebug
-# > Task :navigation:navigation-runtime-ktx:lintDebug
-\$SUPPORT/navigation/navigation\-runtime\-ktx/lint\-baseline\.xml: Information: [0-9]+ errors/warnings were listed in the baseline file \(lint\-baseline\.xml\) but not found in the project; perhaps they have been fixed\? Another possible explanation is that lint recently stopped analyzing \(and including results from\) dependent projects by default\. You can turn this back on with android\.lintOptions\.checkDependencies=true\. Unmatched issue types: IllegalExperimentalApiUsage \([0-9]+\) \[LintBaseline\]
-# > Task :autofill:autofill:generateApi
-class androidx\.autofill\.inline\.common\.ImageViewStyle with androidx\.autofill\.inline\.common\.BundledStyle
-class androidx\.autofill\.inline\.common\.ImageViewStyle\.Builder with androidx\.autofill\.inline\.common\.ViewStyle\.BaseBuilder , androidx\.autofill\.inline\.common\.BundledStyle\.Builder
-class androidx\.autofill\.inline\.common\.TextViewStyle with androidx\.autofill\.inline\.common\.BundledStyle
-class androidx\.autofill\.inline\.common\.TextViewStyle\.Builder with androidx\.autofill\.inline\.common\.ViewStyle\.BaseBuilder , androidx\.autofill\.inline\.common\.BundledStyle\.Builder
-class androidx\.autofill\.inline\.common\.ViewStyle with androidx\.autofill\.inline\.common\.BundledStyle
-androidx\.autofill\.inline\.common\.BundledStyle\#assertIsValid
-androidx\.autofill\.inline\.common\.BundledStyle\#isValid
-androidx\.autofill\.inline\.common\.BundledStyle\#getBundle
-class androidx\.autofill\.inline\.common\.ViewStyle\.Builder with androidx\.autofill\.inline\.common\.ViewStyle\.BaseBuilder , androidx\.autofill\.inline\.common\.BundledStyle\.Builder
-class androidx\.autofill\.inline\.v[0-9]+\.InlineSuggestionUi\.Style with androidx\.autofill\.inline\.common\.BundledStyle
-class androidx\.autofill\.inline\.v[0-9]+\.InlineSuggestionUi\.Style\.Builder with androidx\.autofill\.inline\.common\.BundledStyle\.Builder
-class androidx\.autofill\.inline\.v[0-9]+\.InlineSuggestionUi\.Content with androidx\.autofill\.inline\.common\.SlicedContent
-androidx\.autofill\.inline\.common\.SlicedContent\#getVersion
-androidx\.autofill\.inline\.common\.SlicedContent\#getSlice
-class androidx\.autofill\.inline\.v[0-9]+\.InlineSuggestionUi\.Content\.Builder with androidx\.autofill\.inline\.common\.SlicedContent\.Builder
-# > Task :camera:camera-camera2:generateApi
-class androidx\.camera\.core\.impl\.SessionConfig\.ValidatingBuilder with androidx\.camera\.core\.impl\.SessionConfig\.BaseBuilder
-class androidx\.camera\.core\.impl\.SessionConfig\.Builder with androidx\.camera\.core\.impl\.SessionConfig\.BaseBuilder
-# > Task :core:core:generateApi
-class androidx\.core\.graphics\.drawable\.IconCompat with androidx\.versionedparcelable\.CustomVersionedParcelable
-class androidx\.core\.graphics\.TypefaceCompatApi[0-9]+Impl with androidx\.core\.graphics\.TypefaceCompatApi[0-9]+Impl , androidx\.core\.graphics\.TypefaceCompatBaseImpl
-class androidx\.core\.graphics\.TypefaceCompatApi[0-9]+Impl with androidx\.core\.graphics\.TypefaceCompatBaseImpl
-# > Task :hilt:hilt-lifecycle-viewmodel:generateApi
-class androidx\.hilt\.lifecycle\.HiltViewModelFactory with androidx\.lifecycle\.ViewModelProvider\.KeyedFactory , androidx\.lifecycle\.ViewModelProvider\.OnRequeryFactory
-class androidx\.lifecycle\.AbstractSavedStateViewModelFactory with androidx\.lifecycle\.ViewModelProvider\.KeyedFactory , androidx\.lifecycle\.ViewModelProvider\.OnRequeryFactory
-# > Task :leanback:leanback:generateApi
-class androidx\.leanback\.app\.HeadersFragment with androidx\.leanback\.app\.BaseRowFragment
-androidx\.leanback\.app\.BaseRowFragment\#getAdapter
-androidx\.leanback\.app\.BaseRowFragment\#setAlignment
-androidx\.leanback\.app\.BaseRowFragment\#setSelectedPosition
-androidx\.leanback\.app\.BaseRowFragment\#onTransitionPrepare
-androidx\.leanback\.app\.BaseRowFragment\#onDestroyView
-androidx\.leanback\.app\.BaseRowFragment\#setAdapter
-androidx\.leanback\.app\.BaseRowFragment\#getVerticalGridView
-androidx\.leanback\.app\.BaseRowFragment\#getSelectedPosition
-androidx\.leanback\.app\.BaseRowFragment\#getBridgeAdapter
-androidx\.leanback\.app\.BaseRowFragment\#getPresenterSelector
-androidx\.leanback\.app\.BaseRowFragment\#onCreateView
-androidx\.leanback\.app\.BaseRowFragment\#onSaveInstanceState
-androidx\.leanback\.app\.BaseRowFragment\#setPresenterSelector
-class androidx\.leanback\.app\.HeadersSupportFragment with androidx\.leanback\.app\.BaseRowSupportFragment
-androidx\.leanback\.app\.BaseRowSupportFragment\#getAdapter
-androidx\.leanback\.app\.BaseRowSupportFragment\#setAlignment
-androidx\.leanback\.app\.BaseRowSupportFragment\#setSelectedPosition
-androidx\.leanback\.app\.BaseRowSupportFragment\#onTransitionPrepare
-androidx\.leanback\.app\.BaseRowSupportFragment\#onDestroyView
-androidx\.leanback\.app\.BaseRowSupportFragment\#setAdapter
-androidx\.leanback\.app\.BaseRowSupportFragment\#getVerticalGridView
-androidx\.leanback\.app\.BaseRowSupportFragment\#getSelectedPosition
-androidx\.leanback\.app\.BaseRowSupportFragment\#getBridgeAdapter
-androidx\.leanback\.app\.BaseRowSupportFragment\#getPresenterSelector
-androidx\.leanback\.app\.BaseRowSupportFragment\#onCreateView
-androidx\.leanback\.app\.BaseRowSupportFragment\#onSaveInstanceState
-androidx\.leanback\.app\.BaseRowSupportFragment\#setPresenterSelector
-class androidx\.leanback\.app\.RowsFragment with androidx\.leanback\.app\.BaseRowFragment
-androidx\.leanback\.app\.BaseRowFragment\#onTransitionStart
-class androidx\.leanback\.app\.RowsSupportFragment with androidx\.leanback\.app\.BaseRowSupportFragment
-androidx\.leanback\.app\.BaseRowSupportFragment\#onTransitionStart
-androidx\.leanback\.app\.BaseRowSupportFragment\#getPresenterSelectorandroidx\.leanback\.app\.BaseRowFragment\#getAdapter
-androidx\.leanback\.app\.BaseRowFragment\#setAlignmentandroidx\.leanback\.app\.BaseRowSupportFragment\#onSaveInstanceState
-androidx\.leanback\.app\.BaseRowSupportFragment\#setPresenterSelectorandroidx\.leanback\.app\.BaseRowFragment\#setSelectedPosition
-class androidx\.leanback\.widget\.SearchEditText with androidx\.leanback\.widget\.StreamingTextView
-androidx\.leanback\.widget\.StreamingTextView\#setFinalRecognizedText
-androidx\.leanback\.widget\.StreamingTextView\#isLayoutRtl
-androidx\.leanback\.widget\.StreamingTextView\#reset
-androidx\.leanback\.widget\.StreamingTextView\#updateRecognizedText
-androidx\.leanback\.widget\.StreamingTextView\#onInitializeAccessibilityNodeInfo
-androidx\.leanback\.widget\.StreamingTextView\#setCustomSelectionActionModeCallback
-# > Task :lifecycle:lifecycle-viewmodel-savedstate:generateApi
-class androidx\.lifecycle\.SavedStateViewModelFactory with androidx\.lifecycle\.ViewModelProvider\.KeyedFactory , androidx\.lifecycle\.ViewModelProvider\.OnRequeryFactory
-# > Task :media2:media2-common:generateApi
-class androidx\.media[0-9]+\.common\.CallbackMediaItem with androidx\.versionedparcelable\.CustomVersionedParcelable
-class androidx\.media[0-9]+\.common\.FileMediaItem with androidx\.versionedparcelable\.CustomVersionedParcelable
-class androidx\.media[0-9]+\.common\.MediaItem with androidx\.versionedparcelable\.CustomVersionedParcelable
-androidx\.versionedparcelable\.CustomVersionedParcelable\#onPostParceling
-class androidx\.media[0-9]+\.common\.MediaMetadata with androidx\.versionedparcelable\.CustomVersionedParcelable
-class androidx\.media[0-9]+\.common\.SessionPlayer\.TrackInfo with androidx\.versionedparcelable\.CustomVersionedParcelable
-class androidx\.media[0-9]+\.common\.UriMediaItem with androidx\.versionedparcelable\.CustomVersionedParcelable
-# > Task :media2:media2-player:generateApi
-class androidx\.media[0-9]+\.player\.MediaPlayer\.TrackInfo with androidx\.versionedparcelable\.CustomVersionedParcelable
-# > Task :media2:media2-widget:generateApi
-class androidx\.media[0-9]+\.session\.MediaController\.Builder with androidx\.media[0-9]+\.session\.MediaController\.BuilderBase
-class androidx\.media[0-9]+\.widget\.MediaControlView with androidx\.media[0-9]+\.widget\.MediaViewGroup
-androidx\.media[0-9]+\.widget\.MediaViewGroup\#onVisibilityAggregated
-class androidx\.media[0-9]+\.widget\.VideoView with androidx\.media[0-9]+\.widget\.SelectiveLayout , androidx\.media[0-9]+\.widget\.MediaViewGroup
-androidx\.media[0-9]+\.widget\.SelectiveLayout\#generateLayoutParams
-androidx\.media[0-9]+\.widget\.SelectiveLayout\#onLayout
-androidx\.media[0-9]+\.widget\.SelectiveLayout\#shouldDelayChildPressedState
-# > Task :media2:media2-session:generateApi
-class androidx\.media[0-9]+\.session\.MediaBrowser\.Builder with androidx\.media[0-9]+\.session\.MediaController\.BuilderBase
-class androidx\.media[0-9]+\.session\.MediaLibraryService\.MediaLibrarySession\.Builder with androidx\.media[0-9]+\.session\.MediaSession\.BuilderBase
-class androidx\.media[0-9]+\.session\.MediaSession\.Builder with androidx\.media[0-9]+\.session\.MediaSession\.BuilderBase
-class androidx\.media[0-9]+\.session\.LibraryResult with androidx\.versionedparcelable\.CustomVersionedParcelable
-class androidx\.media[0-9]+\.session\.SessionResult with androidx\.versionedparcelable\.CustomVersionedParcelable
-# > Task :vectordrawable:vectordrawable:generateApi
-class androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCompat with androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon
-androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon\#setFilterBitmap
-androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon\#setColorFilter
-androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon\#getMinimumHeight
-androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon\#setHotspot
-androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon\#getPadding
-androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon\#setChangingConfigurations
-androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon\#jumpToCurrentState
-androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon\#applyTheme
-androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon\#setHotspotBounds
-androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon\#clearColorFilter
-androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon\#getState
-androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon\#getTransparentRegion
-androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon\#getMinimumWidth
-androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon\#setState
-androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon\#getCurrent
-# > Task :tvprovider:tvprovider:generateApi
-class androidx\.tvprovider\.media\.tv\.PreviewProgram with androidx\.tvprovider\.media\.tv\.BasePreviewProgram , androidx\.tvprovider\.media\.tv\.BaseProgram
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getReviewRating
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getSeasonTitle
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getInteractionCount
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#isLive
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getTitle
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#isBrowsable
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getContentId
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getReleaseDate
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getIntent
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getEpisodeTitle
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getAudioLanguages
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getLogoContentDescription
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getEpisodeNumber
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getLongDescription
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getLastPlaybackPositionMillis
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getVideoHeight
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getPosterArtAspectRatio
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getType
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getGenre
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getEndTimeUtcMillis
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getPosterArtUri
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getPreviewAudioUri
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getPackageName
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getLogoUri
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getSeriesId
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getInternalProviderId
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getTvSeriesItemType
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getStartTimeUtcMillis
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getInternalProviderDataByteArray
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getAuthor
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getItemCount
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getIntentUri
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getId
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getOfferPrice
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getDescription
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getThumbnailAspectRatio
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getAvailability
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getContentRatings
-androidx\.tvprovider\.media\.tv\.BaseProgram\#hashCode
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getReviewRatingStyle
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getDurationMillis
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getInternalProviderFlag[0-9]+
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getSeasonNumber
-androidx\.tvprovider\.media\.tv\.BaseProgram\#isSearchable
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getVideoWidth
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getPreviewVideoUri
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getInteractionType
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#getStartingPrice
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getThumbnailUri
-androidx\.tvprovider\.media\.tv\.BasePreviewProgram\#isTransient
-androidx\.tvprovider\.media\.tv\.BaseProgram\#getCanonicalGenres
-class androidx\.tvprovider\.media\.tv\.PreviewProgram\.Builder with androidx\.tvprovider\.media\.tv\.BasePreviewProgram\.Builder , androidx\.tvprovider\.media\.tv\.BaseProgram\.Builder
-class androidx\.tvprovider\.media\.tv\.PreviewProgram with androidx\.tvprovider\.media\.tv\.BasePreviewProgram , androidx\.tvprovider\.media\.tv\.BaseProgram class androidx\.tvprovider\.media\.tv\.Program with androidx\.tvprovider\.media\.tv\.BaseProgram
-class androidx\.tvprovider\.media\.tv\.Program\.Builder with androidx\.tvprovider\.media\.tv\.BaseProgram\.Builder
-class androidx\.tvprovider\.media\.tv\.WatchNextProgram with androidx\.tvprovider\.media\.tv\.BasePreviewProgram , androidx\.tvprovider\.media\.tv\.BaseProgram
-class androidx\.tvprovider\.media\.tv\.WatchNextProgram\.Builder with androidx\.tvprovider\.media\.tv\.BasePreviewProgram\.Builder , androidx\.tvprovider\.media\.tv\.BaseProgram\.Builder
-class androidx\.tvprovider\.media\.tv\.Program with androidx\.tvprovider\.media\.tv\.BaseProgram
-# > Task :vectordrawable:vectordrawable-animated:generateApi
-class androidx\.vectordrawable\.graphics\.drawable\.AnimatedVectorDrawableCompat with androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon
-androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon\#setStateclass androidx\.vectordrawable\.graphics\.drawable\.AnimatedVectorDrawableCompat with androidx\.vectordrawable\.graphics\.drawable\.VectorDrawableCommon
 # > Task :docs-public:dokkaKotlinDocs
 No documentation for .*
 Unresolved link to .*
 Unresolved function .*
 at java.base.*
 # > Task :compose:ui:ui-inspection:externalNativeBuildDebug
-Build compose_inspection_jni_.*
\ No newline at end of file
+Build compose_inspection_jni_.*
+# > Task :security:security-identity-credential:lintDebug
+Error processing \$CHECKOUT\/prebuilts\/androidx\/external\/org\/bouncycastle\/bcprov\-jdk[0-9]+on\/[0-9]+\.[0-9]+\/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar\:META\-INF\/versions\/[0-9]+\/org\/bouncycastle\/jcajce\/provider\/asymmetric\/edec\/KeyFactorySpi\.class\: broken class file\? \(This feature requires ASM[0-9]+\)
+Error processing \$CHECKOUT\/prebuilts\/androidx\/external\/org\/bouncycastle\/bcprov\-jdk[0-9]+on\/[0-9]+\.[0-9]+\/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar\:META\-INF\/versions\/[0-9]+\/org\/bouncycastle\/jcajce\/provider\/asymmetric\/edec\/KeyFactorySpi\$Ed[0-9]+\.class\: broken class file\? \(This feature requires ASM[0-9]+\)
+Error processing \$CHECKOUT\/prebuilts\/androidx\/external\/org\/bouncycastle\/bcprov\-jdk[0-9]+on\/[0-9]+\.[0-9]+\/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar\:META\-INF\/versions\/[0-9]+\/org\/bouncycastle\/jcajce\/provider\/asymmetric\/edec\/KeyFactorySpi\$EdDSA\.class\: broken class file\? \(This feature requires ASM[0-9]+\)
+Error processing \$CHECKOUT\/prebuilts\/androidx\/external\/org\/bouncycastle\/bcprov\-jdk[0-9]+on\/[0-9]+\.[0-9]+\/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar\:META\-INF\/versions\/[0-9]+\/org\/bouncycastle\/jcajce\/provider\/asymmetric\/edec\/KeyFactorySpi\$X[0-9]+\.class\: broken class file\? \(This feature requires ASM[0-9]+\)
+Error processing \$CHECKOUT\/prebuilts\/androidx\/external\/org\/bouncycastle\/bcprov\-jdk[0-9]+on\/[0-9]+\.[0-9]+\/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar\:META\-INF\/versions\/[0-9]+\/org\/bouncycastle\/jcajce\/provider\/asymmetric\/edec\/KeyFactorySpi\$XDH\.class\: broken class file\? \(This feature requires ASM[0-9]+\)
+Error processing \$CHECKOUT\/prebuilts\/androidx\/external\/org\/bouncycastle\/bcprov\-jdk[0-9]+on\/[0-9]+\.[0-9]+\/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar\:META\-INF\/versions\/[0-9]+\/org\/bouncycastle\/jcajce\/provider\/asymmetric\/edec\/KeyPairGeneratorSpi\.class\: broken class file\? \(This feature requires ASM[0-9]+\)
+Error processing \$CHECKOUT\/prebuilts\/androidx\/external\/org\/bouncycastle\/bcprov\-jdk[0-9]+on\/[0-9]+\.[0-9]+\/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar\:META\-INF\/versions\/[0-9]+\/org\/bouncycastle\/jcajce\/provider\/asymmetric\/edec\/KeyPairGeneratorSpi\$Ed[0-9]+\.class\: broken class file\? \(This feature requires ASM[0-9]+\)
+Error processing \$CHECKOUT\/prebuilts\/androidx\/external\/org\/bouncycastle\/bcprov\-jdk[0-9]+on\/[0-9]+\.[0-9]+\/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar\:META\-INF\/versions\/[0-9]+\/org\/bouncycastle\/jcajce\/provider\/asymmetric\/edec\/KeyPairGeneratorSpi\$EdDSA\.class\: broken class file\? \(This feature requires ASM[0-9]+\)
+Error processing \$CHECKOUT\/prebuilts\/androidx\/external\/org\/bouncycastle\/bcprov\-jdk[0-9]+on\/[0-9]+\.[0-9]+\/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar\:META\-INF\/versions\/[0-9]+\/org\/bouncycastle\/jcajce\/provider\/asymmetric\/edec\/KeyPairGeneratorSpi\$X[0-9]+\.class\: broken class file\? \(This feature requires ASM[0-9]+\)
+Error processing \$CHECKOUT\/prebuilts\/androidx\/external\/org\/bouncycastle\/bcprov\-jdk[0-9]+on\/[0-9]+\.[0-9]+\/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar\:META\-INF\/versions\/[0-9]+\/org\/bouncycastle\/jcajce\/provider\/asymmetric\/edec\/KeyPairGeneratorSpi\$XDH\.class\: broken class file\? \(This feature requires ASM[0-9]+\)
+Error processing \$CHECKOUT\/prebuilts\/androidx\/external\/org\/bouncycastle\/bcprov\-jdk[0-9]+on\/[0-9]+\.[0-9]+\/bcprov\-jdk[0-9]+on\-[0-9]+\.[0-9]+\.jar\:META\-INF\/versions\/[0-9]+\/module\-info\.class\: broken class file\? \(This feature requires ASM[0-9]+\)
\ No newline at end of file
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentStore.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentStore.java
index 71626f1..41bd97e 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentStore.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentStore.java
@@ -215,6 +215,7 @@
     }
 
     @NonNull
+    @SuppressWarnings("MixedMutabilityReturnType")
     List<Fragment> getFragments() {
         if (mAdded.isEmpty()) {
             return Collections.emptyList();
diff --git a/gradlew b/gradlew
index 3b76e03..f5d3479 100755
--- a/gradlew
+++ b/gradlew
@@ -222,39 +222,48 @@
   TMPDIR_ARG="-Djava.io.tmpdir=$TMPDIR"
 fi
 
-# expand the "--ci" flag
-compact="--ci"
-expanded="--stacktrace\
- -Pandroidx.summarizeStderr\
- -Pandroidx.allWarningsAsErrors\
- -Pandroidx.coverageEnabled=true\
- -Pandroidx.enableAffectedModuleDetection\
- -Pandroidx.validateNoUnrecognizedMessages\
- -PverifyUpToDate\
- --no-watch-fs\
- --no-daemon\
- --offline"
-# Make a copy of our list of arguments, and iterate through the copy
-for arg in "$@"; do
-  # Remove this argument from our list of arguments.
-  # By the time we've completed this loop, we will have removed the original copy of
-  # each argument, and potentially re-added a new copy or an expansion of each.
-  shift
-  # Determine whether to expand this argument
-  if [ "$arg" == "$compact" ]; then
-    # Add the expansion to our arguments
-    set -- "$@" $expanded
-    echo "gradlew expanded '$compact' into '$expanded'"
-    echo
-    # We avoid re-adding this argument itself back into the list for two reasons:
-    # 1. This argument might not be directly understood by Gradle
-    # 2. We want to enforce that all behaviors enabled by this flag can be toggled independently,
-    # so we don't want it to be easy to inadvertently check for the presence of this flag
-    # specifically
-  else
-    # Add this argument back into our arguments
-    set -- "$@" "$arg"
+# Expand some arguments
+for compact in "--ci" "--strict"; do
+  if [ "$compact" == "--ci" ]; then
+    expanded="--strict\
+     --stacktrace\
+     -Pandroidx.summarizeStderr\
+     -Pandroidx.coverageEnabled=true\
+     -Pandroidx.enableAffectedModuleDetection\
+     --no-watch-fs"
   fi
+  if [ "$compact" == "--strict" ]; then
+    expanded="-Pandroidx.allWarningsAsErrors\
+     -Pandroidx.validateNoUnrecognizedMessages\
+     -PverifyUpToDate\
+     --no-watch-fs\
+     --no-daemon\
+     --offline"
+  fi
+
+  # Expand an individual argument
+  # Start by making a copy of our list of arguments and iterating through the copy
+  for arg in "$@"; do
+    # Remove this argument from our list of arguments.
+    # By the time we've completed this loop, we will have removed the original copy of
+    # each argument, and potentially re-added a new copy or an expansion of each.
+    shift
+    # Determine whether to expand this argument
+    if [ "$arg" == "$compact" ]; then
+      # Add the expansion to our arguments
+      set -- "$@" $expanded
+      echo "gradlew expanded '$compact' into '$expanded'"
+      echo
+      # We avoid re-adding this argument itself back into the list for two reasons:
+      # 1. This argument might not be directly understood by Gradle
+      # 2. We want to enforce that all behaviors enabled by this flag can be toggled independently,
+      # so we don't want it to be easy to inadvertently check for the presence of this flag
+      # specifically
+    else
+      # Add this argument back into our arguments
+      set -- "$@" "$arg"
+    fi
+  done
 done
 
 function tryToDiagnosePossibleDaemonFailure() {
diff --git a/lifecycle/lifecycle-viewmodel-compose/api/current.txt b/lifecycle/lifecycle-viewmodel-compose/api/current.txt
index 72357ec..a6f6f3b 100644
--- a/lifecycle/lifecycle-viewmodel-compose/api/current.txt
+++ b/lifecycle/lifecycle-viewmodel-compose/api/current.txt
@@ -2,8 +2,8 @@
 package androidx.lifecycle.viewmodel.compose {
 
   public final class LocalViewModelStoreOwner {
-    method public androidx.compose.runtime.ProvidableCompositionLocal<androidx.lifecycle.ViewModelStoreOwner> asProvidableCompositionLocal();
     method @androidx.compose.runtime.Composable public androidx.lifecycle.ViewModelStoreOwner getCurrent();
+    method public infix androidx.compose.runtime.ProvidedValue<androidx.lifecycle.ViewModelStoreOwner> provides(androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner);
     property @androidx.compose.runtime.Composable public final androidx.lifecycle.ViewModelStoreOwner current;
     field public static final androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner INSTANCE;
   }
diff --git a/lifecycle/lifecycle-viewmodel-compose/api/public_plus_experimental_current.txt b/lifecycle/lifecycle-viewmodel-compose/api/public_plus_experimental_current.txt
index 72357ec..a6f6f3b 100644
--- a/lifecycle/lifecycle-viewmodel-compose/api/public_plus_experimental_current.txt
+++ b/lifecycle/lifecycle-viewmodel-compose/api/public_plus_experimental_current.txt
@@ -2,8 +2,8 @@
 package androidx.lifecycle.viewmodel.compose {
 
   public final class LocalViewModelStoreOwner {
-    method public androidx.compose.runtime.ProvidableCompositionLocal<androidx.lifecycle.ViewModelStoreOwner> asProvidableCompositionLocal();
     method @androidx.compose.runtime.Composable public androidx.lifecycle.ViewModelStoreOwner getCurrent();
+    method public infix androidx.compose.runtime.ProvidedValue<androidx.lifecycle.ViewModelStoreOwner> provides(androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner);
     property @androidx.compose.runtime.Composable public final androidx.lifecycle.ViewModelStoreOwner current;
     field public static final androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner INSTANCE;
   }
diff --git a/lifecycle/lifecycle-viewmodel-compose/api/restricted_current.txt b/lifecycle/lifecycle-viewmodel-compose/api/restricted_current.txt
index 72357ec..a6f6f3b 100644
--- a/lifecycle/lifecycle-viewmodel-compose/api/restricted_current.txt
+++ b/lifecycle/lifecycle-viewmodel-compose/api/restricted_current.txt
@@ -2,8 +2,8 @@
 package androidx.lifecycle.viewmodel.compose {
 
   public final class LocalViewModelStoreOwner {
-    method public androidx.compose.runtime.ProvidableCompositionLocal<androidx.lifecycle.ViewModelStoreOwner> asProvidableCompositionLocal();
     method @androidx.compose.runtime.Composable public androidx.lifecycle.ViewModelStoreOwner getCurrent();
+    method public infix androidx.compose.runtime.ProvidedValue<androidx.lifecycle.ViewModelStoreOwner> provides(androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner);
     property @androidx.compose.runtime.Composable public final androidx.lifecycle.ViewModelStoreOwner current;
     field public static final androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner INSTANCE;
   }
diff --git a/lifecycle/lifecycle-viewmodel-compose/build.gradle b/lifecycle/lifecycle-viewmodel-compose/build.gradle
index a89b2a0..f914120 100644
--- a/lifecycle/lifecycle-viewmodel-compose/build.gradle
+++ b/lifecycle/lifecycle-viewmodel-compose/build.gradle
@@ -43,7 +43,7 @@
     androidTestImplementation(ANDROIDX_TEST_RUNNER)
     androidTestImplementation(JUNIT)
     androidTestImplementation(TRUTH)
-    androidTestImplementation "androidx.fragment:fragment:1.2.4"
+    androidTestImplementation "androidx.fragment:fragment:1.3.0"
     androidTestImplementation "androidx.appcompat:appcompat:1.1.0"
     androidTestImplementation projectOrArtifact(":activity:activity-compose")
 }
diff --git a/lifecycle/lifecycle-viewmodel-compose/src/androidTest/java/androidx/lifecycle/viewmodel/compose/ViewModelTest.kt b/lifecycle/lifecycle-viewmodel-compose/src/androidTest/java/androidx/lifecycle/viewmodel/compose/ViewModelTest.kt
index d07f871..1122d1f 100644
--- a/lifecycle/lifecycle-viewmodel-compose/src/androidTest/java/androidx/lifecycle/viewmodel/compose/ViewModelTest.kt
+++ b/lifecycle/lifecycle-viewmodel-compose/src/androidTest/java/androidx/lifecycle/viewmodel/compose/ViewModelTest.kt
@@ -42,9 +42,7 @@
     public fun viewModelCreatedViaDefaultFactory() {
         val owner = FakeViewModelStoreOwner()
         rule.setContent {
-            CompositionLocalProvider(
-                LocalViewModelStoreOwner.asProvidableCompositionLocal() provides owner
-            ) {
+            CompositionLocalProvider(LocalViewModelStoreOwner provides owner) {
                 viewModel<TestViewModel>()
             }
         }
@@ -57,9 +55,7 @@
         val owner = FakeViewModelStoreOwner()
         var createdInComposition: Any? = null
         rule.setContent {
-            CompositionLocalProvider(
-                LocalViewModelStoreOwner.asProvidableCompositionLocal() provides owner
-            ) {
+            CompositionLocalProvider(LocalViewModelStoreOwner provides owner) {
                 createdInComposition = viewModel<TestViewModel>()
             }
         }
@@ -74,9 +70,7 @@
         val owner = FakeViewModelStoreOwner()
         var createdInComposition: Any? = null
         rule.setContent {
-            CompositionLocalProvider(
-                LocalViewModelStoreOwner.asProvidableCompositionLocal() provides owner
-            ) {
+            CompositionLocalProvider(LocalViewModelStoreOwner provides owner) {
                 createdInComposition = viewModel<TestViewModel>()
             }
         }
@@ -91,9 +85,7 @@
         val owner = FakeViewModelStoreOwner()
         var createdInComposition: Any? = null
         rule.setContent {
-            CompositionLocalProvider(
-                LocalViewModelStoreOwner.asProvidableCompositionLocal() provides owner
-            ) {
+            CompositionLocalProvider(LocalViewModelStoreOwner provides owner) {
                 createdInComposition =
                     viewModel<TestViewModel>(key = "test")
             }
@@ -109,9 +101,7 @@
         val owner = FakeViewModelStoreOwner()
         val customFactory = FakeViewModelProviderFactory()
         rule.setContent {
-            CompositionLocalProvider(
-                LocalViewModelStoreOwner.asProvidableCompositionLocal() provides owner
-            ) {
+            CompositionLocalProvider(LocalViewModelStoreOwner provides owner) {
                 viewModel<TestViewModel>(factory = customFactory)
             }
         }
@@ -124,9 +114,7 @@
         val owner = FakeViewModelStoreOwner()
         val customFactory = FakeViewModelProviderFactory()
         rule.setContent {
-            CompositionLocalProvider(
-                LocalViewModelStoreOwner.asProvidableCompositionLocal() provides owner
-            ) {
+            CompositionLocalProvider(LocalViewModelStoreOwner provides owner) {
                 viewModel<TestViewModel>(factory = customFactory)
             }
         }
@@ -140,9 +128,7 @@
         var createdInComposition: Any? = null
         val customFactory = FakeViewModelProviderFactory()
         rule.setContent {
-            CompositionLocalProvider(
-                LocalViewModelStoreOwner.asProvidableCompositionLocal() provides owner
-            ) {
+            CompositionLocalProvider(LocalViewModelStoreOwner provides owner) {
                 createdInComposition = viewModel<TestViewModel>()
             }
         }
@@ -158,9 +144,7 @@
         var createdInComposition: Any? = null
         val customFactory = FakeViewModelProviderFactory()
         rule.setContent {
-            CompositionLocalProvider(
-                LocalViewModelStoreOwner.asProvidableCompositionLocal() provides owner
-            ) {
+            CompositionLocalProvider(LocalViewModelStoreOwner provides owner) {
                 createdInComposition =
                     viewModel<TestViewModel>(key = "test")
             }
diff --git a/lifecycle/lifecycle-viewmodel-compose/src/main/java/androidx/lifecycle/viewmodel/compose/LocalViewModelStoreOwner.kt b/lifecycle/lifecycle-viewmodel-compose/src/main/java/androidx/lifecycle/viewmodel/compose/LocalViewModelStoreOwner.kt
index c3ea604..3c3d03c 100644
--- a/lifecycle/lifecycle-viewmodel-compose/src/main/java/androidx/lifecycle/viewmodel/compose/LocalViewModelStoreOwner.kt
+++ b/lifecycle/lifecycle-viewmodel-compose/src/main/java/androidx/lifecycle/viewmodel/compose/LocalViewModelStoreOwner.kt
@@ -17,7 +17,8 @@
 package androidx.lifecycle.viewmodel.compose
 
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.ProvidableCompositionLocal
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.ProvidedValue
 import androidx.compose.runtime.compositionLocalOf
 import androidx.compose.ui.platform.LocalView
 import androidx.lifecycle.ViewModelStoreOwner
@@ -40,9 +41,11 @@
             ?: error("No ViewModelStoreOwner provided")
 
     /**
-     * Returns a [ProvidableCompositionLocal] which you can use to override the value for the
-     * subtree.
+     * Associates a [LocalViewModelStoreOwner] key to a value in a call to
+     * [CompositionLocalProvider].
      */
-    public fun asProvidableCompositionLocal():
-        ProvidableCompositionLocal<ViewModelStoreOwner?> = LocalViewModelStoreOwner
+    public infix fun provides(viewModelStoreOwner: ViewModelStoreOwner):
+        ProvidedValue<ViewModelStoreOwner?> {
+            return LocalViewModelStoreOwner.provides(viewModelStoreOwner)
+        }
 }
diff --git a/lifecycle/settings.gradle b/lifecycle/settings.gradle
index 5ca714e..c700624 100644
--- a/lifecycle/settings.gradle
+++ b/lifecycle/settings.gradle
@@ -24,6 +24,7 @@
     if (name == ":annotation:annotation") return true
     if (name == ":internal-testutils-runtime") return true
     if (name == ":internal-testutils-truth") return true
+    if (name == ":compose:internal-lint-checks") return true
     return false
 })
 
diff --git a/lint-checks/integration-tests/build.gradle b/lint-checks/integration-tests/build.gradle
new file mode 100644
index 0000000..e9737b0
--- /dev/null
+++ b/lint-checks/integration-tests/build.gradle
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import androidx.build.BuildOnServerKt
+import androidx.build.uptodatedness.EnableCachingKt
+import org.apache.tools.ant.filters.ReplaceTokens
+
+import static androidx.build.dependencies.DependenciesKt.KOTLIN_STDLIB
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+    id("AndroidXUiPlugin")
+    id("org.jetbrains.kotlin.android")
+}
+
+dependencies {
+    implementation("androidx.annotation:annotation:1.0.0")
+    implementation(KOTLIN_STDLIB)
+}
+
+androidx {
+    name = "Lint Checks Integration Tests"
+    description = "This is a sample library for confirming that lint checks execute correctly, b/177437928"
+}
+
+android {
+    lintOptions {
+        // lint is supposed to detect errors in this project
+        // We don't need to see the errors in stdout
+        textOutput("${buildDir}/lint-output.txt")
+        // We don't want errors to cause lint to fail
+        abortOnError false
+    }
+}
+
+
+class CompareFilesTask extends DefaultTask {
+    @InputFile
+    File actualFile
+    @InputFile
+    File expectedFile
+
+    @TaskAction
+    def compare() {
+        def actualResults = actualFile.text
+        def expectedResults = expectedFile.text
+        if (actualResults != expectedResults) {
+            throw new GradleException("Incorrect lint results.\n" +
+                "\n" +
+                "Actual   text: '" + actualResults + "'\n" +
+                "\n" +
+                "Expected text: '" + expectedResults + "'\n" +
+                "\n" +
+                "Are all lint checks running?\n" +
+                "\n" +
+                "Actual   output at: " + actualFile + "\n" +
+                "Expected output at: " + expectedFile + "\n")
+        }
+    }
+}
+
+def lintOutputFile = project.file("${buildDir}/reports/lint-results-debug.xml")
+def lintOutputFileNormalized = project.file("${buildDir}/lint-results-normalized/lint-results-debug.xml.normalized")
+
+def normalizeLintOutput = tasks.register("normalizeLintOutput", Copy) {
+    from(lintOutputFile) {
+        filter { line ->
+            return line.replace("${project.rootProject.projectDir}", "\$SUPPORT")
+        }
+    }
+    into(lintOutputFileNormalized.parentFile)
+    rename(".*", lintOutputFileNormalized.name)
+    dependsOn("lintDebug")
+}
+
+def validateLint = tasks.register("validateLint", CompareFilesTask) { task ->
+    task.actualFile = lintOutputFileNormalized
+    task.expectedFile = project.file("expected-lint-results.xml")
+    EnableCachingKt.cacheEvenIfNoOutputs(task)
+    dependsOn(normalizeLintOutput)
+}
+
+BuildOnServerKt.addToBuildOnServer(project, validateLint)
diff --git a/lint-checks/integration-tests/expected-lint-results.xml b/lint-checks/integration-tests/expected-lint-results.xml
new file mode 100644
index 0000000..7dd7360
--- /dev/null
+++ b/lint-checks/integration-tests/expected-lint-results.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.2.0-beta04">
+
+    <issue
+        id="UnknownIssueId"
+        severity="Ignore"
+        message="Unknown issue id &quot;ComposableLambdaParameterNaming&quot;"
+        category="Lint"
+        priority="1"
+        summary="Unknown Lint Issue Id"
+        explanation="Lint will report this issue if it is configured with an issue id it does not recognize in for example Gradle files or `lint.xml` configuration files.">
+        <location
+            file="$SUPPORT/lint-checks/integration-tests/build.gradle"/>
+    </issue>
+
+    <issue
+        id="UnknownIssueId"
+        severity="Ignore"
+        message="Unknown issue id &quot;ComposableLambdaParameterPosition&quot;"
+        category="Lint"
+        priority="1"
+        summary="Unknown Lint Issue Id"
+        explanation="Lint will report this issue if it is configured with an issue id it does not recognize in for example Gradle files or `lint.xml` configuration files.">
+        <location
+            file="$SUPPORT/lint-checks/integration-tests/build.gradle"/>
+    </issue>
+
+    <issue
+        id="UnknownIssueId"
+        severity="Ignore"
+        message="Unknown issue id &quot;ComposableNaming&quot;"
+        category="Lint"
+        priority="1"
+        summary="Unknown Lint Issue Id"
+        explanation="Lint will report this issue if it is configured with an issue id it does not recognize in for example Gradle files or `lint.xml` configuration files.">
+        <location
+            file="$SUPPORT/lint-checks/integration-tests/build.gradle"/>
+    </issue>
+
+    <issue
+        id="UnknownIssueId"
+        severity="Ignore"
+        message="Unknown issue id &quot;CompositionLocalNaming&quot;"
+        category="Lint"
+        priority="1"
+        summary="Unknown Lint Issue Id"
+        explanation="Lint will report this issue if it is configured with an issue id it does not recognize in for example Gradle files or `lint.xml` configuration files.">
+        <location
+            file="$SUPPORT/lint-checks/integration-tests/build.gradle"/>
+    </issue>
+
+    <issue
+        id="BanConcurrentHashMap"
+        severity="Error"
+        message="Detected ConcurrentHashMap usage."
+        category="Correctness"
+        priority="5"
+        summary="ConcurrentHashMap usage is not allowed"
+        explanation="ConcurrentHashMap has an issue on Android’s Lollipop release that can lead to lost updates under thread contention."
+        errorLine1="import java.util.concurrent.ConcurrentHashMap;"
+        errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="$SUPPORT/lint-checks/integration-tests/src/main/java/Sample.java"
+            line="19"
+            column="1"/>
+    </issue>
+
+    <issue
+        id="UnnecessaryLambdaCreation"
+        severity="Error"
+        message="Creating an unnecessary lambda to emit a captured lambda"
+        category="Performance"
+        priority="5"
+        summary="Creating an unnecessary lambda to emit a captured lambda"
+        explanation="Creating this extra lambda instead of just passing the already captured lambda means that during code generation the Compose compiler will insert code around this lambda to track invalidations. This adds some extra runtime cost so you should instead just directly pass the lambda as a parameter to the function."
+        errorLine1="        lambda()"
+        errorLine2="        ~~~~~~">
+        <location
+            file="$SUPPORT/lint-checks/integration-tests/src/main/java/ComposeSample.kt"
+            line="29"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="UnknownNullness"
+        severity="Fatal"
+        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
+        category="Interoperability:Kotlin Interoperability"
+        priority="6"
+        summary="Unknown nullness"
+        explanation="To improve referencing this code from Kotlin, consider adding&#xA;explicit nullness information here with either `@NonNull` or `@Nullable`.&#xA;&#xA;You can set the environment variable&#xA;    `ANDROID_LINT_NULLNESS_IGNORE_DEPRECATED=true`&#xA;if you want lint to ignore classes and members that have been annotated with&#xA;`@Deprecated`."
+        url="https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
+        urls="https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
+        errorLine1="    public static Sample confirmIntrinisicLintChecksRun() {"
+        errorLine2="                  ~~~~~~">
+        <location
+            file="$SUPPORT/lint-checks/integration-tests/src/main/java/Sample.java"
+            line="28"
+            column="19"/>
+    </issue>
+
+    <issue
+        id="UnknownNullness"
+        severity="Fatal"
+        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
+        category="Interoperability:Kotlin Interoperability"
+        priority="6"
+        summary="Unknown nullness"
+        explanation="To improve referencing this code from Kotlin, consider adding&#xA;explicit nullness information here with either `@NonNull` or `@Nullable`.&#xA;&#xA;You can set the environment variable&#xA;    `ANDROID_LINT_NULLNESS_IGNORE_DEPRECATED=true`&#xA;if you want lint to ignore classes and members that have been annotated with&#xA;`@Deprecated`."
+        url="https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
+        urls="https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
+        errorLine1="    public static void confirmCustomAndroidXChecksRun(ConcurrentHashMap m) {"
+        errorLine2="                                                      ~~~~~~~~~~~~~~~~~">
+        <location
+            file="$SUPPORT/lint-checks/integration-tests/src/main/java/Sample.java"
+            line="37"
+            column="55"/>
+    </issue>
+
+</issues>
diff --git a/lint-checks/integration-tests/lint-baseline.xml b/lint-checks/integration-tests/lint-baseline.xml
new file mode 100644
index 0000000..bc3b76a
--- /dev/null
+++ b/lint-checks/integration-tests/lint-baseline.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.2.0-beta04" client="gradle" variant="debug" version="4.2.0-beta04">
+
+    <issue
+        id="UnknownIssueId"
+        message="Unknown issue id &quot;ComposableLambdaParameterNaming&quot;">
+        <location
+            file="build.gradle"/>
+    </issue>
+
+    <issue
+        id="UnknownIssueId"
+        message="Unknown issue id &quot;ComposableLambdaParameterPosition&quot;">
+        <location
+            file="build.gradle"/>
+    </issue>
+
+    <issue
+        id="UnknownIssueId"
+        message="Unknown issue id &quot;ComposableNaming&quot;">
+        <location
+            file="build.gradle"/>
+    </issue>
+
+    <issue
+        id="UnknownIssueId"
+        message="Unknown issue id &quot;CompositionLocalNaming&quot;">
+        <location
+            file="build.gradle"/>
+    </issue>
+
+</issues>
diff --git a/lint-checks/integration-tests/src/main/AndroidManifest.xml b/lint-checks/integration-tests/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..1a39913
--- /dev/null
+++ b/lint-checks/integration-tests/src/main/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<manifest package="androidx.lint.integration.tests" />
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt b/lint-checks/integration-tests/src/main/java/ComposeSample.kt
similarity index 67%
copy from compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt
copy to lint-checks/integration-tests/src/main/java/ComposeSample.kt
index 63fdeeb..c3e2c63 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ExperimentalLayout.kt
+++ b/lint-checks/integration-tests/src/main/java/ComposeSample.kt
@@ -14,7 +14,18 @@
  * limitations under the License.
  */
 
-package androidx.compose.foundation.layout
+package androidx
 
-@RequiresOptIn("The API of this layout is experimental and is likely to change in the future.")
-annotation class ExperimentalLayout
+fun lambdaFunction(lambda: () -> Unit) {
+    lambda()
+}
+
+/**
+ * This function uses an unnecessary lambda and should trigger UnnecessaryLambdaCreationDetector
+ */
+fun confirmCustomComposeLintChecksRun() {
+    val lambda = {}
+    lambdaFunction {
+        lambda()
+    }
+}
diff --git a/lint-checks/integration-tests/src/main/java/Sample.java b/lint-checks/integration-tests/src/main/java/Sample.java
new file mode 100644
index 0000000..5d2ba27
--- /dev/null
+++ b/lint-checks/integration-tests/src/main/java/Sample.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+public class Sample {
+
+    /**
+     * This function does not specify the nullability of its return type.
+     * Lint should catch this and report an error.
+     * If Lint does not catch this, then Lint's intrinsic checks are not running
+     */
+    public static Sample confirmIntrinisicLintChecksRun() {
+        return null;
+    }
+
+    /**
+     * This function uses a disallowed annotation
+     * Lint should catch this and report an error.
+     * If Lint does not catch this, then our AndroidX-specific checks are not running
+     */
+    public static void confirmCustomAndroidXChecksRun(ConcurrentHashMap m) {
+    }
+
+    private Sample() {
+    }
+}
diff --git a/navigation/navigation-compose/src/main/java/androidx/navigation/compose/NavHost.kt b/navigation/navigation-compose/src/main/java/androidx/navigation/compose/NavHost.kt
index c0c80e0..ca68e69 100644
--- a/navigation/navigation-compose/src/main/java/androidx/navigation/compose/NavHost.kt
+++ b/navigation/navigation-compose/src/main/java/androidx/navigation/compose/NavHost.kt
@@ -114,8 +114,7 @@
             // while in the scope of the composable, we provide the navBackStackEntry as the
             // ViewModelStoreOwner and LifecycleOwner
             CompositionLocalProvider(
-                LocalViewModelStoreOwner.asProvidableCompositionLocal()
-                    provides currentNavBackStackEntry,
+                LocalViewModelStoreOwner provides currentNavBackStackEntry,
                 LocalLifecycleOwner provides currentNavBackStackEntry,
                 LocalSavedStateRegistryOwner provides currentNavBackStackEntry
             ) {
diff --git a/navigation/settings.gradle b/navigation/settings.gradle
index cfedfc6..2b1ff64 100644
--- a/navigation/settings.gradle
+++ b/navigation/settings.gradle
@@ -28,6 +28,7 @@
     if (name.startsWith(":internal-testutils-navigation")) return true
     if (name.startsWith(":internal-testutils-runtime")) return true
     if (name.startsWith(":internal-testutils-truth")) return true
+    if (name == ":compose:internal-lint-checks") return true
     return false
 })
 
diff --git a/paging/common/src/main/kotlin/androidx/paging/PagingSource.kt b/paging/common/src/main/kotlin/androidx/paging/PagingSource.kt
index acd691e..bfeaf97 100644
--- a/paging/common/src/main/kotlin/androidx/paging/PagingSource.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/PagingSource.kt
@@ -77,7 +77,7 @@
  * `RecyclerView`.
  *
  * @sample androidx.paging.samples.pageKeyedPagingSourceSample
- * @sample androidx.paging.samples.pageIndexedPagingSourceSample
+ * @sample androidx.paging.samples.itemKeyedPagingSourceSample
  *
  * @see Pager
  */
diff --git a/paging/common/src/main/kotlin/androidx/paging/RemoteMediator.kt b/paging/common/src/main/kotlin/androidx/paging/RemoteMediator.kt
index c735b9b..706f33e 100644
--- a/paging/common/src/main/kotlin/androidx/paging/RemoteMediator.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/RemoteMediator.kt
@@ -96,6 +96,8 @@
      * immediately dispatched when the first [PagingData] is submitted:
      *  * [LAUNCH_INITIAL_REFRESH] to immediately dispatch [load] asynchronously with load type
      *  [REFRESH], to update paginated content when the stream is initialized.
+     *  Note: This also prevents [RemoteMediator] from triggering [PREPEND] or [APPEND] until
+     *  [REFRESH] succeeds.
      *  * [SKIP_INITIAL_REFRESH] to wait for a refresh request from the UI before dispatching [load]
      *  asynchronously with load type [REFRESH].
      */
@@ -131,6 +133,9 @@
         /**
          * Immediately dispatch a [load] asynchronously with load type [REFRESH], to update
          * paginated content when the stream is initialized.
+         *
+         * Note: This also prevents [RemoteMediator] from triggering [PREPEND] or [APPEND] until
+         * [REFRESH] succeeds.
          */
         LAUNCH_INITIAL_REFRESH,
 
diff --git a/paging/guava/src/main/java/androidx/paging/ListenableFutureRemoteMediator.kt b/paging/guava/src/main/java/androidx/paging/ListenableFutureRemoteMediator.kt
index af9973c..982a4e9 100644
--- a/paging/guava/src/main/java/androidx/paging/ListenableFutureRemoteMediator.kt
+++ b/paging/guava/src/main/java/androidx/paging/ListenableFutureRemoteMediator.kt
@@ -16,6 +16,9 @@
 
 package androidx.paging
 
+import androidx.paging.LoadType.APPEND
+import androidx.paging.LoadType.PREPEND
+import androidx.paging.LoadType.REFRESH
 import androidx.paging.RemoteMediator.InitializeAction.LAUNCH_INITIAL_REFRESH
 import com.google.common.util.concurrent.Futures
 import com.google.common.util.concurrent.ListenableFuture
@@ -71,6 +74,8 @@
      * @return [InitializeAction] indicating the action to take after initialization:
      *  * [LAUNCH_INITIAL_REFRESH] to immediately dispatch a [load] asynchronously with load type
      *  [LoadType.REFRESH], to update paginated content when the stream is initialized.
+     *  Note: This also prevents [RemoteMediator] from triggering [PREPEND] or [APPEND] until
+     *  [REFRESH] succeeds.
      *  * [SKIP_INITIAL_REFRESH][InitializeAction.SKIP_INITIAL_REFRESH] to wait for a
      *  refresh request from the UI before dispatching a [load] with load type [LoadType.REFRESH].
      */
diff --git a/paging/rxjava2/src/main/java/androidx/paging/rxjava2/RxRemoteMediator.kt b/paging/rxjava2/src/main/java/androidx/paging/rxjava2/RxRemoteMediator.kt
index e9cc0d4..b6f6d3e 100644
--- a/paging/rxjava2/src/main/java/androidx/paging/rxjava2/RxRemoteMediator.kt
+++ b/paging/rxjava2/src/main/java/androidx/paging/rxjava2/RxRemoteMediator.kt
@@ -19,6 +19,9 @@
 import androidx.paging.ExperimentalPagingApi
 import androidx.paging.LoadState
 import androidx.paging.LoadType
+import androidx.paging.LoadType.APPEND
+import androidx.paging.LoadType.PREPEND
+import androidx.paging.LoadType.REFRESH
 import androidx.paging.PagingData
 import androidx.paging.PagingSource
 import androidx.paging.PagingState
@@ -78,6 +81,8 @@
      * @return [InitializeAction] indicating the action to take after initialization:
      *  * [LAUNCH_INITIAL_REFRESH] to immediately dispatch a [load] asynchronously with load type
      *  [LoadType.REFRESH], to update paginated content when the stream is initialized.
+     *  Note: This also prevents [RemoteMediator] from triggering [PREPEND] or [APPEND] until
+     *  [REFRESH] succeeds.
      *  * [SKIP_INITIAL_REFRESH][InitializeAction.SKIP_INITIAL_REFRESH] to wait for a
      *  refresh request from the UI before dispatching a [load] with load type [LoadType.REFRESH].
      */
diff --git a/paging/rxjava3/src/main/java/androidx/paging/rxjava3/RxRemoteMediator.kt b/paging/rxjava3/src/main/java/androidx/paging/rxjava3/RxRemoteMediator.kt
index 942bedf..3d6301f 100644
--- a/paging/rxjava3/src/main/java/androidx/paging/rxjava3/RxRemoteMediator.kt
+++ b/paging/rxjava3/src/main/java/androidx/paging/rxjava3/RxRemoteMediator.kt
@@ -19,6 +19,9 @@
 import androidx.paging.ExperimentalPagingApi
 import androidx.paging.LoadState
 import androidx.paging.LoadType
+import androidx.paging.LoadType.APPEND
+import androidx.paging.LoadType.PREPEND
+import androidx.paging.LoadType.REFRESH
 import androidx.paging.PagingData
 import androidx.paging.PagingSource
 import androidx.paging.PagingState
@@ -77,6 +80,8 @@
      * @return [InitializeAction] indicating the action to take after initialization:
      *  * [LAUNCH_INITIAL_REFRESH] to immediately dispatch a [load] asynchronously with load type
      *  [LoadType.REFRESH], to update paginated content when the stream is initialized.
+     *  Note: This also prevents [RemoteMediator] from triggering [PREPEND] or [APPEND] until
+     *  [REFRESH] succeeds.
      *  * [SKIP_INITIAL_REFRESH][InitializeAction.SKIP_INITIAL_REFRESH] to wait for a
      *  refresh request from the UI before dispatching a [load] with load type [LoadType.REFRESH].
      */
diff --git a/paging/samples/build.gradle b/paging/samples/build.gradle
index e928707..2164fe3 100644
--- a/paging/samples/build.gradle
+++ b/paging/samples/build.gradle
@@ -38,8 +38,8 @@
 
     implementation("androidx.appcompat:appcompat:1.2.0")
     implementation("androidx.annotation:annotation-experimental:1.1.0-beta01")
-    implementation("androidx.fragment:fragment-ktx:1.3.0-rc01")
-    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0-rc01")
+    implementation("androidx.fragment:fragment-ktx:1.3.0")
+    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0")
     implementation("androidx.recyclerview:recyclerview:1.2.0-beta01")
     implementation("androidx.room:room-ktx:2.3.0-beta01")
     implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
diff --git a/paging/samples/src/main/java/androidx/paging/samples/PagingSourceSample.kt b/paging/samples/src/main/java/androidx/paging/samples/PagingSourceSample.kt
index deb08a9..bd894fc 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/PagingSourceSample.kt
+++ b/paging/samples/src/main/java/androidx/paging/samples/PagingSourceSample.kt
@@ -49,9 +49,9 @@
 }
 
 @Sampled
-fun pageKeyedPagingSourceSample() {
+fun itemKeyedPagingSourceSample() {
     /**
-     * Sample Page-Keyed PagingSource, which uses String tokens to load pages.
+     * Sample item-keyed [PagingSource], which uses String tokens to load pages.
      *
      * Loads Items from network requests via Retrofit to a backend service.
      */
@@ -86,9 +86,9 @@
 }
 
 @Sampled
-fun pageIndexedPagingSourceSample() {
+fun pageKeyedPagingSourceSample() {
     /**
-     * Sample Page-Indexed PagingSource, which uses Int page number to load pages.
+     * Sample page-keyed PagingSource, which uses Int page number to load pages.
      *
      * Loads Items from network requests via Retrofit to a backend service.
      *
diff --git a/paging/samples/src/main/java/androidx/paging/samples/RemoteMediatorSample.kt b/paging/samples/src/main/java/androidx/paging/samples/RemoteMediatorSample.kt
index 09b1c86..0b40372 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/RemoteMediatorSample.kt
+++ b/paging/samples/src/main/java/androidx/paging/samples/RemoteMediatorSample.kt
@@ -30,11 +30,13 @@
 import androidx.room.withTransaction
 import retrofit2.HttpException
 import java.io.IOException
+import java.util.concurrent.TimeUnit
 
 private interface ItemDao {
     fun withTransaction(block: () -> Any)
     fun insertAll(items: List<Item>)
     fun removeAll()
+    fun lastUpdated(): Long
 }
 
 private interface ItemKeyDao {
@@ -63,6 +65,19 @@
     ) : RemoteMediator<Int, User>() {
         val userDao = database.userDao()
 
+        override suspend fun initialize(): InitializeAction {
+            val cacheTimeout = TimeUnit.HOURS.convert(1, TimeUnit.MILLISECONDS)
+            return if (System.currentTimeMillis() - userDao.lastUpdated() >= cacheTimeout) {
+                // Cached data is up-to-date, so there is no need to re-fetch from network.
+                InitializeAction.SKIP_INITIAL_REFRESH
+            } else {
+                // Need to refresh cached data from network; returning LAUNCH_INITIAL_REFRESH here
+                // will also block RemoteMediator's APPEND and PREPEND from running until REFRESH
+                // succeeds.
+                InitializeAction.LAUNCH_INITIAL_REFRESH
+            }
+        }
+
         override suspend fun load(
             loadType: LoadType,
             state: PagingState<Int, User>
@@ -136,6 +151,19 @@
         val userDao = database.userDao()
         val remoteKeyDao = database.remoteKeyDao()
 
+        override suspend fun initialize(): InitializeAction {
+            val cacheTimeout = TimeUnit.HOURS.convert(1, TimeUnit.MILLISECONDS)
+            return if (System.currentTimeMillis() - userDao.lastUpdated() >= cacheTimeout) {
+                // Cached data is up-to-date, so there is no need to re-fetch from network.
+                InitializeAction.SKIP_INITIAL_REFRESH
+            } else {
+                // Need to refresh cached data from network; returning LAUNCH_INITIAL_REFRESH here
+                // will also block RemoteMediator's APPEND and PREPEND from running until REFRESH
+                // succeeds.
+                InitializeAction.LAUNCH_INITIAL_REFRESH
+            }
+        }
+
         override suspend fun load(
             loadType: LoadType,
             state: PagingState<Int, User>
diff --git a/paging/samples/src/main/java/androidx/paging/samples/java/PagingSourceListenableFutureSample.java b/paging/samples/src/main/java/androidx/paging/samples/java/PagingSourceListenableFutureSample.java
new file mode 100644
index 0000000..10060d7
--- /dev/null
+++ b/paging/samples/src/main/java/androidx/paging/samples/java/PagingSourceListenableFutureSample.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.paging.samples.java;
+
+import androidx.annotation.NonNull;
+import androidx.paging.ListenableFuturePagingSource;
+import androidx.paging.PagingState;
+import androidx.paging.samples.shared.ExampleGuavaBackendService;
+import androidx.paging.samples.shared.SearchUserResponse;
+import androidx.paging.samples.shared.User;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.util.concurrent.Executor;
+
+import retrofit2.HttpException;
+
+class PagingSourceListenableFutureSample extends ListenableFuturePagingSource<Integer, User> {
+    @NonNull
+    private ExampleGuavaBackendService mBackend;
+    @NonNull
+    private String mQuery;
+    @NonNull
+    private Executor mBgExecutor;
+
+    PagingSourceListenableFutureSample(
+            @NonNull ExampleGuavaBackendService backend,
+            @NonNull String query, @NonNull Executor bgExecutor) {
+        mBackend = backend;
+        mQuery = query;
+        mBgExecutor = bgExecutor;
+    }
+
+    @NotNull
+    @Override
+    public ListenableFuture<LoadResult<Integer, User>> loadFuture(
+            @NotNull LoadParams<Integer> params) {
+        // Start refresh at page 1 if undefined.
+        Integer nextPageNumber = params.getKey();
+        if (nextPageNumber == null) {
+            nextPageNumber = 1;
+        }
+
+        ListenableFuture<LoadResult<Integer, User>> pageFuture = Futures.transform(
+                mBackend.searchUsers(mQuery, nextPageNumber),
+                this::toLoadResult, mBgExecutor);
+
+        ListenableFuture<LoadResult<Integer, User>> partialLoadResultFuture = Futures.catching(
+                pageFuture, HttpException.class,
+                LoadResult.Error::new, mBgExecutor);
+
+        return Futures.catching(partialLoadResultFuture,
+                IOException.class, LoadResult.Error::new, mBgExecutor);
+    }
+
+    private LoadResult<Integer, User> toLoadResult(@NonNull SearchUserResponse response) {
+        return new LoadResult.Page<>(
+                response.getUsers(),
+                null, // Only paging forward.
+                response.getNextPageNumber(),
+                LoadResult.Page.COUNT_UNDEFINED,
+                LoadResult.Page.COUNT_UNDEFINED);
+    }
+
+    @Nullable
+    @Override
+    public Integer getRefreshKey(@NotNull PagingState<Integer, User> state) {
+        Integer anchorPosition = state.getAnchorPosition();
+        if (anchorPosition == null) {
+            return null;
+        }
+
+        LoadResult.Page<Integer, User> anchorPage = state.closestPageToPosition(anchorPosition);
+        if (anchorPage == null) {
+            return null;
+        }
+
+        Integer prevKey = anchorPage.getPrevKey();
+        if (prevKey != null) {
+            return prevKey + 1;
+        }
+
+        Integer nextKey = anchorPage.getNextKey();
+        if (nextKey != null) {
+            return nextKey + 1;
+        }
+
+        return null;
+    }
+}
diff --git a/paging/samples/src/main/java/androidx/paging/samples/java/PagingSourceRxSample.java b/paging/samples/src/main/java/androidx/paging/samples/java/PagingSourceRxSample.java
new file mode 100644
index 0000000..94a3ecf
--- /dev/null
+++ b/paging/samples/src/main/java/androidx/paging/samples/java/PagingSourceRxSample.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.paging.samples.java;
+
+import androidx.annotation.NonNull;
+import androidx.paging.PagingState;
+import androidx.paging.rxjava2.RxPagingSource;
+import androidx.paging.samples.shared.ExampleRxBackendService;
+import androidx.paging.samples.shared.SearchUserResponse;
+import androidx.paging.samples.shared.User;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import io.reactivex.Single;
+import io.reactivex.schedulers.Schedulers;
+
+class PagingSourceRxSample extends RxPagingSource<Integer, User> {
+    @NonNull
+    private ExampleRxBackendService mBackend;
+    @NonNull
+    private String mQuery;
+
+    PagingSourceRxSample(@NonNull ExampleRxBackendService backend,
+            @NonNull String query) {
+        mBackend = backend;
+        mQuery = query;
+    }
+
+    @NotNull
+    @Override
+    public Single<LoadResult<Integer, User>> loadSingle(
+            @NotNull LoadParams<Integer> params) {
+        // Start refresh at page 1 if undefined.
+        Integer nextPageNumber = params.getKey();
+        if (nextPageNumber == null) {
+            nextPageNumber = 1;
+        }
+
+        return mBackend.searchUsers(mQuery, nextPageNumber)
+                .subscribeOn(Schedulers.io())
+                .map(this::toLoadResult)
+                .onErrorReturn(LoadResult.Error::new);
+    }
+
+    private LoadResult<Integer, User> toLoadResult(
+            @NonNull SearchUserResponse response) {
+        return new LoadResult.Page<>(
+                response.getUsers(),
+                null, // Only paging forward.
+                response.getNextPageNumber(),
+                LoadResult.Page.COUNT_UNDEFINED,
+                LoadResult.Page.COUNT_UNDEFINED);
+    }
+
+    @Nullable
+    @Override
+    public Integer getRefreshKey(@NotNull PagingState<Integer, User> state) {
+        Integer anchorPosition = state.getAnchorPosition();
+        if (anchorPosition == null) {
+            return null;
+        }
+
+        LoadResult.Page<Integer, User> anchorPage = state.closestPageToPosition(anchorPosition);
+        if (anchorPage == null) {
+            return null;
+        }
+
+        Integer prevKey = anchorPage.getPrevKey();
+        if (prevKey != null) {
+            return prevKey + 1;
+        }
+
+        Integer nextKey = anchorPage.getNextKey();
+        if (nextKey != null) {
+            return nextKey + 1;
+        }
+
+        return null;
+    }
+}
diff --git a/paging/samples/src/main/java/androidx/paging/samples/java/RemoteMediatorGuavaItemKeyedSample.java b/paging/samples/src/main/java/androidx/paging/samples/java/RemoteMediatorGuavaItemKeyedSample.java
index 5b25b85..f0087d7 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/java/RemoteMediatorGuavaItemKeyedSample.java
+++ b/paging/samples/src/main/java/androidx/paging/samples/java/RemoteMediatorGuavaItemKeyedSample.java
@@ -33,6 +33,7 @@
 
 import java.io.IOException;
 import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
 
 import retrofit2.HttpException;
 
@@ -56,6 +57,27 @@
 
     @NotNull
     @Override
+    public ListenableFuture<InitializeAction> initializeFuture() {
+        long cacheTimeout = TimeUnit.HOURS.convert(1, TimeUnit.MILLISECONDS);
+        return Futures.transform(
+                mUserDao.lastUpdatedFuture(),
+                lastUpdatedMillis -> {
+                    if (System.currentTimeMillis() - lastUpdatedMillis >= cacheTimeout) {
+                        // Cached data is up-to-date, so there is no need to re-fetch
+                        // from the network.
+                        return InitializeAction.SKIP_INITIAL_REFRESH;
+                    } else {
+                        // Need to refresh cached data from network; returning
+                        // LAUNCH_INITIAL_REFRESH here will also block RemoteMediator's
+                        // APPEND and PREPEND from running until REFRESH succeeds.
+                        return InitializeAction.LAUNCH_INITIAL_REFRESH;
+                    }
+                },
+                mBgExecutor);
+    }
+
+    @NotNull
+    @Override
     public ListenableFuture<MediatorResult> loadFuture(@NotNull LoadType loadType,
             @NotNull PagingState<Integer, User> state) {
         // The network load method takes an optional `after=<user.id>` parameter. For every
diff --git a/paging/samples/src/main/java/androidx/paging/samples/java/RemoteMediatorGuavaPageKeyedSample.java b/paging/samples/src/main/java/androidx/paging/samples/java/RemoteMediatorGuavaPageKeyedSample.java
index 3592ee0..56b344c 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/java/RemoteMediatorGuavaPageKeyedSample.java
+++ b/paging/samples/src/main/java/androidx/paging/samples/java/RemoteMediatorGuavaPageKeyedSample.java
@@ -35,6 +35,7 @@
 
 import java.io.IOException;
 import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
 
 import retrofit2.HttpException;
 
@@ -60,6 +61,27 @@
 
     @NotNull
     @Override
+    public ListenableFuture<InitializeAction> initializeFuture() {
+        long cacheTimeout = TimeUnit.HOURS.convert(1, TimeUnit.MILLISECONDS);
+        return Futures.transform(
+                mUserDao.lastUpdatedFuture(),
+                lastUpdatedMillis -> {
+                    if (System.currentTimeMillis() - lastUpdatedMillis >= cacheTimeout) {
+                        // Cached data is up-to-date, so there is no need to re-fetch
+                        // from the network.
+                        return InitializeAction.SKIP_INITIAL_REFRESH;
+                    } else {
+                        // Need to refresh cached data from network; returning
+                        // LAUNCH_INITIAL_REFRESH here will also block RemoteMediator's
+                        // APPEND and PREPEND from running until REFRESH succeeds.
+                        return InitializeAction.LAUNCH_INITIAL_REFRESH;
+                    }
+                },
+                mBgExecutor);
+    }
+
+    @NotNull
+    @Override
     public ListenableFuture<MediatorResult> loadFuture(@NotNull LoadType loadType,
             @NotNull PagingState<Integer, User> state) {
         // The network load method takes an optional `after=<user.id>` parameter. For every
diff --git a/paging/samples/src/main/java/androidx/paging/samples/java/RemoteMediatorRxItemKeyedSample.java b/paging/samples/src/main/java/androidx/paging/samples/java/RemoteMediatorRxItemKeyedSample.java
index c36fba8..80519d0 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/java/RemoteMediatorRxItemKeyedSample.java
+++ b/paging/samples/src/main/java/androidx/paging/samples/java/RemoteMediatorRxItemKeyedSample.java
@@ -30,6 +30,7 @@
 import org.jetbrains.annotations.NotNull;
 
 import java.io.IOException;
+import java.util.concurrent.TimeUnit;
 
 import io.reactivex.Single;
 import io.reactivex.functions.Function;
@@ -54,6 +55,25 @@
 
     @NotNull
     @Override
+    public Single<InitializeAction> initializeSingle() {
+        long cacheTimeout = TimeUnit.HOURS.convert(1, TimeUnit.MILLISECONDS);
+        return mUserDao.lastUpdatedSingle()
+                .map(lastUpdatedMillis -> {
+                    if (System.currentTimeMillis() - lastUpdatedMillis >= cacheTimeout) {
+                        // Cached data is up-to-date, so there is no need to re-fetch
+                        // from the network.
+                        return InitializeAction.SKIP_INITIAL_REFRESH;
+                    } else {
+                        // Need to refresh cached data from network; returning
+                        // LAUNCH_INITIAL_REFRESH here will also block RemoteMediator's
+                        // APPEND and PREPEND from running until REFRESH succeeds.
+                        return InitializeAction.LAUNCH_INITIAL_REFRESH;
+                    }
+                });
+    }
+
+    @NotNull
+    @Override
     public Single<MediatorResult> loadSingle(@NotNull LoadType loadType,
             @NotNull PagingState<Integer, User> state) {
         // The network load method takes an optional `after=<user.id>` parameter. For every
diff --git a/paging/samples/src/main/java/androidx/paging/samples/java/RemoteMediatorRxPageKeyedSample.java b/paging/samples/src/main/java/androidx/paging/samples/java/RemoteMediatorRxPageKeyedSample.java
index 01a692f..92d9111 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/java/RemoteMediatorRxPageKeyedSample.java
+++ b/paging/samples/src/main/java/androidx/paging/samples/java/RemoteMediatorRxPageKeyedSample.java
@@ -33,6 +33,7 @@
 import org.jetbrains.annotations.NotNull;
 
 import java.io.IOException;
+import java.util.concurrent.TimeUnit;
 
 import io.reactivex.Single;
 import io.reactivex.functions.Function;
@@ -59,6 +60,25 @@
 
     @NotNull
     @Override
+    public Single<InitializeAction> initializeSingle() {
+        long cacheTimeout = TimeUnit.HOURS.convert(1, TimeUnit.MILLISECONDS);
+        return mUserDao.lastUpdatedSingle()
+                .map(lastUpdatedMillis -> {
+                    if (System.currentTimeMillis() - lastUpdatedMillis >= cacheTimeout) {
+                        // Cached data is up-to-date, so there is no need to re-fetch
+                        // from the network.
+                        return InitializeAction.SKIP_INITIAL_REFRESH;
+                    } else {
+                        // Need to refresh cached data from network; returning
+                        // LAUNCH_INITIAL_REFRESH here will also block RemoteMediator's
+                        // APPEND and PREPEND from running until REFRESH succeeds.
+                        return InitializeAction.LAUNCH_INITIAL_REFRESH;
+                    }
+                });
+    }
+
+    @NotNull
+    @Override
     public Single<MediatorResult> loadSingle(@NotNull LoadType loadType,
             @NotNull PagingState<Integer, User> state) {
         // The network load method takes an optional [String] parameter. For every page
diff --git a/paging/samples/src/main/java/androidx/paging/samples/shared/ExampleBackendService.kt b/paging/samples/src/main/java/androidx/paging/samples/shared/ExampleBackendService.kt
index 10a2839..15fefb7 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/shared/ExampleBackendService.kt
+++ b/paging/samples/src/main/java/androidx/paging/samples/shared/ExampleBackendService.kt
@@ -22,5 +22,6 @@
 
 class SearchUserResponse(
     val users: List<User>,
-    val nextKey: String?
+    val nextKey: String?,
+    val nextPageNumber: Int?,
 )
\ No newline at end of file
diff --git a/paging/samples/src/main/java/androidx/paging/samples/shared/ExampleGuavaBackendService.kt b/paging/samples/src/main/java/androidx/paging/samples/shared/ExampleGuavaBackendService.kt
index 0d85f7c..4432451 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/shared/ExampleGuavaBackendService.kt
+++ b/paging/samples/src/main/java/androidx/paging/samples/shared/ExampleGuavaBackendService.kt
@@ -20,4 +20,5 @@
 
 interface ExampleGuavaBackendService {
     fun searchUsers(query: String, after: String?): ListenableFuture<SearchUserResponse>
+    fun searchUsers(query: String, pageNumber: Int?): ListenableFuture<SearchUserResponse>
 }
diff --git a/paging/samples/src/main/java/androidx/paging/samples/shared/ExampleRxBackendService.kt b/paging/samples/src/main/java/androidx/paging/samples/shared/ExampleRxBackendService.kt
index 10b3244..b92aaab 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/shared/ExampleRxBackendService.kt
+++ b/paging/samples/src/main/java/androidx/paging/samples/shared/ExampleRxBackendService.kt
@@ -20,4 +20,5 @@
 
 interface ExampleRxBackendService {
     fun searchUsers(query: String, after: String?): Single<SearchUserResponse>
+    fun searchUsers(query: String, pageNumber: Int?): Single<SearchUserResponse>
 }
diff --git a/paging/samples/src/main/java/androidx/paging/samples/shared/UserDao.kt b/paging/samples/src/main/java/androidx/paging/samples/shared/UserDao.kt
index b3b5985..a90bf2c 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/shared/UserDao.kt
+++ b/paging/samples/src/main/java/androidx/paging/samples/shared/UserDao.kt
@@ -21,6 +21,8 @@
 import androidx.room.Insert
 import androidx.room.OnConflictStrategy
 import androidx.room.Query
+import com.google.common.util.concurrent.ListenableFuture
+import io.reactivex.Single
 
 @Dao
 interface UserDao {
@@ -35,4 +37,10 @@
     // in both Java and Kotlin samples.
     @Query("DELETE FROM users WHERE label = :query")
     fun deleteByQuery(query: String)
+
+    suspend fun lastUpdated(): Long
+
+    fun lastUpdatedFuture(): ListenableFuture<Long>
+
+    fun lastUpdatedSingle(): Single<Long>
 }
\ No newline at end of file
diff --git a/paging/settings.gradle b/paging/settings.gradle
index e181f5b..29b5522b 100644
--- a/paging/settings.gradle
+++ b/paging/settings.gradle
@@ -24,6 +24,7 @@
     if (name == ":annotation:annotation-sampled") return true
     if (name == ":internal-testutils-ktx") return true
     if (name == ":internal-testutils-paging") return true
+    if (name == ":compose:internal-lint-checks") return true
     return false
 })
 
diff --git a/playground-common/playground-include-settings.gradle b/playground-common/playground-include-settings.gradle
index f08d223..4228541 100644
--- a/playground-common/playground-include-settings.gradle
+++ b/playground-common/playground-include-settings.gradle
@@ -70,10 +70,6 @@
             new File(supportRoot, "testutils/testutils-common"))
     settings.includeProject(":internal-testutils-gradle-plugin",
             new File(supportRoot, "testutils/testutils-gradle-plugin"))
-
-    // AndroidXUiPlugin dependencies
-    settings.includeProject(":compose:internal-lint-checks",
-            new File(supportRoot, "compose/internal-lint-checks"))
 }
 
 /**
diff --git a/playground-common/playground.properties b/playground-common/playground.properties
index 816bd6c..a55cd7c 100644
--- a/playground-common/playground.properties
+++ b/playground-common/playground.properties
@@ -28,7 +28,7 @@
 androidx.enableDocumentation=false
 # Disable coverage
 androidx.coverageEnabled=false
-androidx.playground.snapshotBuildId=7128032
+androidx.playground.snapshotBuildId=7137486
 androidx.playground.metalavaBuildId=7109364
 androidx.playground.dokkaBuildId=7019924
 androidx.studio.type=playground
diff --git a/recyclerview/recyclerview/api/1.2.0-beta02.txt b/recyclerview/recyclerview/api/1.2.0-beta02.txt
new file mode 100644
index 0000000..e1ffd69
--- /dev/null
+++ b/recyclerview/recyclerview/api/1.2.0-beta02.txt
@@ -0,0 +1,1091 @@
+// Signature format: 4.0
+package androidx.recyclerview.widget {
+
+  public final class AdapterListUpdateCallback implements androidx.recyclerview.widget.ListUpdateCallback {
+    ctor public AdapterListUpdateCallback(androidx.recyclerview.widget.RecyclerView.Adapter);
+    method public void onChanged(int, int, Object!);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public final class AsyncDifferConfig<T> {
+    method public java.util.concurrent.Executor getBackgroundThreadExecutor();
+    method public androidx.recyclerview.widget.DiffUtil.ItemCallback<T!> getDiffCallback();
+  }
+
+  public static final class AsyncDifferConfig.Builder<T> {
+    ctor public AsyncDifferConfig.Builder(androidx.recyclerview.widget.DiffUtil.ItemCallback<T!>);
+    method public androidx.recyclerview.widget.AsyncDifferConfig<T!> build();
+    method public androidx.recyclerview.widget.AsyncDifferConfig.Builder<T!> setBackgroundThreadExecutor(java.util.concurrent.Executor!);
+  }
+
+  public class AsyncListDiffer<T> {
+    ctor public AsyncListDiffer(androidx.recyclerview.widget.RecyclerView.Adapter, androidx.recyclerview.widget.DiffUtil.ItemCallback<T!>);
+    ctor public AsyncListDiffer(androidx.recyclerview.widget.ListUpdateCallback, androidx.recyclerview.widget.AsyncDifferConfig<T!>);
+    method public void addListListener(androidx.recyclerview.widget.AsyncListDiffer.ListListener<T!>);
+    method public java.util.List<T!> getCurrentList();
+    method public void removeListListener(androidx.recyclerview.widget.AsyncListDiffer.ListListener<T!>);
+    method public void submitList(java.util.List<T!>?);
+    method public void submitList(java.util.List<T!>?, Runnable?);
+  }
+
+  public static interface AsyncListDiffer.ListListener<T> {
+    method public void onCurrentListChanged(java.util.List<T!>, java.util.List<T!>);
+  }
+
+  public class AsyncListUtil<T> {
+    ctor public AsyncListUtil(Class<T!>, int, androidx.recyclerview.widget.AsyncListUtil.DataCallback<T!>, androidx.recyclerview.widget.AsyncListUtil.ViewCallback);
+    method public T? getItem(int);
+    method public int getItemCount();
+    method public void onRangeChanged();
+    method public void refresh();
+  }
+
+  public abstract static class AsyncListUtil.DataCallback<T> {
+    ctor public AsyncListUtil.DataCallback();
+    method @WorkerThread public abstract void fillData(T![], int, int);
+    method @WorkerThread public int getMaxCachedTiles();
+    method @WorkerThread public void recycleData(T![], int);
+    method @WorkerThread public abstract int refreshData();
+  }
+
+  public abstract static class AsyncListUtil.ViewCallback {
+    ctor public AsyncListUtil.ViewCallback();
+    method @UiThread public void extendRangeInto(int[], int[], int);
+    method @UiThread public abstract void getItemRangeInto(int[]);
+    method @UiThread public abstract void onDataRefresh();
+    method @UiThread public abstract void onItemLoaded(int);
+    field public static final int HINT_SCROLL_ASC = 2; // 0x2
+    field public static final int HINT_SCROLL_DESC = 1; // 0x1
+    field public static final int HINT_SCROLL_NONE = 0; // 0x0
+  }
+
+  public class BatchingListUpdateCallback implements androidx.recyclerview.widget.ListUpdateCallback {
+    ctor public BatchingListUpdateCallback(androidx.recyclerview.widget.ListUpdateCallback);
+    method public void dispatchLastEvent();
+    method public void onChanged(int, int, Object!);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public final class ConcatAdapter extends androidx.recyclerview.widget.RecyclerView.Adapter<androidx.recyclerview.widget.RecyclerView.ViewHolder> {
+    ctor @java.lang.SafeVarargs public ConcatAdapter(androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>!...);
+    ctor @java.lang.SafeVarargs public ConcatAdapter(androidx.recyclerview.widget.ConcatAdapter.Config, androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>!...);
+    ctor public ConcatAdapter(java.util.List<? extends androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>>);
+    ctor public ConcatAdapter(androidx.recyclerview.widget.ConcatAdapter.Config, java.util.List<? extends androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>>);
+    method public boolean addAdapter(androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>);
+    method public boolean addAdapter(int, androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>);
+    method public java.util.List<? extends androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>> getAdapters();
+    method public int getItemCount();
+    method public void onBindViewHolder(androidx.recyclerview.widget.RecyclerView.ViewHolder, int);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder onCreateViewHolder(android.view.ViewGroup, int);
+    method public boolean onFailedToRecycleView(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onViewAttachedToWindow(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onViewDetachedFromWindow(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onViewRecycled(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public boolean removeAdapter(androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>);
+  }
+
+  public static final class ConcatAdapter.Config {
+    field public static final androidx.recyclerview.widget.ConcatAdapter.Config DEFAULT;
+    field public final boolean isolateViewTypes;
+    field public final androidx.recyclerview.widget.ConcatAdapter.Config.StableIdMode stableIdMode;
+  }
+
+  public static final class ConcatAdapter.Config.Builder {
+    ctor public ConcatAdapter.Config.Builder();
+    method public androidx.recyclerview.widget.ConcatAdapter.Config build();
+    method public androidx.recyclerview.widget.ConcatAdapter.Config.Builder setIsolateViewTypes(boolean);
+    method public androidx.recyclerview.widget.ConcatAdapter.Config.Builder setStableIdMode(androidx.recyclerview.widget.ConcatAdapter.Config.StableIdMode);
+  }
+
+  public enum ConcatAdapter.Config.StableIdMode {
+    enum_constant public static final androidx.recyclerview.widget.ConcatAdapter.Config.StableIdMode ISOLATED_STABLE_IDS;
+    enum_constant public static final androidx.recyclerview.widget.ConcatAdapter.Config.StableIdMode NO_STABLE_IDS;
+    enum_constant public static final androidx.recyclerview.widget.ConcatAdapter.Config.StableIdMode SHARED_STABLE_IDS;
+  }
+
+  public class DefaultItemAnimator extends androidx.recyclerview.widget.SimpleItemAnimator {
+    ctor public DefaultItemAnimator();
+    method public boolean animateAdd(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder!, androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animateMove(androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animateRemove(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void endAnimation(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void endAnimations();
+    method public boolean isRunning();
+    method public void runPendingAnimations();
+  }
+
+  public class DiffUtil {
+    method public static androidx.recyclerview.widget.DiffUtil.DiffResult calculateDiff(androidx.recyclerview.widget.DiffUtil.Callback);
+    method public static androidx.recyclerview.widget.DiffUtil.DiffResult calculateDiff(androidx.recyclerview.widget.DiffUtil.Callback, boolean);
+  }
+
+  public abstract static class DiffUtil.Callback {
+    ctor public DiffUtil.Callback();
+    method public abstract boolean areContentsTheSame(int, int);
+    method public abstract boolean areItemsTheSame(int, int);
+    method public Object? getChangePayload(int, int);
+    method public abstract int getNewListSize();
+    method public abstract int getOldListSize();
+  }
+
+  public static class DiffUtil.DiffResult {
+    method public int convertNewPositionToOld(@IntRange(from=0) int);
+    method public int convertOldPositionToNew(@IntRange(from=0) int);
+    method public void dispatchUpdatesTo(androidx.recyclerview.widget.RecyclerView.Adapter);
+    method public void dispatchUpdatesTo(androidx.recyclerview.widget.ListUpdateCallback);
+    field public static final int NO_POSITION = -1; // 0xffffffff
+  }
+
+  public abstract static class DiffUtil.ItemCallback<T> {
+    ctor public DiffUtil.ItemCallback();
+    method public abstract boolean areContentsTheSame(T, T);
+    method public abstract boolean areItemsTheSame(T, T);
+    method public Object? getChangePayload(T, T);
+  }
+
+  public class DividerItemDecoration extends androidx.recyclerview.widget.RecyclerView.ItemDecoration {
+    ctor public DividerItemDecoration(android.content.Context!, int);
+    method public android.graphics.drawable.Drawable? getDrawable();
+    method public void setDrawable(android.graphics.drawable.Drawable);
+    method public void setOrientation(int);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public class GridLayoutManager extends androidx.recyclerview.widget.LinearLayoutManager {
+    ctor public GridLayoutManager(android.content.Context!, android.util.AttributeSet!, int, int);
+    ctor public GridLayoutManager(android.content.Context!, int);
+    ctor public GridLayoutManager(android.content.Context!, int, int, boolean);
+    method public int getSpanCount();
+    method public androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup! getSpanSizeLookup();
+    method public boolean isUsingSpansToEstimateScrollbarDimensions();
+    method public void setSpanCount(int);
+    method public void setSpanSizeLookup(androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup!);
+    method public void setUsingSpansToEstimateScrollbarDimensions(boolean);
+    field public static final int DEFAULT_SPAN_COUNT = -1; // 0xffffffff
+  }
+
+  public static final class GridLayoutManager.DefaultSpanSizeLookup extends androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup {
+    ctor public GridLayoutManager.DefaultSpanSizeLookup();
+    method public int getSpanSize(int);
+  }
+
+  public static class GridLayoutManager.LayoutParams extends androidx.recyclerview.widget.RecyclerView.LayoutParams {
+    ctor public GridLayoutManager.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public GridLayoutManager.LayoutParams(int, int);
+    ctor public GridLayoutManager.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public GridLayoutManager.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public GridLayoutManager.LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public int getSpanIndex();
+    method public int getSpanSize();
+    field public static final int INVALID_SPAN_ID = -1; // 0xffffffff
+  }
+
+  public abstract static class GridLayoutManager.SpanSizeLookup {
+    ctor public GridLayoutManager.SpanSizeLookup();
+    method public int getSpanGroupIndex(int, int);
+    method public int getSpanIndex(int, int);
+    method public abstract int getSpanSize(int);
+    method public void invalidateSpanGroupIndexCache();
+    method public void invalidateSpanIndexCache();
+    method public boolean isSpanGroupIndexCacheEnabled();
+    method public boolean isSpanIndexCacheEnabled();
+    method public void setSpanGroupIndexCacheEnabled(boolean);
+    method public void setSpanIndexCacheEnabled(boolean);
+  }
+
+  public class ItemTouchHelper extends androidx.recyclerview.widget.RecyclerView.ItemDecoration implements androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener {
+    ctor public ItemTouchHelper(androidx.recyclerview.widget.ItemTouchHelper.Callback);
+    method public void attachToRecyclerView(androidx.recyclerview.widget.RecyclerView?);
+    method public void onChildViewAttachedToWindow(android.view.View);
+    method public void onChildViewDetachedFromWindow(android.view.View);
+    method public void startDrag(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void startSwipe(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    field public static final int ACTION_STATE_DRAG = 2; // 0x2
+    field public static final int ACTION_STATE_IDLE = 0; // 0x0
+    field public static final int ACTION_STATE_SWIPE = 1; // 0x1
+    field public static final int ANIMATION_TYPE_DRAG = 8; // 0x8
+    field public static final int ANIMATION_TYPE_SWIPE_CANCEL = 4; // 0x4
+    field public static final int ANIMATION_TYPE_SWIPE_SUCCESS = 2; // 0x2
+    field public static final int DOWN = 2; // 0x2
+    field public static final int END = 32; // 0x20
+    field public static final int LEFT = 4; // 0x4
+    field public static final int RIGHT = 8; // 0x8
+    field public static final int START = 16; // 0x10
+    field public static final int UP = 1; // 0x1
+  }
+
+  public abstract static class ItemTouchHelper.Callback {
+    ctor public ItemTouchHelper.Callback();
+    method public boolean canDropOver(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder! chooseDropTarget(androidx.recyclerview.widget.RecyclerView.ViewHolder, java.util.List<androidx.recyclerview.widget.RecyclerView.ViewHolder!>, int, int);
+    method public void clearView(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public int convertToAbsoluteDirection(int, int);
+    method public static int convertToRelativeDirection(int, int);
+    method public long getAnimationDuration(androidx.recyclerview.widget.RecyclerView, int, float, float);
+    method public int getBoundingBoxMargin();
+    method public static androidx.recyclerview.widget.ItemTouchUIUtil getDefaultUIUtil();
+    method public float getMoveThreshold(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public abstract int getMovementFlags(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public float getSwipeEscapeVelocity(float);
+    method public float getSwipeThreshold(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public float getSwipeVelocityThreshold(float);
+    method public int interpolateOutOfBoundsScroll(androidx.recyclerview.widget.RecyclerView, int, int, int, long);
+    method public boolean isItemViewSwipeEnabled();
+    method public boolean isLongPressDragEnabled();
+    method public static int makeFlag(int, int);
+    method public static int makeMovementFlags(int, int);
+    method public void onChildDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, float, float, int, boolean);
+    method public void onChildDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder!, float, float, int, boolean);
+    method public abstract boolean onMove(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onMoved(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, int, int);
+    method public void onSelectedChanged(androidx.recyclerview.widget.RecyclerView.ViewHolder?, int);
+    method public abstract void onSwiped(androidx.recyclerview.widget.RecyclerView.ViewHolder, int);
+    field public static final int DEFAULT_DRAG_ANIMATION_DURATION = 200; // 0xc8
+    field public static final int DEFAULT_SWIPE_ANIMATION_DURATION = 250; // 0xfa
+  }
+
+  public abstract static class ItemTouchHelper.SimpleCallback extends androidx.recyclerview.widget.ItemTouchHelper.Callback {
+    ctor public ItemTouchHelper.SimpleCallback(int, int);
+    method public int getDragDirs(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public int getMovementFlags(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public int getSwipeDirs(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void setDefaultDragDirs(int);
+    method public void setDefaultSwipeDirs(int);
+  }
+
+  public static interface ItemTouchHelper.ViewDropHandler {
+    method public void prepareForDrop(android.view.View, android.view.View, int, int);
+  }
+
+  public interface ItemTouchUIUtil {
+    method public void clearView(android.view.View!);
+    method public void onDraw(android.graphics.Canvas!, androidx.recyclerview.widget.RecyclerView!, android.view.View!, float, float, int, boolean);
+    method public void onDrawOver(android.graphics.Canvas!, androidx.recyclerview.widget.RecyclerView!, android.view.View!, float, float, int, boolean);
+    method public void onSelected(android.view.View!);
+  }
+
+  public class LinearLayoutManager extends androidx.recyclerview.widget.RecyclerView.LayoutManager implements androidx.recyclerview.widget.ItemTouchHelper.ViewDropHandler androidx.recyclerview.widget.RecyclerView.SmoothScroller.ScrollVectorProvider {
+    ctor public LinearLayoutManager(android.content.Context!);
+    ctor public LinearLayoutManager(android.content.Context!, int, boolean);
+    ctor public LinearLayoutManager(android.content.Context!, android.util.AttributeSet!, int, int);
+    method protected void calculateExtraLayoutSpace(androidx.recyclerview.widget.RecyclerView.State, int[]);
+    method public android.graphics.PointF! computeScrollVectorForPosition(int);
+    method public int findFirstCompletelyVisibleItemPosition();
+    method public int findFirstVisibleItemPosition();
+    method public int findLastCompletelyVisibleItemPosition();
+    method public int findLastVisibleItemPosition();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateDefaultLayoutParams();
+    method @Deprecated protected int getExtraLayoutSpace(androidx.recyclerview.widget.RecyclerView.State!);
+    method public int getInitialPrefetchItemCount();
+    method public int getOrientation();
+    method public boolean getRecycleChildrenOnDetach();
+    method public boolean getReverseLayout();
+    method public boolean getStackFromEnd();
+    method protected boolean isLayoutRTL();
+    method public boolean isSmoothScrollbarEnabled();
+    method public void prepareForDrop(android.view.View, android.view.View, int, int);
+    method public void scrollToPositionWithOffset(int, int);
+    method public void setInitialPrefetchItemCount(int);
+    method public void setOrientation(int);
+    method public void setRecycleChildrenOnDetach(boolean);
+    method public void setReverseLayout(boolean);
+    method public void setSmoothScrollbarEnabled(boolean);
+    method public void setStackFromEnd(boolean);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int INVALID_OFFSET = -2147483648; // 0x80000000
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  protected static class LinearLayoutManager.LayoutChunkResult {
+    ctor protected LinearLayoutManager.LayoutChunkResult();
+    field public int mConsumed;
+    field public boolean mFinished;
+    field public boolean mFocusable;
+    field public boolean mIgnoreConsumed;
+  }
+
+  public class LinearSmoothScroller extends androidx.recyclerview.widget.RecyclerView.SmoothScroller {
+    ctor public LinearSmoothScroller(android.content.Context!);
+    method public int calculateDtToFit(int, int, int, int, int);
+    method public int calculateDxToMakeVisible(android.view.View!, int);
+    method public int calculateDyToMakeVisible(android.view.View!, int);
+    method protected float calculateSpeedPerPixel(android.util.DisplayMetrics!);
+    method protected int calculateTimeForDeceleration(int);
+    method protected int calculateTimeForScrolling(int);
+    method protected int getHorizontalSnapPreference();
+    method protected int getVerticalSnapPreference();
+    method protected void onSeekTargetStep(int, int, androidx.recyclerview.widget.RecyclerView.State!, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action!);
+    method protected void onStart();
+    method protected void onStop();
+    method protected void onTargetFound(android.view.View!, androidx.recyclerview.widget.RecyclerView.State!, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action!);
+    method protected void updateActionForInterimTarget(androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action!);
+    field public static final int SNAP_TO_ANY = 0; // 0x0
+    field public static final int SNAP_TO_END = 1; // 0x1
+    field public static final int SNAP_TO_START = -1; // 0xffffffff
+    field protected final android.view.animation.DecelerateInterpolator! mDecelerateInterpolator;
+    field protected int mInterimTargetDx;
+    field protected int mInterimTargetDy;
+    field protected final android.view.animation.LinearInterpolator! mLinearInterpolator;
+    field protected android.graphics.PointF! mTargetVector;
+  }
+
+  public class LinearSnapHelper extends androidx.recyclerview.widget.SnapHelper {
+    ctor public LinearSnapHelper();
+    method public int[]! calculateDistanceToFinalSnap(androidx.recyclerview.widget.RecyclerView.LayoutManager, android.view.View);
+    method public android.view.View! findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public int findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int, int);
+  }
+
+  public abstract class ListAdapter<T, VH extends androidx.recyclerview.widget.RecyclerView.ViewHolder> extends androidx.recyclerview.widget.RecyclerView.Adapter<VH> {
+    ctor protected ListAdapter(androidx.recyclerview.widget.DiffUtil.ItemCallback<T!>);
+    ctor protected ListAdapter(androidx.recyclerview.widget.AsyncDifferConfig<T!>);
+    method public java.util.List<T!> getCurrentList();
+    method protected T! getItem(int);
+    method public int getItemCount();
+    method public void onCurrentListChanged(java.util.List<T!>, java.util.List<T!>);
+    method public void submitList(java.util.List<T!>?);
+    method public void submitList(java.util.List<T!>?, Runnable?);
+  }
+
+  public interface ListUpdateCallback {
+    method public void onChanged(int, int, Object?);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public abstract class OrientationHelper {
+    method public static androidx.recyclerview.widget.OrientationHelper! createHorizontalHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public static androidx.recyclerview.widget.OrientationHelper! createOrientationHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int);
+    method public static androidx.recyclerview.widget.OrientationHelper! createVerticalHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public abstract int getDecoratedEnd(android.view.View!);
+    method public abstract int getDecoratedMeasurement(android.view.View!);
+    method public abstract int getDecoratedMeasurementInOther(android.view.View!);
+    method public abstract int getDecoratedStart(android.view.View!);
+    method public abstract int getEnd();
+    method public abstract int getEndAfterPadding();
+    method public abstract int getEndPadding();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutManager! getLayoutManager();
+    method public abstract int getMode();
+    method public abstract int getModeInOther();
+    method public abstract int getStartAfterPadding();
+    method public abstract int getTotalSpace();
+    method public int getTotalSpaceChange();
+    method public abstract int getTransformedEndWithDecoration(android.view.View!);
+    method public abstract int getTransformedStartWithDecoration(android.view.View!);
+    method public abstract void offsetChild(android.view.View!, int);
+    method public abstract void offsetChildren(int);
+    method public void onLayoutComplete();
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+    field protected final androidx.recyclerview.widget.RecyclerView.LayoutManager! mLayoutManager;
+  }
+
+  public class PagerSnapHelper extends androidx.recyclerview.widget.SnapHelper {
+    ctor public PagerSnapHelper();
+    method public int[]? calculateDistanceToFinalSnap(androidx.recyclerview.widget.RecyclerView.LayoutManager, android.view.View);
+    method public android.view.View? findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public int findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int, int);
+  }
+
+  public class RecyclerView extends android.view.ViewGroup implements androidx.core.view.NestedScrollingChild2 androidx.core.view.NestedScrollingChild3 androidx.core.view.ScrollingView {
+    ctor public RecyclerView(android.content.Context);
+    ctor public RecyclerView(android.content.Context, android.util.AttributeSet?);
+    ctor public RecyclerView(android.content.Context, android.util.AttributeSet?, int);
+    method public void addItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration, int);
+    method public void addItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration);
+    method public void addOnChildAttachStateChangeListener(androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener);
+    method public void addOnItemTouchListener(androidx.recyclerview.widget.RecyclerView.OnItemTouchListener);
+    method public void addOnScrollListener(androidx.recyclerview.widget.RecyclerView.OnScrollListener);
+    method public void addRecyclerListener(androidx.recyclerview.widget.RecyclerView.RecyclerListener);
+    method public void clearOnChildAttachStateChangeListeners();
+    method public void clearOnScrollListeners();
+    method public int computeHorizontalScrollExtent();
+    method public int computeHorizontalScrollOffset();
+    method public int computeHorizontalScrollRange();
+    method public int computeVerticalScrollExtent();
+    method public int computeVerticalScrollOffset();
+    method public int computeVerticalScrollRange();
+    method public boolean dispatchNestedPreScroll(int, int, int[]!, int[]!, int);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]!, int);
+    method public final void dispatchNestedScroll(int, int, int, int, int[]!, int, int[]);
+    method public boolean drawChild(android.graphics.Canvas!, android.view.View!, long);
+    method public android.view.View? findChildViewUnder(float, float);
+    method public android.view.View? findContainingItemView(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? findContainingViewHolder(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? findViewHolderForAdapterPosition(int);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder! findViewHolderForItemId(long);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? findViewHolderForLayoutPosition(int);
+    method @Deprecated public androidx.recyclerview.widget.RecyclerView.ViewHolder? findViewHolderForPosition(int);
+    method public boolean fling(int, int);
+    method public androidx.recyclerview.widget.RecyclerView.Adapter? getAdapter();
+    method public int getChildAdapterPosition(android.view.View);
+    method public long getChildItemId(android.view.View);
+    method public int getChildLayoutPosition(android.view.View);
+    method @Deprecated public int getChildPosition(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder! getChildViewHolder(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate? getCompatAccessibilityDelegate();
+    method public void getDecoratedBoundsWithMargins(android.view.View, android.graphics.Rect);
+    method public androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory getEdgeEffectFactory();
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator? getItemAnimator();
+    method public androidx.recyclerview.widget.RecyclerView.ItemDecoration getItemDecorationAt(int);
+    method public int getItemDecorationCount();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutManager? getLayoutManager();
+    method public int getMaxFlingVelocity();
+    method public int getMinFlingVelocity();
+    method public androidx.recyclerview.widget.RecyclerView.OnFlingListener? getOnFlingListener();
+    method public boolean getPreserveFocusAfterLayout();
+    method public androidx.recyclerview.widget.RecyclerView.RecycledViewPool getRecycledViewPool();
+    method public int getScrollState();
+    method public boolean hasFixedSize();
+    method public boolean hasNestedScrollingParent(int);
+    method public boolean hasPendingAdapterUpdates();
+    method public void invalidateItemDecorations();
+    method public boolean isAnimating();
+    method public boolean isComputingLayout();
+    method @Deprecated public boolean isLayoutFrozen();
+    method public final boolean isLayoutSuppressed();
+    method public void nestedScrollBy(int, int);
+    method public void offsetChildrenHorizontal(@Px int);
+    method public void offsetChildrenVertical(@Px int);
+    method public void onChildAttachedToWindow(android.view.View);
+    method public void onChildDetachedFromWindow(android.view.View);
+    method public void onDraw(android.graphics.Canvas!);
+    method public void onScrollStateChanged(int);
+    method public void onScrolled(@Px int, @Px int);
+    method public void removeItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration);
+    method public void removeItemDecorationAt(int);
+    method public void removeOnChildAttachStateChangeListener(androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener);
+    method public void removeOnItemTouchListener(androidx.recyclerview.widget.RecyclerView.OnItemTouchListener);
+    method public void removeOnScrollListener(androidx.recyclerview.widget.RecyclerView.OnScrollListener);
+    method public void removeRecyclerListener(androidx.recyclerview.widget.RecyclerView.RecyclerListener);
+    method public void scrollToPosition(int);
+    method public void setAccessibilityDelegateCompat(androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate?);
+    method public void setAdapter(androidx.recyclerview.widget.RecyclerView.Adapter?);
+    method public void setChildDrawingOrderCallback(androidx.recyclerview.widget.RecyclerView.ChildDrawingOrderCallback?);
+    method public void setEdgeEffectFactory(androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory);
+    method public void setHasFixedSize(boolean);
+    method public void setItemAnimator(androidx.recyclerview.widget.RecyclerView.ItemAnimator?);
+    method public void setItemViewCacheSize(int);
+    method @Deprecated public void setLayoutFrozen(boolean);
+    method public void setLayoutManager(androidx.recyclerview.widget.RecyclerView.LayoutManager?);
+    method @Deprecated public void setLayoutTransition(android.animation.LayoutTransition!);
+    method public void setOnFlingListener(androidx.recyclerview.widget.RecyclerView.OnFlingListener?);
+    method @Deprecated public void setOnScrollListener(androidx.recyclerview.widget.RecyclerView.OnScrollListener?);
+    method public void setPreserveFocusAfterLayout(boolean);
+    method public void setRecycledViewPool(androidx.recyclerview.widget.RecyclerView.RecycledViewPool?);
+    method @Deprecated public void setRecyclerListener(androidx.recyclerview.widget.RecyclerView.RecyclerListener?);
+    method public void setScrollingTouchSlop(int);
+    method public void setViewCacheExtension(androidx.recyclerview.widget.RecyclerView.ViewCacheExtension?);
+    method public void smoothScrollBy(@Px int, @Px int);
+    method public void smoothScrollBy(@Px int, @Px int, android.view.animation.Interpolator?);
+    method public void smoothScrollBy(@Px int, @Px int, android.view.animation.Interpolator?, int);
+    method public void smoothScrollToPosition(int);
+    method public boolean startNestedScroll(int, int);
+    method public void stopNestedScroll(int);
+    method public void stopScroll();
+    method public final void suppressLayout(boolean);
+    method public void swapAdapter(androidx.recyclerview.widget.RecyclerView.Adapter?, boolean);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int INVALID_TYPE = -1; // 0xffffffff
+    field public static final long NO_ID = -1L; // 0xffffffffffffffffL
+    field public static final int NO_POSITION = -1; // 0xffffffff
+    field public static final int SCROLL_STATE_DRAGGING = 1; // 0x1
+    field public static final int SCROLL_STATE_IDLE = 0; // 0x0
+    field public static final int SCROLL_STATE_SETTLING = 2; // 0x2
+    field public static final int TOUCH_SLOP_DEFAULT = 0; // 0x0
+    field public static final int TOUCH_SLOP_PAGING = 1; // 0x1
+    field public static final int UNDEFINED_DURATION = -2147483648; // 0x80000000
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public abstract static class RecyclerView.Adapter<VH extends androidx.recyclerview.widget.RecyclerView.ViewHolder> {
+    ctor public RecyclerView.Adapter();
+    method public final void bindViewHolder(VH, int);
+    method public final VH createViewHolder(android.view.ViewGroup, int);
+    method public int findRelativeAdapterPositionIn(androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>, androidx.recyclerview.widget.RecyclerView.ViewHolder, int);
+    method public abstract int getItemCount();
+    method public long getItemId(int);
+    method public int getItemViewType(int);
+    method public final androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy getStateRestorationPolicy();
+    method public final boolean hasObservers();
+    method public final boolean hasStableIds();
+    method public final void notifyDataSetChanged();
+    method public final void notifyItemChanged(int);
+    method public final void notifyItemChanged(int, Object?);
+    method public final void notifyItemInserted(int);
+    method public final void notifyItemMoved(int, int);
+    method public final void notifyItemRangeChanged(int, int);
+    method public final void notifyItemRangeChanged(int, int, Object?);
+    method public final void notifyItemRangeInserted(int, int);
+    method public final void notifyItemRangeRemoved(int, int);
+    method public final void notifyItemRemoved(int);
+    method public void onAttachedToRecyclerView(androidx.recyclerview.widget.RecyclerView);
+    method public abstract void onBindViewHolder(VH, int);
+    method public void onBindViewHolder(VH, int, java.util.List<java.lang.Object!>);
+    method public abstract VH onCreateViewHolder(android.view.ViewGroup, int);
+    method public void onDetachedFromRecyclerView(androidx.recyclerview.widget.RecyclerView);
+    method public boolean onFailedToRecycleView(VH);
+    method public void onViewAttachedToWindow(VH);
+    method public void onViewDetachedFromWindow(VH);
+    method public void onViewRecycled(VH);
+    method public void registerAdapterDataObserver(androidx.recyclerview.widget.RecyclerView.AdapterDataObserver);
+    method public void setHasStableIds(boolean);
+    method public void setStateRestorationPolicy(androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy);
+    method public void unregisterAdapterDataObserver(androidx.recyclerview.widget.RecyclerView.AdapterDataObserver);
+  }
+
+  public enum RecyclerView.Adapter.StateRestorationPolicy {
+    enum_constant public static final androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy ALLOW;
+    enum_constant public static final androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy PREVENT;
+    enum_constant public static final androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy PREVENT_WHEN_EMPTY;
+  }
+
+  public abstract static class RecyclerView.AdapterDataObserver {
+    ctor public RecyclerView.AdapterDataObserver();
+    method public void onChanged();
+    method public void onItemRangeChanged(int, int);
+    method public void onItemRangeChanged(int, int, Object?);
+    method public void onItemRangeInserted(int, int);
+    method public void onItemRangeMoved(int, int, int);
+    method public void onItemRangeRemoved(int, int);
+    method public void onStateRestorationPolicyChanged();
+  }
+
+  public static interface RecyclerView.ChildDrawingOrderCallback {
+    method public int onGetChildDrawingOrder(int, int);
+  }
+
+  public static class RecyclerView.EdgeEffectFactory {
+    ctor public RecyclerView.EdgeEffectFactory();
+    method protected android.widget.EdgeEffect createEdgeEffect(androidx.recyclerview.widget.RecyclerView, @androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.EdgeDirection int);
+    field public static final int DIRECTION_BOTTOM = 3; // 0x3
+    field public static final int DIRECTION_LEFT = 0; // 0x0
+    field public static final int DIRECTION_RIGHT = 2; // 0x2
+    field public static final int DIRECTION_TOP = 1; // 0x1
+  }
+
+  @IntDef({androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_LEFT, androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_TOP, androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_RIGHT, androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_BOTTOM}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RecyclerView.EdgeEffectFactory.EdgeDirection {
+  }
+
+  public abstract static class RecyclerView.ItemAnimator {
+    ctor public RecyclerView.ItemAnimator();
+    method public abstract boolean animateAppearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateDisappearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?);
+    method public abstract boolean animatePersistence(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public boolean canReuseUpdatedViewHolder(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public boolean canReuseUpdatedViewHolder(androidx.recyclerview.widget.RecyclerView.ViewHolder, java.util.List<java.lang.Object!>);
+    method public final void dispatchAnimationFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public final void dispatchAnimationStarted(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public final void dispatchAnimationsFinished();
+    method public abstract void endAnimation(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public abstract void endAnimations();
+    method public long getAddDuration();
+    method public long getChangeDuration();
+    method public long getMoveDuration();
+    method public long getRemoveDuration();
+    method public abstract boolean isRunning();
+    method public final boolean isRunning(androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemAnimatorFinishedListener?);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo obtainHolderInfo();
+    method public void onAnimationFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onAnimationStarted(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo recordPostLayoutInformation(androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo recordPreLayoutInformation(androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.ViewHolder, @androidx.recyclerview.widget.RecyclerView.ItemAnimator.AdapterChanges int, java.util.List<java.lang.Object!>);
+    method public abstract void runPendingAnimations();
+    method public void setAddDuration(long);
+    method public void setChangeDuration(long);
+    method public void setMoveDuration(long);
+    method public void setRemoveDuration(long);
+    field public static final int FLAG_APPEARED_IN_PRE_LAYOUT = 4096; // 0x1000
+    field public static final int FLAG_CHANGED = 2; // 0x2
+    field public static final int FLAG_INVALIDATED = 4; // 0x4
+    field public static final int FLAG_MOVED = 2048; // 0x800
+    field public static final int FLAG_REMOVED = 8; // 0x8
+  }
+
+  @IntDef(flag=true, value={androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_CHANGED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_REMOVED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_MOVED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_INVALIDATED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_APPEARED_IN_PRE_LAYOUT}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RecyclerView.ItemAnimator.AdapterChanges {
+  }
+
+  public static interface RecyclerView.ItemAnimator.ItemAnimatorFinishedListener {
+    method public void onAnimationsFinished();
+  }
+
+  public static class RecyclerView.ItemAnimator.ItemHolderInfo {
+    ctor public RecyclerView.ItemAnimator.ItemHolderInfo();
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo setFrom(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo setFrom(androidx.recyclerview.widget.RecyclerView.ViewHolder, @androidx.recyclerview.widget.RecyclerView.ItemAnimator.AdapterChanges int);
+    field public int bottom;
+    field @androidx.recyclerview.widget.RecyclerView.ItemAnimator.AdapterChanges public int changeFlags;
+    field public int left;
+    field public int right;
+    field public int top;
+  }
+
+  public abstract static class RecyclerView.ItemDecoration {
+    ctor public RecyclerView.ItemDecoration();
+    method @Deprecated public void getItemOffsets(android.graphics.Rect, int, androidx.recyclerview.widget.RecyclerView);
+    method public void getItemOffsets(android.graphics.Rect, android.view.View, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State);
+    method public void onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State);
+    method @Deprecated public void onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView);
+    method public void onDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State);
+    method @Deprecated public void onDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView);
+  }
+
+  public abstract static class RecyclerView.LayoutManager {
+    ctor public RecyclerView.LayoutManager();
+    method public void addDisappearingView(android.view.View!);
+    method public void addDisappearingView(android.view.View!, int);
+    method public void addView(android.view.View!);
+    method public void addView(android.view.View!, int);
+    method public void assertInLayoutOrScroll(String!);
+    method public void assertNotInLayoutOrScroll(String!);
+    method public void attachView(android.view.View, int, androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public void attachView(android.view.View, int);
+    method public void attachView(android.view.View);
+    method public void calculateItemDecorationsForChild(android.view.View, android.graphics.Rect);
+    method public boolean canScrollHorizontally();
+    method public boolean canScrollVertically();
+    method public boolean checkLayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public static int chooseSize(int, int, int);
+    method public void collectAdjacentPrefetchPositions(int, int, androidx.recyclerview.widget.RecyclerView.State!, androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry!);
+    method public void collectInitialPrefetchPositions(int, androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry!);
+    method public int computeHorizontalScrollExtent(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeHorizontalScrollOffset(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeHorizontalScrollRange(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeVerticalScrollExtent(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeVerticalScrollOffset(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeVerticalScrollRange(androidx.recyclerview.widget.RecyclerView.State);
+    method public void detachAndScrapAttachedViews(androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void detachAndScrapView(android.view.View, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void detachAndScrapViewAt(int, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void detachView(android.view.View);
+    method public void detachViewAt(int);
+    method public void endAnimation(android.view.View!);
+    method public android.view.View? findContainingItemView(android.view.View);
+    method public android.view.View? findViewByPosition(int);
+    method public abstract androidx.recyclerview.widget.RecyclerView.LayoutParams! generateDefaultLayoutParams();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateLayoutParams(android.content.Context!, android.util.AttributeSet!);
+    method public int getBaseline();
+    method public int getBottomDecorationHeight(android.view.View);
+    method public android.view.View? getChildAt(int);
+    method public int getChildCount();
+    method @Deprecated public static int getChildMeasureSpec(int, int, int, boolean);
+    method public static int getChildMeasureSpec(int, int, int, int, boolean);
+    method public boolean getClipToPadding();
+    method public int getColumnCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public int getDecoratedBottom(android.view.View);
+    method public void getDecoratedBoundsWithMargins(android.view.View, android.graphics.Rect);
+    method public int getDecoratedLeft(android.view.View);
+    method public int getDecoratedMeasuredHeight(android.view.View);
+    method public int getDecoratedMeasuredWidth(android.view.View);
+    method public int getDecoratedRight(android.view.View);
+    method public int getDecoratedTop(android.view.View);
+    method public android.view.View? getFocusedChild();
+    method @Px public int getHeight();
+    method public int getHeightMode();
+    method public int getItemCount();
+    method public int getItemViewType(android.view.View);
+    method public int getLayoutDirection();
+    method public int getLeftDecorationWidth(android.view.View);
+    method @Px public int getMinimumHeight();
+    method @Px public int getMinimumWidth();
+    method @Px public int getPaddingBottom();
+    method @Px public int getPaddingEnd();
+    method @Px public int getPaddingLeft();
+    method @Px public int getPaddingRight();
+    method @Px public int getPaddingStart();
+    method @Px public int getPaddingTop();
+    method public int getPosition(android.view.View);
+    method public static androidx.recyclerview.widget.RecyclerView.LayoutManager.Properties! getProperties(android.content.Context, android.util.AttributeSet?, int, int);
+    method public int getRightDecorationWidth(android.view.View);
+    method public int getRowCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public int getSelectionModeForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public int getTopDecorationHeight(android.view.View);
+    method public void getTransformedBoundingBox(android.view.View, boolean, android.graphics.Rect);
+    method @Px public int getWidth();
+    method public int getWidthMode();
+    method public boolean hasFocus();
+    method public void ignoreView(android.view.View);
+    method public boolean isAttachedToWindow();
+    method public boolean isAutoMeasureEnabled();
+    method public boolean isFocused();
+    method public final boolean isItemPrefetchEnabled();
+    method public boolean isLayoutHierarchical(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public boolean isMeasurementCacheEnabled();
+    method public boolean isSmoothScrolling();
+    method public boolean isViewPartiallyVisible(android.view.View, boolean, boolean);
+    method public void layoutDecorated(android.view.View, int, int, int, int);
+    method public void layoutDecoratedWithMargins(android.view.View, int, int, int, int);
+    method public void measureChild(android.view.View, int, int);
+    method public void measureChildWithMargins(android.view.View, int, int);
+    method public void moveView(int, int);
+    method public void offsetChildrenHorizontal(@Px int);
+    method public void offsetChildrenVertical(@Px int);
+    method public void onAdapterChanged(androidx.recyclerview.widget.RecyclerView.Adapter?, androidx.recyclerview.widget.RecyclerView.Adapter?);
+    method public boolean onAddFocusables(androidx.recyclerview.widget.RecyclerView, java.util.ArrayList<android.view.View!>, int, int);
+    method @CallSuper public void onAttachedToWindow(androidx.recyclerview.widget.RecyclerView!);
+    method @Deprecated public void onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView!);
+    method @CallSuper public void onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView!, androidx.recyclerview.widget.RecyclerView.Recycler!);
+    method public android.view.View? onFocusSearchFailed(android.view.View, int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public void onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityEvent(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityNodeInfo(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method public void onInitializeAccessibilityNodeInfoForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method public android.view.View? onInterceptFocusSearch(android.view.View, int);
+    method public void onItemsAdded(androidx.recyclerview.widget.RecyclerView, int, int);
+    method public void onItemsChanged(androidx.recyclerview.widget.RecyclerView);
+    method public void onItemsMoved(androidx.recyclerview.widget.RecyclerView, int, int, int);
+    method public void onItemsRemoved(androidx.recyclerview.widget.RecyclerView, int, int);
+    method public void onItemsUpdated(androidx.recyclerview.widget.RecyclerView, int, int);
+    method public void onItemsUpdated(androidx.recyclerview.widget.RecyclerView, int, int, Object?);
+    method public void onLayoutChildren(androidx.recyclerview.widget.RecyclerView.Recycler!, androidx.recyclerview.widget.RecyclerView.State!);
+    method public void onLayoutCompleted(androidx.recyclerview.widget.RecyclerView.State!);
+    method public void onMeasure(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, int, int);
+    method @Deprecated public boolean onRequestChildFocus(androidx.recyclerview.widget.RecyclerView, android.view.View, android.view.View?);
+    method public boolean onRequestChildFocus(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State, android.view.View, android.view.View?);
+    method public void onRestoreInstanceState(android.os.Parcelable!);
+    method public android.os.Parcelable? onSaveInstanceState();
+    method public void onScrollStateChanged(int);
+    method public boolean performAccessibilityAction(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, int, android.os.Bundle?);
+    method public boolean performAccessibilityActionForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, int, android.os.Bundle?);
+    method public void postOnAnimation(Runnable!);
+    method public void removeAllViews();
+    method public void removeAndRecycleAllViews(androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void removeAndRecycleView(android.view.View, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void removeAndRecycleViewAt(int, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public boolean removeCallbacks(Runnable!);
+    method public void removeDetachedView(android.view.View);
+    method public void removeView(android.view.View!);
+    method public void removeViewAt(int);
+    method public boolean requestChildRectangleOnScreen(androidx.recyclerview.widget.RecyclerView, android.view.View, android.graphics.Rect, boolean);
+    method public boolean requestChildRectangleOnScreen(androidx.recyclerview.widget.RecyclerView, android.view.View, android.graphics.Rect, boolean, boolean);
+    method public void requestLayout();
+    method public void requestSimpleAnimationsInNextLayout();
+    method public int scrollHorizontallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler!, androidx.recyclerview.widget.RecyclerView.State!);
+    method public void scrollToPosition(int);
+    method public int scrollVerticallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler!, androidx.recyclerview.widget.RecyclerView.State!);
+    method @Deprecated public void setAutoMeasureEnabled(boolean);
+    method public final void setItemPrefetchEnabled(boolean);
+    method public void setMeasuredDimension(android.graphics.Rect!, int, int);
+    method public void setMeasuredDimension(int, int);
+    method public void setMeasurementCacheEnabled(boolean);
+    method public void smoothScrollToPosition(androidx.recyclerview.widget.RecyclerView!, androidx.recyclerview.widget.RecyclerView.State!, int);
+    method public void startSmoothScroll(androidx.recyclerview.widget.RecyclerView.SmoothScroller!);
+    method public void stopIgnoringView(android.view.View);
+    method public boolean supportsPredictiveItemAnimations();
+  }
+
+  public static interface RecyclerView.LayoutManager.LayoutPrefetchRegistry {
+    method public void addPosition(int, int);
+  }
+
+  public static class RecyclerView.LayoutManager.Properties {
+    ctor public RecyclerView.LayoutManager.Properties();
+    field public int orientation;
+    field public boolean reverseLayout;
+    field public int spanCount;
+    field public boolean stackFromEnd;
+  }
+
+  public static class RecyclerView.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+    ctor public RecyclerView.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public RecyclerView.LayoutParams(int, int);
+    ctor public RecyclerView.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public RecyclerView.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public RecyclerView.LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public int getAbsoluteAdapterPosition();
+    method public int getBindingAdapterPosition();
+    method @Deprecated public int getViewAdapterPosition();
+    method public int getViewLayoutPosition();
+    method @Deprecated public int getViewPosition();
+    method public boolean isItemChanged();
+    method public boolean isItemRemoved();
+    method public boolean isViewInvalid();
+    method public boolean viewNeedsUpdate();
+  }
+
+  public static interface RecyclerView.OnChildAttachStateChangeListener {
+    method public void onChildViewAttachedToWindow(android.view.View);
+    method public void onChildViewDetachedFromWindow(android.view.View);
+  }
+
+  public abstract static class RecyclerView.OnFlingListener {
+    ctor public RecyclerView.OnFlingListener();
+    method public abstract boolean onFling(int, int);
+  }
+
+  public static interface RecyclerView.OnItemTouchListener {
+    method public boolean onInterceptTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+    method public void onRequestDisallowInterceptTouchEvent(boolean);
+    method public void onTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+  }
+
+  public abstract static class RecyclerView.OnScrollListener {
+    ctor public RecyclerView.OnScrollListener();
+    method public void onScrollStateChanged(androidx.recyclerview.widget.RecyclerView, int);
+    method public void onScrolled(androidx.recyclerview.widget.RecyclerView, int, int);
+  }
+
+  public static class RecyclerView.RecycledViewPool {
+    ctor public RecyclerView.RecycledViewPool();
+    method public void clear();
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? getRecycledView(int);
+    method public int getRecycledViewCount(int);
+    method public void putRecycledView(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void setMaxRecycledViews(int, int);
+  }
+
+  public final class RecyclerView.Recycler {
+    ctor public RecyclerView.Recycler();
+    method public void bindViewToPosition(android.view.View, int);
+    method public void clear();
+    method public int convertPreLayoutPositionToPostLayout(int);
+    method public java.util.List<androidx.recyclerview.widget.RecyclerView.ViewHolder!> getScrapList();
+    method public android.view.View getViewForPosition(int);
+    method public void recycleView(android.view.View);
+    method public void setViewCacheSize(int);
+  }
+
+  public static interface RecyclerView.RecyclerListener {
+    method public void onViewRecycled(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+  }
+
+  public static class RecyclerView.SimpleOnItemTouchListener implements androidx.recyclerview.widget.RecyclerView.OnItemTouchListener {
+    ctor public RecyclerView.SimpleOnItemTouchListener();
+    method public boolean onInterceptTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+    method public void onRequestDisallowInterceptTouchEvent(boolean);
+    method public void onTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+  }
+
+  public abstract static class RecyclerView.SmoothScroller {
+    ctor public RecyclerView.SmoothScroller();
+    method public android.graphics.PointF? computeScrollVectorForPosition(int);
+    method public android.view.View! findViewByPosition(int);
+    method public int getChildCount();
+    method public int getChildPosition(android.view.View!);
+    method public androidx.recyclerview.widget.RecyclerView.LayoutManager? getLayoutManager();
+    method public int getTargetPosition();
+    method @Deprecated public void instantScrollToPosition(int);
+    method public boolean isPendingInitialRun();
+    method public boolean isRunning();
+    method protected void normalize(android.graphics.PointF);
+    method protected void onChildAttachedToWindow(android.view.View!);
+    method protected abstract void onSeekTargetStep(@Px int, @Px int, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action);
+    method protected abstract void onStart();
+    method protected abstract void onStop();
+    method protected abstract void onTargetFound(android.view.View, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action);
+    method public void setTargetPosition(int);
+    method protected final void stop();
+  }
+
+  public static class RecyclerView.SmoothScroller.Action {
+    ctor public RecyclerView.SmoothScroller.Action(@Px int, @Px int);
+    ctor public RecyclerView.SmoothScroller.Action(@Px int, @Px int, int);
+    ctor public RecyclerView.SmoothScroller.Action(@Px int, @Px int, int, android.view.animation.Interpolator?);
+    method public int getDuration();
+    method @Px public int getDx();
+    method @Px public int getDy();
+    method public android.view.animation.Interpolator? getInterpolator();
+    method public void jumpTo(int);
+    method public void setDuration(int);
+    method public void setDx(@Px int);
+    method public void setDy(@Px int);
+    method public void setInterpolator(android.view.animation.Interpolator?);
+    method public void update(@Px int, @Px int, int, android.view.animation.Interpolator?);
+    field public static final int UNDEFINED_DURATION = -2147483648; // 0x80000000
+  }
+
+  public static interface RecyclerView.SmoothScroller.ScrollVectorProvider {
+    method public android.graphics.PointF? computeScrollVectorForPosition(int);
+  }
+
+  public static class RecyclerView.State {
+    ctor public RecyclerView.State();
+    method public boolean didStructureChange();
+    method public <T> T! get(int);
+    method public int getItemCount();
+    method public int getRemainingScrollHorizontal();
+    method public int getRemainingScrollVertical();
+    method public int getTargetScrollPosition();
+    method public boolean hasTargetScrollPosition();
+    method public boolean isMeasuring();
+    method public boolean isPreLayout();
+    method public void put(int, Object!);
+    method public void remove(int);
+    method public boolean willRunPredictiveAnimations();
+    method public boolean willRunSimpleAnimations();
+  }
+
+  public abstract static class RecyclerView.ViewCacheExtension {
+    ctor public RecyclerView.ViewCacheExtension();
+    method public abstract android.view.View? getViewForPositionAndType(androidx.recyclerview.widget.RecyclerView.Recycler, int, int);
+  }
+
+  public abstract static class RecyclerView.ViewHolder {
+    ctor public RecyclerView.ViewHolder(android.view.View);
+    method public final int getAbsoluteAdapterPosition();
+    method @Deprecated public final int getAdapterPosition();
+    method public final androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>? getBindingAdapter();
+    method public final int getBindingAdapterPosition();
+    method public final long getItemId();
+    method public final int getItemViewType();
+    method public final int getLayoutPosition();
+    method public final int getOldPosition();
+    method @Deprecated public final int getPosition();
+    method public final boolean isRecyclable();
+    method public final void setIsRecyclable(boolean);
+    field public final android.view.View itemView;
+  }
+
+  public class RecyclerViewAccessibilityDelegate extends androidx.core.view.AccessibilityDelegateCompat {
+    ctor public RecyclerViewAccessibilityDelegate(androidx.recyclerview.widget.RecyclerView);
+    method public androidx.core.view.AccessibilityDelegateCompat getItemDelegate();
+  }
+
+  public static class RecyclerViewAccessibilityDelegate.ItemDelegate extends androidx.core.view.AccessibilityDelegateCompat {
+    ctor public RecyclerViewAccessibilityDelegate.ItemDelegate(androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate);
+  }
+
+  public abstract class SimpleItemAnimator extends androidx.recyclerview.widget.RecyclerView.ItemAnimator {
+    ctor public SimpleItemAnimator();
+    method public abstract boolean animateAdd(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public boolean animateAppearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder!, androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animateDisappearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?);
+    method public abstract boolean animateMove(androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animatePersistence(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateRemove(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchAddFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchAddStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchChangeFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public final void dispatchChangeStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public final void dispatchMoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchMoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchRemoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchRemoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public boolean getSupportsChangeAnimations();
+    method public void onAddFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onAddStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onChangeFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public void onChangeStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public void onMoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onMoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onRemoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onRemoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void setSupportsChangeAnimations(boolean);
+  }
+
+  public abstract class SnapHelper extends androidx.recyclerview.widget.RecyclerView.OnFlingListener {
+    ctor public SnapHelper();
+    method public void attachToRecyclerView(androidx.recyclerview.widget.RecyclerView?) throws java.lang.IllegalStateException;
+    method public abstract int[]? calculateDistanceToFinalSnap(androidx.recyclerview.widget.RecyclerView.LayoutManager, android.view.View);
+    method public int[]! calculateScrollDistance(int, int);
+    method protected androidx.recyclerview.widget.RecyclerView.SmoothScroller? createScroller(androidx.recyclerview.widget.RecyclerView.LayoutManager);
+    method @Deprecated protected androidx.recyclerview.widget.LinearSmoothScroller? createSnapScroller(androidx.recyclerview.widget.RecyclerView.LayoutManager);
+    method public abstract android.view.View? findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public abstract int findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int, int);
+    method public boolean onFling(int, int);
+  }
+
+  public class SortedList<T> {
+    ctor public SortedList(Class<T!>, androidx.recyclerview.widget.SortedList.Callback<T!>);
+    ctor public SortedList(Class<T!>, androidx.recyclerview.widget.SortedList.Callback<T!>, int);
+    method public int add(T!);
+    method public void addAll(T![], boolean);
+    method public void addAll(T!...);
+    method public void addAll(java.util.Collection<T!>);
+    method public void beginBatchedUpdates();
+    method public void clear();
+    method public void endBatchedUpdates();
+    method public T! get(int) throws java.lang.IndexOutOfBoundsException;
+    method public int indexOf(T!);
+    method public void recalculatePositionOfItemAt(int);
+    method public boolean remove(T!);
+    method public T! removeItemAt(int);
+    method public void replaceAll(T![], boolean);
+    method public void replaceAll(T!...);
+    method public void replaceAll(java.util.Collection<T!>);
+    method public int size();
+    method public void updateItemAt(int, T!);
+    field public static final int INVALID_POSITION = -1; // 0xffffffff
+  }
+
+  public static class SortedList.BatchedCallback<T2> extends androidx.recyclerview.widget.SortedList.Callback<T2> {
+    ctor public SortedList.BatchedCallback(androidx.recyclerview.widget.SortedList.Callback<T2!>!);
+    method public boolean areContentsTheSame(T2!, T2!);
+    method public boolean areItemsTheSame(T2!, T2!);
+    method public int compare(T2!, T2!);
+    method public void dispatchLastEvent();
+    method public void onChanged(int, int);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public abstract static class SortedList.Callback<T2> implements java.util.Comparator<T2> androidx.recyclerview.widget.ListUpdateCallback {
+    ctor public SortedList.Callback();
+    method public abstract boolean areContentsTheSame(T2!, T2!);
+    method public abstract boolean areItemsTheSame(T2!, T2!);
+    method public abstract int compare(T2!, T2!);
+    method public Object? getChangePayload(T2!, T2!);
+    method public abstract void onChanged(int, int);
+    method public void onChanged(int, int, Object!);
+  }
+
+  public abstract class SortedListAdapterCallback<T2> extends androidx.recyclerview.widget.SortedList.Callback<T2> {
+    ctor public SortedListAdapterCallback(androidx.recyclerview.widget.RecyclerView.Adapter!);
+    method public void onChanged(int, int);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public class StaggeredGridLayoutManager extends androidx.recyclerview.widget.RecyclerView.LayoutManager implements androidx.recyclerview.widget.RecyclerView.SmoothScroller.ScrollVectorProvider {
+    ctor public StaggeredGridLayoutManager(android.content.Context!, android.util.AttributeSet!, int, int);
+    ctor public StaggeredGridLayoutManager(int, int);
+    method public android.graphics.PointF! computeScrollVectorForPosition(int);
+    method public int[]! findFirstCompletelyVisibleItemPositions(int[]!);
+    method public int[]! findFirstVisibleItemPositions(int[]!);
+    method public int[]! findLastCompletelyVisibleItemPositions(int[]!);
+    method public int[]! findLastVisibleItemPositions(int[]!);
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateDefaultLayoutParams();
+    method public int getGapStrategy();
+    method public int getOrientation();
+    method public boolean getReverseLayout();
+    method public int getSpanCount();
+    method public void invalidateSpanAssignments();
+    method public void scrollToPositionWithOffset(int, int);
+    method public void setGapStrategy(int);
+    method public void setOrientation(int);
+    method public void setReverseLayout(boolean);
+    method public void setSpanCount(int);
+    field @Deprecated public static final int GAP_HANDLING_LAZY = 1; // 0x1
+    field public static final int GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS = 2; // 0x2
+    field public static final int GAP_HANDLING_NONE = 0; // 0x0
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public static class StaggeredGridLayoutManager.LayoutParams extends androidx.recyclerview.widget.RecyclerView.LayoutParams {
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public StaggeredGridLayoutManager.LayoutParams(int, int);
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public StaggeredGridLayoutManager.LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public final int getSpanIndex();
+    method public boolean isFullSpan();
+    method public void setFullSpan(boolean);
+    field public static final int INVALID_SPAN_ID = -1; // 0xffffffff
+  }
+
+}
+
diff --git a/recyclerview/recyclerview/api/public_plus_experimental_1.2.0-beta02.txt b/recyclerview/recyclerview/api/public_plus_experimental_1.2.0-beta02.txt
new file mode 100644
index 0000000..e1ffd69
--- /dev/null
+++ b/recyclerview/recyclerview/api/public_plus_experimental_1.2.0-beta02.txt
@@ -0,0 +1,1091 @@
+// Signature format: 4.0
+package androidx.recyclerview.widget {
+
+  public final class AdapterListUpdateCallback implements androidx.recyclerview.widget.ListUpdateCallback {
+    ctor public AdapterListUpdateCallback(androidx.recyclerview.widget.RecyclerView.Adapter);
+    method public void onChanged(int, int, Object!);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public final class AsyncDifferConfig<T> {
+    method public java.util.concurrent.Executor getBackgroundThreadExecutor();
+    method public androidx.recyclerview.widget.DiffUtil.ItemCallback<T!> getDiffCallback();
+  }
+
+  public static final class AsyncDifferConfig.Builder<T> {
+    ctor public AsyncDifferConfig.Builder(androidx.recyclerview.widget.DiffUtil.ItemCallback<T!>);
+    method public androidx.recyclerview.widget.AsyncDifferConfig<T!> build();
+    method public androidx.recyclerview.widget.AsyncDifferConfig.Builder<T!> setBackgroundThreadExecutor(java.util.concurrent.Executor!);
+  }
+
+  public class AsyncListDiffer<T> {
+    ctor public AsyncListDiffer(androidx.recyclerview.widget.RecyclerView.Adapter, androidx.recyclerview.widget.DiffUtil.ItemCallback<T!>);
+    ctor public AsyncListDiffer(androidx.recyclerview.widget.ListUpdateCallback, androidx.recyclerview.widget.AsyncDifferConfig<T!>);
+    method public void addListListener(androidx.recyclerview.widget.AsyncListDiffer.ListListener<T!>);
+    method public java.util.List<T!> getCurrentList();
+    method public void removeListListener(androidx.recyclerview.widget.AsyncListDiffer.ListListener<T!>);
+    method public void submitList(java.util.List<T!>?);
+    method public void submitList(java.util.List<T!>?, Runnable?);
+  }
+
+  public static interface AsyncListDiffer.ListListener<T> {
+    method public void onCurrentListChanged(java.util.List<T!>, java.util.List<T!>);
+  }
+
+  public class AsyncListUtil<T> {
+    ctor public AsyncListUtil(Class<T!>, int, androidx.recyclerview.widget.AsyncListUtil.DataCallback<T!>, androidx.recyclerview.widget.AsyncListUtil.ViewCallback);
+    method public T? getItem(int);
+    method public int getItemCount();
+    method public void onRangeChanged();
+    method public void refresh();
+  }
+
+  public abstract static class AsyncListUtil.DataCallback<T> {
+    ctor public AsyncListUtil.DataCallback();
+    method @WorkerThread public abstract void fillData(T![], int, int);
+    method @WorkerThread public int getMaxCachedTiles();
+    method @WorkerThread public void recycleData(T![], int);
+    method @WorkerThread public abstract int refreshData();
+  }
+
+  public abstract static class AsyncListUtil.ViewCallback {
+    ctor public AsyncListUtil.ViewCallback();
+    method @UiThread public void extendRangeInto(int[], int[], int);
+    method @UiThread public abstract void getItemRangeInto(int[]);
+    method @UiThread public abstract void onDataRefresh();
+    method @UiThread public abstract void onItemLoaded(int);
+    field public static final int HINT_SCROLL_ASC = 2; // 0x2
+    field public static final int HINT_SCROLL_DESC = 1; // 0x1
+    field public static final int HINT_SCROLL_NONE = 0; // 0x0
+  }
+
+  public class BatchingListUpdateCallback implements androidx.recyclerview.widget.ListUpdateCallback {
+    ctor public BatchingListUpdateCallback(androidx.recyclerview.widget.ListUpdateCallback);
+    method public void dispatchLastEvent();
+    method public void onChanged(int, int, Object!);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public final class ConcatAdapter extends androidx.recyclerview.widget.RecyclerView.Adapter<androidx.recyclerview.widget.RecyclerView.ViewHolder> {
+    ctor @java.lang.SafeVarargs public ConcatAdapter(androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>!...);
+    ctor @java.lang.SafeVarargs public ConcatAdapter(androidx.recyclerview.widget.ConcatAdapter.Config, androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>!...);
+    ctor public ConcatAdapter(java.util.List<? extends androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>>);
+    ctor public ConcatAdapter(androidx.recyclerview.widget.ConcatAdapter.Config, java.util.List<? extends androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>>);
+    method public boolean addAdapter(androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>);
+    method public boolean addAdapter(int, androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>);
+    method public java.util.List<? extends androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>> getAdapters();
+    method public int getItemCount();
+    method public void onBindViewHolder(androidx.recyclerview.widget.RecyclerView.ViewHolder, int);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder onCreateViewHolder(android.view.ViewGroup, int);
+    method public boolean onFailedToRecycleView(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onViewAttachedToWindow(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onViewDetachedFromWindow(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onViewRecycled(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public boolean removeAdapter(androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>);
+  }
+
+  public static final class ConcatAdapter.Config {
+    field public static final androidx.recyclerview.widget.ConcatAdapter.Config DEFAULT;
+    field public final boolean isolateViewTypes;
+    field public final androidx.recyclerview.widget.ConcatAdapter.Config.StableIdMode stableIdMode;
+  }
+
+  public static final class ConcatAdapter.Config.Builder {
+    ctor public ConcatAdapter.Config.Builder();
+    method public androidx.recyclerview.widget.ConcatAdapter.Config build();
+    method public androidx.recyclerview.widget.ConcatAdapter.Config.Builder setIsolateViewTypes(boolean);
+    method public androidx.recyclerview.widget.ConcatAdapter.Config.Builder setStableIdMode(androidx.recyclerview.widget.ConcatAdapter.Config.StableIdMode);
+  }
+
+  public enum ConcatAdapter.Config.StableIdMode {
+    enum_constant public static final androidx.recyclerview.widget.ConcatAdapter.Config.StableIdMode ISOLATED_STABLE_IDS;
+    enum_constant public static final androidx.recyclerview.widget.ConcatAdapter.Config.StableIdMode NO_STABLE_IDS;
+    enum_constant public static final androidx.recyclerview.widget.ConcatAdapter.Config.StableIdMode SHARED_STABLE_IDS;
+  }
+
+  public class DefaultItemAnimator extends androidx.recyclerview.widget.SimpleItemAnimator {
+    ctor public DefaultItemAnimator();
+    method public boolean animateAdd(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder!, androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animateMove(androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animateRemove(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void endAnimation(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void endAnimations();
+    method public boolean isRunning();
+    method public void runPendingAnimations();
+  }
+
+  public class DiffUtil {
+    method public static androidx.recyclerview.widget.DiffUtil.DiffResult calculateDiff(androidx.recyclerview.widget.DiffUtil.Callback);
+    method public static androidx.recyclerview.widget.DiffUtil.DiffResult calculateDiff(androidx.recyclerview.widget.DiffUtil.Callback, boolean);
+  }
+
+  public abstract static class DiffUtil.Callback {
+    ctor public DiffUtil.Callback();
+    method public abstract boolean areContentsTheSame(int, int);
+    method public abstract boolean areItemsTheSame(int, int);
+    method public Object? getChangePayload(int, int);
+    method public abstract int getNewListSize();
+    method public abstract int getOldListSize();
+  }
+
+  public static class DiffUtil.DiffResult {
+    method public int convertNewPositionToOld(@IntRange(from=0) int);
+    method public int convertOldPositionToNew(@IntRange(from=0) int);
+    method public void dispatchUpdatesTo(androidx.recyclerview.widget.RecyclerView.Adapter);
+    method public void dispatchUpdatesTo(androidx.recyclerview.widget.ListUpdateCallback);
+    field public static final int NO_POSITION = -1; // 0xffffffff
+  }
+
+  public abstract static class DiffUtil.ItemCallback<T> {
+    ctor public DiffUtil.ItemCallback();
+    method public abstract boolean areContentsTheSame(T, T);
+    method public abstract boolean areItemsTheSame(T, T);
+    method public Object? getChangePayload(T, T);
+  }
+
+  public class DividerItemDecoration extends androidx.recyclerview.widget.RecyclerView.ItemDecoration {
+    ctor public DividerItemDecoration(android.content.Context!, int);
+    method public android.graphics.drawable.Drawable? getDrawable();
+    method public void setDrawable(android.graphics.drawable.Drawable);
+    method public void setOrientation(int);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public class GridLayoutManager extends androidx.recyclerview.widget.LinearLayoutManager {
+    ctor public GridLayoutManager(android.content.Context!, android.util.AttributeSet!, int, int);
+    ctor public GridLayoutManager(android.content.Context!, int);
+    ctor public GridLayoutManager(android.content.Context!, int, int, boolean);
+    method public int getSpanCount();
+    method public androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup! getSpanSizeLookup();
+    method public boolean isUsingSpansToEstimateScrollbarDimensions();
+    method public void setSpanCount(int);
+    method public void setSpanSizeLookup(androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup!);
+    method public void setUsingSpansToEstimateScrollbarDimensions(boolean);
+    field public static final int DEFAULT_SPAN_COUNT = -1; // 0xffffffff
+  }
+
+  public static final class GridLayoutManager.DefaultSpanSizeLookup extends androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup {
+    ctor public GridLayoutManager.DefaultSpanSizeLookup();
+    method public int getSpanSize(int);
+  }
+
+  public static class GridLayoutManager.LayoutParams extends androidx.recyclerview.widget.RecyclerView.LayoutParams {
+    ctor public GridLayoutManager.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public GridLayoutManager.LayoutParams(int, int);
+    ctor public GridLayoutManager.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public GridLayoutManager.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public GridLayoutManager.LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public int getSpanIndex();
+    method public int getSpanSize();
+    field public static final int INVALID_SPAN_ID = -1; // 0xffffffff
+  }
+
+  public abstract static class GridLayoutManager.SpanSizeLookup {
+    ctor public GridLayoutManager.SpanSizeLookup();
+    method public int getSpanGroupIndex(int, int);
+    method public int getSpanIndex(int, int);
+    method public abstract int getSpanSize(int);
+    method public void invalidateSpanGroupIndexCache();
+    method public void invalidateSpanIndexCache();
+    method public boolean isSpanGroupIndexCacheEnabled();
+    method public boolean isSpanIndexCacheEnabled();
+    method public void setSpanGroupIndexCacheEnabled(boolean);
+    method public void setSpanIndexCacheEnabled(boolean);
+  }
+
+  public class ItemTouchHelper extends androidx.recyclerview.widget.RecyclerView.ItemDecoration implements androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener {
+    ctor public ItemTouchHelper(androidx.recyclerview.widget.ItemTouchHelper.Callback);
+    method public void attachToRecyclerView(androidx.recyclerview.widget.RecyclerView?);
+    method public void onChildViewAttachedToWindow(android.view.View);
+    method public void onChildViewDetachedFromWindow(android.view.View);
+    method public void startDrag(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void startSwipe(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    field public static final int ACTION_STATE_DRAG = 2; // 0x2
+    field public static final int ACTION_STATE_IDLE = 0; // 0x0
+    field public static final int ACTION_STATE_SWIPE = 1; // 0x1
+    field public static final int ANIMATION_TYPE_DRAG = 8; // 0x8
+    field public static final int ANIMATION_TYPE_SWIPE_CANCEL = 4; // 0x4
+    field public static final int ANIMATION_TYPE_SWIPE_SUCCESS = 2; // 0x2
+    field public static final int DOWN = 2; // 0x2
+    field public static final int END = 32; // 0x20
+    field public static final int LEFT = 4; // 0x4
+    field public static final int RIGHT = 8; // 0x8
+    field public static final int START = 16; // 0x10
+    field public static final int UP = 1; // 0x1
+  }
+
+  public abstract static class ItemTouchHelper.Callback {
+    ctor public ItemTouchHelper.Callback();
+    method public boolean canDropOver(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder! chooseDropTarget(androidx.recyclerview.widget.RecyclerView.ViewHolder, java.util.List<androidx.recyclerview.widget.RecyclerView.ViewHolder!>, int, int);
+    method public void clearView(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public int convertToAbsoluteDirection(int, int);
+    method public static int convertToRelativeDirection(int, int);
+    method public long getAnimationDuration(androidx.recyclerview.widget.RecyclerView, int, float, float);
+    method public int getBoundingBoxMargin();
+    method public static androidx.recyclerview.widget.ItemTouchUIUtil getDefaultUIUtil();
+    method public float getMoveThreshold(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public abstract int getMovementFlags(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public float getSwipeEscapeVelocity(float);
+    method public float getSwipeThreshold(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public float getSwipeVelocityThreshold(float);
+    method public int interpolateOutOfBoundsScroll(androidx.recyclerview.widget.RecyclerView, int, int, int, long);
+    method public boolean isItemViewSwipeEnabled();
+    method public boolean isLongPressDragEnabled();
+    method public static int makeFlag(int, int);
+    method public static int makeMovementFlags(int, int);
+    method public void onChildDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, float, float, int, boolean);
+    method public void onChildDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder!, float, float, int, boolean);
+    method public abstract boolean onMove(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onMoved(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, int, int);
+    method public void onSelectedChanged(androidx.recyclerview.widget.RecyclerView.ViewHolder?, int);
+    method public abstract void onSwiped(androidx.recyclerview.widget.RecyclerView.ViewHolder, int);
+    field public static final int DEFAULT_DRAG_ANIMATION_DURATION = 200; // 0xc8
+    field public static final int DEFAULT_SWIPE_ANIMATION_DURATION = 250; // 0xfa
+  }
+
+  public abstract static class ItemTouchHelper.SimpleCallback extends androidx.recyclerview.widget.ItemTouchHelper.Callback {
+    ctor public ItemTouchHelper.SimpleCallback(int, int);
+    method public int getDragDirs(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public int getMovementFlags(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public int getSwipeDirs(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void setDefaultDragDirs(int);
+    method public void setDefaultSwipeDirs(int);
+  }
+
+  public static interface ItemTouchHelper.ViewDropHandler {
+    method public void prepareForDrop(android.view.View, android.view.View, int, int);
+  }
+
+  public interface ItemTouchUIUtil {
+    method public void clearView(android.view.View!);
+    method public void onDraw(android.graphics.Canvas!, androidx.recyclerview.widget.RecyclerView!, android.view.View!, float, float, int, boolean);
+    method public void onDrawOver(android.graphics.Canvas!, androidx.recyclerview.widget.RecyclerView!, android.view.View!, float, float, int, boolean);
+    method public void onSelected(android.view.View!);
+  }
+
+  public class LinearLayoutManager extends androidx.recyclerview.widget.RecyclerView.LayoutManager implements androidx.recyclerview.widget.ItemTouchHelper.ViewDropHandler androidx.recyclerview.widget.RecyclerView.SmoothScroller.ScrollVectorProvider {
+    ctor public LinearLayoutManager(android.content.Context!);
+    ctor public LinearLayoutManager(android.content.Context!, int, boolean);
+    ctor public LinearLayoutManager(android.content.Context!, android.util.AttributeSet!, int, int);
+    method protected void calculateExtraLayoutSpace(androidx.recyclerview.widget.RecyclerView.State, int[]);
+    method public android.graphics.PointF! computeScrollVectorForPosition(int);
+    method public int findFirstCompletelyVisibleItemPosition();
+    method public int findFirstVisibleItemPosition();
+    method public int findLastCompletelyVisibleItemPosition();
+    method public int findLastVisibleItemPosition();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateDefaultLayoutParams();
+    method @Deprecated protected int getExtraLayoutSpace(androidx.recyclerview.widget.RecyclerView.State!);
+    method public int getInitialPrefetchItemCount();
+    method public int getOrientation();
+    method public boolean getRecycleChildrenOnDetach();
+    method public boolean getReverseLayout();
+    method public boolean getStackFromEnd();
+    method protected boolean isLayoutRTL();
+    method public boolean isSmoothScrollbarEnabled();
+    method public void prepareForDrop(android.view.View, android.view.View, int, int);
+    method public void scrollToPositionWithOffset(int, int);
+    method public void setInitialPrefetchItemCount(int);
+    method public void setOrientation(int);
+    method public void setRecycleChildrenOnDetach(boolean);
+    method public void setReverseLayout(boolean);
+    method public void setSmoothScrollbarEnabled(boolean);
+    method public void setStackFromEnd(boolean);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int INVALID_OFFSET = -2147483648; // 0x80000000
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  protected static class LinearLayoutManager.LayoutChunkResult {
+    ctor protected LinearLayoutManager.LayoutChunkResult();
+    field public int mConsumed;
+    field public boolean mFinished;
+    field public boolean mFocusable;
+    field public boolean mIgnoreConsumed;
+  }
+
+  public class LinearSmoothScroller extends androidx.recyclerview.widget.RecyclerView.SmoothScroller {
+    ctor public LinearSmoothScroller(android.content.Context!);
+    method public int calculateDtToFit(int, int, int, int, int);
+    method public int calculateDxToMakeVisible(android.view.View!, int);
+    method public int calculateDyToMakeVisible(android.view.View!, int);
+    method protected float calculateSpeedPerPixel(android.util.DisplayMetrics!);
+    method protected int calculateTimeForDeceleration(int);
+    method protected int calculateTimeForScrolling(int);
+    method protected int getHorizontalSnapPreference();
+    method protected int getVerticalSnapPreference();
+    method protected void onSeekTargetStep(int, int, androidx.recyclerview.widget.RecyclerView.State!, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action!);
+    method protected void onStart();
+    method protected void onStop();
+    method protected void onTargetFound(android.view.View!, androidx.recyclerview.widget.RecyclerView.State!, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action!);
+    method protected void updateActionForInterimTarget(androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action!);
+    field public static final int SNAP_TO_ANY = 0; // 0x0
+    field public static final int SNAP_TO_END = 1; // 0x1
+    field public static final int SNAP_TO_START = -1; // 0xffffffff
+    field protected final android.view.animation.DecelerateInterpolator! mDecelerateInterpolator;
+    field protected int mInterimTargetDx;
+    field protected int mInterimTargetDy;
+    field protected final android.view.animation.LinearInterpolator! mLinearInterpolator;
+    field protected android.graphics.PointF! mTargetVector;
+  }
+
+  public class LinearSnapHelper extends androidx.recyclerview.widget.SnapHelper {
+    ctor public LinearSnapHelper();
+    method public int[]! calculateDistanceToFinalSnap(androidx.recyclerview.widget.RecyclerView.LayoutManager, android.view.View);
+    method public android.view.View! findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public int findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int, int);
+  }
+
+  public abstract class ListAdapter<T, VH extends androidx.recyclerview.widget.RecyclerView.ViewHolder> extends androidx.recyclerview.widget.RecyclerView.Adapter<VH> {
+    ctor protected ListAdapter(androidx.recyclerview.widget.DiffUtil.ItemCallback<T!>);
+    ctor protected ListAdapter(androidx.recyclerview.widget.AsyncDifferConfig<T!>);
+    method public java.util.List<T!> getCurrentList();
+    method protected T! getItem(int);
+    method public int getItemCount();
+    method public void onCurrentListChanged(java.util.List<T!>, java.util.List<T!>);
+    method public void submitList(java.util.List<T!>?);
+    method public void submitList(java.util.List<T!>?, Runnable?);
+  }
+
+  public interface ListUpdateCallback {
+    method public void onChanged(int, int, Object?);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public abstract class OrientationHelper {
+    method public static androidx.recyclerview.widget.OrientationHelper! createHorizontalHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public static androidx.recyclerview.widget.OrientationHelper! createOrientationHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int);
+    method public static androidx.recyclerview.widget.OrientationHelper! createVerticalHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public abstract int getDecoratedEnd(android.view.View!);
+    method public abstract int getDecoratedMeasurement(android.view.View!);
+    method public abstract int getDecoratedMeasurementInOther(android.view.View!);
+    method public abstract int getDecoratedStart(android.view.View!);
+    method public abstract int getEnd();
+    method public abstract int getEndAfterPadding();
+    method public abstract int getEndPadding();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutManager! getLayoutManager();
+    method public abstract int getMode();
+    method public abstract int getModeInOther();
+    method public abstract int getStartAfterPadding();
+    method public abstract int getTotalSpace();
+    method public int getTotalSpaceChange();
+    method public abstract int getTransformedEndWithDecoration(android.view.View!);
+    method public abstract int getTransformedStartWithDecoration(android.view.View!);
+    method public abstract void offsetChild(android.view.View!, int);
+    method public abstract void offsetChildren(int);
+    method public void onLayoutComplete();
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+    field protected final androidx.recyclerview.widget.RecyclerView.LayoutManager! mLayoutManager;
+  }
+
+  public class PagerSnapHelper extends androidx.recyclerview.widget.SnapHelper {
+    ctor public PagerSnapHelper();
+    method public int[]? calculateDistanceToFinalSnap(androidx.recyclerview.widget.RecyclerView.LayoutManager, android.view.View);
+    method public android.view.View? findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public int findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int, int);
+  }
+
+  public class RecyclerView extends android.view.ViewGroup implements androidx.core.view.NestedScrollingChild2 androidx.core.view.NestedScrollingChild3 androidx.core.view.ScrollingView {
+    ctor public RecyclerView(android.content.Context);
+    ctor public RecyclerView(android.content.Context, android.util.AttributeSet?);
+    ctor public RecyclerView(android.content.Context, android.util.AttributeSet?, int);
+    method public void addItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration, int);
+    method public void addItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration);
+    method public void addOnChildAttachStateChangeListener(androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener);
+    method public void addOnItemTouchListener(androidx.recyclerview.widget.RecyclerView.OnItemTouchListener);
+    method public void addOnScrollListener(androidx.recyclerview.widget.RecyclerView.OnScrollListener);
+    method public void addRecyclerListener(androidx.recyclerview.widget.RecyclerView.RecyclerListener);
+    method public void clearOnChildAttachStateChangeListeners();
+    method public void clearOnScrollListeners();
+    method public int computeHorizontalScrollExtent();
+    method public int computeHorizontalScrollOffset();
+    method public int computeHorizontalScrollRange();
+    method public int computeVerticalScrollExtent();
+    method public int computeVerticalScrollOffset();
+    method public int computeVerticalScrollRange();
+    method public boolean dispatchNestedPreScroll(int, int, int[]!, int[]!, int);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]!, int);
+    method public final void dispatchNestedScroll(int, int, int, int, int[]!, int, int[]);
+    method public boolean drawChild(android.graphics.Canvas!, android.view.View!, long);
+    method public android.view.View? findChildViewUnder(float, float);
+    method public android.view.View? findContainingItemView(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? findContainingViewHolder(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? findViewHolderForAdapterPosition(int);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder! findViewHolderForItemId(long);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? findViewHolderForLayoutPosition(int);
+    method @Deprecated public androidx.recyclerview.widget.RecyclerView.ViewHolder? findViewHolderForPosition(int);
+    method public boolean fling(int, int);
+    method public androidx.recyclerview.widget.RecyclerView.Adapter? getAdapter();
+    method public int getChildAdapterPosition(android.view.View);
+    method public long getChildItemId(android.view.View);
+    method public int getChildLayoutPosition(android.view.View);
+    method @Deprecated public int getChildPosition(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder! getChildViewHolder(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate? getCompatAccessibilityDelegate();
+    method public void getDecoratedBoundsWithMargins(android.view.View, android.graphics.Rect);
+    method public androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory getEdgeEffectFactory();
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator? getItemAnimator();
+    method public androidx.recyclerview.widget.RecyclerView.ItemDecoration getItemDecorationAt(int);
+    method public int getItemDecorationCount();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutManager? getLayoutManager();
+    method public int getMaxFlingVelocity();
+    method public int getMinFlingVelocity();
+    method public androidx.recyclerview.widget.RecyclerView.OnFlingListener? getOnFlingListener();
+    method public boolean getPreserveFocusAfterLayout();
+    method public androidx.recyclerview.widget.RecyclerView.RecycledViewPool getRecycledViewPool();
+    method public int getScrollState();
+    method public boolean hasFixedSize();
+    method public boolean hasNestedScrollingParent(int);
+    method public boolean hasPendingAdapterUpdates();
+    method public void invalidateItemDecorations();
+    method public boolean isAnimating();
+    method public boolean isComputingLayout();
+    method @Deprecated public boolean isLayoutFrozen();
+    method public final boolean isLayoutSuppressed();
+    method public void nestedScrollBy(int, int);
+    method public void offsetChildrenHorizontal(@Px int);
+    method public void offsetChildrenVertical(@Px int);
+    method public void onChildAttachedToWindow(android.view.View);
+    method public void onChildDetachedFromWindow(android.view.View);
+    method public void onDraw(android.graphics.Canvas!);
+    method public void onScrollStateChanged(int);
+    method public void onScrolled(@Px int, @Px int);
+    method public void removeItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration);
+    method public void removeItemDecorationAt(int);
+    method public void removeOnChildAttachStateChangeListener(androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener);
+    method public void removeOnItemTouchListener(androidx.recyclerview.widget.RecyclerView.OnItemTouchListener);
+    method public void removeOnScrollListener(androidx.recyclerview.widget.RecyclerView.OnScrollListener);
+    method public void removeRecyclerListener(androidx.recyclerview.widget.RecyclerView.RecyclerListener);
+    method public void scrollToPosition(int);
+    method public void setAccessibilityDelegateCompat(androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate?);
+    method public void setAdapter(androidx.recyclerview.widget.RecyclerView.Adapter?);
+    method public void setChildDrawingOrderCallback(androidx.recyclerview.widget.RecyclerView.ChildDrawingOrderCallback?);
+    method public void setEdgeEffectFactory(androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory);
+    method public void setHasFixedSize(boolean);
+    method public void setItemAnimator(androidx.recyclerview.widget.RecyclerView.ItemAnimator?);
+    method public void setItemViewCacheSize(int);
+    method @Deprecated public void setLayoutFrozen(boolean);
+    method public void setLayoutManager(androidx.recyclerview.widget.RecyclerView.LayoutManager?);
+    method @Deprecated public void setLayoutTransition(android.animation.LayoutTransition!);
+    method public void setOnFlingListener(androidx.recyclerview.widget.RecyclerView.OnFlingListener?);
+    method @Deprecated public void setOnScrollListener(androidx.recyclerview.widget.RecyclerView.OnScrollListener?);
+    method public void setPreserveFocusAfterLayout(boolean);
+    method public void setRecycledViewPool(androidx.recyclerview.widget.RecyclerView.RecycledViewPool?);
+    method @Deprecated public void setRecyclerListener(androidx.recyclerview.widget.RecyclerView.RecyclerListener?);
+    method public void setScrollingTouchSlop(int);
+    method public void setViewCacheExtension(androidx.recyclerview.widget.RecyclerView.ViewCacheExtension?);
+    method public void smoothScrollBy(@Px int, @Px int);
+    method public void smoothScrollBy(@Px int, @Px int, android.view.animation.Interpolator?);
+    method public void smoothScrollBy(@Px int, @Px int, android.view.animation.Interpolator?, int);
+    method public void smoothScrollToPosition(int);
+    method public boolean startNestedScroll(int, int);
+    method public void stopNestedScroll(int);
+    method public void stopScroll();
+    method public final void suppressLayout(boolean);
+    method public void swapAdapter(androidx.recyclerview.widget.RecyclerView.Adapter?, boolean);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int INVALID_TYPE = -1; // 0xffffffff
+    field public static final long NO_ID = -1L; // 0xffffffffffffffffL
+    field public static final int NO_POSITION = -1; // 0xffffffff
+    field public static final int SCROLL_STATE_DRAGGING = 1; // 0x1
+    field public static final int SCROLL_STATE_IDLE = 0; // 0x0
+    field public static final int SCROLL_STATE_SETTLING = 2; // 0x2
+    field public static final int TOUCH_SLOP_DEFAULT = 0; // 0x0
+    field public static final int TOUCH_SLOP_PAGING = 1; // 0x1
+    field public static final int UNDEFINED_DURATION = -2147483648; // 0x80000000
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public abstract static class RecyclerView.Adapter<VH extends androidx.recyclerview.widget.RecyclerView.ViewHolder> {
+    ctor public RecyclerView.Adapter();
+    method public final void bindViewHolder(VH, int);
+    method public final VH createViewHolder(android.view.ViewGroup, int);
+    method public int findRelativeAdapterPositionIn(androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>, androidx.recyclerview.widget.RecyclerView.ViewHolder, int);
+    method public abstract int getItemCount();
+    method public long getItemId(int);
+    method public int getItemViewType(int);
+    method public final androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy getStateRestorationPolicy();
+    method public final boolean hasObservers();
+    method public final boolean hasStableIds();
+    method public final void notifyDataSetChanged();
+    method public final void notifyItemChanged(int);
+    method public final void notifyItemChanged(int, Object?);
+    method public final void notifyItemInserted(int);
+    method public final void notifyItemMoved(int, int);
+    method public final void notifyItemRangeChanged(int, int);
+    method public final void notifyItemRangeChanged(int, int, Object?);
+    method public final void notifyItemRangeInserted(int, int);
+    method public final void notifyItemRangeRemoved(int, int);
+    method public final void notifyItemRemoved(int);
+    method public void onAttachedToRecyclerView(androidx.recyclerview.widget.RecyclerView);
+    method public abstract void onBindViewHolder(VH, int);
+    method public void onBindViewHolder(VH, int, java.util.List<java.lang.Object!>);
+    method public abstract VH onCreateViewHolder(android.view.ViewGroup, int);
+    method public void onDetachedFromRecyclerView(androidx.recyclerview.widget.RecyclerView);
+    method public boolean onFailedToRecycleView(VH);
+    method public void onViewAttachedToWindow(VH);
+    method public void onViewDetachedFromWindow(VH);
+    method public void onViewRecycled(VH);
+    method public void registerAdapterDataObserver(androidx.recyclerview.widget.RecyclerView.AdapterDataObserver);
+    method public void setHasStableIds(boolean);
+    method public void setStateRestorationPolicy(androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy);
+    method public void unregisterAdapterDataObserver(androidx.recyclerview.widget.RecyclerView.AdapterDataObserver);
+  }
+
+  public enum RecyclerView.Adapter.StateRestorationPolicy {
+    enum_constant public static final androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy ALLOW;
+    enum_constant public static final androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy PREVENT;
+    enum_constant public static final androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy PREVENT_WHEN_EMPTY;
+  }
+
+  public abstract static class RecyclerView.AdapterDataObserver {
+    ctor public RecyclerView.AdapterDataObserver();
+    method public void onChanged();
+    method public void onItemRangeChanged(int, int);
+    method public void onItemRangeChanged(int, int, Object?);
+    method public void onItemRangeInserted(int, int);
+    method public void onItemRangeMoved(int, int, int);
+    method public void onItemRangeRemoved(int, int);
+    method public void onStateRestorationPolicyChanged();
+  }
+
+  public static interface RecyclerView.ChildDrawingOrderCallback {
+    method public int onGetChildDrawingOrder(int, int);
+  }
+
+  public static class RecyclerView.EdgeEffectFactory {
+    ctor public RecyclerView.EdgeEffectFactory();
+    method protected android.widget.EdgeEffect createEdgeEffect(androidx.recyclerview.widget.RecyclerView, @androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.EdgeDirection int);
+    field public static final int DIRECTION_BOTTOM = 3; // 0x3
+    field public static final int DIRECTION_LEFT = 0; // 0x0
+    field public static final int DIRECTION_RIGHT = 2; // 0x2
+    field public static final int DIRECTION_TOP = 1; // 0x1
+  }
+
+  @IntDef({androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_LEFT, androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_TOP, androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_RIGHT, androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_BOTTOM}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RecyclerView.EdgeEffectFactory.EdgeDirection {
+  }
+
+  public abstract static class RecyclerView.ItemAnimator {
+    ctor public RecyclerView.ItemAnimator();
+    method public abstract boolean animateAppearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateDisappearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?);
+    method public abstract boolean animatePersistence(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public boolean canReuseUpdatedViewHolder(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public boolean canReuseUpdatedViewHolder(androidx.recyclerview.widget.RecyclerView.ViewHolder, java.util.List<java.lang.Object!>);
+    method public final void dispatchAnimationFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public final void dispatchAnimationStarted(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public final void dispatchAnimationsFinished();
+    method public abstract void endAnimation(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public abstract void endAnimations();
+    method public long getAddDuration();
+    method public long getChangeDuration();
+    method public long getMoveDuration();
+    method public long getRemoveDuration();
+    method public abstract boolean isRunning();
+    method public final boolean isRunning(androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemAnimatorFinishedListener?);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo obtainHolderInfo();
+    method public void onAnimationFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onAnimationStarted(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo recordPostLayoutInformation(androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo recordPreLayoutInformation(androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.ViewHolder, @androidx.recyclerview.widget.RecyclerView.ItemAnimator.AdapterChanges int, java.util.List<java.lang.Object!>);
+    method public abstract void runPendingAnimations();
+    method public void setAddDuration(long);
+    method public void setChangeDuration(long);
+    method public void setMoveDuration(long);
+    method public void setRemoveDuration(long);
+    field public static final int FLAG_APPEARED_IN_PRE_LAYOUT = 4096; // 0x1000
+    field public static final int FLAG_CHANGED = 2; // 0x2
+    field public static final int FLAG_INVALIDATED = 4; // 0x4
+    field public static final int FLAG_MOVED = 2048; // 0x800
+    field public static final int FLAG_REMOVED = 8; // 0x8
+  }
+
+  @IntDef(flag=true, value={androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_CHANGED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_REMOVED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_MOVED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_INVALIDATED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_APPEARED_IN_PRE_LAYOUT}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RecyclerView.ItemAnimator.AdapterChanges {
+  }
+
+  public static interface RecyclerView.ItemAnimator.ItemAnimatorFinishedListener {
+    method public void onAnimationsFinished();
+  }
+
+  public static class RecyclerView.ItemAnimator.ItemHolderInfo {
+    ctor public RecyclerView.ItemAnimator.ItemHolderInfo();
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo setFrom(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo setFrom(androidx.recyclerview.widget.RecyclerView.ViewHolder, @androidx.recyclerview.widget.RecyclerView.ItemAnimator.AdapterChanges int);
+    field public int bottom;
+    field @androidx.recyclerview.widget.RecyclerView.ItemAnimator.AdapterChanges public int changeFlags;
+    field public int left;
+    field public int right;
+    field public int top;
+  }
+
+  public abstract static class RecyclerView.ItemDecoration {
+    ctor public RecyclerView.ItemDecoration();
+    method @Deprecated public void getItemOffsets(android.graphics.Rect, int, androidx.recyclerview.widget.RecyclerView);
+    method public void getItemOffsets(android.graphics.Rect, android.view.View, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State);
+    method public void onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State);
+    method @Deprecated public void onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView);
+    method public void onDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State);
+    method @Deprecated public void onDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView);
+  }
+
+  public abstract static class RecyclerView.LayoutManager {
+    ctor public RecyclerView.LayoutManager();
+    method public void addDisappearingView(android.view.View!);
+    method public void addDisappearingView(android.view.View!, int);
+    method public void addView(android.view.View!);
+    method public void addView(android.view.View!, int);
+    method public void assertInLayoutOrScroll(String!);
+    method public void assertNotInLayoutOrScroll(String!);
+    method public void attachView(android.view.View, int, androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public void attachView(android.view.View, int);
+    method public void attachView(android.view.View);
+    method public void calculateItemDecorationsForChild(android.view.View, android.graphics.Rect);
+    method public boolean canScrollHorizontally();
+    method public boolean canScrollVertically();
+    method public boolean checkLayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public static int chooseSize(int, int, int);
+    method public void collectAdjacentPrefetchPositions(int, int, androidx.recyclerview.widget.RecyclerView.State!, androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry!);
+    method public void collectInitialPrefetchPositions(int, androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry!);
+    method public int computeHorizontalScrollExtent(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeHorizontalScrollOffset(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeHorizontalScrollRange(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeVerticalScrollExtent(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeVerticalScrollOffset(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeVerticalScrollRange(androidx.recyclerview.widget.RecyclerView.State);
+    method public void detachAndScrapAttachedViews(androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void detachAndScrapView(android.view.View, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void detachAndScrapViewAt(int, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void detachView(android.view.View);
+    method public void detachViewAt(int);
+    method public void endAnimation(android.view.View!);
+    method public android.view.View? findContainingItemView(android.view.View);
+    method public android.view.View? findViewByPosition(int);
+    method public abstract androidx.recyclerview.widget.RecyclerView.LayoutParams! generateDefaultLayoutParams();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateLayoutParams(android.content.Context!, android.util.AttributeSet!);
+    method public int getBaseline();
+    method public int getBottomDecorationHeight(android.view.View);
+    method public android.view.View? getChildAt(int);
+    method public int getChildCount();
+    method @Deprecated public static int getChildMeasureSpec(int, int, int, boolean);
+    method public static int getChildMeasureSpec(int, int, int, int, boolean);
+    method public boolean getClipToPadding();
+    method public int getColumnCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public int getDecoratedBottom(android.view.View);
+    method public void getDecoratedBoundsWithMargins(android.view.View, android.graphics.Rect);
+    method public int getDecoratedLeft(android.view.View);
+    method public int getDecoratedMeasuredHeight(android.view.View);
+    method public int getDecoratedMeasuredWidth(android.view.View);
+    method public int getDecoratedRight(android.view.View);
+    method public int getDecoratedTop(android.view.View);
+    method public android.view.View? getFocusedChild();
+    method @Px public int getHeight();
+    method public int getHeightMode();
+    method public int getItemCount();
+    method public int getItemViewType(android.view.View);
+    method public int getLayoutDirection();
+    method public int getLeftDecorationWidth(android.view.View);
+    method @Px public int getMinimumHeight();
+    method @Px public int getMinimumWidth();
+    method @Px public int getPaddingBottom();
+    method @Px public int getPaddingEnd();
+    method @Px public int getPaddingLeft();
+    method @Px public int getPaddingRight();
+    method @Px public int getPaddingStart();
+    method @Px public int getPaddingTop();
+    method public int getPosition(android.view.View);
+    method public static androidx.recyclerview.widget.RecyclerView.LayoutManager.Properties! getProperties(android.content.Context, android.util.AttributeSet?, int, int);
+    method public int getRightDecorationWidth(android.view.View);
+    method public int getRowCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public int getSelectionModeForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public int getTopDecorationHeight(android.view.View);
+    method public void getTransformedBoundingBox(android.view.View, boolean, android.graphics.Rect);
+    method @Px public int getWidth();
+    method public int getWidthMode();
+    method public boolean hasFocus();
+    method public void ignoreView(android.view.View);
+    method public boolean isAttachedToWindow();
+    method public boolean isAutoMeasureEnabled();
+    method public boolean isFocused();
+    method public final boolean isItemPrefetchEnabled();
+    method public boolean isLayoutHierarchical(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public boolean isMeasurementCacheEnabled();
+    method public boolean isSmoothScrolling();
+    method public boolean isViewPartiallyVisible(android.view.View, boolean, boolean);
+    method public void layoutDecorated(android.view.View, int, int, int, int);
+    method public void layoutDecoratedWithMargins(android.view.View, int, int, int, int);
+    method public void measureChild(android.view.View, int, int);
+    method public void measureChildWithMargins(android.view.View, int, int);
+    method public void moveView(int, int);
+    method public void offsetChildrenHorizontal(@Px int);
+    method public void offsetChildrenVertical(@Px int);
+    method public void onAdapterChanged(androidx.recyclerview.widget.RecyclerView.Adapter?, androidx.recyclerview.widget.RecyclerView.Adapter?);
+    method public boolean onAddFocusables(androidx.recyclerview.widget.RecyclerView, java.util.ArrayList<android.view.View!>, int, int);
+    method @CallSuper public void onAttachedToWindow(androidx.recyclerview.widget.RecyclerView!);
+    method @Deprecated public void onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView!);
+    method @CallSuper public void onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView!, androidx.recyclerview.widget.RecyclerView.Recycler!);
+    method public android.view.View? onFocusSearchFailed(android.view.View, int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public void onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityEvent(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityNodeInfo(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method public void onInitializeAccessibilityNodeInfoForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method public android.view.View? onInterceptFocusSearch(android.view.View, int);
+    method public void onItemsAdded(androidx.recyclerview.widget.RecyclerView, int, int);
+    method public void onItemsChanged(androidx.recyclerview.widget.RecyclerView);
+    method public void onItemsMoved(androidx.recyclerview.widget.RecyclerView, int, int, int);
+    method public void onItemsRemoved(androidx.recyclerview.widget.RecyclerView, int, int);
+    method public void onItemsUpdated(androidx.recyclerview.widget.RecyclerView, int, int);
+    method public void onItemsUpdated(androidx.recyclerview.widget.RecyclerView, int, int, Object?);
+    method public void onLayoutChildren(androidx.recyclerview.widget.RecyclerView.Recycler!, androidx.recyclerview.widget.RecyclerView.State!);
+    method public void onLayoutCompleted(androidx.recyclerview.widget.RecyclerView.State!);
+    method public void onMeasure(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, int, int);
+    method @Deprecated public boolean onRequestChildFocus(androidx.recyclerview.widget.RecyclerView, android.view.View, android.view.View?);
+    method public boolean onRequestChildFocus(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State, android.view.View, android.view.View?);
+    method public void onRestoreInstanceState(android.os.Parcelable!);
+    method public android.os.Parcelable? onSaveInstanceState();
+    method public void onScrollStateChanged(int);
+    method public boolean performAccessibilityAction(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, int, android.os.Bundle?);
+    method public boolean performAccessibilityActionForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, int, android.os.Bundle?);
+    method public void postOnAnimation(Runnable!);
+    method public void removeAllViews();
+    method public void removeAndRecycleAllViews(androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void removeAndRecycleView(android.view.View, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void removeAndRecycleViewAt(int, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public boolean removeCallbacks(Runnable!);
+    method public void removeDetachedView(android.view.View);
+    method public void removeView(android.view.View!);
+    method public void removeViewAt(int);
+    method public boolean requestChildRectangleOnScreen(androidx.recyclerview.widget.RecyclerView, android.view.View, android.graphics.Rect, boolean);
+    method public boolean requestChildRectangleOnScreen(androidx.recyclerview.widget.RecyclerView, android.view.View, android.graphics.Rect, boolean, boolean);
+    method public void requestLayout();
+    method public void requestSimpleAnimationsInNextLayout();
+    method public int scrollHorizontallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler!, androidx.recyclerview.widget.RecyclerView.State!);
+    method public void scrollToPosition(int);
+    method public int scrollVerticallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler!, androidx.recyclerview.widget.RecyclerView.State!);
+    method @Deprecated public void setAutoMeasureEnabled(boolean);
+    method public final void setItemPrefetchEnabled(boolean);
+    method public void setMeasuredDimension(android.graphics.Rect!, int, int);
+    method public void setMeasuredDimension(int, int);
+    method public void setMeasurementCacheEnabled(boolean);
+    method public void smoothScrollToPosition(androidx.recyclerview.widget.RecyclerView!, androidx.recyclerview.widget.RecyclerView.State!, int);
+    method public void startSmoothScroll(androidx.recyclerview.widget.RecyclerView.SmoothScroller!);
+    method public void stopIgnoringView(android.view.View);
+    method public boolean supportsPredictiveItemAnimations();
+  }
+
+  public static interface RecyclerView.LayoutManager.LayoutPrefetchRegistry {
+    method public void addPosition(int, int);
+  }
+
+  public static class RecyclerView.LayoutManager.Properties {
+    ctor public RecyclerView.LayoutManager.Properties();
+    field public int orientation;
+    field public boolean reverseLayout;
+    field public int spanCount;
+    field public boolean stackFromEnd;
+  }
+
+  public static class RecyclerView.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+    ctor public RecyclerView.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public RecyclerView.LayoutParams(int, int);
+    ctor public RecyclerView.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public RecyclerView.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public RecyclerView.LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public int getAbsoluteAdapterPosition();
+    method public int getBindingAdapterPosition();
+    method @Deprecated public int getViewAdapterPosition();
+    method public int getViewLayoutPosition();
+    method @Deprecated public int getViewPosition();
+    method public boolean isItemChanged();
+    method public boolean isItemRemoved();
+    method public boolean isViewInvalid();
+    method public boolean viewNeedsUpdate();
+  }
+
+  public static interface RecyclerView.OnChildAttachStateChangeListener {
+    method public void onChildViewAttachedToWindow(android.view.View);
+    method public void onChildViewDetachedFromWindow(android.view.View);
+  }
+
+  public abstract static class RecyclerView.OnFlingListener {
+    ctor public RecyclerView.OnFlingListener();
+    method public abstract boolean onFling(int, int);
+  }
+
+  public static interface RecyclerView.OnItemTouchListener {
+    method public boolean onInterceptTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+    method public void onRequestDisallowInterceptTouchEvent(boolean);
+    method public void onTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+  }
+
+  public abstract static class RecyclerView.OnScrollListener {
+    ctor public RecyclerView.OnScrollListener();
+    method public void onScrollStateChanged(androidx.recyclerview.widget.RecyclerView, int);
+    method public void onScrolled(androidx.recyclerview.widget.RecyclerView, int, int);
+  }
+
+  public static class RecyclerView.RecycledViewPool {
+    ctor public RecyclerView.RecycledViewPool();
+    method public void clear();
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? getRecycledView(int);
+    method public int getRecycledViewCount(int);
+    method public void putRecycledView(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void setMaxRecycledViews(int, int);
+  }
+
+  public final class RecyclerView.Recycler {
+    ctor public RecyclerView.Recycler();
+    method public void bindViewToPosition(android.view.View, int);
+    method public void clear();
+    method public int convertPreLayoutPositionToPostLayout(int);
+    method public java.util.List<androidx.recyclerview.widget.RecyclerView.ViewHolder!> getScrapList();
+    method public android.view.View getViewForPosition(int);
+    method public void recycleView(android.view.View);
+    method public void setViewCacheSize(int);
+  }
+
+  public static interface RecyclerView.RecyclerListener {
+    method public void onViewRecycled(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+  }
+
+  public static class RecyclerView.SimpleOnItemTouchListener implements androidx.recyclerview.widget.RecyclerView.OnItemTouchListener {
+    ctor public RecyclerView.SimpleOnItemTouchListener();
+    method public boolean onInterceptTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+    method public void onRequestDisallowInterceptTouchEvent(boolean);
+    method public void onTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+  }
+
+  public abstract static class RecyclerView.SmoothScroller {
+    ctor public RecyclerView.SmoothScroller();
+    method public android.graphics.PointF? computeScrollVectorForPosition(int);
+    method public android.view.View! findViewByPosition(int);
+    method public int getChildCount();
+    method public int getChildPosition(android.view.View!);
+    method public androidx.recyclerview.widget.RecyclerView.LayoutManager? getLayoutManager();
+    method public int getTargetPosition();
+    method @Deprecated public void instantScrollToPosition(int);
+    method public boolean isPendingInitialRun();
+    method public boolean isRunning();
+    method protected void normalize(android.graphics.PointF);
+    method protected void onChildAttachedToWindow(android.view.View!);
+    method protected abstract void onSeekTargetStep(@Px int, @Px int, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action);
+    method protected abstract void onStart();
+    method protected abstract void onStop();
+    method protected abstract void onTargetFound(android.view.View, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action);
+    method public void setTargetPosition(int);
+    method protected final void stop();
+  }
+
+  public static class RecyclerView.SmoothScroller.Action {
+    ctor public RecyclerView.SmoothScroller.Action(@Px int, @Px int);
+    ctor public RecyclerView.SmoothScroller.Action(@Px int, @Px int, int);
+    ctor public RecyclerView.SmoothScroller.Action(@Px int, @Px int, int, android.view.animation.Interpolator?);
+    method public int getDuration();
+    method @Px public int getDx();
+    method @Px public int getDy();
+    method public android.view.animation.Interpolator? getInterpolator();
+    method public void jumpTo(int);
+    method public void setDuration(int);
+    method public void setDx(@Px int);
+    method public void setDy(@Px int);
+    method public void setInterpolator(android.view.animation.Interpolator?);
+    method public void update(@Px int, @Px int, int, android.view.animation.Interpolator?);
+    field public static final int UNDEFINED_DURATION = -2147483648; // 0x80000000
+  }
+
+  public static interface RecyclerView.SmoothScroller.ScrollVectorProvider {
+    method public android.graphics.PointF? computeScrollVectorForPosition(int);
+  }
+
+  public static class RecyclerView.State {
+    ctor public RecyclerView.State();
+    method public boolean didStructureChange();
+    method public <T> T! get(int);
+    method public int getItemCount();
+    method public int getRemainingScrollHorizontal();
+    method public int getRemainingScrollVertical();
+    method public int getTargetScrollPosition();
+    method public boolean hasTargetScrollPosition();
+    method public boolean isMeasuring();
+    method public boolean isPreLayout();
+    method public void put(int, Object!);
+    method public void remove(int);
+    method public boolean willRunPredictiveAnimations();
+    method public boolean willRunSimpleAnimations();
+  }
+
+  public abstract static class RecyclerView.ViewCacheExtension {
+    ctor public RecyclerView.ViewCacheExtension();
+    method public abstract android.view.View? getViewForPositionAndType(androidx.recyclerview.widget.RecyclerView.Recycler, int, int);
+  }
+
+  public abstract static class RecyclerView.ViewHolder {
+    ctor public RecyclerView.ViewHolder(android.view.View);
+    method public final int getAbsoluteAdapterPosition();
+    method @Deprecated public final int getAdapterPosition();
+    method public final androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>? getBindingAdapter();
+    method public final int getBindingAdapterPosition();
+    method public final long getItemId();
+    method public final int getItemViewType();
+    method public final int getLayoutPosition();
+    method public final int getOldPosition();
+    method @Deprecated public final int getPosition();
+    method public final boolean isRecyclable();
+    method public final void setIsRecyclable(boolean);
+    field public final android.view.View itemView;
+  }
+
+  public class RecyclerViewAccessibilityDelegate extends androidx.core.view.AccessibilityDelegateCompat {
+    ctor public RecyclerViewAccessibilityDelegate(androidx.recyclerview.widget.RecyclerView);
+    method public androidx.core.view.AccessibilityDelegateCompat getItemDelegate();
+  }
+
+  public static class RecyclerViewAccessibilityDelegate.ItemDelegate extends androidx.core.view.AccessibilityDelegateCompat {
+    ctor public RecyclerViewAccessibilityDelegate.ItemDelegate(androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate);
+  }
+
+  public abstract class SimpleItemAnimator extends androidx.recyclerview.widget.RecyclerView.ItemAnimator {
+    ctor public SimpleItemAnimator();
+    method public abstract boolean animateAdd(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public boolean animateAppearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder!, androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animateDisappearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?);
+    method public abstract boolean animateMove(androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animatePersistence(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateRemove(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchAddFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchAddStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchChangeFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public final void dispatchChangeStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public final void dispatchMoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchMoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchRemoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchRemoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public boolean getSupportsChangeAnimations();
+    method public void onAddFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onAddStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onChangeFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public void onChangeStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public void onMoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onMoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onRemoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onRemoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void setSupportsChangeAnimations(boolean);
+  }
+
+  public abstract class SnapHelper extends androidx.recyclerview.widget.RecyclerView.OnFlingListener {
+    ctor public SnapHelper();
+    method public void attachToRecyclerView(androidx.recyclerview.widget.RecyclerView?) throws java.lang.IllegalStateException;
+    method public abstract int[]? calculateDistanceToFinalSnap(androidx.recyclerview.widget.RecyclerView.LayoutManager, android.view.View);
+    method public int[]! calculateScrollDistance(int, int);
+    method protected androidx.recyclerview.widget.RecyclerView.SmoothScroller? createScroller(androidx.recyclerview.widget.RecyclerView.LayoutManager);
+    method @Deprecated protected androidx.recyclerview.widget.LinearSmoothScroller? createSnapScroller(androidx.recyclerview.widget.RecyclerView.LayoutManager);
+    method public abstract android.view.View? findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public abstract int findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int, int);
+    method public boolean onFling(int, int);
+  }
+
+  public class SortedList<T> {
+    ctor public SortedList(Class<T!>, androidx.recyclerview.widget.SortedList.Callback<T!>);
+    ctor public SortedList(Class<T!>, androidx.recyclerview.widget.SortedList.Callback<T!>, int);
+    method public int add(T!);
+    method public void addAll(T![], boolean);
+    method public void addAll(T!...);
+    method public void addAll(java.util.Collection<T!>);
+    method public void beginBatchedUpdates();
+    method public void clear();
+    method public void endBatchedUpdates();
+    method public T! get(int) throws java.lang.IndexOutOfBoundsException;
+    method public int indexOf(T!);
+    method public void recalculatePositionOfItemAt(int);
+    method public boolean remove(T!);
+    method public T! removeItemAt(int);
+    method public void replaceAll(T![], boolean);
+    method public void replaceAll(T!...);
+    method public void replaceAll(java.util.Collection<T!>);
+    method public int size();
+    method public void updateItemAt(int, T!);
+    field public static final int INVALID_POSITION = -1; // 0xffffffff
+  }
+
+  public static class SortedList.BatchedCallback<T2> extends androidx.recyclerview.widget.SortedList.Callback<T2> {
+    ctor public SortedList.BatchedCallback(androidx.recyclerview.widget.SortedList.Callback<T2!>!);
+    method public boolean areContentsTheSame(T2!, T2!);
+    method public boolean areItemsTheSame(T2!, T2!);
+    method public int compare(T2!, T2!);
+    method public void dispatchLastEvent();
+    method public void onChanged(int, int);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public abstract static class SortedList.Callback<T2> implements java.util.Comparator<T2> androidx.recyclerview.widget.ListUpdateCallback {
+    ctor public SortedList.Callback();
+    method public abstract boolean areContentsTheSame(T2!, T2!);
+    method public abstract boolean areItemsTheSame(T2!, T2!);
+    method public abstract int compare(T2!, T2!);
+    method public Object? getChangePayload(T2!, T2!);
+    method public abstract void onChanged(int, int);
+    method public void onChanged(int, int, Object!);
+  }
+
+  public abstract class SortedListAdapterCallback<T2> extends androidx.recyclerview.widget.SortedList.Callback<T2> {
+    ctor public SortedListAdapterCallback(androidx.recyclerview.widget.RecyclerView.Adapter!);
+    method public void onChanged(int, int);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public class StaggeredGridLayoutManager extends androidx.recyclerview.widget.RecyclerView.LayoutManager implements androidx.recyclerview.widget.RecyclerView.SmoothScroller.ScrollVectorProvider {
+    ctor public StaggeredGridLayoutManager(android.content.Context!, android.util.AttributeSet!, int, int);
+    ctor public StaggeredGridLayoutManager(int, int);
+    method public android.graphics.PointF! computeScrollVectorForPosition(int);
+    method public int[]! findFirstCompletelyVisibleItemPositions(int[]!);
+    method public int[]! findFirstVisibleItemPositions(int[]!);
+    method public int[]! findLastCompletelyVisibleItemPositions(int[]!);
+    method public int[]! findLastVisibleItemPositions(int[]!);
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateDefaultLayoutParams();
+    method public int getGapStrategy();
+    method public int getOrientation();
+    method public boolean getReverseLayout();
+    method public int getSpanCount();
+    method public void invalidateSpanAssignments();
+    method public void scrollToPositionWithOffset(int, int);
+    method public void setGapStrategy(int);
+    method public void setOrientation(int);
+    method public void setReverseLayout(boolean);
+    method public void setSpanCount(int);
+    field @Deprecated public static final int GAP_HANDLING_LAZY = 1; // 0x1
+    field public static final int GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS = 2; // 0x2
+    field public static final int GAP_HANDLING_NONE = 0; // 0x0
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public static class StaggeredGridLayoutManager.LayoutParams extends androidx.recyclerview.widget.RecyclerView.LayoutParams {
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public StaggeredGridLayoutManager.LayoutParams(int, int);
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public StaggeredGridLayoutManager.LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public final int getSpanIndex();
+    method public boolean isFullSpan();
+    method public void setFullSpan(boolean);
+    field public static final int INVALID_SPAN_ID = -1; // 0xffffffff
+  }
+
+}
+
diff --git a/recyclerview/recyclerview/api/res-1.2.0-beta02.txt b/recyclerview/recyclerview/api/res-1.2.0-beta02.txt
new file mode 100644
index 0000000..475bfc43
--- /dev/null
+++ b/recyclerview/recyclerview/api/res-1.2.0-beta02.txt
@@ -0,0 +1,9 @@
+attr fastScrollEnabled
+attr fastScrollHorizontalThumbDrawable
+attr fastScrollHorizontalTrackDrawable
+attr fastScrollVerticalThumbDrawable
+attr fastScrollVerticalTrackDrawable
+attr layoutManager
+attr reverseLayout
+attr spanCount
+attr stackFromEnd
diff --git a/recyclerview/recyclerview/api/restricted_1.2.0-beta02.txt b/recyclerview/recyclerview/api/restricted_1.2.0-beta02.txt
new file mode 100644
index 0000000..5240856
--- /dev/null
+++ b/recyclerview/recyclerview/api/restricted_1.2.0-beta02.txt
@@ -0,0 +1,1094 @@
+// Signature format: 4.0
+package androidx.recyclerview.widget {
+
+  public final class AdapterListUpdateCallback implements androidx.recyclerview.widget.ListUpdateCallback {
+    ctor public AdapterListUpdateCallback(androidx.recyclerview.widget.RecyclerView.Adapter);
+    method public void onChanged(int, int, Object!);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public final class AsyncDifferConfig<T> {
+    method public java.util.concurrent.Executor getBackgroundThreadExecutor();
+    method public androidx.recyclerview.widget.DiffUtil.ItemCallback<T!> getDiffCallback();
+  }
+
+  public static final class AsyncDifferConfig.Builder<T> {
+    ctor public AsyncDifferConfig.Builder(androidx.recyclerview.widget.DiffUtil.ItemCallback<T!>);
+    method public androidx.recyclerview.widget.AsyncDifferConfig<T!> build();
+    method public androidx.recyclerview.widget.AsyncDifferConfig.Builder<T!> setBackgroundThreadExecutor(java.util.concurrent.Executor!);
+  }
+
+  public class AsyncListDiffer<T> {
+    ctor public AsyncListDiffer(androidx.recyclerview.widget.RecyclerView.Adapter, androidx.recyclerview.widget.DiffUtil.ItemCallback<T!>);
+    ctor public AsyncListDiffer(androidx.recyclerview.widget.ListUpdateCallback, androidx.recyclerview.widget.AsyncDifferConfig<T!>);
+    method public void addListListener(androidx.recyclerview.widget.AsyncListDiffer.ListListener<T!>);
+    method public java.util.List<T!> getCurrentList();
+    method public void removeListListener(androidx.recyclerview.widget.AsyncListDiffer.ListListener<T!>);
+    method public void submitList(java.util.List<T!>?);
+    method public void submitList(java.util.List<T!>?, Runnable?);
+  }
+
+  public static interface AsyncListDiffer.ListListener<T> {
+    method public void onCurrentListChanged(java.util.List<T!>, java.util.List<T!>);
+  }
+
+  public class AsyncListUtil<T> {
+    ctor public AsyncListUtil(Class<T!>, int, androidx.recyclerview.widget.AsyncListUtil.DataCallback<T!>, androidx.recyclerview.widget.AsyncListUtil.ViewCallback);
+    method public T? getItem(int);
+    method public int getItemCount();
+    method public void onRangeChanged();
+    method public void refresh();
+  }
+
+  public abstract static class AsyncListUtil.DataCallback<T> {
+    ctor public AsyncListUtil.DataCallback();
+    method @WorkerThread public abstract void fillData(T![], int, int);
+    method @WorkerThread public int getMaxCachedTiles();
+    method @WorkerThread public void recycleData(T![], int);
+    method @WorkerThread public abstract int refreshData();
+  }
+
+  public abstract static class AsyncListUtil.ViewCallback {
+    ctor public AsyncListUtil.ViewCallback();
+    method @UiThread public void extendRangeInto(int[], int[], int);
+    method @UiThread public abstract void getItemRangeInto(int[]);
+    method @UiThread public abstract void onDataRefresh();
+    method @UiThread public abstract void onItemLoaded(int);
+    field public static final int HINT_SCROLL_ASC = 2; // 0x2
+    field public static final int HINT_SCROLL_DESC = 1; // 0x1
+    field public static final int HINT_SCROLL_NONE = 0; // 0x0
+  }
+
+  public class BatchingListUpdateCallback implements androidx.recyclerview.widget.ListUpdateCallback {
+    ctor public BatchingListUpdateCallback(androidx.recyclerview.widget.ListUpdateCallback);
+    method public void dispatchLastEvent();
+    method public void onChanged(int, int, Object!);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public final class ConcatAdapter extends androidx.recyclerview.widget.RecyclerView.Adapter<androidx.recyclerview.widget.RecyclerView.ViewHolder> {
+    ctor @java.lang.SafeVarargs public ConcatAdapter(androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>!...);
+    ctor @java.lang.SafeVarargs public ConcatAdapter(androidx.recyclerview.widget.ConcatAdapter.Config, androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>!...);
+    ctor public ConcatAdapter(java.util.List<? extends androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>>);
+    ctor public ConcatAdapter(androidx.recyclerview.widget.ConcatAdapter.Config, java.util.List<? extends androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>>);
+    method public boolean addAdapter(androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>);
+    method public boolean addAdapter(int, androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>);
+    method public java.util.List<? extends androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>> getAdapters();
+    method public int getItemCount();
+    method public void onBindViewHolder(androidx.recyclerview.widget.RecyclerView.ViewHolder, int);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder onCreateViewHolder(android.view.ViewGroup, int);
+    method public boolean onFailedToRecycleView(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onViewAttachedToWindow(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onViewDetachedFromWindow(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onViewRecycled(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public boolean removeAdapter(androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>);
+  }
+
+  public static final class ConcatAdapter.Config {
+    field public static final androidx.recyclerview.widget.ConcatAdapter.Config DEFAULT;
+    field public final boolean isolateViewTypes;
+    field public final androidx.recyclerview.widget.ConcatAdapter.Config.StableIdMode stableIdMode;
+  }
+
+  public static final class ConcatAdapter.Config.Builder {
+    ctor public ConcatAdapter.Config.Builder();
+    method public androidx.recyclerview.widget.ConcatAdapter.Config build();
+    method public androidx.recyclerview.widget.ConcatAdapter.Config.Builder setIsolateViewTypes(boolean);
+    method public androidx.recyclerview.widget.ConcatAdapter.Config.Builder setStableIdMode(androidx.recyclerview.widget.ConcatAdapter.Config.StableIdMode);
+  }
+
+  public enum ConcatAdapter.Config.StableIdMode {
+    enum_constant public static final androidx.recyclerview.widget.ConcatAdapter.Config.StableIdMode ISOLATED_STABLE_IDS;
+    enum_constant public static final androidx.recyclerview.widget.ConcatAdapter.Config.StableIdMode NO_STABLE_IDS;
+    enum_constant public static final androidx.recyclerview.widget.ConcatAdapter.Config.StableIdMode SHARED_STABLE_IDS;
+  }
+
+  public class DefaultItemAnimator extends androidx.recyclerview.widget.SimpleItemAnimator {
+    ctor public DefaultItemAnimator();
+    method public boolean animateAdd(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder!, androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animateMove(androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animateRemove(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void endAnimation(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void endAnimations();
+    method public boolean isRunning();
+    method public void runPendingAnimations();
+  }
+
+  public class DiffUtil {
+    method public static androidx.recyclerview.widget.DiffUtil.DiffResult calculateDiff(androidx.recyclerview.widget.DiffUtil.Callback);
+    method public static androidx.recyclerview.widget.DiffUtil.DiffResult calculateDiff(androidx.recyclerview.widget.DiffUtil.Callback, boolean);
+  }
+
+  public abstract static class DiffUtil.Callback {
+    ctor public DiffUtil.Callback();
+    method public abstract boolean areContentsTheSame(int, int);
+    method public abstract boolean areItemsTheSame(int, int);
+    method public Object? getChangePayload(int, int);
+    method public abstract int getNewListSize();
+    method public abstract int getOldListSize();
+  }
+
+  public static class DiffUtil.DiffResult {
+    method public int convertNewPositionToOld(@IntRange(from=0) int);
+    method public int convertOldPositionToNew(@IntRange(from=0) int);
+    method public void dispatchUpdatesTo(androidx.recyclerview.widget.RecyclerView.Adapter);
+    method public void dispatchUpdatesTo(androidx.recyclerview.widget.ListUpdateCallback);
+    field public static final int NO_POSITION = -1; // 0xffffffff
+  }
+
+  public abstract static class DiffUtil.ItemCallback<T> {
+    ctor public DiffUtil.ItemCallback();
+    method public abstract boolean areContentsTheSame(T, T);
+    method public abstract boolean areItemsTheSame(T, T);
+    method public Object? getChangePayload(T, T);
+  }
+
+  public class DividerItemDecoration extends androidx.recyclerview.widget.RecyclerView.ItemDecoration {
+    ctor public DividerItemDecoration(android.content.Context!, int);
+    method public android.graphics.drawable.Drawable? getDrawable();
+    method public void setDrawable(android.graphics.drawable.Drawable);
+    method public void setOrientation(int);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public class GridLayoutManager extends androidx.recyclerview.widget.LinearLayoutManager {
+    ctor public GridLayoutManager(android.content.Context!, android.util.AttributeSet!, int, int);
+    ctor public GridLayoutManager(android.content.Context!, int);
+    ctor public GridLayoutManager(android.content.Context!, int, @androidx.recyclerview.widget.RecyclerView.Orientation int, boolean);
+    method public int getSpanCount();
+    method public androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup! getSpanSizeLookup();
+    method public boolean isUsingSpansToEstimateScrollbarDimensions();
+    method public void setSpanCount(int);
+    method public void setSpanSizeLookup(androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup!);
+    method public void setUsingSpansToEstimateScrollbarDimensions(boolean);
+    field public static final int DEFAULT_SPAN_COUNT = -1; // 0xffffffff
+  }
+
+  public static final class GridLayoutManager.DefaultSpanSizeLookup extends androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup {
+    ctor public GridLayoutManager.DefaultSpanSizeLookup();
+    method public int getSpanSize(int);
+  }
+
+  public static class GridLayoutManager.LayoutParams extends androidx.recyclerview.widget.RecyclerView.LayoutParams {
+    ctor public GridLayoutManager.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public GridLayoutManager.LayoutParams(int, int);
+    ctor public GridLayoutManager.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public GridLayoutManager.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public GridLayoutManager.LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public int getSpanIndex();
+    method public int getSpanSize();
+    field public static final int INVALID_SPAN_ID = -1; // 0xffffffff
+  }
+
+  public abstract static class GridLayoutManager.SpanSizeLookup {
+    ctor public GridLayoutManager.SpanSizeLookup();
+    method public int getSpanGroupIndex(int, int);
+    method public int getSpanIndex(int, int);
+    method public abstract int getSpanSize(int);
+    method public void invalidateSpanGroupIndexCache();
+    method public void invalidateSpanIndexCache();
+    method public boolean isSpanGroupIndexCacheEnabled();
+    method public boolean isSpanIndexCacheEnabled();
+    method public void setSpanGroupIndexCacheEnabled(boolean);
+    method public void setSpanIndexCacheEnabled(boolean);
+  }
+
+  public class ItemTouchHelper extends androidx.recyclerview.widget.RecyclerView.ItemDecoration implements androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener {
+    ctor public ItemTouchHelper(androidx.recyclerview.widget.ItemTouchHelper.Callback);
+    method public void attachToRecyclerView(androidx.recyclerview.widget.RecyclerView?);
+    method public void onChildViewAttachedToWindow(android.view.View);
+    method public void onChildViewDetachedFromWindow(android.view.View);
+    method public void startDrag(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void startSwipe(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    field public static final int ACTION_STATE_DRAG = 2; // 0x2
+    field public static final int ACTION_STATE_IDLE = 0; // 0x0
+    field public static final int ACTION_STATE_SWIPE = 1; // 0x1
+    field public static final int ANIMATION_TYPE_DRAG = 8; // 0x8
+    field public static final int ANIMATION_TYPE_SWIPE_CANCEL = 4; // 0x4
+    field public static final int ANIMATION_TYPE_SWIPE_SUCCESS = 2; // 0x2
+    field public static final int DOWN = 2; // 0x2
+    field public static final int END = 32; // 0x20
+    field public static final int LEFT = 4; // 0x4
+    field public static final int RIGHT = 8; // 0x8
+    field public static final int START = 16; // 0x10
+    field public static final int UP = 1; // 0x1
+  }
+
+  public abstract static class ItemTouchHelper.Callback {
+    ctor public ItemTouchHelper.Callback();
+    method public boolean canDropOver(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder! chooseDropTarget(androidx.recyclerview.widget.RecyclerView.ViewHolder, java.util.List<androidx.recyclerview.widget.RecyclerView.ViewHolder!>, int, int);
+    method public void clearView(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public int convertToAbsoluteDirection(int, int);
+    method public static int convertToRelativeDirection(int, int);
+    method public long getAnimationDuration(androidx.recyclerview.widget.RecyclerView, int, float, float);
+    method public int getBoundingBoxMargin();
+    method public static androidx.recyclerview.widget.ItemTouchUIUtil getDefaultUIUtil();
+    method public float getMoveThreshold(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public abstract int getMovementFlags(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public float getSwipeEscapeVelocity(float);
+    method public float getSwipeThreshold(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public float getSwipeVelocityThreshold(float);
+    method public int interpolateOutOfBoundsScroll(androidx.recyclerview.widget.RecyclerView, int, int, int, long);
+    method public boolean isItemViewSwipeEnabled();
+    method public boolean isLongPressDragEnabled();
+    method public static int makeFlag(int, int);
+    method public static int makeMovementFlags(int, int);
+    method public void onChildDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, float, float, int, boolean);
+    method public void onChildDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder!, float, float, int, boolean);
+    method public abstract boolean onMove(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onMoved(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, androidx.recyclerview.widget.RecyclerView.ViewHolder, int, int, int);
+    method public void onSelectedChanged(androidx.recyclerview.widget.RecyclerView.ViewHolder?, int);
+    method public abstract void onSwiped(androidx.recyclerview.widget.RecyclerView.ViewHolder, int);
+    field public static final int DEFAULT_DRAG_ANIMATION_DURATION = 200; // 0xc8
+    field public static final int DEFAULT_SWIPE_ANIMATION_DURATION = 250; // 0xfa
+  }
+
+  public abstract static class ItemTouchHelper.SimpleCallback extends androidx.recyclerview.widget.ItemTouchHelper.Callback {
+    ctor public ItemTouchHelper.SimpleCallback(int, int);
+    method public int getDragDirs(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public int getMovementFlags(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public int getSwipeDirs(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void setDefaultDragDirs(int);
+    method public void setDefaultSwipeDirs(int);
+  }
+
+  public static interface ItemTouchHelper.ViewDropHandler {
+    method public void prepareForDrop(android.view.View, android.view.View, int, int);
+  }
+
+  public interface ItemTouchUIUtil {
+    method public void clearView(android.view.View!);
+    method public void onDraw(android.graphics.Canvas!, androidx.recyclerview.widget.RecyclerView!, android.view.View!, float, float, int, boolean);
+    method public void onDrawOver(android.graphics.Canvas!, androidx.recyclerview.widget.RecyclerView!, android.view.View!, float, float, int, boolean);
+    method public void onSelected(android.view.View!);
+  }
+
+  public class LinearLayoutManager extends androidx.recyclerview.widget.RecyclerView.LayoutManager implements androidx.recyclerview.widget.ItemTouchHelper.ViewDropHandler androidx.recyclerview.widget.RecyclerView.SmoothScroller.ScrollVectorProvider {
+    ctor public LinearLayoutManager(android.content.Context!);
+    ctor public LinearLayoutManager(android.content.Context!, @androidx.recyclerview.widget.RecyclerView.Orientation int, boolean);
+    ctor public LinearLayoutManager(android.content.Context!, android.util.AttributeSet!, int, int);
+    method protected void calculateExtraLayoutSpace(androidx.recyclerview.widget.RecyclerView.State, int[]);
+    method public android.graphics.PointF! computeScrollVectorForPosition(int);
+    method public int findFirstCompletelyVisibleItemPosition();
+    method public int findFirstVisibleItemPosition();
+    method public int findLastCompletelyVisibleItemPosition();
+    method public int findLastVisibleItemPosition();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateDefaultLayoutParams();
+    method @Deprecated protected int getExtraLayoutSpace(androidx.recyclerview.widget.RecyclerView.State!);
+    method public int getInitialPrefetchItemCount();
+    method @androidx.recyclerview.widget.RecyclerView.Orientation public int getOrientation();
+    method public boolean getRecycleChildrenOnDetach();
+    method public boolean getReverseLayout();
+    method public boolean getStackFromEnd();
+    method protected boolean isLayoutRTL();
+    method public boolean isSmoothScrollbarEnabled();
+    method public void prepareForDrop(android.view.View, android.view.View, int, int);
+    method public void scrollToPositionWithOffset(int, int);
+    method public void setInitialPrefetchItemCount(int);
+    method public void setOrientation(@androidx.recyclerview.widget.RecyclerView.Orientation int);
+    method public void setRecycleChildrenOnDetach(boolean);
+    method public void setReverseLayout(boolean);
+    method public void setSmoothScrollbarEnabled(boolean);
+    method public void setStackFromEnd(boolean);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int INVALID_OFFSET = -2147483648; // 0x80000000
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  protected static class LinearLayoutManager.LayoutChunkResult {
+    ctor protected LinearLayoutManager.LayoutChunkResult();
+    field public int mConsumed;
+    field public boolean mFinished;
+    field public boolean mFocusable;
+    field public boolean mIgnoreConsumed;
+  }
+
+  public class LinearSmoothScroller extends androidx.recyclerview.widget.RecyclerView.SmoothScroller {
+    ctor public LinearSmoothScroller(android.content.Context!);
+    method public int calculateDtToFit(int, int, int, int, int);
+    method public int calculateDxToMakeVisible(android.view.View!, int);
+    method public int calculateDyToMakeVisible(android.view.View!, int);
+    method protected float calculateSpeedPerPixel(android.util.DisplayMetrics!);
+    method protected int calculateTimeForDeceleration(int);
+    method protected int calculateTimeForScrolling(int);
+    method protected int getHorizontalSnapPreference();
+    method protected int getVerticalSnapPreference();
+    method protected void onSeekTargetStep(int, int, androidx.recyclerview.widget.RecyclerView.State!, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action!);
+    method protected void onStart();
+    method protected void onStop();
+    method protected void onTargetFound(android.view.View!, androidx.recyclerview.widget.RecyclerView.State!, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action!);
+    method protected void updateActionForInterimTarget(androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action!);
+    field public static final int SNAP_TO_ANY = 0; // 0x0
+    field public static final int SNAP_TO_END = 1; // 0x1
+    field public static final int SNAP_TO_START = -1; // 0xffffffff
+    field protected final android.view.animation.DecelerateInterpolator! mDecelerateInterpolator;
+    field protected int mInterimTargetDx;
+    field protected int mInterimTargetDy;
+    field protected final android.view.animation.LinearInterpolator! mLinearInterpolator;
+    field protected android.graphics.PointF! mTargetVector;
+  }
+
+  public class LinearSnapHelper extends androidx.recyclerview.widget.SnapHelper {
+    ctor public LinearSnapHelper();
+    method public int[]! calculateDistanceToFinalSnap(androidx.recyclerview.widget.RecyclerView.LayoutManager, android.view.View);
+    method public android.view.View! findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public int findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int, int);
+  }
+
+  public abstract class ListAdapter<T, VH extends androidx.recyclerview.widget.RecyclerView.ViewHolder> extends androidx.recyclerview.widget.RecyclerView.Adapter<VH> {
+    ctor protected ListAdapter(androidx.recyclerview.widget.DiffUtil.ItemCallback<T!>);
+    ctor protected ListAdapter(androidx.recyclerview.widget.AsyncDifferConfig<T!>);
+    method public java.util.List<T!> getCurrentList();
+    method protected T! getItem(int);
+    method public int getItemCount();
+    method public void onCurrentListChanged(java.util.List<T!>, java.util.List<T!>);
+    method public void submitList(java.util.List<T!>?);
+    method public void submitList(java.util.List<T!>?, Runnable?);
+  }
+
+  public interface ListUpdateCallback {
+    method public void onChanged(int, int, Object?);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public abstract class OrientationHelper {
+    method public static androidx.recyclerview.widget.OrientationHelper! createHorizontalHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public static androidx.recyclerview.widget.OrientationHelper! createOrientationHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager!, @androidx.recyclerview.widget.RecyclerView.Orientation int);
+    method public static androidx.recyclerview.widget.OrientationHelper! createVerticalHelper(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public abstract int getDecoratedEnd(android.view.View!);
+    method public abstract int getDecoratedMeasurement(android.view.View!);
+    method public abstract int getDecoratedMeasurementInOther(android.view.View!);
+    method public abstract int getDecoratedStart(android.view.View!);
+    method public abstract int getEnd();
+    method public abstract int getEndAfterPadding();
+    method public abstract int getEndPadding();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutManager! getLayoutManager();
+    method public abstract int getMode();
+    method public abstract int getModeInOther();
+    method public abstract int getStartAfterPadding();
+    method public abstract int getTotalSpace();
+    method public int getTotalSpaceChange();
+    method public abstract int getTransformedEndWithDecoration(android.view.View!);
+    method public abstract int getTransformedStartWithDecoration(android.view.View!);
+    method public abstract void offsetChild(android.view.View!, int);
+    method public abstract void offsetChildren(int);
+    method public void onLayoutComplete();
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+    field protected final androidx.recyclerview.widget.RecyclerView.LayoutManager! mLayoutManager;
+  }
+
+  public class PagerSnapHelper extends androidx.recyclerview.widget.SnapHelper {
+    ctor public PagerSnapHelper();
+    method public int[]? calculateDistanceToFinalSnap(androidx.recyclerview.widget.RecyclerView.LayoutManager, android.view.View);
+    method public android.view.View? findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public int findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int, int);
+  }
+
+  public class RecyclerView extends android.view.ViewGroup implements androidx.core.view.NestedScrollingChild2 androidx.core.view.NestedScrollingChild3 androidx.core.view.ScrollingView {
+    ctor public RecyclerView(android.content.Context);
+    ctor public RecyclerView(android.content.Context, android.util.AttributeSet?);
+    ctor public RecyclerView(android.content.Context, android.util.AttributeSet?, int);
+    method public void addItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration, int);
+    method public void addItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration);
+    method public void addOnChildAttachStateChangeListener(androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener);
+    method public void addOnItemTouchListener(androidx.recyclerview.widget.RecyclerView.OnItemTouchListener);
+    method public void addOnScrollListener(androidx.recyclerview.widget.RecyclerView.OnScrollListener);
+    method public void addRecyclerListener(androidx.recyclerview.widget.RecyclerView.RecyclerListener);
+    method public void clearOnChildAttachStateChangeListeners();
+    method public void clearOnScrollListeners();
+    method public int computeHorizontalScrollExtent();
+    method public int computeHorizontalScrollOffset();
+    method public int computeHorizontalScrollRange();
+    method public int computeVerticalScrollExtent();
+    method public int computeVerticalScrollOffset();
+    method public int computeVerticalScrollRange();
+    method public boolean dispatchNestedPreScroll(int, int, int[]!, int[]!, int);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]!, int);
+    method public final void dispatchNestedScroll(int, int, int, int, int[]!, int, int[]);
+    method public boolean drawChild(android.graphics.Canvas!, android.view.View!, long);
+    method public android.view.View? findChildViewUnder(float, float);
+    method public android.view.View? findContainingItemView(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? findContainingViewHolder(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? findViewHolderForAdapterPosition(int);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder! findViewHolderForItemId(long);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? findViewHolderForLayoutPosition(int);
+    method @Deprecated public androidx.recyclerview.widget.RecyclerView.ViewHolder? findViewHolderForPosition(int);
+    method public boolean fling(int, int);
+    method public androidx.recyclerview.widget.RecyclerView.Adapter? getAdapter();
+    method public int getChildAdapterPosition(android.view.View);
+    method public long getChildItemId(android.view.View);
+    method public int getChildLayoutPosition(android.view.View);
+    method @Deprecated public int getChildPosition(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder! getChildViewHolder(android.view.View);
+    method public androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate? getCompatAccessibilityDelegate();
+    method public void getDecoratedBoundsWithMargins(android.view.View, android.graphics.Rect);
+    method public androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory getEdgeEffectFactory();
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator? getItemAnimator();
+    method public androidx.recyclerview.widget.RecyclerView.ItemDecoration getItemDecorationAt(int);
+    method public int getItemDecorationCount();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutManager? getLayoutManager();
+    method public int getMaxFlingVelocity();
+    method public int getMinFlingVelocity();
+    method public androidx.recyclerview.widget.RecyclerView.OnFlingListener? getOnFlingListener();
+    method public boolean getPreserveFocusAfterLayout();
+    method public androidx.recyclerview.widget.RecyclerView.RecycledViewPool getRecycledViewPool();
+    method public int getScrollState();
+    method public boolean hasFixedSize();
+    method public boolean hasNestedScrollingParent(int);
+    method public boolean hasPendingAdapterUpdates();
+    method public void invalidateItemDecorations();
+    method public boolean isAnimating();
+    method public boolean isComputingLayout();
+    method @Deprecated public boolean isLayoutFrozen();
+    method public final boolean isLayoutSuppressed();
+    method public void nestedScrollBy(int, int);
+    method public void offsetChildrenHorizontal(@Px int);
+    method public void offsetChildrenVertical(@Px int);
+    method public void onChildAttachedToWindow(android.view.View);
+    method public void onChildDetachedFromWindow(android.view.View);
+    method public void onDraw(android.graphics.Canvas!);
+    method public void onScrollStateChanged(int);
+    method public void onScrolled(@Px int, @Px int);
+    method public void removeItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration);
+    method public void removeItemDecorationAt(int);
+    method public void removeOnChildAttachStateChangeListener(androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener);
+    method public void removeOnItemTouchListener(androidx.recyclerview.widget.RecyclerView.OnItemTouchListener);
+    method public void removeOnScrollListener(androidx.recyclerview.widget.RecyclerView.OnScrollListener);
+    method public void removeRecyclerListener(androidx.recyclerview.widget.RecyclerView.RecyclerListener);
+    method public void scrollToPosition(int);
+    method public void setAccessibilityDelegateCompat(androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate?);
+    method public void setAdapter(androidx.recyclerview.widget.RecyclerView.Adapter?);
+    method public void setChildDrawingOrderCallback(androidx.recyclerview.widget.RecyclerView.ChildDrawingOrderCallback?);
+    method public void setEdgeEffectFactory(androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory);
+    method public void setHasFixedSize(boolean);
+    method public void setItemAnimator(androidx.recyclerview.widget.RecyclerView.ItemAnimator?);
+    method public void setItemViewCacheSize(int);
+    method @Deprecated public void setLayoutFrozen(boolean);
+    method public void setLayoutManager(androidx.recyclerview.widget.RecyclerView.LayoutManager?);
+    method @Deprecated public void setLayoutTransition(android.animation.LayoutTransition!);
+    method public void setOnFlingListener(androidx.recyclerview.widget.RecyclerView.OnFlingListener?);
+    method @Deprecated public void setOnScrollListener(androidx.recyclerview.widget.RecyclerView.OnScrollListener?);
+    method public void setPreserveFocusAfterLayout(boolean);
+    method public void setRecycledViewPool(androidx.recyclerview.widget.RecyclerView.RecycledViewPool?);
+    method @Deprecated public void setRecyclerListener(androidx.recyclerview.widget.RecyclerView.RecyclerListener?);
+    method public void setScrollingTouchSlop(int);
+    method public void setViewCacheExtension(androidx.recyclerview.widget.RecyclerView.ViewCacheExtension?);
+    method public void smoothScrollBy(@Px int, @Px int);
+    method public void smoothScrollBy(@Px int, @Px int, android.view.animation.Interpolator?);
+    method public void smoothScrollBy(@Px int, @Px int, android.view.animation.Interpolator?, int);
+    method public void smoothScrollToPosition(int);
+    method public boolean startNestedScroll(int, int);
+    method public void stopNestedScroll(int);
+    method public void stopScroll();
+    method public final void suppressLayout(boolean);
+    method public void swapAdapter(androidx.recyclerview.widget.RecyclerView.Adapter?, boolean);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int INVALID_TYPE = -1; // 0xffffffff
+    field public static final long NO_ID = -1L; // 0xffffffffffffffffL
+    field public static final int NO_POSITION = -1; // 0xffffffff
+    field public static final int SCROLL_STATE_DRAGGING = 1; // 0x1
+    field public static final int SCROLL_STATE_IDLE = 0; // 0x0
+    field public static final int SCROLL_STATE_SETTLING = 2; // 0x2
+    field public static final int TOUCH_SLOP_DEFAULT = 0; // 0x0
+    field public static final int TOUCH_SLOP_PAGING = 1; // 0x1
+    field public static final int UNDEFINED_DURATION = -2147483648; // 0x80000000
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public abstract static class RecyclerView.Adapter<VH extends androidx.recyclerview.widget.RecyclerView.ViewHolder> {
+    ctor public RecyclerView.Adapter();
+    method public final void bindViewHolder(VH, int);
+    method public final VH createViewHolder(android.view.ViewGroup, int);
+    method public int findRelativeAdapterPositionIn(androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>, androidx.recyclerview.widget.RecyclerView.ViewHolder, int);
+    method public abstract int getItemCount();
+    method public long getItemId(int);
+    method public int getItemViewType(int);
+    method public final androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy getStateRestorationPolicy();
+    method public final boolean hasObservers();
+    method public final boolean hasStableIds();
+    method public final void notifyDataSetChanged();
+    method public final void notifyItemChanged(int);
+    method public final void notifyItemChanged(int, Object?);
+    method public final void notifyItemInserted(int);
+    method public final void notifyItemMoved(int, int);
+    method public final void notifyItemRangeChanged(int, int);
+    method public final void notifyItemRangeChanged(int, int, Object?);
+    method public final void notifyItemRangeInserted(int, int);
+    method public final void notifyItemRangeRemoved(int, int);
+    method public final void notifyItemRemoved(int);
+    method public void onAttachedToRecyclerView(androidx.recyclerview.widget.RecyclerView);
+    method public abstract void onBindViewHolder(VH, int);
+    method public void onBindViewHolder(VH, int, java.util.List<java.lang.Object!>);
+    method public abstract VH onCreateViewHolder(android.view.ViewGroup, int);
+    method public void onDetachedFromRecyclerView(androidx.recyclerview.widget.RecyclerView);
+    method public boolean onFailedToRecycleView(VH);
+    method public void onViewAttachedToWindow(VH);
+    method public void onViewDetachedFromWindow(VH);
+    method public void onViewRecycled(VH);
+    method public void registerAdapterDataObserver(androidx.recyclerview.widget.RecyclerView.AdapterDataObserver);
+    method public void setHasStableIds(boolean);
+    method public void setStateRestorationPolicy(androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy);
+    method public void unregisterAdapterDataObserver(androidx.recyclerview.widget.RecyclerView.AdapterDataObserver);
+  }
+
+  public enum RecyclerView.Adapter.StateRestorationPolicy {
+    enum_constant public static final androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy ALLOW;
+    enum_constant public static final androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy PREVENT;
+    enum_constant public static final androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy PREVENT_WHEN_EMPTY;
+  }
+
+  public abstract static class RecyclerView.AdapterDataObserver {
+    ctor public RecyclerView.AdapterDataObserver();
+    method public void onChanged();
+    method public void onItemRangeChanged(int, int);
+    method public void onItemRangeChanged(int, int, Object?);
+    method public void onItemRangeInserted(int, int);
+    method public void onItemRangeMoved(int, int, int);
+    method public void onItemRangeRemoved(int, int);
+    method public void onStateRestorationPolicyChanged();
+  }
+
+  public static interface RecyclerView.ChildDrawingOrderCallback {
+    method public int onGetChildDrawingOrder(int, int);
+  }
+
+  public static class RecyclerView.EdgeEffectFactory {
+    ctor public RecyclerView.EdgeEffectFactory();
+    method protected android.widget.EdgeEffect createEdgeEffect(androidx.recyclerview.widget.RecyclerView, @androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.EdgeDirection int);
+    field public static final int DIRECTION_BOTTOM = 3; // 0x3
+    field public static final int DIRECTION_LEFT = 0; // 0x0
+    field public static final int DIRECTION_RIGHT = 2; // 0x2
+    field public static final int DIRECTION_TOP = 1; // 0x1
+  }
+
+  @IntDef({androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_LEFT, androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_TOP, androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_RIGHT, androidx.recyclerview.widget.RecyclerView.EdgeEffectFactory.DIRECTION_BOTTOM}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RecyclerView.EdgeEffectFactory.EdgeDirection {
+  }
+
+  public abstract static class RecyclerView.ItemAnimator {
+    ctor public RecyclerView.ItemAnimator();
+    method public abstract boolean animateAppearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateDisappearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?);
+    method public abstract boolean animatePersistence(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public boolean canReuseUpdatedViewHolder(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public boolean canReuseUpdatedViewHolder(androidx.recyclerview.widget.RecyclerView.ViewHolder, java.util.List<java.lang.Object!>);
+    method public final void dispatchAnimationFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public final void dispatchAnimationStarted(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public final void dispatchAnimationsFinished();
+    method public abstract void endAnimation(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public abstract void endAnimations();
+    method public long getAddDuration();
+    method public long getChangeDuration();
+    method public long getMoveDuration();
+    method public long getRemoveDuration();
+    method public abstract boolean isRunning();
+    method public final boolean isRunning(androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemAnimatorFinishedListener?);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo obtainHolderInfo();
+    method public void onAnimationFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public void onAnimationStarted(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo recordPostLayoutInformation(androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo recordPreLayoutInformation(androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.ViewHolder, @androidx.recyclerview.widget.RecyclerView.ItemAnimator.AdapterChanges int, java.util.List<java.lang.Object!>);
+    method public abstract void runPendingAnimations();
+    method public void setAddDuration(long);
+    method public void setChangeDuration(long);
+    method public void setMoveDuration(long);
+    method public void setRemoveDuration(long);
+    field public static final int FLAG_APPEARED_IN_PRE_LAYOUT = 4096; // 0x1000
+    field public static final int FLAG_CHANGED = 2; // 0x2
+    field public static final int FLAG_INVALIDATED = 4; // 0x4
+    field public static final int FLAG_MOVED = 2048; // 0x800
+    field public static final int FLAG_REMOVED = 8; // 0x8
+  }
+
+  @IntDef(flag=true, value={androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_CHANGED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_REMOVED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_MOVED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_INVALIDATED, androidx.recyclerview.widget.RecyclerView.ItemAnimator.FLAG_APPEARED_IN_PRE_LAYOUT}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RecyclerView.ItemAnimator.AdapterChanges {
+  }
+
+  public static interface RecyclerView.ItemAnimator.ItemAnimatorFinishedListener {
+    method public void onAnimationsFinished();
+  }
+
+  public static class RecyclerView.ItemAnimator.ItemHolderInfo {
+    ctor public RecyclerView.ItemAnimator.ItemHolderInfo();
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo setFrom(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+    method public androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo setFrom(androidx.recyclerview.widget.RecyclerView.ViewHolder, @androidx.recyclerview.widget.RecyclerView.ItemAnimator.AdapterChanges int);
+    field public int bottom;
+    field @androidx.recyclerview.widget.RecyclerView.ItemAnimator.AdapterChanges public int changeFlags;
+    field public int left;
+    field public int right;
+    field public int top;
+  }
+
+  public abstract static class RecyclerView.ItemDecoration {
+    ctor public RecyclerView.ItemDecoration();
+    method @Deprecated public void getItemOffsets(android.graphics.Rect, int, androidx.recyclerview.widget.RecyclerView);
+    method public void getItemOffsets(android.graphics.Rect, android.view.View, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State);
+    method public void onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State);
+    method @Deprecated public void onDraw(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView);
+    method public void onDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State);
+    method @Deprecated public void onDrawOver(android.graphics.Canvas, androidx.recyclerview.widget.RecyclerView);
+  }
+
+  public abstract static class RecyclerView.LayoutManager {
+    ctor public RecyclerView.LayoutManager();
+    method public void addDisappearingView(android.view.View!);
+    method public void addDisappearingView(android.view.View!, int);
+    method public void addView(android.view.View!);
+    method public void addView(android.view.View!, int);
+    method public void assertInLayoutOrScroll(String!);
+    method public void assertNotInLayoutOrScroll(String!);
+    method public void attachView(android.view.View, int, androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public void attachView(android.view.View, int);
+    method public void attachView(android.view.View);
+    method public void calculateItemDecorationsForChild(android.view.View, android.graphics.Rect);
+    method public boolean canScrollHorizontally();
+    method public boolean canScrollVertically();
+    method public boolean checkLayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public static int chooseSize(int, int, int);
+    method public void collectAdjacentPrefetchPositions(int, int, androidx.recyclerview.widget.RecyclerView.State!, androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry!);
+    method public void collectInitialPrefetchPositions(int, androidx.recyclerview.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry!);
+    method public int computeHorizontalScrollExtent(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeHorizontalScrollOffset(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeHorizontalScrollRange(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeVerticalScrollExtent(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeVerticalScrollOffset(androidx.recyclerview.widget.RecyclerView.State);
+    method public int computeVerticalScrollRange(androidx.recyclerview.widget.RecyclerView.State);
+    method public void detachAndScrapAttachedViews(androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void detachAndScrapView(android.view.View, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void detachAndScrapViewAt(int, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void detachView(android.view.View);
+    method public void detachViewAt(int);
+    method public void endAnimation(android.view.View!);
+    method public android.view.View? findContainingItemView(android.view.View);
+    method public android.view.View? findViewByPosition(int);
+    method public abstract androidx.recyclerview.widget.RecyclerView.LayoutParams! generateDefaultLayoutParams();
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateLayoutParams(android.content.Context!, android.util.AttributeSet!);
+    method public int getBaseline();
+    method public int getBottomDecorationHeight(android.view.View);
+    method public android.view.View? getChildAt(int);
+    method public int getChildCount();
+    method @Deprecated public static int getChildMeasureSpec(int, int, int, boolean);
+    method public static int getChildMeasureSpec(int, int, int, int, boolean);
+    method public boolean getClipToPadding();
+    method public int getColumnCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public int getDecoratedBottom(android.view.View);
+    method public void getDecoratedBoundsWithMargins(android.view.View, android.graphics.Rect);
+    method public int getDecoratedLeft(android.view.View);
+    method public int getDecoratedMeasuredHeight(android.view.View);
+    method public int getDecoratedMeasuredWidth(android.view.View);
+    method public int getDecoratedRight(android.view.View);
+    method public int getDecoratedTop(android.view.View);
+    method public android.view.View? getFocusedChild();
+    method @Px public int getHeight();
+    method public int getHeightMode();
+    method public int getItemCount();
+    method public int getItemViewType(android.view.View);
+    method public int getLayoutDirection();
+    method public int getLeftDecorationWidth(android.view.View);
+    method @Px public int getMinimumHeight();
+    method @Px public int getMinimumWidth();
+    method @Px public int getPaddingBottom();
+    method @Px public int getPaddingEnd();
+    method @Px public int getPaddingLeft();
+    method @Px public int getPaddingRight();
+    method @Px public int getPaddingStart();
+    method @Px public int getPaddingTop();
+    method public int getPosition(android.view.View);
+    method public static androidx.recyclerview.widget.RecyclerView.LayoutManager.Properties! getProperties(android.content.Context, android.util.AttributeSet?, int, int);
+    method public int getRightDecorationWidth(android.view.View);
+    method public int getRowCountForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public int getSelectionModeForAccessibility(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public int getTopDecorationHeight(android.view.View);
+    method public void getTransformedBoundingBox(android.view.View, boolean, android.graphics.Rect);
+    method @Px public int getWidth();
+    method public int getWidthMode();
+    method public boolean hasFocus();
+    method public void ignoreView(android.view.View);
+    method public boolean isAttachedToWindow();
+    method public boolean isAutoMeasureEnabled();
+    method public boolean isFocused();
+    method public final boolean isItemPrefetchEnabled();
+    method public boolean isLayoutHierarchical(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public boolean isMeasurementCacheEnabled();
+    method public boolean isSmoothScrolling();
+    method public boolean isViewPartiallyVisible(android.view.View, boolean, boolean);
+    method public void layoutDecorated(android.view.View, int, int, int, int);
+    method public void layoutDecoratedWithMargins(android.view.View, int, int, int, int);
+    method public void measureChild(android.view.View, int, int);
+    method public void measureChildWithMargins(android.view.View, int, int);
+    method public void moveView(int, int);
+    method public void offsetChildrenHorizontal(@Px int);
+    method public void offsetChildrenVertical(@Px int);
+    method public void onAdapterChanged(androidx.recyclerview.widget.RecyclerView.Adapter?, androidx.recyclerview.widget.RecyclerView.Adapter?);
+    method public boolean onAddFocusables(androidx.recyclerview.widget.RecyclerView, java.util.ArrayList<android.view.View!>, int, int);
+    method @CallSuper public void onAttachedToWindow(androidx.recyclerview.widget.RecyclerView!);
+    method @Deprecated public void onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView!);
+    method @CallSuper public void onDetachedFromWindow(androidx.recyclerview.widget.RecyclerView!, androidx.recyclerview.widget.RecyclerView.Recycler!);
+    method public android.view.View? onFocusSearchFailed(android.view.View, int, androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State);
+    method public void onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityEvent(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityNodeInfo(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method public void onInitializeAccessibilityNodeInfoForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method public android.view.View? onInterceptFocusSearch(android.view.View, int);
+    method public void onItemsAdded(androidx.recyclerview.widget.RecyclerView, int, int);
+    method public void onItemsChanged(androidx.recyclerview.widget.RecyclerView);
+    method public void onItemsMoved(androidx.recyclerview.widget.RecyclerView, int, int, int);
+    method public void onItemsRemoved(androidx.recyclerview.widget.RecyclerView, int, int);
+    method public void onItemsUpdated(androidx.recyclerview.widget.RecyclerView, int, int);
+    method public void onItemsUpdated(androidx.recyclerview.widget.RecyclerView, int, int, Object?);
+    method public void onLayoutChildren(androidx.recyclerview.widget.RecyclerView.Recycler!, androidx.recyclerview.widget.RecyclerView.State!);
+    method public void onLayoutCompleted(androidx.recyclerview.widget.RecyclerView.State!);
+    method public void onMeasure(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, int, int);
+    method @Deprecated public boolean onRequestChildFocus(androidx.recyclerview.widget.RecyclerView, android.view.View, android.view.View?);
+    method public boolean onRequestChildFocus(androidx.recyclerview.widget.RecyclerView, androidx.recyclerview.widget.RecyclerView.State, android.view.View, android.view.View?);
+    method public void onRestoreInstanceState(android.os.Parcelable!);
+    method public android.os.Parcelable? onSaveInstanceState();
+    method public void onScrollStateChanged(int);
+    method public boolean performAccessibilityAction(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, int, android.os.Bundle?);
+    method public boolean performAccessibilityActionForItem(androidx.recyclerview.widget.RecyclerView.Recycler, androidx.recyclerview.widget.RecyclerView.State, android.view.View, int, android.os.Bundle?);
+    method public void postOnAnimation(Runnable!);
+    method public void removeAllViews();
+    method public void removeAndRecycleAllViews(androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void removeAndRecycleView(android.view.View, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public void removeAndRecycleViewAt(int, androidx.recyclerview.widget.RecyclerView.Recycler);
+    method public boolean removeCallbacks(Runnable!);
+    method public void removeDetachedView(android.view.View);
+    method public void removeView(android.view.View!);
+    method public void removeViewAt(int);
+    method public boolean requestChildRectangleOnScreen(androidx.recyclerview.widget.RecyclerView, android.view.View, android.graphics.Rect, boolean);
+    method public boolean requestChildRectangleOnScreen(androidx.recyclerview.widget.RecyclerView, android.view.View, android.graphics.Rect, boolean, boolean);
+    method public void requestLayout();
+    method public void requestSimpleAnimationsInNextLayout();
+    method public int scrollHorizontallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler!, androidx.recyclerview.widget.RecyclerView.State!);
+    method public void scrollToPosition(int);
+    method public int scrollVerticallyBy(int, androidx.recyclerview.widget.RecyclerView.Recycler!, androidx.recyclerview.widget.RecyclerView.State!);
+    method @Deprecated public void setAutoMeasureEnabled(boolean);
+    method public final void setItemPrefetchEnabled(boolean);
+    method public void setMeasuredDimension(android.graphics.Rect!, int, int);
+    method public void setMeasuredDimension(int, int);
+    method public void setMeasurementCacheEnabled(boolean);
+    method public void smoothScrollToPosition(androidx.recyclerview.widget.RecyclerView!, androidx.recyclerview.widget.RecyclerView.State!, int);
+    method public void startSmoothScroll(androidx.recyclerview.widget.RecyclerView.SmoothScroller!);
+    method public void stopIgnoringView(android.view.View);
+    method public boolean supportsPredictiveItemAnimations();
+  }
+
+  public static interface RecyclerView.LayoutManager.LayoutPrefetchRegistry {
+    method public void addPosition(int, int);
+  }
+
+  public static class RecyclerView.LayoutManager.Properties {
+    ctor public RecyclerView.LayoutManager.Properties();
+    field public int orientation;
+    field public boolean reverseLayout;
+    field public int spanCount;
+    field public boolean stackFromEnd;
+  }
+
+  public static class RecyclerView.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+    ctor public RecyclerView.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public RecyclerView.LayoutParams(int, int);
+    ctor public RecyclerView.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public RecyclerView.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public RecyclerView.LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public int getAbsoluteAdapterPosition();
+    method public int getBindingAdapterPosition();
+    method @Deprecated public int getViewAdapterPosition();
+    method public int getViewLayoutPosition();
+    method @Deprecated public int getViewPosition();
+    method public boolean isItemChanged();
+    method public boolean isItemRemoved();
+    method public boolean isViewInvalid();
+    method public boolean viewNeedsUpdate();
+  }
+
+  public static interface RecyclerView.OnChildAttachStateChangeListener {
+    method public void onChildViewAttachedToWindow(android.view.View);
+    method public void onChildViewDetachedFromWindow(android.view.View);
+  }
+
+  public abstract static class RecyclerView.OnFlingListener {
+    ctor public RecyclerView.OnFlingListener();
+    method public abstract boolean onFling(int, int);
+  }
+
+  public static interface RecyclerView.OnItemTouchListener {
+    method public boolean onInterceptTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+    method public void onRequestDisallowInterceptTouchEvent(boolean);
+    method public void onTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+  }
+
+  public abstract static class RecyclerView.OnScrollListener {
+    ctor public RecyclerView.OnScrollListener();
+    method public void onScrollStateChanged(androidx.recyclerview.widget.RecyclerView, int);
+    method public void onScrolled(androidx.recyclerview.widget.RecyclerView, int, int);
+  }
+
+  @IntDef({androidx.recyclerview.widget.RecyclerView.HORIZONTAL, androidx.recyclerview.widget.RecyclerView.VERTICAL}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RecyclerView.Orientation {
+  }
+
+  public static class RecyclerView.RecycledViewPool {
+    ctor public RecyclerView.RecycledViewPool();
+    method public void clear();
+    method public androidx.recyclerview.widget.RecyclerView.ViewHolder? getRecycledView(int);
+    method public int getRecycledViewCount(int);
+    method public void putRecycledView(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void setMaxRecycledViews(int, int);
+  }
+
+  public final class RecyclerView.Recycler {
+    ctor public RecyclerView.Recycler();
+    method public void bindViewToPosition(android.view.View, int);
+    method public void clear();
+    method public int convertPreLayoutPositionToPostLayout(int);
+    method public java.util.List<androidx.recyclerview.widget.RecyclerView.ViewHolder!> getScrapList();
+    method public android.view.View getViewForPosition(int);
+    method public void recycleView(android.view.View);
+    method public void setViewCacheSize(int);
+  }
+
+  public static interface RecyclerView.RecyclerListener {
+    method public void onViewRecycled(androidx.recyclerview.widget.RecyclerView.ViewHolder);
+  }
+
+  public static class RecyclerView.SimpleOnItemTouchListener implements androidx.recyclerview.widget.RecyclerView.OnItemTouchListener {
+    ctor public RecyclerView.SimpleOnItemTouchListener();
+    method public boolean onInterceptTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+    method public void onRequestDisallowInterceptTouchEvent(boolean);
+    method public void onTouchEvent(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent);
+  }
+
+  public abstract static class RecyclerView.SmoothScroller {
+    ctor public RecyclerView.SmoothScroller();
+    method public android.graphics.PointF? computeScrollVectorForPosition(int);
+    method public android.view.View! findViewByPosition(int);
+    method public int getChildCount();
+    method public int getChildPosition(android.view.View!);
+    method public androidx.recyclerview.widget.RecyclerView.LayoutManager? getLayoutManager();
+    method public int getTargetPosition();
+    method @Deprecated public void instantScrollToPosition(int);
+    method public boolean isPendingInitialRun();
+    method public boolean isRunning();
+    method protected void normalize(android.graphics.PointF);
+    method protected void onChildAttachedToWindow(android.view.View!);
+    method protected abstract void onSeekTargetStep(@Px int, @Px int, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action);
+    method protected abstract void onStart();
+    method protected abstract void onStop();
+    method protected abstract void onTargetFound(android.view.View, androidx.recyclerview.widget.RecyclerView.State, androidx.recyclerview.widget.RecyclerView.SmoothScroller.Action);
+    method public void setTargetPosition(int);
+    method protected final void stop();
+  }
+
+  public static class RecyclerView.SmoothScroller.Action {
+    ctor public RecyclerView.SmoothScroller.Action(@Px int, @Px int);
+    ctor public RecyclerView.SmoothScroller.Action(@Px int, @Px int, int);
+    ctor public RecyclerView.SmoothScroller.Action(@Px int, @Px int, int, android.view.animation.Interpolator?);
+    method public int getDuration();
+    method @Px public int getDx();
+    method @Px public int getDy();
+    method public android.view.animation.Interpolator? getInterpolator();
+    method public void jumpTo(int);
+    method public void setDuration(int);
+    method public void setDx(@Px int);
+    method public void setDy(@Px int);
+    method public void setInterpolator(android.view.animation.Interpolator?);
+    method public void update(@Px int, @Px int, int, android.view.animation.Interpolator?);
+    field public static final int UNDEFINED_DURATION = -2147483648; // 0x80000000
+  }
+
+  public static interface RecyclerView.SmoothScroller.ScrollVectorProvider {
+    method public android.graphics.PointF? computeScrollVectorForPosition(int);
+  }
+
+  public static class RecyclerView.State {
+    ctor public RecyclerView.State();
+    method public boolean didStructureChange();
+    method public <T> T! get(int);
+    method public int getItemCount();
+    method public int getRemainingScrollHorizontal();
+    method public int getRemainingScrollVertical();
+    method public int getTargetScrollPosition();
+    method public boolean hasTargetScrollPosition();
+    method public boolean isMeasuring();
+    method public boolean isPreLayout();
+    method public void put(int, Object!);
+    method public void remove(int);
+    method public boolean willRunPredictiveAnimations();
+    method public boolean willRunSimpleAnimations();
+  }
+
+  public abstract static class RecyclerView.ViewCacheExtension {
+    ctor public RecyclerView.ViewCacheExtension();
+    method public abstract android.view.View? getViewForPositionAndType(androidx.recyclerview.widget.RecyclerView.Recycler, int, int);
+  }
+
+  public abstract static class RecyclerView.ViewHolder {
+    ctor public RecyclerView.ViewHolder(android.view.View);
+    method public final int getAbsoluteAdapterPosition();
+    method @Deprecated public final int getAdapterPosition();
+    method public final androidx.recyclerview.widget.RecyclerView.Adapter<? extends androidx.recyclerview.widget.RecyclerView.ViewHolder>? getBindingAdapter();
+    method public final int getBindingAdapterPosition();
+    method public final long getItemId();
+    method public final int getItemViewType();
+    method public final int getLayoutPosition();
+    method public final int getOldPosition();
+    method @Deprecated public final int getPosition();
+    method public final boolean isRecyclable();
+    method public final void setIsRecyclable(boolean);
+    field public final android.view.View itemView;
+  }
+
+  public class RecyclerViewAccessibilityDelegate extends androidx.core.view.AccessibilityDelegateCompat {
+    ctor public RecyclerViewAccessibilityDelegate(androidx.recyclerview.widget.RecyclerView);
+    method public androidx.core.view.AccessibilityDelegateCompat getItemDelegate();
+  }
+
+  public static class RecyclerViewAccessibilityDelegate.ItemDelegate extends androidx.core.view.AccessibilityDelegateCompat {
+    ctor public RecyclerViewAccessibilityDelegate.ItemDelegate(androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate);
+  }
+
+  public abstract class SimpleItemAnimator extends androidx.recyclerview.widget.RecyclerView.ItemAnimator {
+    ctor public SimpleItemAnimator();
+    method public abstract boolean animateAdd(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public boolean animateAppearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateChange(androidx.recyclerview.widget.RecyclerView.ViewHolder!, androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animateDisappearance(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo?);
+    method public abstract boolean animateMove(androidx.recyclerview.widget.RecyclerView.ViewHolder!, int, int, int, int);
+    method public boolean animatePersistence(androidx.recyclerview.widget.RecyclerView.ViewHolder, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo, androidx.recyclerview.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateRemove(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchAddFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchAddStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchChangeFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public final void dispatchChangeStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public final void dispatchMoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchMoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchRemoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public final void dispatchRemoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public boolean getSupportsChangeAnimations();
+    method public void onAddFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onAddStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onChangeFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public void onChangeStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!, boolean);
+    method public void onMoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onMoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onRemoveFinished(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void onRemoveStarting(androidx.recyclerview.widget.RecyclerView.ViewHolder!);
+    method public void setSupportsChangeAnimations(boolean);
+  }
+
+  public abstract class SnapHelper extends androidx.recyclerview.widget.RecyclerView.OnFlingListener {
+    ctor public SnapHelper();
+    method public void attachToRecyclerView(androidx.recyclerview.widget.RecyclerView?) throws java.lang.IllegalStateException;
+    method public abstract int[]? calculateDistanceToFinalSnap(androidx.recyclerview.widget.RecyclerView.LayoutManager, android.view.View);
+    method public int[]! calculateScrollDistance(int, int);
+    method protected androidx.recyclerview.widget.RecyclerView.SmoothScroller? createScroller(androidx.recyclerview.widget.RecyclerView.LayoutManager);
+    method @Deprecated protected androidx.recyclerview.widget.LinearSmoothScroller? createSnapScroller(androidx.recyclerview.widget.RecyclerView.LayoutManager);
+    method public abstract android.view.View? findSnapView(androidx.recyclerview.widget.RecyclerView.LayoutManager!);
+    method public abstract int findTargetSnapPosition(androidx.recyclerview.widget.RecyclerView.LayoutManager!, int, int);
+    method public boolean onFling(int, int);
+  }
+
+  public class SortedList<T> {
+    ctor public SortedList(Class<T!>, androidx.recyclerview.widget.SortedList.Callback<T!>);
+    ctor public SortedList(Class<T!>, androidx.recyclerview.widget.SortedList.Callback<T!>, int);
+    method public int add(T!);
+    method public void addAll(T![], boolean);
+    method public void addAll(T!...);
+    method public void addAll(java.util.Collection<T!>);
+    method public void beginBatchedUpdates();
+    method public void clear();
+    method public void endBatchedUpdates();
+    method public T! get(int) throws java.lang.IndexOutOfBoundsException;
+    method public int indexOf(T!);
+    method public void recalculatePositionOfItemAt(int);
+    method public boolean remove(T!);
+    method public T! removeItemAt(int);
+    method public void replaceAll(T![], boolean);
+    method public void replaceAll(T!...);
+    method public void replaceAll(java.util.Collection<T!>);
+    method public int size();
+    method public void updateItemAt(int, T!);
+    field public static final int INVALID_POSITION = -1; // 0xffffffff
+  }
+
+  public static class SortedList.BatchedCallback<T2> extends androidx.recyclerview.widget.SortedList.Callback<T2> {
+    ctor public SortedList.BatchedCallback(androidx.recyclerview.widget.SortedList.Callback<T2!>!);
+    method public boolean areContentsTheSame(T2!, T2!);
+    method public boolean areItemsTheSame(T2!, T2!);
+    method public int compare(T2!, T2!);
+    method public void dispatchLastEvent();
+    method public void onChanged(int, int);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public abstract static class SortedList.Callback<T2> implements java.util.Comparator<T2> androidx.recyclerview.widget.ListUpdateCallback {
+    ctor public SortedList.Callback();
+    method public abstract boolean areContentsTheSame(T2!, T2!);
+    method public abstract boolean areItemsTheSame(T2!, T2!);
+    method public abstract int compare(T2!, T2!);
+    method public Object? getChangePayload(T2!, T2!);
+    method public abstract void onChanged(int, int);
+    method public void onChanged(int, int, Object!);
+  }
+
+  public abstract class SortedListAdapterCallback<T2> extends androidx.recyclerview.widget.SortedList.Callback<T2> {
+    ctor public SortedListAdapterCallback(androidx.recyclerview.widget.RecyclerView.Adapter!);
+    method public void onChanged(int, int);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public class StaggeredGridLayoutManager extends androidx.recyclerview.widget.RecyclerView.LayoutManager implements androidx.recyclerview.widget.RecyclerView.SmoothScroller.ScrollVectorProvider {
+    ctor public StaggeredGridLayoutManager(android.content.Context!, android.util.AttributeSet!, int, int);
+    ctor public StaggeredGridLayoutManager(int, int);
+    method public android.graphics.PointF! computeScrollVectorForPosition(int);
+    method public int[]! findFirstCompletelyVisibleItemPositions(int[]!);
+    method public int[]! findFirstVisibleItemPositions(int[]!);
+    method public int[]! findLastCompletelyVisibleItemPositions(int[]!);
+    method public int[]! findLastVisibleItemPositions(int[]!);
+    method public androidx.recyclerview.widget.RecyclerView.LayoutParams! generateDefaultLayoutParams();
+    method public int getGapStrategy();
+    method public int getOrientation();
+    method public boolean getReverseLayout();
+    method public int getSpanCount();
+    method public void invalidateSpanAssignments();
+    method public void scrollToPositionWithOffset(int, int);
+    method public void setGapStrategy(int);
+    method public void setOrientation(int);
+    method public void setReverseLayout(boolean);
+    method public void setSpanCount(int);
+    field @Deprecated public static final int GAP_HANDLING_LAZY = 1; // 0x1
+    field public static final int GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS = 2; // 0x2
+    field public static final int GAP_HANDLING_NONE = 0; // 0x0
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public static class StaggeredGridLayoutManager.LayoutParams extends androidx.recyclerview.widget.RecyclerView.LayoutParams {
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+    ctor public StaggeredGridLayoutManager.LayoutParams(int, int);
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.view.ViewGroup.LayoutParams!);
+    ctor public StaggeredGridLayoutManager.LayoutParams(androidx.recyclerview.widget.RecyclerView.LayoutParams!);
+    method public final int getSpanIndex();
+    method public boolean isFullSpan();
+    method public void setFullSpan(boolean);
+    field public static final int INVALID_SPAN_ID = -1; // 0xffffffff
+  }
+
+}
+
diff --git a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/ConcatAdapterController.java b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/ConcatAdapterController.java
index 3e84a93..c718ad8 100644
--- a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/ConcatAdapterController.java
+++ b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/ConcatAdapterController.java
@@ -486,6 +486,7 @@
         return wrapper.adapter;
     }
 
+    @SuppressWarnings("MixedMutabilityReturnType")
     public List<Adapter<? extends ViewHolder>> getCopyOfAdapters() {
         if (mWrappers.isEmpty()) {
             return Collections.emptyList();
diff --git a/room/runtime/build.gradle b/room/runtime/build.gradle
index e29963ae..eabb529 100644
--- a/room/runtime/build.gradle
+++ b/room/runtime/build.gradle
@@ -42,7 +42,7 @@
     implementation("androidx.arch.core:core-runtime:2.0.1")
     compileOnly("androidx.paging:paging-common:2.0.0")
     compileOnly("androidx.lifecycle:lifecycle-livedata-core:2.0.0")
-    implementation projectOrArtifact(":annotation:annotation-experimental")
+    implementation "androidx.annotation:annotation-experimental:1.1.0-beta01"
     compileOnly KOTLIN_STDLIB // Due to :annotation-experimental
 
     testImplementation("androidx.arch.core:core-testing:2.0.1")
diff --git a/samples/Support4Demos/src/main/java/com/example/android/supportv4/app/SharingSupport.java b/samples/Support4Demos/src/main/java/com/example/android/supportv4/app/SharingSupport.java
index 5a0fb01..6e4e26e 100644
--- a/samples/Support4Demos/src/main/java/com/example/android/supportv4/app/SharingSupport.java
+++ b/samples/Support4Demos/src/main/java/com/example/android/supportv4/app/SharingSupport.java
@@ -70,6 +70,7 @@
                 .startChooser();
     }
 
+    @SuppressWarnings("CatchAndPrintStackTrace")
     public void onShareFileClick(View v) {
         try {
             // This file will be accessed by the target of the share through
@@ -90,6 +91,7 @@
         }
     }
 
+    @SuppressWarnings("CatchAndPrintStackTrace")
     public void onShareMultipleFileClick(View v) {
         try {
             // These files will be accessed by the target of the share through
diff --git a/samples/Support4Demos/src/main/java/com/example/android/supportv4/media/utils/ResourceHelper.java b/samples/Support4Demos/src/main/java/com/example/android/supportv4/media/utils/ResourceHelper.java
index 08af89a..2083b0c 100644
--- a/samples/Support4Demos/src/main/java/com/example/android/supportv4/media/utils/ResourceHelper.java
+++ b/samples/Support4Demos/src/main/java/com/example/android/supportv4/media/utils/ResourceHelper.java
@@ -33,6 +33,7 @@
      * @param defaultColor default to use.
      * @return color value
      */
+    @SuppressWarnings("CatchAndPrintStackTrace")
     public static int getThemeColor(Context context, int attribute, int defaultColor) {
         int themeColor = 0;
         String packageName = context.getPackageName();
diff --git a/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/AsyncListUtilActivity.java b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/AsyncListUtilActivity.java
index 839c798..65f96a9 100644
--- a/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/AsyncListUtilActivity.java
+++ b/samples/Support7Demos/src/main/java/com/example/android/supportv7/widget/AsyncListUtilActivity.java
@@ -129,6 +129,7 @@
                             }
                         }
 
+                        @SuppressWarnings("CatchAndPrintStackTrace")
                         private void sleep() {
                             try {
                                 Thread.sleep(DELAY_MS);
diff --git a/security/identity-credential/api/current.txt b/security/identity-credential/api/current.txt
index 85ebbcb..1396722 100644
--- a/security/identity-credential/api/current.txt
+++ b/security/identity-credential/api/current.txt
@@ -40,17 +40,22 @@
   public abstract class IdentityCredential {
     method public abstract java.security.KeyPair createEphemeralKeyPair();
     method public abstract byte[] decryptMessageFromReader(byte[]) throws androidx.security.identity.MessageDecryptionException;
+    method public byte[] delete(byte[]);
     method public abstract byte[] encryptMessageToReader(byte[]);
     method public abstract java.util.Collection<java.security.cert.X509Certificate!> getAuthKeysNeedingCertification();
     method public abstract int[] getAuthenticationDataUsageCount();
     method public abstract java.util.Collection<java.security.cert.X509Certificate!> getCredentialKeyCertificateChain();
     method public abstract androidx.biometric.BiometricPrompt.CryptoObject? getCryptoObject();
     method public abstract androidx.security.identity.ResultData getEntries(byte[]?, java.util.Map<java.lang.String!,java.util.Collection<java.lang.String!>!>, byte[]?) throws androidx.security.identity.EphemeralPublicKeyNotFoundException, androidx.security.identity.InvalidReaderSignatureException, androidx.security.identity.InvalidRequestMessageException, androidx.security.identity.NoAuthenticationKeyAvailableException;
+    method public byte[] proveOwnership(byte[]);
     method public abstract void setAllowUsingExhaustedKeys(boolean);
+    method public void setAllowUsingExpiredKeys(boolean);
     method public abstract void setAvailableAuthenticationKeys(int, int);
     method public abstract void setReaderEphemeralPublicKey(java.security.PublicKey) throws java.security.InvalidKeyException;
     method public abstract void setSessionTranscript(byte[]);
-    method public abstract void storeStaticAuthenticationData(java.security.cert.X509Certificate, byte[]) throws androidx.security.identity.UnknownAuthenticationKeyException;
+    method @Deprecated public abstract void storeStaticAuthenticationData(java.security.cert.X509Certificate, byte[]) throws androidx.security.identity.UnknownAuthenticationKeyException;
+    method public void storeStaticAuthenticationData(java.security.cert.X509Certificate, android.icu.util.Calendar, byte[]) throws androidx.security.identity.UnknownAuthenticationKeyException;
+    method public byte[] update(androidx.security.identity.PersonalizationData);
   }
 
   public class IdentityCredentialException extends java.lang.Exception {
@@ -60,15 +65,31 @@
 
   public abstract class IdentityCredentialStore {
     method public abstract androidx.security.identity.WritableIdentityCredential createCredential(String, String) throws androidx.security.identity.AlreadyPersonalizedException, androidx.security.identity.DocTypeNotSupportedException;
-    method public abstract byte[]? deleteCredentialByName(String);
+    method @Deprecated public abstract byte[]? deleteCredentialByName(String);
+    method public androidx.security.identity.IdentityCredentialStoreCapabilities getCapabilities();
     method public abstract androidx.security.identity.IdentityCredential? getCredentialByName(String, int) throws androidx.security.identity.CipherSuiteNotSupportedException;
     method public static androidx.security.identity.IdentityCredentialStore getDirectAccessInstance(android.content.Context);
+    method public static androidx.security.identity.IdentityCredentialStore? getHardwareInstance(android.content.Context);
     method public static androidx.security.identity.IdentityCredentialStore getInstance(android.content.Context);
-    method public abstract String![] getSupportedDocTypes();
+    method public static androidx.security.identity.IdentityCredentialStore getSoftwareInstance(android.content.Context);
+    method @Deprecated public abstract String![] getSupportedDocTypes();
     method public static boolean isDirectAccessSupported(android.content.Context);
     field public static final int CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256 = 1; // 0x1
   }
 
+  public class IdentityCredentialStoreCapabilities {
+    method public int getFeatureVersion();
+    method public java.util.Set<java.lang.String!> getSupportedDocTypes();
+    method public boolean isDeleteSupported();
+    method public boolean isDirectAccess();
+    method public boolean isHardwareBacked();
+    method public boolean isProveOwnershipSupported();
+    method public boolean isStaticAuthenticationDataExpirationSupported();
+    method public boolean isUpdateSupported();
+    field public static final int FEATURE_VERSION_202009 = 202009; // 0x31519
+    field public static final int FEATURE_VERSION_202101 = 202101; // 0x31575
+  }
+
   public class InvalidReaderSignatureException extends androidx.security.identity.IdentityCredentialException {
     ctor public InvalidReaderSignatureException(String);
     ctor public InvalidReaderSignatureException(String, Throwable);
diff --git a/security/identity-credential/api/public_plus_experimental_current.txt b/security/identity-credential/api/public_plus_experimental_current.txt
index 85ebbcb..1396722 100644
--- a/security/identity-credential/api/public_plus_experimental_current.txt
+++ b/security/identity-credential/api/public_plus_experimental_current.txt
@@ -40,17 +40,22 @@
   public abstract class IdentityCredential {
     method public abstract java.security.KeyPair createEphemeralKeyPair();
     method public abstract byte[] decryptMessageFromReader(byte[]) throws androidx.security.identity.MessageDecryptionException;
+    method public byte[] delete(byte[]);
     method public abstract byte[] encryptMessageToReader(byte[]);
     method public abstract java.util.Collection<java.security.cert.X509Certificate!> getAuthKeysNeedingCertification();
     method public abstract int[] getAuthenticationDataUsageCount();
     method public abstract java.util.Collection<java.security.cert.X509Certificate!> getCredentialKeyCertificateChain();
     method public abstract androidx.biometric.BiometricPrompt.CryptoObject? getCryptoObject();
     method public abstract androidx.security.identity.ResultData getEntries(byte[]?, java.util.Map<java.lang.String!,java.util.Collection<java.lang.String!>!>, byte[]?) throws androidx.security.identity.EphemeralPublicKeyNotFoundException, androidx.security.identity.InvalidReaderSignatureException, androidx.security.identity.InvalidRequestMessageException, androidx.security.identity.NoAuthenticationKeyAvailableException;
+    method public byte[] proveOwnership(byte[]);
     method public abstract void setAllowUsingExhaustedKeys(boolean);
+    method public void setAllowUsingExpiredKeys(boolean);
     method public abstract void setAvailableAuthenticationKeys(int, int);
     method public abstract void setReaderEphemeralPublicKey(java.security.PublicKey) throws java.security.InvalidKeyException;
     method public abstract void setSessionTranscript(byte[]);
-    method public abstract void storeStaticAuthenticationData(java.security.cert.X509Certificate, byte[]) throws androidx.security.identity.UnknownAuthenticationKeyException;
+    method @Deprecated public abstract void storeStaticAuthenticationData(java.security.cert.X509Certificate, byte[]) throws androidx.security.identity.UnknownAuthenticationKeyException;
+    method public void storeStaticAuthenticationData(java.security.cert.X509Certificate, android.icu.util.Calendar, byte[]) throws androidx.security.identity.UnknownAuthenticationKeyException;
+    method public byte[] update(androidx.security.identity.PersonalizationData);
   }
 
   public class IdentityCredentialException extends java.lang.Exception {
@@ -60,15 +65,31 @@
 
   public abstract class IdentityCredentialStore {
     method public abstract androidx.security.identity.WritableIdentityCredential createCredential(String, String) throws androidx.security.identity.AlreadyPersonalizedException, androidx.security.identity.DocTypeNotSupportedException;
-    method public abstract byte[]? deleteCredentialByName(String);
+    method @Deprecated public abstract byte[]? deleteCredentialByName(String);
+    method public androidx.security.identity.IdentityCredentialStoreCapabilities getCapabilities();
     method public abstract androidx.security.identity.IdentityCredential? getCredentialByName(String, int) throws androidx.security.identity.CipherSuiteNotSupportedException;
     method public static androidx.security.identity.IdentityCredentialStore getDirectAccessInstance(android.content.Context);
+    method public static androidx.security.identity.IdentityCredentialStore? getHardwareInstance(android.content.Context);
     method public static androidx.security.identity.IdentityCredentialStore getInstance(android.content.Context);
-    method public abstract String![] getSupportedDocTypes();
+    method public static androidx.security.identity.IdentityCredentialStore getSoftwareInstance(android.content.Context);
+    method @Deprecated public abstract String![] getSupportedDocTypes();
     method public static boolean isDirectAccessSupported(android.content.Context);
     field public static final int CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256 = 1; // 0x1
   }
 
+  public class IdentityCredentialStoreCapabilities {
+    method public int getFeatureVersion();
+    method public java.util.Set<java.lang.String!> getSupportedDocTypes();
+    method public boolean isDeleteSupported();
+    method public boolean isDirectAccess();
+    method public boolean isHardwareBacked();
+    method public boolean isProveOwnershipSupported();
+    method public boolean isStaticAuthenticationDataExpirationSupported();
+    method public boolean isUpdateSupported();
+    field public static final int FEATURE_VERSION_202009 = 202009; // 0x31519
+    field public static final int FEATURE_VERSION_202101 = 202101; // 0x31575
+  }
+
   public class InvalidReaderSignatureException extends androidx.security.identity.IdentityCredentialException {
     ctor public InvalidReaderSignatureException(String);
     ctor public InvalidReaderSignatureException(String, Throwable);
diff --git a/security/identity-credential/api/restricted_current.txt b/security/identity-credential/api/restricted_current.txt
index 85ebbcb..1396722 100644
--- a/security/identity-credential/api/restricted_current.txt
+++ b/security/identity-credential/api/restricted_current.txt
@@ -40,17 +40,22 @@
   public abstract class IdentityCredential {
     method public abstract java.security.KeyPair createEphemeralKeyPair();
     method public abstract byte[] decryptMessageFromReader(byte[]) throws androidx.security.identity.MessageDecryptionException;
+    method public byte[] delete(byte[]);
     method public abstract byte[] encryptMessageToReader(byte[]);
     method public abstract java.util.Collection<java.security.cert.X509Certificate!> getAuthKeysNeedingCertification();
     method public abstract int[] getAuthenticationDataUsageCount();
     method public abstract java.util.Collection<java.security.cert.X509Certificate!> getCredentialKeyCertificateChain();
     method public abstract androidx.biometric.BiometricPrompt.CryptoObject? getCryptoObject();
     method public abstract androidx.security.identity.ResultData getEntries(byte[]?, java.util.Map<java.lang.String!,java.util.Collection<java.lang.String!>!>, byte[]?) throws androidx.security.identity.EphemeralPublicKeyNotFoundException, androidx.security.identity.InvalidReaderSignatureException, androidx.security.identity.InvalidRequestMessageException, androidx.security.identity.NoAuthenticationKeyAvailableException;
+    method public byte[] proveOwnership(byte[]);
     method public abstract void setAllowUsingExhaustedKeys(boolean);
+    method public void setAllowUsingExpiredKeys(boolean);
     method public abstract void setAvailableAuthenticationKeys(int, int);
     method public abstract void setReaderEphemeralPublicKey(java.security.PublicKey) throws java.security.InvalidKeyException;
     method public abstract void setSessionTranscript(byte[]);
-    method public abstract void storeStaticAuthenticationData(java.security.cert.X509Certificate, byte[]) throws androidx.security.identity.UnknownAuthenticationKeyException;
+    method @Deprecated public abstract void storeStaticAuthenticationData(java.security.cert.X509Certificate, byte[]) throws androidx.security.identity.UnknownAuthenticationKeyException;
+    method public void storeStaticAuthenticationData(java.security.cert.X509Certificate, android.icu.util.Calendar, byte[]) throws androidx.security.identity.UnknownAuthenticationKeyException;
+    method public byte[] update(androidx.security.identity.PersonalizationData);
   }
 
   public class IdentityCredentialException extends java.lang.Exception {
@@ -60,15 +65,31 @@
 
   public abstract class IdentityCredentialStore {
     method public abstract androidx.security.identity.WritableIdentityCredential createCredential(String, String) throws androidx.security.identity.AlreadyPersonalizedException, androidx.security.identity.DocTypeNotSupportedException;
-    method public abstract byte[]? deleteCredentialByName(String);
+    method @Deprecated public abstract byte[]? deleteCredentialByName(String);
+    method public androidx.security.identity.IdentityCredentialStoreCapabilities getCapabilities();
     method public abstract androidx.security.identity.IdentityCredential? getCredentialByName(String, int) throws androidx.security.identity.CipherSuiteNotSupportedException;
     method public static androidx.security.identity.IdentityCredentialStore getDirectAccessInstance(android.content.Context);
+    method public static androidx.security.identity.IdentityCredentialStore? getHardwareInstance(android.content.Context);
     method public static androidx.security.identity.IdentityCredentialStore getInstance(android.content.Context);
-    method public abstract String![] getSupportedDocTypes();
+    method public static androidx.security.identity.IdentityCredentialStore getSoftwareInstance(android.content.Context);
+    method @Deprecated public abstract String![] getSupportedDocTypes();
     method public static boolean isDirectAccessSupported(android.content.Context);
     field public static final int CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256 = 1; // 0x1
   }
 
+  public class IdentityCredentialStoreCapabilities {
+    method public int getFeatureVersion();
+    method public java.util.Set<java.lang.String!> getSupportedDocTypes();
+    method public boolean isDeleteSupported();
+    method public boolean isDirectAccess();
+    method public boolean isHardwareBacked();
+    method public boolean isProveOwnershipSupported();
+    method public boolean isStaticAuthenticationDataExpirationSupported();
+    method public boolean isUpdateSupported();
+    field public static final int FEATURE_VERSION_202009 = 202009; // 0x31519
+    field public static final int FEATURE_VERSION_202101 = 202101; // 0x31575
+  }
+
   public class InvalidReaderSignatureException extends androidx.security.identity.IdentityCredentialException {
     ctor public InvalidReaderSignatureException(String);
     ctor public InvalidReaderSignatureException(String, Throwable);
diff --git a/security/identity-credential/build.gradle b/security/identity-credential/build.gradle
index 54359f7..677731a 100644
--- a/security/identity-credential/build.gradle
+++ b/security/identity-credential/build.gradle
@@ -31,6 +31,8 @@
     implementation("androidx.annotation:annotation:1.1.0")
     implementation("co.nstant.in:cbor:0.8")
     implementation(project(":biometric:biometric"))
+    implementation("org.bouncycastle:bcprov-jdk15on:1.65")
+    implementation("org.bouncycastle:bcpkix-jdk15on:1.56")
 
     androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
     androidTestImplementation(ANDROIDX_TEST_CORE)
diff --git a/security/identity-credential/src/androidTest/java/androidx/security/identity/cts/DynamicAuthTest.java b/security/identity-credential/src/androidTest/java/androidx/security/identity/cts/DynamicAuthTest.java
index 7f6d550..039b5d9 100644
--- a/security/identity-credential/src/androidTest/java/androidx/security/identity/cts/DynamicAuthTest.java
+++ b/security/identity-credential/src/androidTest/java/androidx/security/identity/cts/DynamicAuthTest.java
@@ -19,16 +19,24 @@
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
 
 import android.content.Context;
+import android.icu.util.Calendar;
+import android.os.SystemClock;
 
+import androidx.security.identity.AccessControlProfile;
+import androidx.security.identity.AccessControlProfileId;
 import androidx.security.identity.EphemeralPublicKeyNotFoundException;
 import androidx.security.identity.IdentityCredential;
 import androidx.security.identity.IdentityCredentialException;
 import androidx.security.identity.IdentityCredentialStore;
 import androidx.security.identity.NoAuthenticationKeyAvailableException;
+import androidx.security.identity.PersonalizationData;
 import androidx.security.identity.ResultData;
+import androidx.security.identity.WritableIdentityCredential;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
 
@@ -38,6 +46,7 @@
 import java.io.ByteArrayOutputStream;
 import java.security.InvalidKeyException;
 import java.security.KeyPair;
+import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.SignatureException;
@@ -46,6 +55,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Date;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
@@ -62,6 +72,97 @@
 
     @SuppressWarnings("deprecation")
     @Test
+    public void checkAuthKey() throws Exception {
+        Context appContext = androidx.test.InstrumentationRegistry.getTargetContext();
+        IdentityCredentialStore store = Util.getIdentityCredentialStore(appContext);
+
+        String credentialName = "test";
+
+        store.deleteCredentialByName(credentialName);
+
+        WritableIdentityCredential wc = store.createCredential(credentialName,
+                "org.iso.18013-5.2019.mdl");
+
+        byte[] challenge = "TheChallenge".getBytes();
+        Collection<X509Certificate> certChain = wc.getCredentialKeyCertificateChain(challenge);
+        // Profile 0 (no authentication)
+        AccessControlProfile noAuthProfile =
+                new AccessControlProfile.Builder(new AccessControlProfileId(0))
+                        .setUserAuthenticationRequired(false)
+                        .build();
+        Collection<AccessControlProfileId> idsNoAuth = new ArrayList<AccessControlProfileId>();
+        idsNoAuth.add(new AccessControlProfileId(0));
+        String mdlNs = "org.iso.18013-5.2019";
+        PersonalizationData personalizationData =
+                new PersonalizationData.Builder()
+                        .addAccessControlProfile(noAuthProfile)
+                        .putEntry(mdlNs, "First name", idsNoAuth, Util.cborEncodeString("Alan"))
+                        .putEntry(mdlNs, "Last name", idsNoAuth, Util.cborEncodeString("Turing"))
+                        .build();
+        byte[] proofOfProvisioningSignature = wc.personalize(personalizationData);
+        byte[] proofOfProvisioning = Util.coseSign1GetData(proofOfProvisioningSignature);
+        byte[] proofOfProvisioningSha256 =
+                MessageDigest.getInstance("SHA256").digest(proofOfProvisioning);
+
+        IdentityCredential credential = store.getCredentialByName(credentialName,
+                IdentityCredentialStore.CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256);
+        assertNotNull(credential);
+        credential.setAvailableAuthenticationKeys(5, 3);
+        assertArrayEquals(
+                new int[]{0, 0, 0, 0, 0},
+                credential.getAuthenticationDataUsageCount());
+
+        Collection<X509Certificate> certificates = null;
+        certificates = credential.getAuthKeysNeedingCertification();
+        assertEquals(5, certificates.size());
+
+        X509Certificate cert = (X509Certificate) certificates.toArray()[0];
+
+        //  - serialNumber: INTEGER 1 (fixed value: same on all certs).
+        assertEquals(1, cert.getSerialNumber().intValue());
+
+        //  - issuer: CN shall be set to "Android Identity Credential Key". (fixed value:
+        //    same on all certs)
+        assertEquals("CN=Android Identity Credential Key",
+                cert.getIssuerX500Principal().getName());
+
+        //  - subject: CN shall be set to "Android Identity Credential Authentication Key". (fixed
+        //    value: same on all certs)
+        assertEquals("CN=Android Identity Credential Authentication Key",
+                cert.getSubjectX500Principal().getName());
+
+        //  - validity: should be from current time and one year in the future (365 days).
+        Date now = new Date();
+
+        // Allow for 10 seconds drift to account for the time drift and loss of precision
+        // when encoding into ASN.1
+        //
+        long diffMilliSecs = now.getTime() - cert.getNotBefore().getTime();
+        final long allowDriftMilliSecs = 10 * 1000;
+        assertTrue(-allowDriftMilliSecs <= diffMilliSecs && diffMilliSecs <= allowDriftMilliSecs);
+
+        final long kMilliSecsInOneYear = 365L * 24 * 60 * 60 * 1000;
+        diffMilliSecs =
+                cert.getNotBefore().getTime() + kMilliSecsInOneYear - cert.getNotAfter().getTime();
+        assertTrue(-allowDriftMilliSecs <= diffMilliSecs && diffMilliSecs <= allowDriftMilliSecs);
+
+        // The extension is expected only if - and only if - the underlying hardware
+        // supports updating the credential.
+        //
+        byte[] icExtension = cert.getExtensionValue("1.3.6.1.4.1.11129.2.1.26");
+        if (store.getCapabilities().isUpdateSupported()) {
+            assertNotNull(icExtension);
+            assertArrayEquals(proofOfProvisioningSha256, Util.getPopSha256FromAuthKeyCert(cert));
+        } else {
+            assertNull(icExtension);
+        }
+
+        // ... and we're done. Clean up after ourselves.
+        store.deleteCredentialByName(credentialName);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Test
     public void dynamicAuthTest() throws Exception {
         Context appContext = androidx.test.InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = Util.getIdentityCredentialStore(appContext);
@@ -495,4 +596,132 @@
 
     // TODO: test storeStaticAuthenticationData() throwing UnknownAuthenticationKeyException
     // on an unknown auth key
+
+    @SuppressWarnings("deprecation")
+    @Test
+    public void dynamicAuthWithExpirationTest() throws Exception {
+        Context appContext = androidx.test.InstrumentationRegistry.getTargetContext();
+        IdentityCredentialStore store = Util.getIdentityCredentialStore(appContext);
+        assumeTrue(store.getCapabilities().isStaticAuthenticationDataExpirationSupported());
+
+        String credentialName = "test";
+
+        store.deleteCredentialByName(credentialName);
+        Collection<X509Certificate> certChain = ProvisioningTest.createCredential(store,
+                credentialName);
+
+        IdentityCredential credential = store.getCredentialByName(credentialName,
+                IdentityCredentialStore.CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256);
+        assertNotNull(credential);
+
+        credential.setAvailableAuthenticationKeys(3, 5);
+
+        Collection<X509Certificate> certificates = null;
+        certificates = credential.getAuthKeysNeedingCertification();
+        assertEquals(3, certificates.size());
+
+        // Endorse an auth-key but set expiration to 10 seconds in the future.
+        //
+        Calendar now = Calendar.getInstance();
+        Calendar tenSecondsFromNow = Calendar.getInstance();
+        tenSecondsFromNow.add(Calendar.SECOND, 10);
+        try {
+            X509Certificate key0Cert = certificates.iterator().next();
+            credential.storeStaticAuthenticationData(key0Cert,
+                    tenSecondsFromNow,
+                    new byte[]{52, 53, 44});
+            certificates = credential.getAuthKeysNeedingCertification();
+        } catch (IdentityCredentialException e) {
+            e.printStackTrace();
+            assertTrue(false);
+        }
+        assertEquals(2, certificates.size());
+        assertArrayEquals(
+                new int[]{0, 0, 0},
+                credential.getAuthenticationDataUsageCount());
+        // Check that presentation works.
+        try {
+            IdentityCredential tc = store.getCredentialByName(credentialName,
+                    IdentityCredentialStore.CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256);
+            KeyPair ekp = tc.createEphemeralKeyPair();
+            KeyPair rekp = Util.createEphemeralKeyPair();
+            tc.setReaderEphemeralPublicKey(rekp.getPublic());
+            tc.setSessionTranscript(Util.buildSessionTranscript(ekp));
+            Map<String, Collection<String>> etr = new LinkedHashMap<>();
+            etr.put("org.iso.18013-5.2019", Arrays.asList("First name", "Last name"));
+            ResultData rd = tc.getEntries(
+                    Util.createItemsRequest(etr, null),
+                    etr,
+                    null);
+        } catch (IdentityCredentialException e) {
+            e.printStackTrace();
+            assertTrue(false);
+        }
+        credential = store.getCredentialByName(credentialName,
+                IdentityCredentialStore.CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256);
+        assertArrayEquals(
+                new int[]{1, 0, 0},
+                credential.getAuthenticationDataUsageCount());
+
+        SystemClock.sleep(11 * 1000);
+
+        certificates = credential.getAuthKeysNeedingCertification();
+        assertEquals(3, certificates.size());
+
+        // Check that presentation now fails..
+        try {
+            IdentityCredential tc = store.getCredentialByName(credentialName,
+                    IdentityCredentialStore.CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256);
+            KeyPair ekp = tc.createEphemeralKeyPair();
+            KeyPair rekp = Util.createEphemeralKeyPair();
+            tc.setReaderEphemeralPublicKey(rekp.getPublic());
+            tc.setSessionTranscript(Util.buildSessionTranscript(ekp));
+            Map<String, Collection<String>> etr = new LinkedHashMap<>();
+            etr.put("org.iso.18013-5.2019", Arrays.asList("First name", "Last name"));
+            ResultData rd = tc.getEntries(
+                    Util.createItemsRequest(etr, null),
+                    etr,
+                    null);
+            assertTrue(false);
+        } catch (NoAuthenticationKeyAvailableException e) {
+            // This is the expected path...
+        } catch (IdentityCredentialException e) {
+            e.printStackTrace();
+            assertTrue(false);
+        }
+        credential = store.getCredentialByName(credentialName,
+                IdentityCredentialStore.CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256);
+        assertArrayEquals(
+                new int[]{1, 0, 0},
+                credential.getAuthenticationDataUsageCount());
+
+        // Check that it works if we use setAllowUsingExpiredKeys(true)
+        try {
+            IdentityCredential tc = store.getCredentialByName(credentialName,
+                    IdentityCredentialStore.CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256);
+            tc.setAllowUsingExpiredKeys(true);   // <-- this is the call that makes the difference!
+            KeyPair ekp = tc.createEphemeralKeyPair();
+            KeyPair rekp = Util.createEphemeralKeyPair();
+            tc.setReaderEphemeralPublicKey(rekp.getPublic());
+            tc.setSessionTranscript(Util.buildSessionTranscript(ekp));
+            Map<String, Collection<String>> etr = new LinkedHashMap<>();
+            etr.put("org.iso.18013-5.2019", Arrays.asList("First name", "Last name"));
+            ResultData rd = tc.getEntries(
+                    Util.createItemsRequest(etr, null),
+                    etr,
+                    null);
+        } catch (IdentityCredentialException e) {
+            e.printStackTrace();
+            assertTrue(false);
+        }
+        credential = store.getCredentialByName(credentialName,
+                IdentityCredentialStore.CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256);
+        assertArrayEquals(
+                new int[]{2, 0, 0},
+                credential.getAuthenticationDataUsageCount());
+
+        // ... and we're done. Clean up after ourselves.
+        store.deleteCredentialByName(credentialName);
+    }
+
 }
diff --git a/security/identity-credential/src/androidTest/java/androidx/security/identity/cts/EphemeralKeyTest.java b/security/identity-credential/src/androidTest/java/androidx/security/identity/cts/EphemeralKeyTest.java
index f9173ab..2d964dc 100644
--- a/security/identity-credential/src/androidTest/java/androidx/security/identity/cts/EphemeralKeyTest.java
+++ b/security/identity-credential/src/androidTest/java/androidx/security/identity/cts/EphemeralKeyTest.java
@@ -39,6 +39,7 @@
 import java.security.InvalidKeyException;
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
+import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.PublicKey;
 import java.security.SecureRandom;
@@ -124,10 +125,10 @@
 
         private PublicKey mHolderEphemeralPublicKey;
         private KeyPair mEphemeralKeyPair;
-        private SecretKey mSecretKey;
-        private SecretKey mReaderSecretKey;
-        private int mCounter;
-        private int mMdlExpectedCounter;
+        private SecretKey mSKDevice;
+        private SecretKey mSKReader;
+        private int mSKDeviceCounter;
+        private int mSKReaderCounter;
 
         private SecureRandom mSecureRandom;
 
@@ -140,8 +141,8 @@
                 byte[] sessionTranscript) throws IdentityCredentialException {
             mCipherSuite = cipherSuite;
             mHolderEphemeralPublicKey = holderEphemeralPublicKey;
-            mCounter = 1;
-            mMdlExpectedCounter = 1;
+            mSKReaderCounter = 1;
+            mSKDeviceCounter = 1;
 
             try {
                 KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC);
@@ -162,21 +163,15 @@
 
                 byte[] sessionTranscriptBytes =
                         Util.prependSemanticTagForEncodedCbor(sessionTranscript);
-                byte[] sharedSecretWithSessionTranscriptBytes =
-                        Util.concatArrays(sharedSecret, sessionTranscriptBytes);
+                byte[] salt = MessageDigest.getInstance("SHA-256").digest(sessionTranscriptBytes);
 
-                byte[] salt = new byte[1];
-                byte[] info = new byte[0];
+                byte[] info = new byte[] {'S', 'K', 'D', 'e', 'v', 'i', 'c', 'e'};
+                byte[] derivedKey = Util.computeHkdf("HmacSha256", sharedSecret, salt, info, 32);
+                mSKDevice = new SecretKeySpec(derivedKey, "AES");
 
-                salt[0] = 0x01;
-                byte[] derivedKey = Util.computeHkdf("HmacSha256",
-                        sharedSecretWithSessionTranscriptBytes, salt, info, 32);
-                mSecretKey = new SecretKeySpec(derivedKey, "AES");
-
-                salt[0] = 0x00;
-                derivedKey = Util.computeHkdf("HmacSha256", sharedSecretWithSessionTranscriptBytes,
-                        salt, info, 32);
-                mReaderSecretKey = new SecretKeySpec(derivedKey, "AES");
+                info = new byte[] {'S', 'K', 'R', 'e', 'a', 'd', 'e', 'r'};
+                derivedKey = Util.computeHkdf("HmacSha256", sharedSecret, salt, info, 32);
+                mSKReader = new SecretKeySpec(derivedKey, "AES");
 
                 mSecureRandom = new SecureRandom();
 
@@ -197,10 +192,10 @@
                 ByteBuffer iv = ByteBuffer.allocate(12);
                 iv.putInt(0, 0x00000000);
                 iv.putInt(4, 0x00000000);
-                iv.putInt(8, mCounter);
+                iv.putInt(8, mSKReaderCounter);
                 Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
                 GCMParameterSpec encryptionParameterSpec = new GCMParameterSpec(128, iv.array());
-                cipher.init(Cipher.ENCRYPT_MODE, mReaderSecretKey, encryptionParameterSpec);
+                cipher.init(Cipher.ENCRYPT_MODE, mSKReader, encryptionParameterSpec);
                 messageCiphertext = cipher.doFinal(messagePlaintext); // This includes the auth tag
             } catch (BadPaddingException
                     | IllegalBlockSizeException
@@ -211,7 +206,7 @@
                 e.printStackTrace();
                 throw new IdentityCredentialException("Error encrypting message", e);
             }
-            mCounter += 1;
+            mSKReaderCounter += 1;
             return messageCiphertext;
         }
 
@@ -220,11 +215,11 @@
             ByteBuffer iv = ByteBuffer.allocate(12);
             iv.putInt(0, 0x00000000);
             iv.putInt(4, 0x00000001);
-            iv.putInt(8, mMdlExpectedCounter);
+            iv.putInt(8, mSKDeviceCounter);
             byte[] plaintext = null;
             try {
                 final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
-                cipher.init(Cipher.DECRYPT_MODE, mSecretKey, new GCMParameterSpec(128, iv.array()));
+                cipher.init(Cipher.DECRYPT_MODE, mSKDevice, new GCMParameterSpec(128, iv.array()));
                 plaintext = cipher.doFinal(messageCiphertext);
             } catch (BadPaddingException
                     | IllegalBlockSizeException
@@ -235,7 +230,7 @@
                 e.printStackTrace();
                 throw new IdentityCredentialException("Error decrypting message", e);
             }
-            mMdlExpectedCounter += 1;
+            mSKDeviceCounter += 1;
             return plaintext;
         }
     }
diff --git a/security/identity-credential/src/androidTest/java/androidx/security/identity/cts/ProvisioningTest.java b/security/identity-credential/src/androidTest/java/androidx/security/identity/cts/ProvisioningTest.java
index 363c0b8..64db9e3 100644
--- a/security/identity-credential/src/androidTest/java/androidx/security/identity/cts/ProvisioningTest.java
+++ b/security/identity-credential/src/androidTest/java/androidx/security/identity/cts/ProvisioningTest.java
@@ -24,8 +24,10 @@
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
 
 import android.content.Context;
 import android.util.Log;
@@ -49,7 +51,9 @@
 import java.io.ByteArrayOutputStream;
 import java.security.InvalidKeyException;
 import java.security.KeyPair;
+import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
@@ -369,7 +373,6 @@
             // The expected path.
         }
         store.deleteCredentialByName("test");
-        // TODO: check retutrned |proofOfDeletion|
     }
 
     @Test
@@ -393,7 +396,7 @@
     }
 
     @Test
-    public void deleteCredential()
+    public void deleteCredentialOld()
             throws IdentityCredentialException, CborException, CertificateEncodingException {
         Context appContext = androidx.test.InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = Util.getIdentityCredentialStore(appContext);
@@ -405,12 +408,13 @@
         // Deleting the credential involves destroying the keys referenced in the returned
         // certificateChain... so get an encoded blob we can turn into a X509 cert when
         // checking the deletion receipt below, post-deletion.
-        byte[] encodedCredentialCert = certificateChain.iterator().next().getEncoded();
+        PublicKey credentialKeyPublic = certificateChain.iterator().next().getPublicKey();
 
         byte[] proofOfDeletionSignature = store.deleteCredentialByName("test");
         byte[] proofOfDeletion = Util.coseSign1GetData(proofOfDeletionSignature);
 
-        // Check the returned CBOR is what is expected.
+        // Check the returned CBOR is what is expected. Specifically note the challenge
+        // is _not_ included because we're using the old method.
         String pretty = Util.cborPrettyPrint(proofOfDeletion);
         assertEquals("['ProofOfDeletion', 'org.iso.18013-5.2019.mdl', false]", pretty);
 
@@ -418,14 +422,97 @@
             assertTrue(Util.coseSign1CheckSignature(
                     proofOfDeletionSignature,
                     new byte[0], // Additional data
+                    credentialKeyPublic));
+        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
+            e.printStackTrace();
+            assertTrue(false);
+        }
+
+        // Finally, check the credential is gone.
+        assertNull(store.getCredentialByName("test",
+                IdentityCredentialStore.CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256));
+    }
+
+    @Test
+    public void deleteCredential()
+            throws IdentityCredentialException, CborException, CertificateEncodingException {
+        Context appContext = androidx.test.InstrumentationRegistry.getTargetContext();
+        IdentityCredentialStore store = Util.getIdentityCredentialStore(appContext);
+        assumeTrue(store.getCapabilities().isDeleteSupported());
+
+        store.deleteCredentialByName("test");
+        assertNull(store.deleteCredentialByName("test"));
+        Collection<X509Certificate> certificateChain = createCredential(store, "test");
+
+        // Deleting the credential involves destroying the keys referenced in the returned
+        // certificateChain... so get an encoded blob we can turn into a X509 cert when
+        // checking the deletion receipt below, post-deletion.
+        PublicKey credentialKeyPublic = certificateChain.iterator().next().getPublicKey();
+
+        IdentityCredential credential = store.getCredentialByName("test",
+                IdentityCredentialStore.CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256);
+        assertNotNull(credential);
+        byte[] proofOfDeletionSignature = credential.delete(new byte[] {0x01, 0x02});
+        byte[] proofOfDeletion = Util.coseSign1GetData(proofOfDeletionSignature);
+
+        // Check the returned CBOR is what is expected. Specifically note the challenge
+        // _is_ included because we're using the new delete() method.
+        String pretty = Util.cborPrettyPrint(proofOfDeletion);
+        assertEquals("['ProofOfDeletion', 'org.iso.18013-5.2019.mdl', [0x01, 0x02], false]",
+                pretty);
+
+        try {
+            assertTrue(Util.coseSign1CheckSignature(
+                    proofOfDeletionSignature,
+                    new byte[0], // Additional data
+                    credentialKeyPublic));
+        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
+            e.printStackTrace();
+            assertTrue(false);
+        }
+
+        // Finally, check the credential is gone.
+        assertNull(store.getCredentialByName("test",
+                IdentityCredentialStore.CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256));
+    }
+
+    @Test
+    public void proofOfOwnership()
+            throws IdentityCredentialException, CborException, CertificateEncodingException {
+        Context appContext = androidx.test.InstrumentationRegistry.getTargetContext();
+        IdentityCredentialStore store = Util.getIdentityCredentialStore(appContext);
+        assumeTrue(store.getCapabilities().isProveOwnershipSupported());
+
+        store.deleteCredentialByName("test");
+        assertNull(store.deleteCredentialByName("test"));
+        Collection<X509Certificate> certificateChain = createCredential(store, "test");
+
+        byte[] encodedCredentialCert = certificateChain.iterator().next().getEncoded();
+
+        IdentityCredential credential = store.getCredentialByName("test",
+                IdentityCredentialStore.CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256);
+        assertNotNull(credential);
+
+        byte[] challenge = new byte[]{0x12, 0x22};
+        byte[] proofOfOwnershipSignature = credential.proveOwnership(challenge);
+        byte[] proofOfOwnership = Util.coseSign1GetData(proofOfOwnershipSignature);
+
+        // Check the returned CBOR is what is expected.
+        String pretty = Util.cborPrettyPrint(proofOfOwnership);
+        assertEquals("['ProofOfOwnership', 'org.iso.18013-5.2019.mdl', [0x12, 0x22], false]",
+                pretty);
+        try {
+            assertTrue(Util.coseSign1CheckSignature(
+                    proofOfOwnershipSignature,
+                    new byte[0], // Additional data
                     certificateChain.iterator().next().getPublicKey()));
         } catch (NoSuchAlgorithmException | InvalidKeyException e) {
             e.printStackTrace();
             assertTrue(false);
         }
 
-        // Finally, check deleting an already deleted credential returns the expected.
-        assertNull(store.deleteCredentialByName("test"));
+        // Finally, check the credential is still there
+        assertNotNull(store.deleteCredentialByName("test"));
     }
 
     @Test
@@ -850,5 +937,206 @@
         store.deleteCredentialByName("test");
     }
 
+    @Test
+    public void testUpdateCredential()
+            throws IdentityCredentialException, CborException,
+            NoSuchAlgorithmException {
+        Context appContext = androidx.test.InstrumentationRegistry.getTargetContext();
+        IdentityCredentialStore store = Util.getIdentityCredentialStore(appContext);
+        assumeTrue(store.getCapabilities().isUpdateSupported());
 
+        // Create the credential...
+        //
+        String credentialName = "test";
+        String exampleDocType = "org.example.myDocType";
+        String exampleNs = "org.example.ns";
+        byte[] challenge = {0x01, 0x02};
+        int acpId = 3;
+        store.deleteCredentialByName(credentialName);
+        WritableIdentityCredential wc = store.createCredential(credentialName, exampleDocType);
+        Collection<X509Certificate> certChain = wc.getCredentialKeyCertificateChain(challenge);
+        AccessControlProfile noAuthProfile =
+                new AccessControlProfile.Builder(new AccessControlProfileId(acpId))
+                        .setUserAuthenticationRequired(false)
+                        .build();
+        Collection<AccessControlProfileId> idsNoAuth = new ArrayList<AccessControlProfileId>();
+        idsNoAuth.add(new AccessControlProfileId(acpId));
+        PersonalizationData personalizationData =
+                new PersonalizationData.Builder()
+                        .addAccessControlProfile(noAuthProfile)
+                        .putEntry(exampleNs, "first_name", idsNoAuth,
+                                Util.cborEncodeString("John"))
+                        .putEntry(exampleNs, "last_name", idsNoAuth,
+                                Util.cborEncodeString("Smith"))
+                        .build();
+        byte[] proofOfProvisioningSignature = wc.personalize(personalizationData);
+        byte[] proofOfProvisioning = Util.coseSign1GetData(proofOfProvisioningSignature);
+        byte[] proofOfProvisioningSha256 = MessageDigest.getInstance("SHA-256").digest(
+                proofOfProvisioning);
+        String pretty = "";
+        try {
+            pretty = Util.cborPrettyPrint(proofOfProvisioning);
+        } catch (CborException e) {
+            e.printStackTrace();
+            assertTrue(false);
+        }
+        assertEquals("[\n"
+                + "  'ProofOfProvisioning',\n"
+                + "  '" + exampleDocType + "',\n"
+                + "  [\n"
+                + "    {\n"
+                + "      'id' : " + acpId + "\n"
+                + "    }\n"
+                + "  ],\n"
+                + "  {\n"
+                + "    '" + exampleNs + "' : [\n"
+                + "      {\n"
+                + "        'name' : 'first_name',\n"
+                + "        'value' : 'John',\n"
+                + "        'accessControlProfiles' : [" + acpId + "]\n"
+                + "      },\n"
+                + "      {\n"
+                + "        'name' : 'last_name',\n"
+                + "        'value' : 'Smith',\n"
+                + "        'accessControlProfiles' : [" + acpId + "]\n"
+                + "      }\n"
+                + "    ]\n"
+                + "  },\n"
+                + "  false\n"
+                + "]", pretty);
+        try {
+            assertTrue(Util.coseSign1CheckSignature(
+                    proofOfProvisioningSignature,
+                    new byte[0], // Additional data
+                    certChain.iterator().next().getPublicKey()));
+        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
+            e.printStackTrace();
+            assertTrue(false);
+        }
+
+        IdentityCredential credential = store.getCredentialByName("test",
+                IdentityCredentialStore.CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256);
+
+        // Configure to use 3 auth keys and endorse all of them
+        credential.setAvailableAuthenticationKeys(3, 5);
+        Collection<X509Certificate> certificates = credential.getAuthKeysNeedingCertification();
+        assertEquals(3, certificates.size());
+        for (X509Certificate cert : certificates) {
+            credential.storeStaticAuthenticationData(cert, new byte[]{1, 2});
+            // Check each cert has the correct ProofOfProvisioning SHA-256 in the
+            // ProofOfBinding CBOR stored at OID 1.3.6.1.4.1.11129.2.1.26
+            byte[] popSha256FromCert = Util.getPopSha256FromAuthKeyCert(cert);
+            assertArrayEquals(popSha256FromCert, proofOfProvisioningSha256);
+        }
+        assertEquals(0, credential.getAuthKeysNeedingCertification().size());
+
+        // Update the credential
+        AccessControlProfile updNoAuthProfile =
+                new AccessControlProfile.Builder(new AccessControlProfileId(31))
+                        .setUserAuthenticationRequired(false)
+                        .build();
+        Collection<AccessControlProfileId> updIds = new ArrayList<AccessControlProfileId>();
+        updIds.add(new AccessControlProfileId(31));
+        String updNs = "org.iso.other_ns";
+        PersonalizationData updPd =
+                new PersonalizationData.Builder()
+                        .addAccessControlProfile(updNoAuthProfile)
+                        .putEntry(updNs, "first_name", updIds,
+                                Util.cborEncodeString("Lawrence"))
+                        .putEntry(updNs, "last_name", updIds,
+                                Util.cborEncodeString("Waterhouse"))
+                        .build();
+
+        byte[] updProofOfProvisioningSignature = credential.update(updPd);
+
+        // Check the ProofOfProvisioning for the updated data (contents _and_ signature)
+        byte[] updProofOfProvisioning = Util.coseSign1GetData(updProofOfProvisioningSignature);
+        byte[] updProofOfProvisioningSha256 = MessageDigest.getInstance("SHA-256").digest(
+                updProofOfProvisioning);
+        try {
+            pretty = Util.cborPrettyPrint(updProofOfProvisioning);
+        } catch (CborException e) {
+            e.printStackTrace();
+            assertTrue(false);
+        }
+        assertEquals("[\n"
+                + "  'ProofOfProvisioning',\n"
+                + "  '" + exampleDocType + "',\n"
+                + "  [\n"
+                + "    {\n"
+                + "      'id' : 31\n"
+                + "    }\n"
+                + "  ],\n"
+                + "  {\n"
+                + "    'org.iso.other_ns' : [\n"
+                + "      {\n"
+                + "        'name' : 'first_name',\n"
+                + "        'value' : 'Lawrence',\n"
+                + "        'accessControlProfiles' : [31]\n"
+                + "      },\n"
+                + "      {\n"
+                + "        'name' : 'last_name',\n"
+                + "        'value' : 'Waterhouse',\n"
+                + "        'accessControlProfiles' : [31]\n"
+                + "      }\n"
+                + "    ]\n"
+                + "  },\n"
+                + "  false\n"
+                + "]", pretty);
+        try {
+            assertTrue(Util.coseSign1CheckSignature(
+                    updProofOfProvisioningSignature,
+                    new byte[0], // Additional data
+                    certChain.iterator().next().getPublicKey()));
+        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
+            e.printStackTrace();
+            assertTrue(false);
+        }
+        // Check the returned CredentialKey cert chain from the now updated
+        // IdentityCredential matches the original certificate chain.
+        //
+        Collection<X509Certificate> readBackCertChain =
+                credential.getCredentialKeyCertificateChain();
+        assertEquals(certChain.size(), readBackCertChain.size());
+        Iterator<X509Certificate> it = readBackCertChain.iterator();
+        for (X509Certificate expectedCert : certChain) {
+            X509Certificate readBackCert = it.next();
+            assertEquals(expectedCert, readBackCert);
+        }
+
+        // Check that the credential is still configured to use 3 auth keys and
+        // that they all need replacement... then check and endorse the
+        // replacements
+        Collection<X509Certificate> updCertificates = credential.getAuthKeysNeedingCertification();
+        assertEquals(3, updCertificates.size());
+        for (X509Certificate cert : updCertificates) {
+            credential.storeStaticAuthenticationData(cert, new byte[]{1, 2});
+            // Check each cert has the correct - *updated* - ProofOfProvisioning SHA-256 in the
+            // ProofOfBinding CBOR stored at OID 1.3.6.1.4.1.11129.2.1.25
+            byte[] popSha256FromCert = Util.getPopSha256FromAuthKeyCert(cert);
+            assertArrayEquals(popSha256FromCert, updProofOfProvisioningSha256);
+        }
+        assertEquals(0, credential.getAuthKeysNeedingCertification().size());
+
+        // Check we can read back the updated data and it matches what we
+        // updated it to.
+        Map<String, Collection<String>> entriesToRequest = new LinkedHashMap<>();
+        entriesToRequest.put(updNs,
+                Arrays.asList("first_name",
+                        "last_name"));
+        ResultData rd = credential.getEntries(
+                Util.createItemsRequest(entriesToRequest, null),
+                entriesToRequest,
+                null);
+
+        Collection<String> resultNamespaces = rd.getNamespaces();
+        assertEquals(resultNamespaces.size(), 1);
+        assertEquals(updNs, resultNamespaces.iterator().next());
+        assertEquals(2, rd.getEntryNames(updNs).size());
+
+        assertEquals("Lawrence", Util.getStringEntry(rd, updNs, "first_name"));
+        assertEquals("Waterhouse", Util.getStringEntry(rd, updNs, "last_name"));
+
+        store.deleteCredentialByName("test");
+    }
 }
diff --git a/security/identity-credential/src/androidTest/java/androidx/security/identity/cts/Util.java b/security/identity-credential/src/androidTest/java/androidx/security/identity/cts/Util.java
index b4ec60e..20b2af8 100644
--- a/security/identity-credential/src/androidTest/java/androidx/security/identity/cts/Util.java
+++ b/security/identity-credential/src/androidTest/java/androidx/security/identity/cts/Util.java
@@ -25,6 +25,9 @@
 import androidx.security.identity.IdentityCredentialStore;
 import androidx.security.identity.ResultData;
 
+import org.bouncycastle.asn1.ASN1InputStream;
+import org.bouncycastle.asn1.ASN1OctetString;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -34,6 +37,7 @@
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
 import java.security.KeyStore;
+import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
 import java.security.PublicKey;
@@ -103,8 +107,8 @@
         //
         // See b/164480361 for more discussion.
         //
-        //return IdentityCredentialStore.getHardwareIdentityCredentialStore(context);
-        return IdentityCredentialStore.getSoftwareIdentityCredentialStore(context);
+        //return IdentityCredentialStore.getHardwareInstance(context);
+        return IdentityCredentialStore.getSoftwareInstance(context);
     }
 
     static byte[] canonicalizeCbor(byte[] encodedCbor) throws CborException {
@@ -1081,15 +1085,9 @@
 
             byte[] sessionTranscriptBytes =
                     Util.prependSemanticTagForEncodedCbor(encodedSessionTranscript);
-            byte[] sharedSecretWithSessionTranscriptBytes =
-                    Util.concatArrays(sharedSecret, sessionTranscriptBytes);
-
-            byte[] salt = new byte[1];
-            byte[] info = new byte[0];
-
-            salt[0] = 0x00;
-            byte[] derivedKey = Util.computeHkdf("HmacSha256",
-                    sharedSecretWithSessionTranscriptBytes, salt, info, 32);
+            byte[] salt = MessageDigest.getInstance("SHA-256").digest(sessionTranscriptBytes);
+            byte[] info = new byte[] {'E', 'M', 'a', 'c', 'K', 'e', 'y'};
+            byte[] derivedKey = Util.computeHkdf("HmacSha256", sharedSecret, salt, info, 32);
             SecretKey secretKey = new SecretKeySpec(derivedKey, "");
             return secretKey;
         } catch (InvalidKeyException
@@ -1334,4 +1332,52 @@
             throw new RuntimeException("Error generating ephemeral key-pair", e);
         }
     }
+
+
+    static byte[] getPopSha256FromAuthKeyCert(X509Certificate cert) {
+        byte[] octetString = cert.getExtensionValue("1.3.6.1.4.1.11129.2.1.26");
+        if (octetString == null) {
+            return null;
+        }
+        try {
+            ASN1InputStream asn1InputStream = new ASN1InputStream(octetString);
+            byte[] cborBytes = ((ASN1OctetString) asn1InputStream.readObject()).getOctets();
+
+            ByteArrayInputStream bais = new ByteArrayInputStream(cborBytes);
+            List<DataItem> dataItems = new CborDecoder(bais).decode();
+            if (dataItems.size() != 1) {
+                throw new RuntimeException("Expected 1 item, found " + dataItems.size());
+            }
+            if (!(dataItems.get(0) instanceof co.nstant.in.cbor.model.Array)) {
+                throw new RuntimeException("Item is not a map");
+            }
+            co.nstant.in.cbor.model.Array array = (co.nstant.in.cbor.model.Array) dataItems.get(0);
+            List<DataItem> items = array.getDataItems();
+            if (items.size() < 2) {
+                throw new RuntimeException(
+                        "Expected at least 2 array items, found " + items.size());
+            }
+            if (!(items.get(0) instanceof UnicodeString)) {
+                throw new RuntimeException("First array item is not a string");
+            }
+            String id = ((UnicodeString) items.get(0)).getString();
+            if (!id.equals("ProofOfBinding")) {
+                throw new RuntimeException("Expected ProofOfBinding, got " + id);
+            }
+            if (!(items.get(1) instanceof ByteString)) {
+                throw new RuntimeException("Second array item is not a bytestring");
+            }
+            byte[] popSha256 = ((ByteString) items.get(1)).getBytes();
+            if (popSha256.length != 32) {
+                throw new RuntimeException(
+                        "Expected bstr to be 32 bytes, it is " + popSha256.length);
+            }
+            return popSha256;
+        } catch (IOException e) {
+            throw new RuntimeException("Error decoding extension data", e);
+        } catch (CborException e) {
+            throw new RuntimeException("Error decoding data", e);
+        }
+    }
+
 }
diff --git a/security/identity-credential/src/main/java/androidx/security/identity/CredentialData.java b/security/identity-credential/src/main/java/androidx/security/identity/CredentialData.java
index 232a630..4736163 100644
--- a/security/identity-credential/src/main/java/androidx/security/identity/CredentialData.java
+++ b/security/identity-credential/src/main/java/androidx/security/identity/CredentialData.java
@@ -17,12 +17,15 @@
 package androidx.security.identity;
 
 import android.content.Context;
+import android.icu.util.Calendar;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
 import android.util.AtomicFile;
 import android.util.Log;
 import android.util.Pair;
 
+import androidx.annotation.NonNull;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.FileNotFoundException;
@@ -85,6 +88,7 @@
     private String mDocType = "";
     private String mCredentialKeyAlias = "";
     private Collection<X509Certificate> mCertificateChain = null;
+    private byte[] mProofOfProvisioningSha256 = null;
     private AbstractList<AccessControlProfile> mAccessControlProfiles = new ArrayList<>();
     private AbstractMap<Integer, AccessControlProfile> mProfileIdToAcpMap = new HashMap<>();
     private AbstractList<PersonalizationData.NamespaceData> mNamespaceDatas = new ArrayList<>();
@@ -111,14 +115,51 @@
     }
 
     /**
+     * Deletes KeyStore keys no longer needed when updating a credential (every KeyStore key
+     * except for CredentialKey).
+     */
+    void deleteKeysForReplacement() {
+        KeyStore ks;
+        try {
+            ks = KeyStore.getInstance("AndroidKeyStore");
+            ks.load(null);
+        } catch (CertificateException
+                | IOException
+                | NoSuchAlgorithmException
+                | KeyStoreException e) {
+            throw new RuntimeException("Error loading keystore", e);
+        }
+
+        // Nuke all keys except for CredentialKey.
+        try {
+            if (!mPerReaderSessionKeyAlias.isEmpty()) {
+                ks.deleteEntry(mPerReaderSessionKeyAlias);
+            }
+            for (String alias : mAcpTimeoutKeyAliases.values()) {
+                ks.deleteEntry(alias);
+            }
+            for (AuthKeyData authKeyData : mAuthKeyDatas) {
+                if (!authKeyData.mAlias.isEmpty()) {
+                    ks.deleteEntry(authKeyData.mAlias);
+                }
+                if (!authKeyData.mPendingAlias.isEmpty()) {
+                    ks.deleteEntry(authKeyData.mPendingAlias);
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new RuntimeException("Error deleting key", e);
+        }
+    }
+
+    /**
      * Creates a new {@link CredentialData} with the given name and saves it to disk.
-     * <p>
-     * The created data will be configured with zero authentication keys and max one use per key.
-     * <p>
-     * The created data can later be loaded via the {@link #loadCredentialData(Context, String)}
-     * method and deleted by calling {@link #delete(Context, String)}.
      *
-     * An auth-bound key will be created for each access control profile with user-authentication.
+     * <p>The created data will be configured with zero authentication keys and max one use per
+     * key and can later be loaded via the {@link #loadCredentialData(Context, String)}
+     * method and deleted by calling {@link #delete(Context, String, byte[])}.
+     *
+     * <p>An auth-bound key will be created for each access control profile with
+     * user-authentication.
      *
      * @param context             the context.
      * @param credentialName      the name of the credential.
@@ -126,6 +167,7 @@
      *                            created.
      * @param certificateChain    the certificate chain for the credential key.
      * @param personalizationData the data for the credential.
+     * @param isReplacement       set to true if this replaces an existing credential
      * @return a new @{link CredentialData} object
      */
     static CredentialData createCredentialData(Context context,
@@ -133,16 +175,20 @@
             String credentialName,
             String credentialKeyAlias,
             Collection<X509Certificate> certificateChain,
-            PersonalizationData personalizationData) {
-
-        if (credentialAlreadyExists(context, credentialName)) {
-            throw new RuntimeException("Credential with given name already exists");
+            PersonalizationData personalizationData,
+            byte[] proofOfProvisioningSha256,
+            boolean isReplacement) {
+        if (!isReplacement) {
+            if (credentialAlreadyExists(context, credentialName)) {
+                throw new RuntimeException("Credential with given name already exists");
+            }
         }
 
         CredentialData data = new CredentialData(context, credentialName);
         data.mDocType = docType;
         data.mCredentialKeyAlias = credentialKeyAlias;
         data.mCertificateChain = certificateChain;
+        data.mProofOfProvisioningSha256 = proofOfProvisioningSha256;
         data.mAccessControlProfiles = new ArrayList<>();
         data.mProfileIdToAcpMap = new HashMap<>();
         for (AccessControlProfile item : personalizationData.getAccessControlProfiles()) {
@@ -248,7 +294,7 @@
     /**
      * Loads a {@link CredentialData} object previously created with
      * {@link #createCredentialData(Context, String, String, String, Collection,
-     * PersonalizationData)}.
+     * PersonalizationData, byte[])}.
      *
      * @param context        the application context
      * @param credentialName the name of the credential.
@@ -292,14 +338,64 @@
         return escapeCredentialName("acp", credentialName);
     }
 
-    // Returns COSE_Sign1 with payload set to ProofOfDeletion
-    static byte[] buildProofOfDeletionSignature(String docType, PrivateKey key) {
+    PrivateKey getCredentialKeyPrivate() {
+        KeyStore ks;
+        KeyStore.Entry entry;
+        try {
+            ks = KeyStore.getInstance("AndroidKeyStore");
+            ks.load(null);
+            entry = ks.getEntry(mCredentialKeyAlias, null);
+        } catch (CertificateException
+                | IOException
+                | NoSuchAlgorithmException
+                | KeyStoreException
+                | UnrecoverableEntryException e) {
+            throw new RuntimeException("Error loading keystore", e);
+        }
+        return ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();
+    }
+
+    // Returns COSE_Sign1 with payload set to ProofOfOwnership
+    @NonNull byte[] proveOwnership(@NonNull byte[] challenge) {
+        PrivateKey key = getCredentialKeyPrivate();
 
         CborBuilder signedDataBuilder = new CborBuilder();
         signedDataBuilder.addArray()
-                .add("ProofOfDeletion")
-                .add(docType)
+                .add("ProofOfOwnership")
+                .add(mDocType)
+                .add(challenge)
                 .add(false);
+        byte[] signatureBytes;
+        try {
+            ByteArrayOutputStream dtsBaos = new ByteArrayOutputStream();
+            CborEncoder dtsEncoder = new CborEncoder(dtsBaos);
+            dtsEncoder.encode(signedDataBuilder.build().get(0));
+            byte[] dataToSign = dtsBaos.toByteArray();
+
+            signatureBytes = Util.coseSign1Sign(key,
+                    dataToSign,
+                    null,
+                    null);
+        } catch (NoSuchAlgorithmException
+                | InvalidKeyException
+                | CertificateEncodingException
+                | CborException e) {
+            throw new RuntimeException("Error building ProofOfOwnership", e);
+        }
+        return signatureBytes;
+    }
+
+    // Returns COSE_Sign1 with payload set to ProofOfDeletion
+    static byte[] buildProofOfDeletionSignature(String docType, PrivateKey key, byte[] challenge) {
+
+        CborBuilder signedDataBuilder = new CborBuilder();
+        ArrayBuilder<CborBuilder> arrayBuilder = signedDataBuilder.addArray();
+        arrayBuilder.add("ProofOfDeletion")
+                .add(docType);
+        if (challenge != null) {
+            arrayBuilder.add(challenge);
+        }
+        arrayBuilder.add(false);
 
         byte[] signatureBytes;
         try {
@@ -321,7 +417,7 @@
         return signatureBytes;
     }
 
-    static byte[] delete(Context context, String credentialName) {
+    static byte[] delete(Context context, String credentialName, byte[] challenge) {
         String filename = getFilenameForCredentialData(credentialName);
         AtomicFile file = new AtomicFile(context.getFileStreamPath(filename));
         try {
@@ -355,7 +451,7 @@
         }
 
         byte[] signature = buildProofOfDeletionSignature(data.mDocType,
-                ((KeyStore.PrivateKeyEntry) entry).getPrivateKey());
+                ((KeyStore.PrivateKeyEntry) entry).getPrivateKey(), challenge);
 
         file.delete();
 
@@ -512,6 +608,10 @@
         ArrayBuilder<MapBuilder<CborBuilder>> authKeyDataArrayBuilder = map.putArray(
                 "authKeyDatas");
         for (AuthKeyData data : mAuthKeyDatas) {
+            long expirationDateMillis = Long.MAX_VALUE;
+            if (data.mExpirationDate != null) {
+                expirationDateMillis = data.mExpirationDate.getTimeInMillis();
+            }
             authKeyDataArrayBuilder.addMap()
                     .put("alias", data.mAlias)
                     .put("useCount", data.mUseCount)
@@ -519,6 +619,7 @@
                     .put("staticAuthenticationData", data.mStaticAuthenticationData)
                     .put("pendingAlias", data.mPendingAlias)
                     .put("pendingCertificate", data.mPendingCertificate)
+                    .put("expirationDateMillis", expirationDateMillis)
                     .end();
         }
     }
@@ -535,6 +636,7 @@
                 throw new RuntimeException("Error encoding certificate", e);
             }
         }
+        map.put("proofOfProvisioningSha256", mProofOfProvisioningSha256);
         map.put("authKeyCount", mAuthKeyCount);
         map.put("authKeyMaxUses", mAuthMaxUsesPerKey);
     }
@@ -564,6 +666,7 @@
 
             loadBasic(map);
             loadCredentialKeyCertChain(map);
+            loadProofOfProvisioningSha256(map);
             loadAccessControlProfiles(map);
             loadNamespaceDatas(map);
             loadAuthKey(map);
@@ -664,6 +767,19 @@
             data.mPendingCertificate = ((ByteString) im.get(
                     new UnicodeString("pendingCertificate"))).getBytes();
 
+            // expirationDateMillis was added in a later release, may not be present
+            long expirationDateMillis = Long.MAX_VALUE;
+            DataItem expirationDateMillisItem = im.get(new UnicodeString("expirationDateMillis"));
+            if (expirationDateMillisItem != null) {
+                if (!(expirationDateMillisItem instanceof Number)) {
+                    throw new RuntimeException("expirationDateMillis not a number");
+                }
+                expirationDateMillis = ((Number) expirationDateMillisItem).getValue().longValue();
+            }
+            Calendar expirationDate = Calendar.getInstance();
+            expirationDate.setTimeInMillis(expirationDateMillis);
+            data.mExpirationDate = expirationDate;
+
             mAuthKeyDatas.add(data);
         }
     }
@@ -699,6 +815,16 @@
         }
     }
 
+    private void loadProofOfProvisioningSha256(co.nstant.in.cbor.model.Map map) {
+        DataItem proofOfProvisioningSha256 = map.get(
+                new UnicodeString("proofOfProvisioningSha256"));
+        if (!(proofOfProvisioningSha256 instanceof ByteString)) {
+            throw new RuntimeException(
+                    "proofOfProvisioningSha256 not found or not bstr");
+        }
+        mProofOfProvisioningSha256 = ((ByteString) proofOfProvisioningSha256).getBytes();
+    }
+
     private void loadCredentialKeyCertChain(co.nstant.in.cbor.model.Map map) {
         DataItem credentialKeyCertChain = map.get(new UnicodeString("credentialKeyCertChain"));
         if (!(credentialKeyCertChain instanceof Array)) {
@@ -830,12 +956,20 @@
 
         ArrayList<X509Certificate> certificates = new ArrayList<X509Certificate>();
 
+        Calendar now = Calendar.getInstance();
+
         // Determine which keys need certification (or re-certification) and generate
         // keys and X.509 certs for these and mark them as pending.
         for (int n = 0; n < mAuthKeyCount; n++) {
             AuthKeyData data = mAuthKeyDatas.get(n);
 
-            boolean newKeyNeeded = data.mAlias.isEmpty() || (data.mUseCount >= mAuthMaxUsesPerKey);
+            boolean keyExceededUseCount = (data.mUseCount >= mAuthMaxUsesPerKey);
+            boolean keyBeyondExpirationDate = false;
+            if (data.mExpirationDate != null) {
+                keyBeyondExpirationDate = now.after(data.mExpirationDate);
+            }
+            boolean newKeyNeeded =
+                    data.mAlias.isEmpty() || keyExceededUseCount || keyBeyondExpirationDate;
             boolean certificationPending = !data.mPendingAlias.isEmpty();
 
             if (newKeyNeeded && !certificationPending) {
@@ -856,8 +990,8 @@
                     kpg.initialize(builder.build());
                     kpg.generateKeyPair();
 
-                    X509Certificate certificate = Util.signPublicKeyWithPrivateKey(aliasForAuthKey,
-                            mCredentialKeyAlias);
+                    X509Certificate certificate = Util.generateAuthenticationKeyCert(
+                            aliasForAuthKey, mCredentialKeyAlias, mProofOfProvisioningSha256);
 
                     data.mPendingAlias = aliasForAuthKey;
                     data.mPendingCertificate = certificate.getEncoded();
@@ -888,6 +1022,7 @@
     }
 
     void storeStaticAuthenticationData(X509Certificate authenticationKey,
+            Calendar expirationDate,
             byte[] staticAuthData)
             throws UnknownAuthenticationKeyException {
         AuthKeyData dataForAuthKey = null;
@@ -935,7 +1070,7 @@
         dataForAuthKey.mUseCount = 0;
         dataForAuthKey.mPendingAlias = "";
         dataForAuthKey.mPendingCertificate = new byte[0];
-
+        dataForAuthKey.mExpirationDate = expirationDate;
         saveToDisk();
     }
 
@@ -947,22 +1082,49 @@
      *
      * The use count of the returned authentication key will be increased by one.
      *
+     * If no key could be found {@code null} is returned.
+     *
      * @param allowUsingExhaustedKeys If {@code true}, allow using an authentication key which
-     *                                use count has been
-     *                                exceeded if no other key is available. If @{code false},
-     *                                this method will
-     *                                throw @{link NoAuthenticationKeyAvailableException} if in
-     *                                the same situation.
+     *                                use count has been exceeded if no other key is available.
+     * @param allowUsingExpiredKeys If {@code true}, allow using an authentication key which
+     *                              is expired.
      * @return A pair containing the authentication key and its associated static authentication
      * data or {@code null} if no key could be found.
      */
-    Pair<PrivateKey, byte[]> selectAuthenticationKey(boolean allowUsingExhaustedKeys)
-            throws NoAuthenticationKeyAvailableException {
+    Pair<PrivateKey, byte[]> selectAuthenticationKey(boolean allowUsingExhaustedKeys,
+            boolean allowUsingExpiredKeys) {
+
+        // First try to find a un-expired key..
+        Pair<PrivateKey, byte[]> keyAndStaticData =
+                selectAuthenticationKeyHelper(allowUsingExhaustedKeys, false);
+        if (keyAndStaticData != null) {
+            return keyAndStaticData;
+        }
+        // Nope, try to see if there's an expired key (if allowed)
+        if (!allowUsingExpiredKeys) {
+            return null;
+        }
+        return selectAuthenticationKeyHelper(allowUsingExhaustedKeys, true);
+    }
+
+    Pair<PrivateKey, byte[]> selectAuthenticationKeyHelper(boolean allowUsingExhaustedKeys,
+            boolean allowUsingExpiredKeys) {
         AuthKeyData candidate = null;
 
+        Calendar now = Calendar.getInstance();
+
         for (int n = 0; n < mAuthKeyCount; n++) {
             AuthKeyData data = mAuthKeyDatas.get(n);
             if (!data.mAlias.isEmpty()) {
+                if (data.mExpirationDate != null) {
+                    if (now.after(data.mExpirationDate)) {
+                        // expired...
+                        if (!allowUsingExpiredKeys) {
+                            continue;
+                        }
+                    }
+                }
+
                 if (candidate == null || data.mUseCount < candidate.mUseCount) {
                     candidate = data;
                 }
@@ -1088,6 +1250,8 @@
         // The X509 certificate for a key pending certification.
         byte[] mPendingCertificate = new byte[0];
 
+        Calendar mExpirationDate = null;
+
         AuthKeyData() {
         }
     }
diff --git a/security/identity-credential/src/main/java/androidx/security/identity/HardwareIdentityCredential.java b/security/identity-credential/src/main/java/androidx/security/identity/HardwareIdentityCredential.java
index 8de65b2..6d577ee 100644
--- a/security/identity-credential/src/main/java/androidx/security/identity/HardwareIdentityCredential.java
+++ b/security/identity-credential/src/main/java/androidx/security/identity/HardwareIdentityCredential.java
@@ -27,6 +27,7 @@
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
 import java.security.KeyPair;
+import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
@@ -50,11 +51,11 @@
     private PublicKey mReaderEphemeralPublicKey = null;
     private byte[] mSessionTranscript = null;
 
-    private SecretKey mSecretKey = null;
-    private SecretKey mReaderSecretKey = null;
+    private SecretKey mSKDevice = null;
+    private SecretKey mSKReader = null;
 
-    private int mEphemeralCounter;
-    private int mReadersExpectedEphemeralCounter;
+    private int mSKDeviceCounter;
+    private int mSKReaderCounter;
 
     private android.security.identity.IdentityCredential mCredential  = null;
 
@@ -86,7 +87,7 @@
     }
 
     private void ensureSessionEncryptionKey() {
-        if (mSecretKey != null) {
+        if (mSKDevice != null) {
             return;
         }
         if (mReaderEphemeralPublicKey == null) {
@@ -103,24 +104,18 @@
 
             byte[] sessionTranscriptBytes =
                     Util.prependSemanticTagForEncodedCbor(mSessionTranscript);
-            byte[] sharedSecretWithSessionTranscriptBytes =
-                    Util.concatArrays(sharedSecret, sessionTranscriptBytes);
+            byte[] salt = MessageDigest.getInstance("SHA-256").digest(sessionTranscriptBytes);
 
-            byte[] salt = new byte[1];
-            byte[] info = new byte[0];
+            byte[] info = new byte[] {'S', 'K', 'D', 'e', 'v', 'i', 'c', 'e'};
+            byte[] derivedKey = Util.computeHkdf("HmacSha256", sharedSecret, salt, info, 32);
+            mSKDevice = new SecretKeySpec(derivedKey, "AES");
 
-            salt[0] = 0x01;
-            byte[] derivedKey = Util.computeHkdf("HmacSha256",
-                    sharedSecretWithSessionTranscriptBytes, salt, info, 32);
-            mSecretKey = new SecretKeySpec(derivedKey, "AES");
+            info = new byte[] {'S', 'K', 'R', 'e', 'a', 'd', 'e', 'r'};
+            derivedKey = Util.computeHkdf("HmacSha256", sharedSecret, salt, info, 32);
+            mSKReader = new SecretKeySpec(derivedKey, "AES");
 
-            salt[0] = 0x00;
-            derivedKey = Util.computeHkdf("HmacSha256", sharedSecretWithSessionTranscriptBytes,
-                    salt, info, 32);
-            mReaderSecretKey = new SecretKeySpec(derivedKey, "AES");
-
-            mEphemeralCounter = 1;
-            mReadersExpectedEphemeralCounter = 1;
+            mSKDeviceCounter = 1;
+            mSKReaderCounter = 1;
 
         } catch (InvalidKeyException
                 | NoSuchAlgorithmException e) {
@@ -137,10 +132,10 @@
             ByteBuffer iv = ByteBuffer.allocate(12);
             iv.putInt(0, 0x00000000);
             iv.putInt(4, 0x00000001);
-            iv.putInt(8, mEphemeralCounter);
+            iv.putInt(8, mSKDeviceCounter);
             Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
             GCMParameterSpec encryptionParameterSpec = new GCMParameterSpec(128, iv.array());
-            cipher.init(Cipher.ENCRYPT_MODE, mSecretKey, encryptionParameterSpec);
+            cipher.init(Cipher.ENCRYPT_MODE, mSKDevice, encryptionParameterSpec);
             messageCiphertextAndAuthTag = cipher.doFinal(messagePlaintext);
         } catch (BadPaddingException
                 | IllegalBlockSizeException
@@ -150,7 +145,7 @@
                 | InvalidAlgorithmParameterException e) {
             throw new RuntimeException("Error encrypting message", e);
         }
-        mEphemeralCounter += 1;
+        mSKDeviceCounter += 1;
         return messageCiphertextAndAuthTag;
     }
 
@@ -162,11 +157,11 @@
         ByteBuffer iv = ByteBuffer.allocate(12);
         iv.putInt(0, 0x00000000);
         iv.putInt(4, 0x00000000);
-        iv.putInt(8, mReadersExpectedEphemeralCounter);
+        iv.putInt(8, mSKReaderCounter);
         byte[] plainText = null;
         try {
             final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
-            cipher.init(Cipher.DECRYPT_MODE, mReaderSecretKey, new GCMParameterSpec(128,
+            cipher.init(Cipher.DECRYPT_MODE, mSKReader, new GCMParameterSpec(128,
                     iv.array()));
             plainText = cipher.doFinal(messageCiphertext);
         } catch (BadPaddingException
@@ -177,7 +172,7 @@
                 | NoSuchPaddingException e) {
             throw new MessageDecryptionException("Error decrypting message", e);
         }
-        mReadersExpectedEphemeralCounter += 1;
+        mSKReaderCounter += 1;
         return plainText;
     }
 
@@ -258,6 +253,7 @@
         return mCredential.getAuthKeysNeedingCertification();
     }
 
+    @SuppressWarnings("deprecation")
     @Override
     public void storeStaticAuthenticationData(@NonNull X509Certificate authenticationKey,
             @NonNull byte[] staticAuthData) throws UnknownAuthenticationKeyException {
@@ -273,5 +269,4 @@
     int[] getAuthenticationDataUsageCount() {
         return mCredential.getAuthenticationDataUsageCount();
     }
-
 }
diff --git a/security/identity-credential/src/main/java/androidx/security/identity/HardwareIdentityCredentialStore.java b/security/identity-credential/src/main/java/androidx/security/identity/HardwareIdentityCredentialStore.java
index c048121..14337da 100644
--- a/security/identity-credential/src/main/java/androidx/security/identity/HardwareIdentityCredentialStore.java
+++ b/security/identity-credential/src/main/java/androidx/security/identity/HardwareIdentityCredentialStore.java
@@ -23,27 +23,35 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
 @RequiresApi(Build.VERSION_CODES.R)
 class HardwareIdentityCredentialStore extends IdentityCredentialStore {
 
     private static final String TAG = "HardwareIdentityCredentialStore";
 
     private android.security.identity.IdentityCredentialStore mStore = null;
+    private boolean mIsDirectAccess = false;
 
     private HardwareIdentityCredentialStore(
-            @NonNull android.security.identity.IdentityCredentialStore store) {
+            @NonNull android.security.identity.IdentityCredentialStore store,
+            boolean isDirectAccess) {
         mStore = store;
+        mIsDirectAccess = isDirectAccess;
     }
 
     static @Nullable IdentityCredentialStore getInstanceIfSupported(@NonNull Context context) {
         android.security.identity.IdentityCredentialStore store =
                 android.security.identity.IdentityCredentialStore.getInstance(context);
         if (store != null) {
-            return new HardwareIdentityCredentialStore(store);
+            return new HardwareIdentityCredentialStore(store, false);
         }
         return null;
     }
 
+    @SuppressWarnings("deprecation")
     public static @NonNull IdentityCredentialStore getInstance(@NonNull Context context) {
         IdentityCredentialStore instance = getInstanceIfSupported(context);
         if (instance != null) {
@@ -57,11 +65,12 @@
         android.security.identity.IdentityCredentialStore store =
                 android.security.identity.IdentityCredentialStore.getDirectAccessInstance(context);
         if (store != null) {
-            return new HardwareIdentityCredentialStore(store);
+            return new HardwareIdentityCredentialStore(store, true);
         }
         return null;
     }
 
+    @SuppressWarnings("deprecation")
     public static @NonNull IdentityCredentialStore getDirectAccessInstance(
             @NonNull Context context) {
         IdentityCredentialStore instance = getDirectAccessInstanceIfSupported(context);
@@ -73,12 +82,22 @@
 
     public static boolean isDirectAccessSupported(@NonNull Context context) {
         IdentityCredentialStore directAccessStore = getDirectAccessInstanceIfSupported(context);
-        return directAccessStore != null;
+        if (directAccessStore != null) {
+            return true;
+        }
+        return false;
     }
 
+    @SuppressWarnings("deprecation")
     @Override
     public @NonNull String[] getSupportedDocTypes() {
-        return mStore.getSupportedDocTypes();
+        Set<String> docTypeSet = getCapabilities().getSupportedDocTypes();
+        String[] docTypes = new String[docTypeSet.size()];
+        int n = 0;
+        for (String docType : docTypeSet) {
+            docTypes[n++] = docType;
+        }
+        return docTypes;
     }
 
     @Override
@@ -113,9 +132,32 @@
         }
     }
 
+    @SuppressWarnings("deprecation")
     @Override
     public @Nullable byte[] deleteCredentialByName(@NonNull String credentialName) {
         return mStore.deleteCredentialByName(credentialName);
     }
 
+    SimpleIdentityCredentialStoreCapabilities mCapabilities = null;
+
+    @Override
+    public @NonNull
+    IdentityCredentialStoreCapabilities getCapabilities() {
+        LinkedHashSet<String> supportedDocTypesSet =
+                new LinkedHashSet<String>(Arrays.asList(mStore.getSupportedDocTypes()));
+
+        if (mCapabilities == null) {
+            // TODO: update for Android 12 platform APIs when available.
+            mCapabilities = new SimpleIdentityCredentialStoreCapabilities(
+                    mIsDirectAccess,
+                    IdentityCredentialStoreCapabilities.FEATURE_VERSION_202009,
+                    true,
+                    supportedDocTypesSet,
+                    false,
+                    false,
+                    false,
+                    false);
+        }
+        return mCapabilities;
+    }
 }
diff --git a/security/identity-credential/src/main/java/androidx/security/identity/HardwareWritableIdentityCredential.java b/security/identity-credential/src/main/java/androidx/security/identity/HardwareWritableIdentityCredential.java
index 9faafb7..ab359458 100644
--- a/security/identity-credential/src/main/java/androidx/security/identity/HardwareWritableIdentityCredential.java
+++ b/security/identity-credential/src/main/java/androidx/security/identity/HardwareWritableIdentityCredential.java
@@ -77,5 +77,4 @@
 
         return mWritableCredential.personalize(builder.build());
     }
-
 }
diff --git a/security/identity-credential/src/main/java/androidx/security/identity/IdentityCredential.java b/security/identity-credential/src/main/java/androidx/security/identity/IdentityCredential.java
index 5fabb4ca..01b4fee 100644
--- a/security/identity-credential/src/main/java/androidx/security/identity/IdentityCredential.java
+++ b/security/identity-credential/src/main/java/androidx/security/identity/IdentityCredential.java
@@ -16,6 +16,8 @@
 
 package androidx.security.identity;
 
+import android.icu.util.Calendar;
+
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
@@ -116,11 +118,10 @@
     /**
      * Sets whether to allow using an authentication key which use count has been exceeded if no
      * other key is available. This must be called prior to calling
-     * {@link #getEntries(byte[], Map, byte[])} or using a
-     * {@link android.hardware.biometrics.BiometricPrompt.CryptoObject} which references this
-     * object.
+     * {@link #getEntries(byte[], Map, byte[])} or using a {@link BiometricPrompt.CryptoObject}
+     * which references this object.
      *
-     * By default this is set to true.
+     * <p>By default this is set to true.</p>
      *
      * @param allowUsingExhaustedKeys whether to allow using an authentication key which use count
      *                                has been exceeded if no other key is available.
@@ -128,6 +129,25 @@
     public abstract void setAllowUsingExhaustedKeys(boolean allowUsingExhaustedKeys);
 
     /**
+     * Sets whether to allow using an authentication key which has been expired if no
+     * other key is available. This must be called prior to calling
+     * {@link #getEntries(byte[], Map, byte[])} or using a {@link BiometricPrompt.CryptoObject}
+     * which references this object.
+     *
+     * <p>By default this is set to false.
+     *
+     * <p>This is only implemented if
+     * {@link IdentityCredentialStoreCapabilities#isStaticAuthenticationDataExpirationSupported()}
+     * returns {@code true}. If not the call fails with {@link UnsupportedOperationException}.
+     *
+     * @param allowUsingExpiredKeys whether to allow using an authentication key which use count
+     *                              has been exceeded if no other key is available.
+     */
+    public void setAllowUsingExpiredKeys(boolean allowUsingExpiredKeys) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
      * Gets a {@link BiometricPrompt.CryptoObject} which can be used with this
      * {@link IdentityCredential}.
      *
@@ -297,16 +317,42 @@
     /**
      * Gets a collection of dynamic authentication keys that need certification.
      *
-     * <p>When there aren't enough certified dynamic authentication keys, either because the key
-     * count has been increased or because one or more keys have reached their usage count, this
-     * method will generate replacement keys and certificates and return them for issuer
-     * certification. The issuer certificates and associated static authentication data must then
-     * be provided back to the {@code IdentityCredential} using
-     * {@link #storeStaticAuthenticationData(X509Certificate, byte[])}.
+     * <p>When there aren't enough certified dynamic authentication keys (either because the key
+     * count has been increased, one or more keys have reached their usage count, or keys have
+     * expired), this method will generate replacement keys and certificates and return them for
+     * issuer certification. The issuer certificates and associated static authentication data
+     * must then be provided back to the {@code IdentityCredential} using
+     * {@link #storeStaticAuthenticationData(X509Certificate, Calendar, byte[])}.
      *
      * <p>Each X.509 certificate is signed by CredentialKey. The certificate chain for CredentialKey
      * can be obtained using the {@link #getCredentialKeyCertificateChain()} method.
      *
+     * <p>The following non-optional fields for the X.509 certificate are set as follows:
+     * <ul>
+     *  <li>version: INTEGER 2 (means v3 certificate).</li>
+     *  <li>serialNumber: INTEGER 1 (fixed value: same on all certs).</li>
+     *  <li>signature: must be set to ECDSA.</li>
+     *  <li>subject: CN shall be set to "Android Identity Credential Authentication Key" (fixed
+     *  value: same on all certs).</li>
+     *  <li>issuer: CN shall be set to "Android Identity Credential Key" (fixed value: same on
+     *  all certs).</li>
+     *  <li>validity: should be from current time and one year in the future (365 days).</li>
+     *  <li>subjectPublicKeyInfo: must contain attested public key.</li>
+     * </ul>
+     *
+     * <p>If {@link IdentityCredentialStoreCapabilities#isUpdateSupported()} returns
+     * {@code true}, each X.509 certificate contains an X.509 extension at OID 1.3.6.1.4.1.11129
+     * .2.1.26 which contains a DER encoded OCTET STRING with the bytes of the CBOR with the
+     * following CDDL:
+     * <pre>
+     *   ProofOfBinding = [
+     *     "ProofOfBinding",
+     *     bstr,              // Contains SHA-256(ProofOfProvisioning)
+     *   ]
+     * </pre>
+     * <p>This CBOR enables an issuer to determine the exact state of the credential it
+     * returns issuer-signed data for.
+     *
      * @return A collection of X.509 certificates for dynamic authentication keys that need issuer
      * certification.
      */
@@ -315,21 +361,49 @@
     /**
      * Store authentication data associated with a dynamic authentication key.
      *
-     * This should only be called for an authenticated key returned by
-     * {@link #getAuthKeysNeedingCertification()}.
+     * <p>This should only be called for an authenticated key returned by
+     * {@link #getAuthKeysNeedingCertification()}.</p>
      *
      * @param authenticationKey The dynamic authentication key for which certification and
-     *                          associated static
-     *                          authentication data is being provided.
+     *                          associated static authentication data is being provided.
+     * @param staticAuthData    Static authentication data provided by the issuer that validates
+     *                          the authenticity
+     *                          and integrity of the credential data fields.
+     * @throws UnknownAuthenticationKeyException If the given authentication key is not recognized.
+     * @deprecated Use {@link #storeStaticAuthenticationData(X509Certificate, Calendar, byte[])}
+     *     instead.
+     */
+    @Deprecated
+    public abstract void storeStaticAuthenticationData(
+            @NonNull X509Certificate authenticationKey,
+            @NonNull byte[] staticAuthData)
+            throws UnknownAuthenticationKeyException;
+
+    /**
+     * Store authentication data associated with a dynamic authentication key.
+     *
+     * <p>This should only be called for an authenticated key returned by
+     * {@link #getAuthKeysNeedingCertification()}.</p>
+     *
+     * <p>This is only implemented if
+     * {@link IdentityCredentialStoreCapabilities#isStaticAuthenticationDataExpirationSupported()}
+     * returns {@code true}. If not the call fails with {@link UnsupportedOperationException}.
+     *
+     * @param authenticationKey The dynamic authentication key for which certification and
+     *                          associated static authentication data is being provided.
+     * @param expirationDate    The expiration date of the static authentication data.
      * @param staticAuthData    Static authentication data provided by the issuer that validates
      *                          the authenticity
      *                          and integrity of the credential data fields.
      * @throws UnknownAuthenticationKeyException If the given authentication key is not recognized.
      */
-    public abstract void storeStaticAuthenticationData(
+    public void storeStaticAuthenticationData(
             @NonNull X509Certificate authenticationKey,
+            @NonNull Calendar expirationDate,
             @NonNull byte[] staticAuthData)
-            throws UnknownAuthenticationKeyException;
+            throws UnknownAuthenticationKeyException {
+        throw new UnsupportedOperationException();
+    }
 
     /**
      * Get the number of times the dynamic authentication keys have been used.
@@ -337,4 +411,88 @@
      * @return int array of dynamic authentication key usage counts.
      */
     public @NonNull abstract int[] getAuthenticationDataUsageCount();
+
+
+    /**
+     * Proves ownership of a credential.
+     *
+     * <p>This method returns a COSE_Sign1 data structure signed by the CredentialKey
+     * with payload set to {@code ProofOfOwnership} as defined below.</p>
+     * <pre>
+     *     ProofOfOwnership = [
+     *          "ProofOfOwnership",           ; tstr
+     *          tstr,                         ; DocType
+     *          bstr,                         ; Challenge
+     *          bool                          ; true if this is a test credential, should
+     *                                        ; always be false.
+     *      ]
+     * </pre>
+     *
+     * <p>This is only implemented if
+     * {@link IdentityCredentialStoreCapabilities#isProveOwnershipSupported()}
+     * returns {@code true}. If not the call fails with {@link UnsupportedOperationException}.
+     *
+     * @param challenge is a non-empty byte array whose contents should be unique, fresh and
+     *                  provided by the issuing authority. The value provided is embedded in the
+     *                  generated CBOR and enables the issuing authority to verify that the
+     *                  returned proof is fresh.
+     * @return the COSE_Sign1 data structure above
+     */
+    public @NonNull byte[] proveOwnership(@NonNull byte[] challenge)  {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Deletes a credential.
+     *
+     * <p>This method returns a COSE_Sign1 data structure signed by the CredentialKey
+     * with payload set to {@code ProofOfDeletion} as defined below.</p>
+     * <pre>
+     *     ProofOfDeletion = [
+     *          "ProofOfDeletion",            ; tstr
+     *          tstr,                         ; DocType
+     *          bstr,                         ; Challenge
+     *          bool                          ; true if this is a test credential, should
+     *                                        ; always be false.
+     *      ]
+     * </pre>
+     *
+     * <p>This is only implemented if
+     * {@link IdentityCredentialStoreCapabilities#isDeleteSupported()}
+     * returns {@code true}. If not the call fails with {@link UnsupportedOperationException}.
+     *
+     * @param challenge is a non-empty byte array whose contents should be unique, fresh and
+     *                  provided by the issuing authority. The value provided is embedded in the
+     *                  generated CBOR and enables the issuing authority to verify that the
+     *                  returned proof is fresh.
+     * @return the COSE_Sign1 data structure above
+     */
+    public @NonNull byte[] delete(@NonNull byte[] challenge)  {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Updates the credential with new access control profiles and data items.
+     *
+     * <p>This method is similar to
+     * {@link WritableIdentityCredential#personalize(PersonalizationData)} except that it operates
+     * on an existing credential, see the documentation for that method for the format of the
+     * returned data.
+     *
+     * <p>If this call succeeds an side-effect is that all dynamic authentication keys for the
+     * credential are deleted. The application will need to use
+     * {@link #getAuthKeysNeedingCertification()} to generate replacement keys and return
+     * them for issuer certification.
+     *
+     * <p>This is only implemented if
+     * {@link IdentityCredentialStoreCapabilities#isUpdateSupported()}
+     * returns {@code true}. If not the call fails with {@link UnsupportedOperationException}.
+     *
+     * @param personalizationData   The data to update, including access control profiles
+     *                              and data elements and their values, grouped into namespaces.
+     * @return A COSE_Sign1 data structure, see above.
+     */
+    public @NonNull byte[] update(@NonNull PersonalizationData personalizationData) {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/security/identity-credential/src/main/java/androidx/security/identity/IdentityCredentialStore.java b/security/identity-credential/src/main/java/androidx/security/identity/IdentityCredentialStore.java
index 7d5941e..3054ad4 100644
--- a/security/identity-credential/src/main/java/androidx/security/identity/IdentityCredentialStore.java
+++ b/security/identity-credential/src/main/java/androidx/security/identity/IdentityCredentialStore.java
@@ -22,7 +22,6 @@
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 
 import java.lang.annotation.Retention;
@@ -65,14 +64,44 @@
  * </ul>
  *
  * <p>Implementing support for user identity documents in secure storage requires dedicated
- * hardware-backed support and may not always be available.
+ * hardware-backed support and may not always be available. In addition to hardware-backed
+ * Identity Credential support (which is only available in Android 11 and later and only
+ * if the device has support for the <a href="https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/master/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl">Identity Credential HAL</a>),
+ * this Jetpack has an Android Keystore backed implementation (also known as the "software"
+ * implementation) which works on any Android device with API level 24 or later.
  *
- * <p>Two different credential stores exist - the <em>default</em> store and the
- * <em>direct access</em> store. Most often credentials will be accessed through the default
- * store but that requires that the Android device be powered up and fully functional.
- * It is desirable to allow identity credential usage when the Android device's battery is too
- * low to boot the Android operating system, so direct access to the secure hardware via NFC
- * may allow data retrieval, if the secure hardware chooses to implement it.
+ * <p>The Identity Credential API is designed to be able to evolve and change over time
+ * but still provide 100% backwards compatibility. This is complicated by the fact that
+ * there may be a version skew between the API used by the application and the version
+ * implemented in secure hardware. To solve this problem, the API provides for a way
+ * for the application to query for hardware capabilities through
+ * {@link IdentityCredentialStoreCapabilities}. The software-based store is designed
+ * so it implements all capabilities that don't explicitly require hardware features. Each
+ * of the methods in that class will state whether it's implemented in the software-based
+ * implementation.
+ *
+ * <p>When provisioning a document, applications should use {@link #getInstance(Context)} to
+ * obtain an {@link IdentityCredentialStore} instance. This method returns a hardware-backed
+ * store if available and a software-based store if not and the application should use
+ * {@link IdentityCredentialStoreCapabilities} to examine if the store supports the
+ * capabilities required by the application. In the negative, the application can
+ * obtain the software-based store by calling {@link #getSoftwareInstance(Context)}.
+ *
+ * <p>Since it's possible for an OS upgrade on a device to include an updated version of the
+ * drivers used for secure hardware, it's possible that {@link #getInstance(Context)} returns the
+ * software implementation at one point and the hardware implementation at a later point.
+ * Therefore, applications should only use {@link #getInstance(Context)} only when creating a
+ * credential, record whether it's hardware- or software-backed (using
+ * {@link IdentityCredentialStoreCapabilities#isHardwareBacked()}, and then use this information
+ * when retrieving the credential (using either {@link #getSoftwareInstance(Context)} or
+ * {@link #getHardwareInstance(Context)}).
+ *
+ * <p>Apart from hardware- vs software-backed, two different flavors of credential stores exist -
+ * the <em>default</em> store and the <em>direct access</em> store. Most often credentials will
+ * be accessed through the default store but that requires that the Android device be powered up
+ * and fully functional. It is desirable to allow identity credential usage when the Android
+ * device's battery is too low to boot the Android operating system, so direct access to the
+ * secure hardware via NFC may allow data retrieval, if the secure hardware chooses to implement it.
  *
  * <p>Credentials provisioned to the direct access store should <strong>always</strong> use reader
  * authentication to protect data elements. The reason for this is user authentication or user
@@ -131,7 +160,11 @@
             Context context) {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
             Context appContext = context.getApplicationContext();
-            return HardwareIdentityCredentialStore.getDirectAccessInstance(appContext);
+            IdentityCredentialStore store = HardwareIdentityCredentialStore.getDirectAccessInstance(
+                    appContext);
+            if (store != null) {
+                return store;
+            }
         }
         throw new RuntimeException("Direct-access IdentityCredential is not supported");
     }
@@ -170,7 +203,9 @@
      * credentials. The default store always supports any document type.
      *
      * @return The supported document types or the empty array if any document type is supported.
+     * @deprecated Use {@link IdentityCredentialStoreCapabilities#getSupportedDocTypes()} instead.
      */
+    @Deprecated
     public abstract @NonNull String[] getSupportedDocTypes();
 
     /**
@@ -215,7 +250,9 @@
      * @param credentialName the name of the credential to delete.
      * @return {@code null} if the credential was not found, the COSE_Sign1 data structure above
      *     if the credential was found and deleted.
+     * @deprecated Use {@link IdentityCredential#delete(byte[])} instead.
      */
+    @Deprecated
     public abstract @Nullable byte[] deleteCredentialByName(@NonNull String credentialName);
 
     /** @hide */
@@ -225,24 +262,47 @@
     public @interface Ciphersuite {
     }
 
-    /** @hide
+    /**
+     * Returns the capabilities of the store.
      *
-     *  See Util.getIdentityCredentialStore() in the tests for why this is made available to tests.
+     * @return the capabilities of the store
      */
-    @RestrictTo(RestrictTo.Scope.TESTS)
-    public static @NonNull IdentityCredentialStore getSoftwareIdentityCredentialStore(@NonNull
+    @NonNull
+    public IdentityCredentialStoreCapabilities getCapabilities() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Gets a {@link IdentityCredentialStore} implemented via Android Keystore. This
+     * is also known as the software implementation.
+     *
+     * @return an implementation of {@link IdentityCredentialStore} implemented on top
+     * of Android Keystore.
+     */
+    @SuppressWarnings("deprecation")
+    public static @NonNull IdentityCredentialStore getSoftwareInstance(@NonNull
             Context context) {
         return SoftwareIdentityCredentialStore.getInstance(context);
     }
 
-    /** @hide
+    /**
+     * Gets a {@link IdentityCredentialStore} implemented via secure hardware using
+     * the
+     * <a href="https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/master/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl">Identity Credential HAL</a>.
      *
-     *  See Util.getIdentityCredentialStore() in the tests for why this is made available to tests.
+     * <p>This only works on devices running Android 11 or later and only if the device has
+     * support for the Identity Credential HAL.
+     *
+     * @return an implementation of {@link IdentityCredentialStore} implemented in
+     * secure hardware or {@code null} if the device doesn't support the Android Identity
+     * Credential HAL.
      */
-    @RequiresApi(api = Build.VERSION_CODES.R)
-    @RestrictTo(RestrictTo.Scope.TESTS)
-    public static @NonNull IdentityCredentialStore getHardwareIdentityCredentialStore(@NonNull
+    @SuppressWarnings("deprecation")
+    public static @Nullable IdentityCredentialStore getHardwareInstance(@NonNull
             Context context) {
-        return HardwareIdentityCredentialStore.getInstance(context);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+            return HardwareIdentityCredentialStore.getInstance(context);
+        }
+        return null;
     }
 }
diff --git a/security/identity-credential/src/main/java/androidx/security/identity/IdentityCredentialStoreCapabilities.java b/security/identity-credential/src/main/java/androidx/security/identity/IdentityCredentialStoreCapabilities.java
new file mode 100644
index 0000000..3fb35d6
--- /dev/null
+++ b/security/identity-credential/src/main/java/androidx/security/identity/IdentityCredentialStoreCapabilities.java
@@ -0,0 +1,172 @@
+/*
+ * 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.security.identity;
+
+import android.icu.util.Calendar;
+
+import androidx.annotation.NonNull;
+
+import java.security.cert.X509Certificate;
+import java.util.Set;
+
+/* TODO: use this
+ *
+ *  {@link android.content.pm.PackageManager#FEATURE_IDENTITY_CREDENTIAL_HARDWARE}
+ *  {@link android.content.pm.PackageManager#FEATURE_IDENTITY_CREDENTIAL_HARDWARE_DIRECT_ACCESS}
+ *
+ * when building against the Android 12 SDK.
+ */
+
+/**
+ * A class that supports querying the capabilities of a {@link IdentityCredentialStore} as
+ * implemented in secure hardware or in software (backed by Android Keystore).
+ *
+ * <p>Capabilities depend on the Android system features and can be queried using
+ * {@link android.content.pm.PackageManager#getSystemAvailableFeatures()} and
+ * {@link android.content.pm.PackageManager#hasSystemFeature(String, int)}.
+ * The feature names in question are <em>android.hardware.identity_credential and</em>
+ * <em>android.hardware.identity_credential_direct_access</em> for the direct access store.
+ *
+ * <p>Known feature versions include {@link #FEATURE_VERSION_202009} and
+ * {@link #FEATURE_VERSION_202101}.
+ */
+public class IdentityCredentialStoreCapabilities {
+    IdentityCredentialStoreCapabilities() {}
+
+    /**
+     * The feature version corresponding to features included in the Identity Credential API
+     * shipped in Android 11.
+     */
+    public static final int FEATURE_VERSION_202009 = 202009;
+
+    /**
+     * The feature version corresponding to features included in the Identity Credential API
+     * shipped in Android 12. This feature version adds support for
+     * {@link IdentityCredential#delete(byte[])},
+     * {@link IdentityCredential#update(PersonalizationData)},
+     * {@link IdentityCredential#proveOwnership(byte[])}, and
+     * {@link IdentityCredential#storeStaticAuthenticationData(X509Certificate, Calendar, byte[])}.
+     */
+    public static final int FEATURE_VERSION_202101 = 202101;
+
+    /**
+     * Returns the feature version of the {@link IdentityCredentialStore}.
+     *
+     * @return the feature version.
+     */
+    public int getFeatureVersion() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns whether the credential store is for direct access.
+     *
+     * <p>This always return {@code false} for the software-based store.
+     *
+     * @return {@code true} if credential store is for direct access, {@code false} if not.
+     */
+    public boolean isDirectAccess() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns whether the credential is backed by Secure Hardware.
+     *
+     * <p>This always return {@code false} for the software-based store.
+     *
+     * <p>Note that the software-based store is still using Android Keystore which
+     * itself is backed by secure hardware.
+     *
+     * @return {@code true} if backed by secure hardware, {@code false} if not.
+     */
+    public boolean isHardwareBacked() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Gets a set of supported document types.
+     *
+     * <p>Only the direct-access store may restrict the kind of document types that can be used for
+     * credentials. The default store always supports any document type.
+     *
+     * <p>This always return the empty set for the software-based store.
+     *
+     * @return The supported document types or the empty set if any document type is supported.
+     */
+    public @NonNull
+    Set<String> getSupportedDocTypes() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns whether {@link IdentityCredential#delete(byte[])} is supported
+     * by the underlying hardware.
+     *
+     * <p>This is supported in feature version {@link #FEATURE_VERSION_202101} and later.
+     *
+     * <p>This is always supported by the software-based store.
+     *
+     * @return {@code true} if supported, {@code false} if not.
+     */
+    public boolean isDeleteSupported() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns true if {@link IdentityCredential#update(PersonalizationData)} is supported
+     * by the underlying hardware.
+     *
+     * <p>This is supported in feature version {@link #FEATURE_VERSION_202101} and later.
+     *
+     * <p>This is always supported by the software-based store.
+     *
+     * @return {@code true} if supported, {@code false} if not.
+     */
+    public boolean isUpdateSupported() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns true if {@link IdentityCredential#proveOwnership(byte[])} is supported by the
+     * underlying hardware.
+     *
+     * <p>This is supported in feature version {@link #FEATURE_VERSION_202101} and later.
+     *
+     * <p>This is always supported by the software-based store.
+     *
+     * @return {@code true} if supported, {@code false} if not.
+     */
+    public boolean isProveOwnershipSupported() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns true if
+     * {@link IdentityCredential#storeStaticAuthenticationData(X509Certificate, Calendar, byte[])}
+     * is supported by the underlying hardware.
+     *
+     * <p>This is supported in feature version {@link #FEATURE_VERSION_202101} and later.
+     *
+     * <p>This is always supported by the software-based store.
+     *
+     * @return {@code true} if supported, {@code false} if not.
+     */
+    public boolean isStaticAuthenticationDataExpirationSupported() {
+        throw new UnsupportedOperationException();
+    }
+
+}
diff --git a/security/identity-credential/src/main/java/androidx/security/identity/SimpleIdentityCredentialStoreCapabilities.java b/security/identity-credential/src/main/java/androidx/security/identity/SimpleIdentityCredentialStoreCapabilities.java
new file mode 100644
index 0000000..5393bf8
--- /dev/null
+++ b/security/identity-credential/src/main/java/androidx/security/identity/SimpleIdentityCredentialStoreCapabilities.java
@@ -0,0 +1,93 @@
+/*
+ * 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.security.identity;
+
+import androidx.annotation.NonNull;
+
+import java.util.Set;
+
+class SimpleIdentityCredentialStoreCapabilities extends IdentityCredentialStoreCapabilities {
+
+    boolean mIsDirectAccess;
+    int mFeatureVersion;
+    boolean mIsHardwareBacked;
+    Set<String> mSupportedDocTypes;
+    boolean mIsDeleteCredentialSupported;
+    boolean mIsUpdateCredentialSupported;
+    boolean mIsProveOwnershipSupported;
+    boolean mIsStaticAuthenticationDataExpirationDateSupported;
+
+    SimpleIdentityCredentialStoreCapabilities(boolean isDirectAccess,
+            int featureVersion,
+            boolean isHardwareBacked,
+            Set<String> supportedDocTypes,
+            boolean isDeleteCredentialSupported,
+            boolean isUpdateCredentialSupported,
+            boolean isProveOwnershipSupported,
+            boolean isStaticAuthenticationDataExpirationDateSupported) {
+        mIsDirectAccess = isDirectAccess;
+        mFeatureVersion = featureVersion;
+        mIsHardwareBacked = isHardwareBacked;
+        mSupportedDocTypes = supportedDocTypes;
+        mIsDeleteCredentialSupported = isDeleteCredentialSupported;
+        mIsProveOwnershipSupported = isProveOwnershipSupported;
+        mIsUpdateCredentialSupported = isUpdateCredentialSupported;
+        mIsStaticAuthenticationDataExpirationDateSupported =
+                isStaticAuthenticationDataExpirationDateSupported;
+    }
+
+    @Override
+    public boolean isDirectAccess() {
+        return mIsDirectAccess;
+    }
+
+    @Override
+    public int getFeatureVersion() {
+        return mFeatureVersion;
+    }
+
+    @Override
+    public boolean isHardwareBacked() {
+        return mIsHardwareBacked;
+    }
+
+    @Override
+    public @NonNull Set<String> getSupportedDocTypes() {
+        return mSupportedDocTypes;
+    }
+
+    @Override
+    public boolean isDeleteSupported() {
+        return mIsDeleteCredentialSupported;
+    }
+
+    @Override
+    public boolean isUpdateSupported() {
+        return mIsUpdateCredentialSupported;
+    }
+
+    @Override
+    public boolean isProveOwnershipSupported() {
+        return mIsProveOwnershipSupported;
+    }
+
+    @Override
+    public boolean isStaticAuthenticationDataExpirationSupported() {
+        return mIsStaticAuthenticationDataExpirationDateSupported;
+    }
+
+}
diff --git a/security/identity-credential/src/main/java/androidx/security/identity/SoftwareIdentityCredential.java b/security/identity-credential/src/main/java/androidx/security/identity/SoftwareIdentityCredential.java
index 9c41e23..5a534a2 100644
--- a/security/identity-credential/src/main/java/androidx/security/identity/SoftwareIdentityCredential.java
+++ b/security/identity-credential/src/main/java/androidx/security/identity/SoftwareIdentityCredential.java
@@ -18,6 +18,7 @@
 
 import android.annotation.SuppressLint;
 import android.content.Context;
+import android.icu.util.Calendar;
 import android.security.keystore.KeyProperties;
 import android.util.Log;
 import android.util.Pair;
@@ -36,6 +37,7 @@
 import java.security.KeyPairGenerator;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
+import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
 import java.security.PublicKey;
@@ -84,11 +86,11 @@
 
     private KeyPair mEphemeralKeyPair = null;
 
-    private SecretKey mSecretKey = null;
-    private SecretKey mReaderSecretKey = null;
+    private SecretKey mSKDevice = null;
+    private SecretKey mSKReader = null;
 
-    private int mEphemeralCounter;
-    private int mReadersExpectedEphemeralCounter;
+    private int mSKDeviceCounter;
+    private int mSKReaderCounter;
     private byte[] mAuthKeyAssociatedData = null;
     private PrivateKey mAuthKey = null;
     private BiometricPrompt.CryptoObject mCryptoObject = null;
@@ -116,9 +118,21 @@
     }
 
     static byte[] delete(Context context, String credentialName) {
-        return CredentialData.delete(context, credentialName);
+        return CredentialData.delete(context, credentialName, null);
     }
 
+    @Override
+    public @NonNull byte[] delete(@NonNull byte[] challenge)  {
+        return CredentialData.delete(mContext, mCredentialName, challenge);
+    }
+
+    @Override
+    public @NonNull byte[] proveOwnership(@NonNull byte[] challenge)  {
+        return mData.proveOwnership(challenge);
+    }
+
+
+
     // This only extracts the requested namespaces, not DocType or RequestInfo. We
     // can do this later if it's needed.
     private static HashMap<String, Collection<String>> parseRequestMessage(
@@ -207,7 +221,7 @@
     }
 
     private void ensureSessionEncryptionKey() {
-        if (mSecretKey != null) {
+        if (mSKDevice != null) {
             return;
         }
         if (mReaderEphemeralPublicKey == null) {
@@ -224,24 +238,18 @@
 
             byte[] sessionTranscriptBytes =
                     Util.prependSemanticTagForEncodedCbor(mSessionTranscript);
-            byte[] sharedSecretWithSessionTranscriptBytes =
-                    Util.concatArrays(sharedSecret, sessionTranscriptBytes);
+            byte[] salt = MessageDigest.getInstance("SHA-256").digest(sessionTranscriptBytes);
 
-            byte[] salt = new byte[1];
-            byte[] info = new byte[0];
+            byte[] info = new byte[] {'S', 'K', 'D', 'e', 'v', 'i', 'c', 'e'};
+            byte[] derivedKey = Util.computeHkdf("HmacSha256", sharedSecret, salt, info, 32);
+            mSKDevice = new SecretKeySpec(derivedKey, "AES");
 
-            salt[0] = 0x01;
-            byte[] derivedKey = Util.computeHkdf("HmacSha256",
-                    sharedSecretWithSessionTranscriptBytes, salt, info, 32);
-            mSecretKey = new SecretKeySpec(derivedKey, "AES");
+            info = new byte[] {'S', 'K', 'R', 'e', 'a', 'd', 'e', 'r'};
+            derivedKey = Util.computeHkdf("HmacSha256", sharedSecret, salt, info, 32);
+            mSKReader = new SecretKeySpec(derivedKey, "AES");
 
-            salt[0] = 0x00;
-            derivedKey = Util.computeHkdf("HmacSha256", sharedSecretWithSessionTranscriptBytes,
-                    salt, info, 32);
-            mReaderSecretKey = new SecretKeySpec(derivedKey, "AES");
-
-            mEphemeralCounter = 1;
-            mReadersExpectedEphemeralCounter = 1;
+            mSKDeviceCounter = 1;
+            mSKReaderCounter = 1;
 
         } catch (InvalidKeyException
                 | NoSuchAlgorithmException e) {
@@ -258,10 +266,10 @@
             ByteBuffer iv = ByteBuffer.allocate(12);
             iv.putInt(0, 0x00000000);
             iv.putInt(4, 0x00000001);
-            iv.putInt(8, mEphemeralCounter);
+            iv.putInt(8, mSKDeviceCounter);
             Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
             GCMParameterSpec encryptionParameterSpec = new GCMParameterSpec(128, iv.array());
-            cipher.init(Cipher.ENCRYPT_MODE, mSecretKey, encryptionParameterSpec);
+            cipher.init(Cipher.ENCRYPT_MODE, mSKDevice, encryptionParameterSpec);
             messageCiphertextAndAuthTag = cipher.doFinal(messagePlaintext);
         } catch (BadPaddingException
                 | IllegalBlockSizeException
@@ -271,7 +279,7 @@
                 | InvalidAlgorithmParameterException e) {
             throw new RuntimeException("Error encrypting message", e);
         }
-        mEphemeralCounter += 1;
+        mSKDeviceCounter += 1;
         return messageCiphertextAndAuthTag;
     }
 
@@ -283,11 +291,11 @@
         ByteBuffer iv = ByteBuffer.allocate(12);
         iv.putInt(0, 0x00000000);
         iv.putInt(4, 0x00000000);
-        iv.putInt(8, mReadersExpectedEphemeralCounter);
+        iv.putInt(8, mSKReaderCounter);
         byte[] plainText = null;
         try {
             final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
-            cipher.init(Cipher.DECRYPT_MODE, mReaderSecretKey, new GCMParameterSpec(128,
+            cipher.init(Cipher.DECRYPT_MODE, mSKReader, new GCMParameterSpec(128,
                     iv.array()));
             plainText = cipher.doFinal(messageCiphertext);
         } catch (BadPaddingException
@@ -298,7 +306,7 @@
                 | NoSuchPaddingException e) {
             throw new MessageDecryptionException("Error decrypting message", e);
         }
-        mReadersExpectedEphemeralCounter += 1;
+        mSKReaderCounter += 1;
         return plainText;
     }
 
@@ -339,7 +347,8 @@
         }
 
         Pair<PrivateKey, byte[]> keyAndStaticData = mData.selectAuthenticationKey(
-                mAllowUsingExhaustedKeys);
+                mAllowUsingExhaustedKeys,
+                mAllowUsingExpiredKeys);
         if (keyAndStaticData == null) {
             throw new NoAuthenticationKeyAvailableException(
                     "No authentication key available for signing");
@@ -349,6 +358,7 @@
     }
 
     boolean mAllowUsingExhaustedKeys = true;
+    boolean mAllowUsingExpiredKeys = false;
 
     @Override
     public void setAllowUsingExhaustedKeys(boolean allowUsingExhaustedKeys) {
@@ -356,6 +366,11 @@
     }
 
     @Override
+    public void setAllowUsingExpiredKeys(boolean allowUsingExpiredKeys) {
+        mAllowUsingExpiredKeys = allowUsingExpiredKeys;
+    }
+
+    @Override
     @Nullable
     public BiometricPrompt.CryptoObject getCryptoObject() {
         ensureCryptoObject();
@@ -707,15 +722,70 @@
         return mData.getAuthKeysNeedingCertification();
     }
 
+    @SuppressWarnings("deprecation")
     @Override
     public void storeStaticAuthenticationData(@NonNull X509Certificate authenticationKey,
             @NonNull byte[] staticAuthData) throws UnknownAuthenticationKeyException {
-        mData.storeStaticAuthenticationData(authenticationKey, staticAuthData);
+        mData.storeStaticAuthenticationData(authenticationKey, null, staticAuthData);
     }
 
     @Override
+    public void storeStaticAuthenticationData(
+            @NonNull X509Certificate authenticationKey,
+            @NonNull Calendar expirationDate,
+            @NonNull byte[] staticAuthData)
+            throws UnknownAuthenticationKeyException {
+        mData.storeStaticAuthenticationData(authenticationKey, expirationDate, staticAuthData);
+    }
+
+
+    @Override
     public @NonNull
     int[] getAuthenticationDataUsageCount() {
         return mData.getAuthKeyUseCounts();
     }
+
+    @Override
+    public @NonNull byte[] update(@NonNull PersonalizationData personalizationData) {
+        try {
+            String docType = mData.getDocType();
+            Collection<X509Certificate> certificates = mData.getCredentialKeyCertificateChain();
+            PrivateKey credentialKey = mData.getCredentialKeyPrivate();
+            int authKeyCount = mData.getAuthKeyCount();
+            int authMaxUsesPerKey = mData.getAuthMaxUsesPerKey();
+
+            byte[] encodedBytes =
+                    SoftwareWritableIdentityCredential.buildProofOfProvisioningWithSignature(
+                            docType,
+                            personalizationData,
+                            credentialKey);
+
+            byte[] proofOfProvisioning = Util.coseSign1GetData(encodedBytes);
+            byte[] proofOfProvisioningSha256 = MessageDigest.getInstance("SHA-256").digest(
+                    proofOfProvisioning);
+
+            // Nuke all KeyStore keys except for CredentialKey (otherwise we leak them)
+            //
+            mData.deleteKeysForReplacement();
+
+            mData = CredentialData.createCredentialData(
+                    mContext,
+                    docType,
+                    mCredentialName,
+                    CredentialData.getAliasFromCredentialName(mCredentialName),
+                    certificates,
+                    personalizationData,
+                    proofOfProvisioningSha256,
+                    true);
+            // Configure with same settings as old object.
+            //
+            mData.setAvailableAuthenticationKeys(authKeyCount, authMaxUsesPerKey);
+
+            return encodedBytes;
+
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("Error digesting ProofOfProvisioning", e);
+        }
+    }
+
 }
diff --git a/security/identity-credential/src/main/java/androidx/security/identity/SoftwareIdentityCredentialStore.java b/security/identity-credential/src/main/java/androidx/security/identity/SoftwareIdentityCredentialStore.java
index d261c06..9aff8dc 100644
--- a/security/identity-credential/src/main/java/androidx/security/identity/SoftwareIdentityCredentialStore.java
+++ b/security/identity-credential/src/main/java/androidx/security/identity/SoftwareIdentityCredentialStore.java
@@ -22,6 +22,9 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import java.util.LinkedHashSet;
+import java.util.Set;
+
 class SoftwareIdentityCredentialStore extends IdentityCredentialStore {
 
     private static final String TAG = "SoftwareIdentityCredentialStore";
@@ -32,23 +35,51 @@
         mContext = context;
     }
 
+    @SuppressWarnings("deprecation")
     public static @NonNull IdentityCredentialStore getInstance(@NonNull Context context) {
         return new SoftwareIdentityCredentialStore(context);
     }
 
+    @SuppressWarnings("deprecation")
     public static @NonNull IdentityCredentialStore getDirectAccessInstance(@NonNull
             Context context) {
         throw new RuntimeException("Direct-access IdentityCredential is not supported");
     }
 
+    @SuppressWarnings("deprecation")
     public static boolean isDirectAccessSupported(@NonNull Context context) {
         return false;
     }
 
+    @SuppressWarnings("deprecation")
     @Override
     public @NonNull String[] getSupportedDocTypes() {
-        // Any document type is supported.
-        return new String[0];
+        Set<String> docTypeSet = getCapabilities().getSupportedDocTypes();
+        String[] docTypes = new String[docTypeSet.size()];
+        int n = 0;
+        for (String docType : docTypeSet) {
+            docTypes[n++] = docType;
+        }
+        return docTypes;
+    }
+
+    SimpleIdentityCredentialStoreCapabilities mCapabilities = null;
+
+    @Override
+    public @NonNull
+    IdentityCredentialStoreCapabilities getCapabilities() {
+        if (mCapabilities == null) {
+            mCapabilities = new SimpleIdentityCredentialStoreCapabilities(
+                    false,
+                    IdentityCredentialStoreCapabilities.FEATURE_VERSION_202101,
+                    false,
+                    new LinkedHashSet<String>(),
+                    true,
+                    true,
+                    true,
+                    true);
+        }
+        return mCapabilities;
     }
 
     @Override
@@ -71,9 +102,9 @@
         return null;
     }
 
+    @SuppressWarnings("deprecation")
     @Override
     public @Nullable byte[] deleteCredentialByName(@NonNull String credentialName) {
         return SoftwareIdentityCredential.delete(mContext, credentialName);
     }
-
 }
diff --git a/security/identity-credential/src/main/java/androidx/security/identity/SoftwareWritableIdentityCredential.java b/security/identity-credential/src/main/java/androidx/security/identity/SoftwareWritableIdentityCredential.java
index 8c8b7be..06be98c 100644
--- a/security/identity-credential/src/main/java/androidx/security/identity/SoftwareWritableIdentityCredential.java
+++ b/security/identity-credential/src/main/java/androidx/security/identity/SoftwareWritableIdentityCredential.java
@@ -31,6 +31,7 @@
 import java.security.KeyPairGenerator;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
+import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.PrivateKey;
@@ -198,21 +199,30 @@
     @Override
     public byte[] personalize(@NonNull PersonalizationData personalizationData) {
 
-        ensureCredentialKey(null);
+        try {
+            ensureCredentialKey(null);
 
-        byte[] encodedBytes = buildProofOfProvisioningWithSignature(mDocType,
-                personalizationData,
-                mKeyPair.getPrivate());
+            byte[] encodedBytes = buildProofOfProvisioningWithSignature(mDocType,
+                    personalizationData,
+                    mKeyPair.getPrivate());
 
-        CredentialData.createCredentialData(
-                mContext,
-                mDocType,
-                mCredentialName,
-                CredentialData.getAliasFromCredentialName(mCredentialName),
-                mCertificates,
-                personalizationData);
+            byte[] proofOfProvisioning = Util.coseSign1GetData(encodedBytes);
+            byte[] proofOfProvisioningSha256 = MessageDigest.getInstance("SHA-256").digest(
+                    proofOfProvisioning);
 
-        return encodedBytes;
+            CredentialData.createCredentialData(
+                    mContext,
+                    mDocType,
+                    mCredentialName,
+                    CredentialData.getAliasFromCredentialName(mCredentialName),
+                    mCertificates,
+                    personalizationData,
+                    proofOfProvisioningSha256,
+                    false);
+
+            return encodedBytes;
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("Error digesting ProofOfProvisioning", e);
+        }
     }
-
 }
diff --git a/security/identity-credential/src/main/java/androidx/security/identity/Util.java b/security/identity-credential/src/main/java/androidx/security/identity/Util.java
index 4f656c3..4e90f88 100644
--- a/security/identity-credential/src/main/java/androidx/security/identity/Util.java
+++ b/security/identity-credential/src/main/java/androidx/security/identity/Util.java
@@ -26,6 +26,12 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -326,123 +332,54 @@
         return result;
     }
 
-    /*
-Certificate:
-    Data:
-        Version: 3 (0x2)
-        Serial Number: 1 (0x1)
-    Signature Algorithm: ecdsa-with-SHA256
-        Issuer: CN=fake
-        Validity
-            Not Before: Jan  1 00:00:00 1970 GMT
-            Not After : Jan  1 00:00:00 2048 GMT
-        Subject: CN=fake
-        Subject Public Key Info:
-            Public Key Algorithm: id-ecPublicKey
-                Public-Key: (256 bit)
-                00000000  04 9b 60 70 8a 99 b6 bf  e3 b8 17 02 9e 93 eb 48  |..`p...........H|
-                00000010  23 b9 39 89 d1 00 bf a0  0f d0 2f bd 6b 11 bc d1  |#.9......./.k...|
-                00000020  19 53 54 28 31 00 f5 49  db 31 fb 9f 7d 99 bf 23  |.ST(1..I.1..}..#|
-                00000030  fb 92 04 6b 23 63 55 98  ad 24 d2 68 c4 83 bf 99  |...k#cU..$.h....|
-                00000040  62                                                |b|
-    Signature Algorithm: ecdsa-with-SHA256
-         30:45:02:20:67:ad:d1:34:ed:a5:68:3f:5b:33:ee:b3:18:a2:
-         eb:03:61:74:0f:21:64:4a:a3:2e:82:b3:92:5c:21:0f:88:3f:
-         02:21:00:b7:38:5c:9b:f2:9c:b1:27:86:37:44:df:eb:4a:b2:
-         6c:11:9a:c1:ff:b2:80:95:ce:fc:5f:26:b4:20:6e:9b:0d
-     */
-
-
-    static @NonNull
-    X509Certificate signPublicKeyWithPrivateKey(String keyToSignAlias,
-            String keyToSignWithAlias) {
-
+    static @NonNull X509Certificate generateAuthenticationKeyCert(String authKeyAlias,
+            String credentialKeyAlias,
+            byte[] proofOfProvisioningSha256) {
         KeyStore ks = null;
         try {
             ks = KeyStore.getInstance("AndroidKeyStore");
             ks.load(null);
 
-            /* First note that KeyStore.getCertificate() returns a self-signed X.509 certificate
-             * for the key in question. As per RFC 5280, section 4.1 an X.509 certificate has the
-             * following structure:
-             *
-             *   Certificate  ::=  SEQUENCE  {
-             *        tbsCertificate       TBSCertificate,
-             *        signatureAlgorithm   AlgorithmIdentifier,
-             *        signatureValue       BIT STRING  }
-             *
-             * Conveniently, the X509Certificate class has a getTBSCertificate() method which
-             * returns the tbsCertificate blob. So all we need to do is just sign that and build
-             * signatureAlgorithm and signatureValue and combine it with tbsCertificate. We don't
-             * need a full-blown ASN.1/DER encoder to do this.
-             */
-            X509Certificate selfSignedCert = (X509Certificate) ks.getCertificate(keyToSignAlias);
-            byte[] tbsCertificate = selfSignedCert.getTBSCertificate();
+            //PublicKey publicKey = (PublicKey) ks.getKey(keyToSignAlias, null);
+            X509Certificate selfSignedCert = (X509Certificate) ks.getCertificate(authKeyAlias);
+            PublicKey publicKey = selfSignedCert.getPublicKey();
 
-            KeyStore.Entry keyToSignWithEntry = ks.getEntry(keyToSignWithAlias, null);
-            Signature s = Signature.getInstance("SHA256withECDSA");
-            s.initSign(((KeyStore.PrivateKeyEntry) keyToSignWithEntry).getPrivateKey());
-            s.update(tbsCertificate);
-            byte[] signatureValue = s.sign();
+            PrivateKey privateKey = ((KeyStore.PrivateKeyEntry) ks.getEntry(credentialKeyAlias,
+                    null)).getPrivateKey();
 
-            /* The DER encoding for a SEQUENCE of length 128-65536 - the length is updated below.
-             *
-             * We assume - and test for below - that the final length is always going to be in
-             * this range. This is a sound assumption given we're using 256-bit EC keys.
-             */
-            byte[] sequence = new byte[]{
-                    0x30, (byte) 0x82, 0x00, 0x00
-            };
+            X500Name issuer = new X500Name("CN=Android Identity Credential Key");
+            X500Name subject = new X500Name("CN=Android Identity Credential Authentication Key");
 
-            /* The DER encoding for the ECDSA with SHA-256 signature algorithm:
-             *
-             *   SEQUENCE (1 elem)
-             *      OBJECT IDENTIFIER 1.2.840.10045.4.3.2 ecdsaWithSHA256 (ANSI X9.62 ECDSA
-             *      algorithm with SHA256)
-             */
-            byte[] signatureAlgorithm = new byte[]{
-                    0x30, 0x0a, 0x06, 0x08, 0x2a, (byte) 0x86, 0x48, (byte) 0xce, 0x3d, 0x04, 0x03,
-                    0x02
-            };
+            Date now = new Date();
+            final long kMilliSecsInOneYear = 365L * 24 * 60 * 60 * 1000;
+            Date expirationDate = new Date(now.getTime() + kMilliSecsInOneYear);
+            BigInteger serial = new BigInteger("1");
+            JcaX509v3CertificateBuilder builder =
+                    new JcaX509v3CertificateBuilder(issuer,
+                            serial,
+                            now,
+                            expirationDate,
+                            subject,
+                            publicKey);
 
-            /* The DER encoding for a BIT STRING with one element - the length is updated below.
-             *
-             * We assume the length of signatureValue is always going to be less than 128. This
-             * assumption works since we know ecdsaWithSHA256 signatures are always 69, 70, or
-             * 71 bytes long when DER encoded.
-             */
-            byte[] bitStringForSignature = new byte[]{0x03, 0x00, 0x00};
-
-            // Calculate sequence length and set it in |sequence|.
-            int sequenceLength = tbsCertificate.length
-                    + signatureAlgorithm.length
-                    + bitStringForSignature.length
-                    + signatureValue.length;
-            if (sequenceLength < 128 || sequenceLength > 65535) {
-                throw new RuntimeException("Unexpected sequenceLength " + sequenceLength);
+            if (proofOfProvisioningSha256 != null) {
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                new CborEncoder(baos).encode(new CborBuilder()
+                        .addArray()
+                        .add("ProofOfBinding")
+                        .add(proofOfProvisioningSha256)
+                        .end()
+                        .build());
+                byte[] encodedProofOfBinding = baos.toByteArray();
+                builder.addExtension(new ASN1ObjectIdentifier("1.3.6.1.4.1.11129.2.1.26"), false,
+                        encodedProofOfBinding);
             }
-            sequence[2] = (byte) (sequenceLength >> 8);
-            sequence[3] = (byte) (sequenceLength & 0xff);
 
-            // Calculate signatureValue length and set it in |bitStringForSignature|.
-            int signatureValueLength = signatureValue.length + 1;
-            if (signatureValueLength >= 128) {
-                throw new RuntimeException(
-                        "Unexpected signatureValueLength " + signatureValueLength);
-            }
-            bitStringForSignature[1] = (byte) signatureValueLength;
-
-            // Finally concatenate everything together.
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            baos.write(sequence);
-            baos.write(tbsCertificate);
-            baos.write(signatureAlgorithm);
-            baos.write(bitStringForSignature);
-            baos.write(signatureValue);
-            byte[] resultingCertBytes = baos.toByteArray();
+            ContentSigner signer = new JcaContentSignerBuilder("SHA256withECDSA").build(privateKey);
+            byte[] encodedCert = builder.build(signer).getEncoded();
 
             CertificateFactory cf = CertificateFactory.getInstance("X.509");
-            ByteArrayInputStream bais = new ByteArrayInputStream(resultingCertBytes);
+            ByteArrayInputStream bais = new ByteArrayInputStream(encodedCert);
             X509Certificate result = (X509Certificate) cf.generateCertificate(bais);
             return result;
         } catch (Exception e) {
@@ -983,7 +920,7 @@
             throw new RuntimeException("Expected at least four items in COSE_Sign1 array");
         }
         if (items.get(1).getMajorType() != MajorType.MAP) {
-            throw new RuntimeException("Item 1 (unprocted headers) is not a map");
+            throw new RuntimeException("Item 1 (unprotected headers) is not a map");
         }
         co.nstant.in.cbor.model.Map map = (co.nstant.in.cbor.model.Map) items.get(1);
         DataItem x5chainItem = map.get(new UnsignedInteger(COSE_LABEL_X5CHAIN));
@@ -1009,5 +946,4 @@
         }
         return ret;
     }
-
 }
diff --git a/serialization/serialization-runtime/src/main/java/androidx/serialization/runtime/internal/SerializationRuntime.java b/serialization/serialization-runtime/src/main/java/androidx/serialization/runtime/internal/SerializationRuntime.java
index 53b0cc3..d0498ce 100644
--- a/serialization/serialization-runtime/src/main/java/androidx/serialization/runtime/internal/SerializationRuntime.java
+++ b/serialization/serialization-runtime/src/main/java/androidx/serialization/runtime/internal/SerializationRuntime.java
@@ -37,6 +37,7 @@
             new CollectionFactory<List<?>>() {
                 @NonNull
                 @Override
+                @SuppressWarnings("MixedMutabilityReturnType")
                 public List<?> create(int capacity) {
                     if (capacity == 0) {
                         return Collections.emptyList();
@@ -50,6 +51,7 @@
             new CollectionFactory<Set<?>>() {
                 @NonNull
                 @Override
+                @SuppressWarnings("MixedMutabilityReturnType")
                 public Set<?> create(int capacity) {
                     if (capacity == 0) {
                         return Collections.emptySet();
diff --git a/settings.gradle b/settings.gradle
index d133174..d2fd728 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -26,7 +26,8 @@
     MAIN,
     COMPOSE,
     FLAN,
-    MEDIA
+    MEDIA,
+    WEAR,
 }
 
 private static Set<BuildType> createRequestedFilter() {
@@ -46,6 +47,8 @@
                 break
             case "MEDIA":
                 filter.add(BuildType.MEDIA)
+            case "WEAR":
+                filter.add(BuildType.WEAR)
                 break
             case "ALL":
                 // Return null so that no filtering is done
@@ -58,7 +61,8 @@
                         "COMPOSE - compose projects\n" +
                         "MAIN    - androidx projects that are not compose\n" +
                         "FLAN    - fragment, lifecycle, activity, and navigation projects\n" +
-                        "MEDIA   - media, media2, and mediarouter projects")
+                        "MEDIA   - media, media2, and mediarouter projects\n" +
+                        "WEAR    - Wear OS projects")
         }
     }
     return filter
@@ -120,12 +124,12 @@
 //
 /////////////////////////////
 
-includeProject(":activity:activity", "activity/activity", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE])
+includeProject(":activity:activity", "activity/activity", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE, BuildType.WEAR])
 includeProject(":activity:activity-compose", "activity/activity-compose", [BuildType.COMPOSE])
 includeProject(":activity:activity-compose:activity-compose-samples", "activity/activity-compose/samples", [BuildType.COMPOSE])
 includeProject(":activity:activity-compose:integration-tests:activity-demos", "activity/activity-compose/integration-tests/activity-demos", [BuildType.COMPOSE])
 includeProject(":activity:activity-ktx", "activity/activity-ktx", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE])
-includeProject(":activity:activity-lint", "activity/activity-lint", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE])
+includeProject(":activity:activity-lint", "activity/activity-lint", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE, BuildType.WEAR])
 includeProject(":activity:integration-tests:testapp", "activity/integration-tests/testapp", [BuildType.MAIN])
 includeProject(":ads-identifier", "ads/ads-identifier", [BuildType.MAIN])
 includeProject(":ads-identifier-benchmark", "ads/ads-identifier-benchmark", [BuildType.MAIN])
@@ -216,6 +220,7 @@
 includeProject(":compose:compiler:compiler", "compose/compiler/compiler", [BuildType.COMPOSE])
 includeProject(":compose:compiler:compiler-hosted", "compose/compiler/compiler-hosted", [BuildType.COMPOSE])
 includeProject(":compose:compiler:compiler-hosted:integration-tests", "compose/compiler/compiler-hosted/integration-tests", [BuildType.COMPOSE])
+includeProject(":compose:compiler:compiler-hosted:integration-tests:kotlin-compiler-repackaged", "compose/compiler/compiler-hosted/integration-tests/kotlin-compiler-repackaged", [BuildType.COMPOSE])
 if (isMultiplatformEnabled()) {
     includeProject(":compose:desktop", "compose/desktop", [BuildType.COMPOSE])
     includeProject(":compose:desktop:desktop", "compose/desktop/desktop", [BuildType.COMPOSE])
@@ -323,9 +328,9 @@
 includeProject(":enterprise-feedback-testing", "enterprise/feedback/testing", [BuildType.MAIN])
 includeProject(":exifinterface:exifinterface", "exifinterface/exifinterface", [BuildType.MAIN])
 includeProject(":fakeannotations", "fakeannotations", [BuildType.MAIN])
-includeProject(":fragment:fragment", "fragment/fragment", [BuildType.MAIN, BuildType.FLAN])
+includeProject(":fragment:fragment", "fragment/fragment", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR])
 includeProject(":fragment:fragment-ktx", "fragment/fragment-ktx", [BuildType.MAIN, BuildType.FLAN])
-includeProject(":fragment:fragment-lint", "fragment/fragment-lint", [BuildType.MAIN, BuildType.FLAN])
+includeProject(":fragment:fragment-lint", "fragment/fragment-lint", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR])
 includeProject(":fragment:fragment-testing", "fragment/fragment-testing", [BuildType.MAIN, BuildType.FLAN])
 includeProject(":fragment:fragment-testing-lint", "fragment/fragment-testing-lint", [BuildType.MAIN, BuildType.FLAN])
 includeProject(":fragment:fragment-truth", "fragment/fragment-truth", [BuildType.MAIN, BuildType.FLAN])
@@ -358,12 +363,12 @@
 includeProject(":lifecycle:integration-tests:incrementality", "lifecycle/integration-tests/incrementality", [BuildType.MAIN, BuildType.FLAN])
 includeProject(":lifecycle:integration-tests:lifecycle-testapp", "lifecycle/integration-tests/testapp", [BuildType.MAIN, BuildType.FLAN])
 includeProject(":lifecycle:integration-tests:lifecycle-testapp-kotlin", "lifecycle/integration-tests/kotlintestapp", [BuildType.MAIN, BuildType.FLAN])
-includeProject(":lifecycle:lifecycle-common", "lifecycle/lifecycle-common", [BuildType.MAIN, BuildType.FLAN])
+includeProject(":lifecycle:lifecycle-common", "lifecycle/lifecycle-common", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR])
 includeProject(":lifecycle:lifecycle-common-java8", "lifecycle/lifecycle-common-java8", [BuildType.MAIN, BuildType.FLAN])
 includeProject(":lifecycle:lifecycle-compiler", "lifecycle/lifecycle-compiler", [BuildType.MAIN, BuildType.FLAN])
 includeProject(":lifecycle:lifecycle-extensions", "lifecycle/lifecycle-extensions", [BuildType.MAIN, BuildType.FLAN])
 includeProject(":lifecycle:lifecycle-livedata", "lifecycle/lifecycle-livedata", [BuildType.MAIN, BuildType.FLAN])
-includeProject(":lifecycle:lifecycle-livedata-core", "lifecycle/lifecycle-livedata-core", [BuildType.MAIN, BuildType.FLAN])
+includeProject(":lifecycle:lifecycle-livedata-core", "lifecycle/lifecycle-livedata-core", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR])
 includeProject(":lifecycle:lifecycle-livedata-core-ktx", "lifecycle/lifecycle-livedata-core-ktx", [BuildType.MAIN, BuildType.FLAN])
 includeProject(":lifecycle:lifecycle-livedata-core-ktx-lint", "lifecycle/lifecycle-livedata-core-ktx-lint", [BuildType.MAIN, BuildType.FLAN])
 includeProject(":lifecycle:lifecycle-livedata-core-truth", "lifecycle/lifecycle-livedata-core-truth", [BuildType.MAIN, BuildType.FLAN])
@@ -371,18 +376,19 @@
 includeProject(":lifecycle:lifecycle-process", "lifecycle/lifecycle-process", [BuildType.MAIN, BuildType.FLAN])
 includeProject(":lifecycle:lifecycle-reactivestreams", "lifecycle/lifecycle-reactivestreams", [BuildType.MAIN, BuildType.FLAN])
 includeProject(":lifecycle:lifecycle-reactivestreams-ktx", "lifecycle/lifecycle-reactivestreams-ktx", [BuildType.MAIN, BuildType.FLAN])
-includeProject(":lifecycle:lifecycle-runtime", "lifecycle/lifecycle-runtime", [BuildType.MAIN, BuildType.FLAN])
-includeProject(":lifecycle:lifecycle-runtime-ktx", "lifecycle/lifecycle-runtime-ktx", [BuildType.MAIN, BuildType.FLAN])
-includeProject(":lifecycle:lifecycle-runtime-ktx-lint", "lifecycle/lifecycle-runtime-ktx-lint", [BuildType.MAIN, BuildType.FLAN])
-includeProject(":lifecycle:lifecycle-runtime-testing", "lifecycle/lifecycle-runtime-testing", [BuildType.MAIN, BuildType.FLAN])
+includeProject(":lifecycle:lifecycle-runtime", "lifecycle/lifecycle-runtime", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR])
+includeProject(":lifecycle:lifecycle-runtime-ktx", "lifecycle/lifecycle-runtime-ktx", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR])
+includeProject(":lifecycle:lifecycle-runtime-ktx-lint", "lifecycle/lifecycle-runtime-ktx-lint", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR])
+includeProject(":lifecycle:lifecycle-runtime-testing", "lifecycle/lifecycle-runtime-testing", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR])
 includeProject(":lifecycle:lifecycle-service", "lifecycle/lifecycle-service", [BuildType.MAIN, BuildType.FLAN])
-includeProject(":lifecycle:lifecycle-viewmodel", "lifecycle/lifecycle-viewmodel", [BuildType.MAIN, BuildType.FLAN])
+includeProject(":lifecycle:lifecycle-viewmodel", "lifecycle/lifecycle-viewmodel", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR])
 includeProject(":lifecycle:lifecycle-viewmodel-compose", "lifecycle/lifecycle-viewmodel-compose", [BuildType.COMPOSE])
 includeProject(":lifecycle:lifecycle-viewmodel-compose:lifecycle-viewmodel-compose-samples", "lifecycle/lifecycle-viewmodel-compose/samples", [BuildType.COMPOSE])
 includeProject(":lifecycle:lifecycle-viewmodel-compose:integration-tests:lifecycle-viewmodel-demos", "lifecycle/lifecycle-viewmodel-compose/integration-tests/lifecycle-viewmodel-demos", [BuildType.COMPOSE])
 includeProject(":lifecycle:lifecycle-viewmodel-ktx", "lifecycle/lifecycle-viewmodel-ktx", [BuildType.MAIN, BuildType.FLAN])
-includeProject(":lifecycle:lifecycle-viewmodel-savedstate", "lifecycle/lifecycle-viewmodel-savedstate", [BuildType.MAIN, BuildType.FLAN])
+includeProject(":lifecycle:lifecycle-viewmodel-savedstate", "lifecycle/lifecycle-viewmodel-savedstate", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR])
 includeProject(":lint-checks", "lint-checks")
+includeProject(":lint-checks:integration-tests", "lint-checks/integration-tests", [BuildType.COMPOSE])
 includeProject(":lint-checks:tests", "lint-checks/tests", [BuildType.MAIN])
 includeProject(":lint-demos:lint-demo-appcompat", "lint-demos/lint-demo-appcompat", [BuildType.MAIN])
 includeProject(":loader:loader", "loader/loader", [BuildType.MAIN])
@@ -461,7 +467,7 @@
 includeProject(":room:room-rxjava2", "room/rxjava2", [BuildType.MAIN])
 includeProject(":room:room-rxjava3", "room/rxjava3", [BuildType.MAIN])
 includeProject(":room:room-testing", "room/testing", [BuildType.MAIN])
-includeProject(":savedstate:savedstate", "savedstate/savedstate", [BuildType.MAIN, BuildType.FLAN])
+includeProject(":savedstate:savedstate", "savedstate/savedstate", [BuildType.MAIN, BuildType.FLAN, BuildType.WEAR])
 includeProject(":savedstate:savedstate-ktx", "savedstate/savedstate-ktx", [BuildType.MAIN, BuildType.FLAN])
 includeProject(":security:security-app-authenticator", "security/security-app-authenticator", [BuildType.MAIN])
 includeProject(":security:security-biometric", "security/security-biometric", [BuildType.MAIN])
@@ -514,35 +520,34 @@
 includeProject(":vectordrawable:vectordrawable-animated", "vectordrawable/vectordrawable-animated", [BuildType.MAIN])
 includeProject(":vectordrawable:vectordrawable-seekable", "vectordrawable/vectordrawable-seekable", [BuildType.MAIN])
 includeProject(":versionedparcelable:versionedparcelable", "versionedparcelable/versionedparcelable", [BuildType.MAIN])
-includeProject(":versionedparcelable:versionedparcelable-compiler", "versionedparcelable/versionedparcelable-compiler", [BuildType.MAIN, BuildType.MEDIA])
+includeProject(":versionedparcelable:versionedparcelable-compiler", "versionedparcelable/versionedparcelable-compiler", [BuildType.MAIN, BuildType.MEDIA, BuildType.WEAR])
 includeProject(":viewpager2:integration-tests:testapp", "viewpager2/integration-tests/testapp", [BuildType.MAIN])
 includeProject(":viewpager2:viewpager2", "viewpager2/viewpager2", [BuildType.MAIN])
 includeProject(":viewpager:viewpager", "viewpager/viewpager", [BuildType.MAIN])
-includeProject(":wear:wear", "wear/wear", [BuildType.MAIN])
-includeProject(":wear:wear-complications-data", "wear/wear-complications-data", [BuildType.MAIN])
-includeProject(":wear:wear-complications-provider", "wear/wear-complications-provider", [BuildType.MAIN])
-includeProject(":wear:wear-complications-provider-samples", "wear/wear-complications-provider/samples", [BuildType.MAIN])
-includeProject(":wear:wear-input", "wear/wear-input", [BuildType.MAIN])
-includeProject(":wear:wear-input-testing", "wear/wear-input-testing", [BuildType.MAIN])
-includeProject(":wear:wear-ongoing", "wear/wear-ongoing", [BuildType.MAIN])
-includeProject(":wear:wear-phone-interactions", "wear/wear-phone-interactions", [BuildType.MAIN])
-includeProject(":wear:wear-remote-interactions", "wear/wear-remote-interactions", [BuildType.MAIN])
-includeProject(":wear:wear-tiles", "wear/wear-tiles", [BuildType.MAIN])
-includeProject(":wear:wear-tiles:wear-tiles-proto", "wear/wear-tiles/wear-tiles-proto",
-        [BuildType.MAIN])
-includeProject(":wear:wear-tiles-data", "wear/wear-tiles-data", [BuildType.MAIN])
-includeProject(":wear:wear-tiles-renderer", "wear/wear-tiles-renderer", [BuildType.MAIN])
-includeProject(":wear:wear-watchface", "wear/wear-watchface", [BuildType.MAIN])
-includeProject(":wear:wear-watchface-complications-rendering", "wear/wear-watchface-complications-rendering", [BuildType.MAIN])
-includeProject(":wear:wear-watchface-client", "wear/wear-watchface-client", [BuildType.MAIN])
-includeProject(":wear:wear-watchface-client-guava", "wear/wear-watchface-client/guava", [BuildType.MAIN])
-includeProject(":wear:wear-watchface-data", "wear/wear-watchface-data", [BuildType.MAIN])
-includeProject(":wear:wear-watchface-editor", "wear/wear-watchface-editor", [BuildType.MAIN])
-includeProject(":wear:wear-watchface-editor-guava", "wear/wear-watchface-editor/guava", [BuildType.MAIN])
-includeProject(":wear:wear-watchface-editor-samples", "wear/wear-watchface-editor/samples", [BuildType.MAIN])
-includeProject(":wear:wear-watchface-guava", "wear/wear-watchface/guava", [BuildType.MAIN])
-includeProject(":wear:wear-watchface-samples", "wear/wear-watchface/samples", [BuildType.MAIN])
-includeProject(":wear:wear-watchface-style", "wear/wear-watchface-style", [BuildType.MAIN])
+includeProject(":wear:wear", "wear/wear", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-complications-data", "wear/wear-complications-data", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-complications-provider", "wear/wear-complications-provider", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-complications-provider-samples", "wear/wear-complications-provider/samples", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-input", "wear/wear-input", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-input-testing", "wear/wear-input-testing", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-ongoing", "wear/wear-ongoing", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-phone-interactions", "wear/wear-phone-interactions", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-remote-interactions", "wear/wear-remote-interactions", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-tiles", "wear/wear-tiles", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-tiles:wear-tiles-proto", "wear/wear-tiles/wear-tiles-proto", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-tiles-data", "wear/wear-tiles-data", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-tiles-renderer", "wear/wear-tiles-renderer", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-watchface", "wear/wear-watchface", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-watchface-complications-rendering", "wear/wear-watchface-complications-rendering", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-watchface-client", "wear/wear-watchface-client", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-watchface-client-guava", "wear/wear-watchface-client/guava", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-watchface-data", "wear/wear-watchface-data", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-watchface-editor", "wear/wear-watchface-editor", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-watchface-editor-guava", "wear/wear-watchface-editor/guava", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-watchface-editor-samples", "wear/wear-watchface-editor/samples", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-watchface-guava", "wear/wear-watchface/guava", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-watchface-samples", "wear/wear-watchface/samples", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-watchface-style", "wear/wear-watchface-style", [BuildType.MAIN, BuildType.WEAR])
 includeProject(":webkit:integration-tests:testapp", "webkit/integration-tests/testapp", [BuildType.MAIN])
 includeProject(":webkit:webkit", "webkit/webkit", [BuildType.MAIN])
 includeProject(":window:window", "window/window", [BuildType.MAIN])
@@ -598,7 +603,7 @@
 /////////////////////////////
 
 includeProject(":internal-testutils-common", "testutils/testutils-common", [BuildType.MAIN, BuildType.COMPOSE])
-includeProject(":internal-testutils-runtime", "testutils/testutils-runtime", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE, BuildType.MEDIA])
+includeProject(":internal-testutils-runtime", "testutils/testutils-runtime", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE, BuildType.MEDIA, BuildType.WEAR])
 includeProject(":internal-testutils-appcompat", "testutils/testutils-appcompat", [BuildType.MAIN])
 includeProject(":internal-testutils-espresso", "testutils/testutils-espresso", [BuildType.MAIN])
 includeProject(":internal-testutils-truth", "testutils/testutils-truth", [BuildType.MAIN, BuildType.FLAN])
diff --git a/slices/core/src/main/java/androidx/slice/compat/SliceProviderCompat.java b/slices/core/src/main/java/androidx/slice/compat/SliceProviderCompat.java
index f8f0f32..6da7d06 100644
--- a/slices/core/src/main/java/androidx/slice/compat/SliceProviderCompat.java
+++ b/slices/core/src/main/java/androidx/slice/compat/SliceProviderCompat.java
@@ -595,6 +595,7 @@
      * Compat version of {@link android.app.slice.SliceManager#getSliceDescendants(Uri)}
      */
     @NonNull
+    @SuppressWarnings("MixedMutabilityReturnType")
     public static Collection<Uri> getSliceDescendants(@NonNull Context context, @NonNull Uri uri) {
         ContentResolver resolver = context.getContentResolver();
         try (ProviderHolder holder = acquireClient(resolver, uri)) {
diff --git a/slices/view/src/main/java/androidx/slice/widget/ActionRow.java b/slices/view/src/main/java/androidx/slice/widget/ActionRow.java
index 9406fc4..efd9763 100644
--- a/slices/view/src/main/java/androidx/slice/widget/ActionRow.java
+++ b/slices/view/src/main/java/androidx/slice/widget/ActionRow.java
@@ -136,6 +136,7 @@
                     addAction(iconItem, tint).setOnClickListener(
                             new OnClickListener() {
                                 @Override
+                                @SuppressWarnings("CatchAndPrintStackTrace")
                                 public void onClick(View v) {
                                     try {
                                         // TODO - should log events here
diff --git a/studiow b/studiow
index 6ba0f23..485d33d 100755
--- a/studiow
+++ b/studiow
@@ -23,6 +23,9 @@
   echo " media"
   echo "  Open the project subset media: Media, Media2, and MediaRouter"
   echo
+  echo " w, wear"
+  echo "  Open the project subset for Wear OS libraries"
+  echo
   echo " a, all"
   echo "  Open the project subset all"
   echo
@@ -63,6 +66,9 @@
   if [ "$subsetArg" == "media" ]; then
     newSubset=media
   fi
+  if [ "$subsetArg" == "w" -o "$subsetArg" == "wear" ]; then
+    newSubset=wear
+  fi
   if [ "$subsetArg" == "a" -o "$subsetArg" == "all" ]; then
     newSubset=all
   fi
diff --git a/transition/transition/src/main/java/androidx/transition/ViewOverlayApi14.java b/transition/transition/src/main/java/androidx/transition/ViewOverlayApi14.java
index deade72..b52631a 100644
--- a/transition/transition/src/main/java/androidx/transition/ViewOverlayApi14.java
+++ b/transition/transition/src/main/java/androidx/transition/ViewOverlayApi14.java
@@ -281,6 +281,7 @@
          * @hide
          */
         @RestrictTo(LIBRARY_GROUP_PREFIX)
+        @SuppressWarnings("CatchAndPrintStackTrace")
         protected ViewParent invalidateChildInParentFast(int left, int top, Rect dirty) {
             if (mHostView != null && sInvalidateChildInParentFastMethod != null) {
                 try {
diff --git a/tv-provider/tv-provider/src/main/java/androidx/tvprovider/media/tv/PreviewChannelHelper.java b/tv-provider/tv-provider/src/main/java/androidx/tvprovider/media/tv/PreviewChannelHelper.java
index 540ec01..9926df9 100644
--- a/tv-provider/tv-provider/src/main/java/androidx/tvprovider/media/tv/PreviewChannelHelper.java
+++ b/tv-provider/tv-provider/src/main/java/androidx/tvprovider/media/tv/PreviewChannelHelper.java
@@ -188,6 +188,7 @@
      * {@link #getPreviewChannel(long) single PreviewChannel by id}, you must get all of
      * your channels at once and then use the returned list as necessary.
      */
+    @SuppressWarnings("MixedMutabilityReturnType")
     public List<PreviewChannel> getAllChannels() {
 
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
diff --git a/wear/wear-watchface-editor/api/current.txt b/wear/wear-watchface-editor/api/current.txt
index b7b2db0..daadcc5 100644
--- a/wear/wear-watchface-editor/api/current.txt
+++ b/wear/wear-watchface-editor/api/current.txt
@@ -2,13 +2,13 @@
 package androidx.wear.watchface.editor {
 
   public final class EditorRequest {
-    ctor public EditorRequest(android.content.ComponentName watchFaceComponentName, android.content.ComponentName editorComponentName, String? watchFaceInstanceId, java.util.Map<java.lang.String,java.lang.String>? initialUserStyle);
+    ctor public EditorRequest(android.content.ComponentName watchFaceComponentName, String editorPackageName, String? watchFaceInstanceId, java.util.Map<java.lang.String,java.lang.String>? initialUserStyle);
     method public static androidx.wear.watchface.editor.EditorRequest? createFromIntent(android.content.Intent intent);
-    method public android.content.ComponentName getEditorComponentName();
+    method public String getEditorPackageName();
     method public java.util.Map<java.lang.String,java.lang.String>? getInitialUserStyle();
     method public android.content.ComponentName getWatchFaceComponentName();
     method public String? getWatchFaceInstanceId();
-    property public final android.content.ComponentName editorComponentName;
+    property public final String editorPackageName;
     property public final java.util.Map<java.lang.String,java.lang.String>? initialUserStyle;
     property public final android.content.ComponentName watchFaceComponentName;
     property public final String? watchFaceInstanceId;
diff --git a/wear/wear-watchface-editor/api/public_plus_experimental_current.txt b/wear/wear-watchface-editor/api/public_plus_experimental_current.txt
index b7b2db0..daadcc5 100644
--- a/wear/wear-watchface-editor/api/public_plus_experimental_current.txt
+++ b/wear/wear-watchface-editor/api/public_plus_experimental_current.txt
@@ -2,13 +2,13 @@
 package androidx.wear.watchface.editor {
 
   public final class EditorRequest {
-    ctor public EditorRequest(android.content.ComponentName watchFaceComponentName, android.content.ComponentName editorComponentName, String? watchFaceInstanceId, java.util.Map<java.lang.String,java.lang.String>? initialUserStyle);
+    ctor public EditorRequest(android.content.ComponentName watchFaceComponentName, String editorPackageName, String? watchFaceInstanceId, java.util.Map<java.lang.String,java.lang.String>? initialUserStyle);
     method public static androidx.wear.watchface.editor.EditorRequest? createFromIntent(android.content.Intent intent);
-    method public android.content.ComponentName getEditorComponentName();
+    method public String getEditorPackageName();
     method public java.util.Map<java.lang.String,java.lang.String>? getInitialUserStyle();
     method public android.content.ComponentName getWatchFaceComponentName();
     method public String? getWatchFaceInstanceId();
-    property public final android.content.ComponentName editorComponentName;
+    property public final String editorPackageName;
     property public final java.util.Map<java.lang.String,java.lang.String>? initialUserStyle;
     property public final android.content.ComponentName watchFaceComponentName;
     property public final String? watchFaceInstanceId;
diff --git a/wear/wear-watchface-editor/api/restricted_current.txt b/wear/wear-watchface-editor/api/restricted_current.txt
index 3213be4..9e49d3e4 100644
--- a/wear/wear-watchface-editor/api/restricted_current.txt
+++ b/wear/wear-watchface-editor/api/restricted_current.txt
@@ -19,13 +19,13 @@
   }
 
   public final class EditorRequest {
-    ctor public EditorRequest(android.content.ComponentName watchFaceComponentName, android.content.ComponentName editorComponentName, String? watchFaceInstanceId, java.util.Map<java.lang.String,java.lang.String>? initialUserStyle);
+    ctor public EditorRequest(android.content.ComponentName watchFaceComponentName, String editorPackageName, String? watchFaceInstanceId, java.util.Map<java.lang.String,java.lang.String>? initialUserStyle);
     method public static androidx.wear.watchface.editor.EditorRequest? createFromIntent(android.content.Intent intent);
-    method public android.content.ComponentName getEditorComponentName();
+    method public String getEditorPackageName();
     method public java.util.Map<java.lang.String,java.lang.String>? getInitialUserStyle();
     method public android.content.ComponentName getWatchFaceComponentName();
     method public String? getWatchFaceInstanceId();
-    property public final android.content.ComponentName editorComponentName;
+    property public final String editorPackageName;
     property public final java.util.Map<java.lang.String,java.lang.String>? initialUserStyle;
     property public final android.content.ComponentName watchFaceComponentName;
     property public final String? watchFaceInstanceId;
diff --git a/wear/wear-watchface-editor/build.gradle b/wear/wear-watchface-editor/build.gradle
index e74dc4f..e80c798 100644
--- a/wear/wear-watchface-editor/build.gradle
+++ b/wear/wear-watchface-editor/build.gradle
@@ -29,7 +29,7 @@
 dependencies {
     api("androidx.annotation:annotation:1.1.0")
     api("androidx.versionedparcelable:versionedparcelable:1.1.0")
-    api("androidx.activity:activity:1.2.0-rc01")
+    api("androidx.activity:activity:1.2.0")
     api(project(":wear:wear-watchface-client"))
     api(project(":wear:wear-watchface-data"))
     api(KOTLIN_STDLIB)
diff --git a/wear/wear-watchface-editor/samples/build.gradle b/wear/wear-watchface-editor/samples/build.gradle
index edf9e8e..6ae54c5 100644
--- a/wear/wear-watchface-editor/samples/build.gradle
+++ b/wear/wear-watchface-editor/samples/build.gradle
@@ -28,7 +28,7 @@
 
 dependencies {
     compileOnly(project(":annotation:annotation-sampled"))
-    api("androidx.fragment:fragment:1.3.0-alpha05")
+    api("androidx.fragment:fragment:1.3.0")
     implementation("androidx.wear:wear:1.1.0-rc01")
     api(project(":wear:wear-watchface-editor"))
     api(KOTLIN_STDLIB)
diff --git a/wear/wear-watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditingSessionTest.kt b/wear/wear-watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditingSessionTest.kt
index 11ec1bf..4c97c61 100644
--- a/wear/wear-watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditingSessionTest.kt
+++ b/wear/wear-watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditingSessionTest.kt
@@ -226,7 +226,7 @@
 @MediumTest
 public class EditorSessionTest {
     private val testComponentName = ComponentName("test.package", "test.class")
-    private val testEditorComponentName = ComponentName("test.package", "test.editor.class")
+    private val testEditorPackageName = "test.package"
     private val testInstanceId = "TEST_INSTANCE_ID"
     private var editorDelegate = Mockito.mock(WatchFace.EditorDelegate::class.java)
     private val screenBounds = Rect(0, 0, 400, 400)
@@ -350,7 +350,7 @@
         return ActivityScenario.launch(
             WatchFaceEditorContractForTest().createIntent(
                 ApplicationProvider.getApplicationContext<Context>(),
-                EditorRequest(testComponentName, testEditorComponentName, instanceId, null)
+                EditorRequest(testComponentName, testEditorPackageName, instanceId, null)
             ).apply {
                 component = ComponentName(
                     ApplicationProvider.getApplicationContext<Context>(),
@@ -916,12 +916,12 @@
         runBlocking {
             val intent = WatchFaceEditorContract().createIntent(
                 ApplicationProvider.getApplicationContext<Context>(),
-                EditorRequest(testComponentName, testEditorComponentName, testInstanceId, null)
+                EditorRequest(testComponentName, testEditorPackageName, testInstanceId, null)
             )
-            assertThat(intent.component).isEqualTo(testEditorComponentName)
+            assertThat(intent.getPackage()).isEqualTo(testEditorPackageName)
 
             val editorRequest = EditorRequest.createFromIntent(intent)!!
-            assertThat(editorRequest.editorComponentName).isEqualTo(testEditorComponentName)
+            assertThat(editorRequest.editorPackageName).isEqualTo(testEditorPackageName)
             assertThat(editorRequest.initialUserStyle).isNull()
             assertThat(editorRequest.watchFaceComponentName).isEqualTo(testComponentName)
             assertThat(editorRequest.watchFaceInstanceId).isEqualTo(testInstanceId)
diff --git a/wear/wear-watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditorSessionGuavaTest.kt b/wear/wear-watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditorSessionGuavaTest.kt
index ea8b0dd..db4bbf4 100644
--- a/wear/wear-watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditorSessionGuavaTest.kt
+++ b/wear/wear-watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditorSessionGuavaTest.kt
@@ -51,7 +51,7 @@
 @MediumTest
 public class EditorSessionGuavaTest {
     private val testComponentName = ComponentName("test.package", "test.class")
-    private val testEditorComponentName = ComponentName("test.package", "test.editor.class")
+    private val testEditorPackageName = "test.package"
     private val testInstanceId = "TEST_INSTANCE_ID"
     private var editorDelegate = Mockito.mock(WatchFace.EditorDelegate::class.java)
     private val screenBounds = Rect(0, 0, 400, 400)
@@ -109,7 +109,7 @@
         return ActivityScenario.launch(
             WatchFaceEditorContractForTest().createIntent(
                 ApplicationProvider.getApplicationContext<Context>(),
-                EditorRequest(testComponentName, testEditorComponentName, instanceId, null)
+                EditorRequest(testComponentName, testEditorPackageName, instanceId, null)
             ).apply {
                 component = ComponentName(
                     ApplicationProvider.getApplicationContext<Context>(),
diff --git a/wear/wear-watchface-editor/src/main/java/androidx/wear/watchface/editor/EditorSession.kt b/wear/wear-watchface-editor/src/main/java/androidx/wear/watchface/editor/EditorSession.kt
index 3d8a39b..7e079c9 100644
--- a/wear/wear-watchface-editor/src/main/java/androidx/wear/watchface/editor/EditorSession.kt
+++ b/wear/wear-watchface-editor/src/main/java/androidx/wear/watchface/editor/EditorSession.kt
@@ -439,7 +439,7 @@
                 it.value.defaultProviderPolicy,
                 it.value.defaultProviderType,
                 it.value.enabled,
-                it.value.renderer.idAndData?.complicationData?.type
+                it.value.renderer.getIdAndData()?.complicationData?.type
                     ?: ComplicationType.NO_DATA,
                 it.value.fixedComplicationProvider
             )
diff --git a/wear/wear-watchface-editor/src/main/java/androidx/wear/watchface/editor/WatchFaceEditorContract.kt b/wear/wear-watchface-editor/src/main/java/androidx/wear/watchface/editor/WatchFaceEditorContract.kt
index b6ae3a6..50792d7 100644
--- a/wear/wear-watchface-editor/src/main/java/androidx/wear/watchface/editor/WatchFaceEditorContract.kt
+++ b/wear/wear-watchface-editor/src/main/java/androidx/wear/watchface/editor/WatchFaceEditorContract.kt
@@ -33,16 +33,13 @@
 internal const val USER_STYLE_KEY: String = "USER_STYLE_KEY"
 internal const val USER_STYLE_VALUES: String = "USER_STYLE_VALUES"
 
-/**
- * The request sent by [WatchFaceEditorContract.createIntent]. The editing session's result should
- * be reported via [Activity.setWatchRequestResult].
- */
+/** The request sent by [WatchFaceEditorContract.createIntent]. */
 public class EditorRequest(
     /** The [ComponentName] of the watch face being edited. */
     public val watchFaceComponentName: ComponentName,
 
-    /** The [ComponentName] of the watch face editor. */
-    public val editorComponentName: ComponentName,
+    /** The package name of the watch face editor APK. */
+    public val editorPackageName: String,
 
     /**
      * Unique ID for the instance of the watch face being edited, only defined for Android R and
@@ -64,7 +61,7 @@
             val componentName =
                 intent.getParcelableExtra<ComponentName>(COMPONENT_NAME_KEY)
                     ?: intent.getParcelableExtra(Constants.EXTRA_WATCH_FACE_COMPONENT)
-            val editorComponentName = intent.component ?: ComponentName("?", "?")
+            val editorPackageName = intent.getPackage() ?: ""
             val instanceId = intent.getStringExtra(INSTANCE_ID_KEY)
             val userStyleKey = intent.getStringArrayExtra(USER_STYLE_KEY)
             val userStyleValue = intent.getStringArrayExtra(USER_STYLE_VALUES)
@@ -74,7 +71,7 @@
                 ) {
                     EditorRequest(
                         componentName,
-                        editorComponentName,
+                        editorPackageName,
                         instanceId,
                         HashMap<String, String>().apply {
                             for (i in userStyleKey.indices) {
@@ -83,7 +80,7 @@
                         }
                     )
                 } else {
-                    EditorRequest(componentName, editorComponentName, instanceId, null)
+                    EditorRequest(componentName, editorPackageName, instanceId, null)
                 }
             }
         }
@@ -118,7 +115,7 @@
             "watchFaceInstanceId must be set from Android R and above"
         }
         return Intent(ACTION_WATCH_FACE_EDITOR).apply {
-            component = input.editorComponentName
+            setPackage(input.editorPackageName)
             putExtra(COMPONENT_NAME_KEY, input.watchFaceComponentName)
             putExtra(INSTANCE_ID_KEY, input.watchFaceInstanceId)
             input.initialUserStyle?.let {
diff --git a/wear/wear-watchface-style/api/current.txt b/wear/wear-watchface-style/api/current.txt
index 8ff45ee..02d740c 100644
--- a/wear/wear-watchface-style/api/current.txt
+++ b/wear/wear-watchface-style/api/current.txt
@@ -60,7 +60,7 @@
   }
 
   public static final class UserStyleSetting.BooleanUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
-    ctor public UserStyleSetting.BooleanUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, boolean defaultValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers);
+    ctor public UserStyleSetting.BooleanUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers, boolean defaultValue);
     method public boolean getDefaultValue();
   }
 
@@ -74,6 +74,7 @@
   }
 
   public static final class UserStyleSetting.ComplicationsUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
+    ctor public UserStyleSetting.ComplicationsUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, java.util.List<androidx.wear.watchface.style.UserStyleSetting.ComplicationsUserStyleSetting.ComplicationsOption> complicationConfig, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers, androidx.wear.watchface.style.UserStyleSetting.ComplicationsUserStyleSetting.ComplicationsOption defaultOption);
     ctor public UserStyleSetting.ComplicationsUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, java.util.List<androidx.wear.watchface.style.UserStyleSetting.ComplicationsUserStyleSetting.ComplicationsOption> complicationConfig, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers);
   }
 
@@ -105,7 +106,7 @@
   }
 
   public static final class UserStyleSetting.CustomValueUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
-    ctor public UserStyleSetting.CustomValueUserStyleSetting(String defaultValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers);
+    ctor public UserStyleSetting.CustomValueUserStyleSetting(java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers, String defaultValue);
   }
 
   public static final class UserStyleSetting.CustomValueUserStyleSetting.CustomValueOption extends androidx.wear.watchface.style.UserStyleSetting.Option {
@@ -115,7 +116,7 @@
   }
 
   public static final class UserStyleSetting.DoubleRangeUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
-    ctor public UserStyleSetting.DoubleRangeUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, double minimumValue, double maximumValue, double defaultValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers);
+    ctor public UserStyleSetting.DoubleRangeUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, double minimumValue, double maximumValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers, double defaultValue);
     method public double getDefaultValue();
     method public double getMaximumValue();
     method public double getMinimumValue();
@@ -141,7 +142,7 @@
   }
 
   public static final class UserStyleSetting.LongRangeUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
-    ctor public UserStyleSetting.LongRangeUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, long minimumValue, long maximumValue, long defaultValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers);
+    ctor public UserStyleSetting.LongRangeUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, long minimumValue, long maximumValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers, long defaultValue);
     method public long getDefaultValue();
     method public long getMaximumValue();
     method public long getMinimumValue();
diff --git a/wear/wear-watchface-style/api/public_plus_experimental_current.txt b/wear/wear-watchface-style/api/public_plus_experimental_current.txt
index e0537d8..f77fe24 100644
--- a/wear/wear-watchface-style/api/public_plus_experimental_current.txt
+++ b/wear/wear-watchface-style/api/public_plus_experimental_current.txt
@@ -60,7 +60,7 @@
   }
 
   public static final class UserStyleSetting.BooleanUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
-    ctor public UserStyleSetting.BooleanUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, boolean defaultValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers);
+    ctor public UserStyleSetting.BooleanUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers, boolean defaultValue);
     method public boolean getDefaultValue();
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.wear.watchface.style.data.BooleanUserStyleSettingWireFormat toWireFormat();
   }
@@ -76,6 +76,7 @@
   }
 
   public static final class UserStyleSetting.ComplicationsUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
+    ctor public UserStyleSetting.ComplicationsUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, java.util.List<androidx.wear.watchface.style.UserStyleSetting.ComplicationsUserStyleSetting.ComplicationsOption> complicationConfig, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers, androidx.wear.watchface.style.UserStyleSetting.ComplicationsUserStyleSetting.ComplicationsOption defaultOption);
     ctor public UserStyleSetting.ComplicationsUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, java.util.List<androidx.wear.watchface.style.UserStyleSetting.ComplicationsUserStyleSetting.ComplicationsOption> complicationConfig, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.wear.watchface.style.data.ComplicationsUserStyleSettingWireFormat toWireFormat();
   }
@@ -109,7 +110,7 @@
   }
 
   public static final class UserStyleSetting.CustomValueUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
-    ctor public UserStyleSetting.CustomValueUserStyleSetting(String defaultValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers);
+    ctor public UserStyleSetting.CustomValueUserStyleSetting(java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers, String defaultValue);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.wear.watchface.style.data.CustomValueUserStyleSettingWireFormat toWireFormat();
   }
 
@@ -121,7 +122,7 @@
   }
 
   public static final class UserStyleSetting.DoubleRangeUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
-    ctor public UserStyleSetting.DoubleRangeUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, double minimumValue, double maximumValue, double defaultValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers);
+    ctor public UserStyleSetting.DoubleRangeUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, double minimumValue, double maximumValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers, double defaultValue);
     method public double getDefaultValue();
     method public double getMaximumValue();
     method public double getMinimumValue();
@@ -151,7 +152,7 @@
   }
 
   public static final class UserStyleSetting.LongRangeUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
-    ctor public UserStyleSetting.LongRangeUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, long minimumValue, long maximumValue, long defaultValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers);
+    ctor public UserStyleSetting.LongRangeUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, long minimumValue, long maximumValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers, long defaultValue);
     method public long getDefaultValue();
     method public long getMaximumValue();
     method public long getMinimumValue();
diff --git a/wear/wear-watchface-style/api/restricted_current.txt b/wear/wear-watchface-style/api/restricted_current.txt
index 5814520..ed6d59c6 100644
--- a/wear/wear-watchface-style/api/restricted_current.txt
+++ b/wear/wear-watchface-style/api/restricted_current.txt
@@ -66,7 +66,7 @@
   }
 
   public static final class UserStyleSetting.BooleanUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
-    ctor public UserStyleSetting.BooleanUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, boolean defaultValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers);
+    ctor public UserStyleSetting.BooleanUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers, boolean defaultValue);
     method public boolean getDefaultValue();
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.wear.watchface.style.data.BooleanUserStyleSettingWireFormat toWireFormat();
   }
@@ -82,6 +82,7 @@
   }
 
   public static final class UserStyleSetting.ComplicationsUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
+    ctor public UserStyleSetting.ComplicationsUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, java.util.List<androidx.wear.watchface.style.UserStyleSetting.ComplicationsUserStyleSetting.ComplicationsOption> complicationConfig, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers, androidx.wear.watchface.style.UserStyleSetting.ComplicationsUserStyleSetting.ComplicationsOption defaultOption);
     ctor public UserStyleSetting.ComplicationsUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, java.util.List<androidx.wear.watchface.style.UserStyleSetting.ComplicationsUserStyleSetting.ComplicationsOption> complicationConfig, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.wear.watchface.style.data.ComplicationsUserStyleSettingWireFormat toWireFormat();
   }
@@ -115,7 +116,7 @@
   }
 
   public static final class UserStyleSetting.CustomValueUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
-    ctor public UserStyleSetting.CustomValueUserStyleSetting(String defaultValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers);
+    ctor public UserStyleSetting.CustomValueUserStyleSetting(java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers, String defaultValue);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.wear.watchface.style.data.CustomValueUserStyleSettingWireFormat toWireFormat();
   }
 
@@ -127,7 +128,7 @@
   }
 
   public static final class UserStyleSetting.DoubleRangeUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
-    ctor public UserStyleSetting.DoubleRangeUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, double minimumValue, double maximumValue, double defaultValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers);
+    ctor public UserStyleSetting.DoubleRangeUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, double minimumValue, double maximumValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers, double defaultValue);
     method public double getDefaultValue();
     method public double getMaximumValue();
     method public double getMinimumValue();
@@ -157,7 +158,7 @@
   }
 
   public static final class UserStyleSetting.LongRangeUserStyleSetting extends androidx.wear.watchface.style.UserStyleSetting {
-    ctor public UserStyleSetting.LongRangeUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, long minimumValue, long maximumValue, long defaultValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers);
+    ctor public UserStyleSetting.LongRangeUserStyleSetting(String id, CharSequence displayName, CharSequence description, android.graphics.drawable.Icon? icon, long minimumValue, long maximumValue, java.util.Collection<? extends androidx.wear.watchface.style.Layer> affectsLayers, long defaultValue);
     method public long getDefaultValue();
     method public long getMaximumValue();
     method public long getMinimumValue();
diff --git a/wear/wear-watchface-style/src/main/java/androidx/wear/watchface/style/UserStyleSetting.kt b/wear/wear-watchface-style/src/main/java/androidx/wear/watchface/style/UserStyleSetting.kt
index 1bdefb1..534dc59 100644
--- a/wear/wear-watchface-style/src/main/java/androidx/wear/watchface/style/UserStyleSetting.kt
+++ b/wear/wear-watchface-style/src/main/java/androidx/wear/watchface/style/UserStyleSetting.kt
@@ -286,14 +286,14 @@
             /** Icon for use in the userStyle selection UI. */
             icon: Icon?,
 
-            /** The default value for this BooleanUserStyleSetting. */
-            defaultValue: Boolean,
-
             /**
              * Used by the style configuration UI. Describes which rendering layers this style
              * affects.
              */
-            affectsLayers: Collection<Layer>
+            affectsLayers: Collection<Layer>,
+
+            /** The default value for this BooleanUserStyleSetting. */
+            defaultValue: Boolean
         ) : super(
             id,
             displayName,
@@ -435,6 +435,7 @@
                 )
         }
 
+        @JvmOverloads
         public constructor (
             /** Identifier for the element, must be unique. */
             id: String,
@@ -450,23 +451,24 @@
             /** Icon for use in the userStyle selection UI. */
             icon: Icon?,
 
-            /**
-             * The configuration for affected complications. The first entry is the default value
-             */
+            /** The configuration for affected complications. */
             complicationConfig: List<ComplicationsOption>,
 
             /**
              * Used by the style configuration UI. Describes which rendering layers this style
              * affects, must include [Layer.COMPLICATIONS].
              */
-            affectsLayers: Collection<Layer>
+            affectsLayers: Collection<Layer>,
+
+            /** The default option, used when data isn't persisted. */
+            defaultOption: ComplicationsOption = complicationConfig.first()
         ) : super(
             id,
             displayName,
             description,
             icon,
             complicationConfig,
-            0,
+            complicationConfig.indexOf(defaultOption),
             affectsLayers
         ) {
             require(affectsLayers.contains(Layer.COMPLICATIONS))
@@ -585,14 +587,14 @@
             /** Maximum value (inclusive). */
             maximumValue: Double,
 
-            /** The default value for this DoubleRangeUserStyleSetting. */
-            defaultValue: Double,
-
             /**
              * Used by the style configuration UI. Describes which rendering layers this style
              * affects.
              */
-            affectsLayers: Collection<Layer>
+            affectsLayers: Collection<Layer>,
+
+            /** The default value for this DoubleRangeUserStyleSetting. */
+            defaultValue: Double
         ) : super(
             id,
             displayName,
@@ -814,14 +816,14 @@
             /** Maximum value (inclusive). */
             maximumValue: Long,
 
-            /** The default value for this LongRangeUserStyleSetting. */
-            defaultValue: Long,
-
             /**
              * Used by the style configuration UI. Describes which rendering layers this style
              * affects.
              */
-            affectsLayers: Collection<Layer>
+            affectsLayers: Collection<Layer>,
+
+            /** The default value for this LongRangeUserStyleSetting. */
+            defaultValue: Long
         ) : super(
             id,
             displayName,
@@ -926,14 +928,14 @@
         }
 
         public constructor (
-            /** The default value. */
-            defaultValue: String,
-
             /**
              * Used by the style configuration UI. Describes which rendering layers this style
              * affects.
              */
-            affectsLayers: Collection<Layer>
+            affectsLayers: Collection<Layer>,
+
+            /** The default value. */
+            defaultValue: String
         ) : super(
             CUSTOM_VALUE_USER_STYLE_SETTING_ID,
             "",
diff --git a/wear/wear-watchface-style/src/test/java/androidx/wear/watchface/style/StyleParcelableTest.kt b/wear/wear-watchface-style/src/test/java/androidx/wear/watchface/style/StyleParcelableTest.kt
index 3766944..3796bda 100644
--- a/wear/wear-watchface-style/src/test/java/androidx/wear/watchface/style/StyleParcelableTest.kt
+++ b/wear/wear-watchface-style/src/test/java/androidx/wear/watchface/style/StyleParcelableTest.kt
@@ -142,12 +142,12 @@
             "displayName3",
             "description3",
             null,
-            true,
-            listOf(Layer.BASE_LAYER)
+            listOf(Layer.BASE_LAYER),
+            true
         )
         val styleSetting4 = CustomValueUserStyleSetting(
-            "default",
-            listOf(Layer.BASE_LAYER)
+            listOf(Layer.BASE_LAYER),
+            "default"
         )
 
         val srcSchema = UserStyleSchema(
@@ -267,8 +267,8 @@
             "displayName2",
             "description2",
             null,
-            true,
-            listOf(Layer.BASE_LAYER)
+            listOf(Layer.BASE_LAYER),
+            true
         )
         assertTrue(booleanUserStyleSettingDefaultTrue.getDefaultValue())
 
@@ -277,8 +277,8 @@
             "displayName2",
             "description2",
             null,
-            false,
-            listOf(Layer.BASE_LAYER)
+            listOf(Layer.BASE_LAYER),
+            false
         )
         assertFalse(booleanUserStyleSettingDefaultFalse.getDefaultValue())
     }
@@ -292,8 +292,8 @@
             null,
             -1.0,
             1.0,
-            -1.0,
-            listOf(Layer.BASE_LAYER)
+            listOf(Layer.BASE_LAYER),
+            -1.0
         )
         assertThat(doubleRangeUserStyleSettingDefaultMin.getDefaultValue()).isEqualTo(-1.0)
 
@@ -304,8 +304,8 @@
             null,
             -1.0,
             1.0,
-            0.5,
-            listOf(Layer.BASE_LAYER)
+            listOf(Layer.BASE_LAYER),
+            0.5
         )
         assertThat(doubleRangeUserStyleSettingDefaultMid.getDefaultValue()).isEqualTo(0.5)
 
@@ -316,8 +316,8 @@
             null,
             -1.0,
             1.0,
-            1.0,
-            listOf(Layer.BASE_LAYER)
+            listOf(Layer.BASE_LAYER),
+            1.0
         )
         assertThat(doubleRangeUserStyleSettingDefaultMax.getDefaultValue()).isEqualTo(1.0)
     }
@@ -331,8 +331,8 @@
             null,
             -1,
             10,
+            listOf(Layer.BASE_LAYER),
             -1,
-            listOf(Layer.BASE_LAYER)
         )
         assertThat(longRangeUserStyleSettingDefaultMin.getDefaultValue()).isEqualTo(-1)
 
@@ -343,8 +343,8 @@
             null,
             -1,
             10,
-            5,
-            listOf(Layer.BASE_LAYER)
+            listOf(Layer.BASE_LAYER),
+            5
         )
         assertThat(longRangeUserStyleSettingDefaultMid.getDefaultValue()).isEqualTo(5)
 
@@ -355,8 +355,8 @@
             null,
             -1,
             10,
-            10,
-            listOf(Layer.BASE_LAYER)
+            listOf(Layer.BASE_LAYER),
+            10
         )
         assertThat(longRangeUserStyleSettingDefaultMax.getDefaultValue()).isEqualTo(10)
     }
@@ -484,12 +484,12 @@
             "displayName3",
             "description3",
             null,
-            true,
-            listOf(Layer.BASE_LAYER)
+            listOf(Layer.BASE_LAYER),
+            true
         )
         val styleSetting4 = CustomValueUserStyleSetting(
-            "default",
-            listOf(Layer.BASE_LAYER)
+            listOf(Layer.BASE_LAYER),
+            "default"
         )
 
         val schema = UserStyleSchema(
diff --git a/wear/wear-watchface-style/src/test/java/androidx/wear/watchface/style/UserStyleRepositoryTest.kt b/wear/wear-watchface-style/src/test/java/androidx/wear/watchface/style/UserStyleRepositoryTest.kt
index de04029..3efa3ea 100644
--- a/wear/wear-watchface-style/src/test/java/androidx/wear/watchface/style/UserStyleRepositoryTest.kt
+++ b/wear/wear-watchface-style/src/test/java/androidx/wear/watchface/style/UserStyleRepositoryTest.kt
@@ -75,8 +75,8 @@
             null,
             0.25,
             1.0,
-            0.75,
-            listOf(Layer.TOP_LAYER)
+            listOf(Layer.TOP_LAYER),
+            0.75
         )
 
     private val mockListener1 = Mockito.mock(UserStyleRepository.UserStyleListener::class.java)
@@ -226,8 +226,8 @@
     @Test
     fun userStyle_mapConstructor_customValueUserStyleSetting() {
         val customStyleSetting = CustomValueUserStyleSetting(
-            "default",
-            listOf(Layer.BASE_LAYER)
+            listOf(Layer.BASE_LAYER),
+            "default"
         )
 
         val userStyleRepository = UserStyleRepository(
@@ -251,12 +251,12 @@
     @Test
     fun userStyle_multiple_CustomValueUserStyleSettings_notAllowed() {
         val customStyleSetting1 = CustomValueUserStyleSetting(
-            "default",
-            listOf(Layer.BASE_LAYER)
+            listOf(Layer.BASE_LAYER),
+            "default"
         )
         val customStyleSetting2 = CustomValueUserStyleSetting(
-            "default",
-            listOf(Layer.BASE_LAYER)
+            listOf(Layer.BASE_LAYER),
+            "default"
         )
 
         try {
@@ -275,8 +275,8 @@
     @Test
     fun setAndGetCustomStyleSetting() {
         val customStyleSetting = CustomValueUserStyleSetting(
-            "default",
-            listOf(Layer.BASE_LAYER)
+            listOf(Layer.BASE_LAYER),
+            "default"
         )
 
         val userStyleRepository = UserStyleRepository(
diff --git a/wear/wear-watchface-style/src/test/java/androidx/wear/watchface/style/UserStyleSettingTest.kt b/wear/wear-watchface-style/src/test/java/androidx/wear/watchface/style/UserStyleSettingTest.kt
index 8c46d61..e5965cb 100644
--- a/wear/wear-watchface-style/src/test/java/androidx/wear/watchface/style/UserStyleSettingTest.kt
+++ b/wear/wear-watchface-style/src/test/java/androidx/wear/watchface/style/UserStyleSettingTest.kt
@@ -36,8 +36,8 @@
                 null,
                 0.0,
                 1.0,
-                defaultValue,
-                listOf(Layer.BASE_LAYER)
+                listOf(Layer.BASE_LAYER),
+                defaultValue
             )
 
         assertThat(rangedUserStyleSetting.getOptionForId("not a number").id)
@@ -61,8 +61,8 @@
                 null,
                 0.0,
                 1.0,
-                defaultValue,
-                listOf(Layer.BASE_LAYER)
+                listOf(Layer.BASE_LAYER),
+                defaultValue
             )
 
         assertThat(rangedUserStyleSetting.getOptionForId("0").id)
@@ -85,8 +85,8 @@
             null,
             0.0,
             1.0,
-            1.0,
-            emptyList()
+            emptyList(),
+            1.0
         )
 
         try {
@@ -98,8 +98,8 @@
                 null,
                 0.0,
                 1.0,
-                1.0,
-                emptyList()
+                emptyList(),
+                1.0
             )
             fail("Should have thrown an exception")
         } catch (e: Exception) {
diff --git a/wear/wear-watchface/api/current.txt b/wear/wear-watchface/api/current.txt
index 08e0956..4e05d3c 100644
--- a/wear/wear-watchface/api/current.txt
+++ b/wear/wear-watchface/api/current.txt
@@ -7,9 +7,8 @@
     method @UiThread public void onAttach(androidx.wear.watchface.Complication complication);
     method @UiThread public void onDetach();
     method @UiThread public void render(android.graphics.Canvas canvas, android.graphics.Rect bounds, android.icu.util.Calendar calendar, androidx.wear.watchface.RenderParameters renderParameters);
-    method public void setIdAndData(androidx.wear.complications.data.IdAndComplicationData? p);
+    method public void setIdAndData(androidx.wear.complications.data.IdAndComplicationData? idAndComplicationData, boolean loadDrawablesAsynchronous);
     method public void setIsHighlighted(boolean p);
-    property public abstract androidx.wear.complications.data.IdAndComplicationData? idAndData;
     property public abstract boolean isHighlighted;
   }
 
@@ -17,17 +16,15 @@
     ctor public CanvasComplicationDrawable(androidx.wear.watchface.complications.rendering.ComplicationDrawable drawable, androidx.wear.watchface.WatchState watchState);
     method public void drawOutline(android.graphics.Canvas canvas, android.graphics.Rect bounds, android.icu.util.Calendar calendar, @ColorInt int color);
     method public final androidx.wear.watchface.complications.rendering.ComplicationDrawable getDrawable();
-    method @UiThread public androidx.wear.complications.data.IdAndComplicationData? getIdAndData();
+    method public androidx.wear.complications.data.IdAndComplicationData? getIdAndData();
     method @UiThread public boolean isHighlighted();
     method public void onAttach(androidx.wear.watchface.Complication complication);
     method public void onDetach();
     method public void render(android.graphics.Canvas canvas, android.graphics.Rect bounds, android.icu.util.Calendar calendar, androidx.wear.watchface.RenderParameters renderParameters);
     method public final void setDrawable(androidx.wear.watchface.complications.rendering.ComplicationDrawable value);
-    method @UiThread public void setIdAndData(androidx.wear.complications.data.IdAndComplicationData? value);
-    method public void setIdComplicationDataSync(androidx.wear.complications.data.IdAndComplicationData? idAndComplicationData);
+    method public void setIdAndData(androidx.wear.complications.data.IdAndComplicationData? idAndComplicationData, boolean loadDrawablesAsynchronous);
     method @UiThread public void setIsHighlighted(boolean value);
     property public final androidx.wear.watchface.complications.rendering.ComplicationDrawable drawable;
-    property @UiThread public androidx.wear.complications.data.IdAndComplicationData? idAndData;
     property @UiThread public boolean isHighlighted;
   }
 
diff --git a/wear/wear-watchface/api/public_plus_experimental_current.txt b/wear/wear-watchface/api/public_plus_experimental_current.txt
index 08e0956..4e05d3c 100644
--- a/wear/wear-watchface/api/public_plus_experimental_current.txt
+++ b/wear/wear-watchface/api/public_plus_experimental_current.txt
@@ -7,9 +7,8 @@
     method @UiThread public void onAttach(androidx.wear.watchface.Complication complication);
     method @UiThread public void onDetach();
     method @UiThread public void render(android.graphics.Canvas canvas, android.graphics.Rect bounds, android.icu.util.Calendar calendar, androidx.wear.watchface.RenderParameters renderParameters);
-    method public void setIdAndData(androidx.wear.complications.data.IdAndComplicationData? p);
+    method public void setIdAndData(androidx.wear.complications.data.IdAndComplicationData? idAndComplicationData, boolean loadDrawablesAsynchronous);
     method public void setIsHighlighted(boolean p);
-    property public abstract androidx.wear.complications.data.IdAndComplicationData? idAndData;
     property public abstract boolean isHighlighted;
   }
 
@@ -17,17 +16,15 @@
     ctor public CanvasComplicationDrawable(androidx.wear.watchface.complications.rendering.ComplicationDrawable drawable, androidx.wear.watchface.WatchState watchState);
     method public void drawOutline(android.graphics.Canvas canvas, android.graphics.Rect bounds, android.icu.util.Calendar calendar, @ColorInt int color);
     method public final androidx.wear.watchface.complications.rendering.ComplicationDrawable getDrawable();
-    method @UiThread public androidx.wear.complications.data.IdAndComplicationData? getIdAndData();
+    method public androidx.wear.complications.data.IdAndComplicationData? getIdAndData();
     method @UiThread public boolean isHighlighted();
     method public void onAttach(androidx.wear.watchface.Complication complication);
     method public void onDetach();
     method public void render(android.graphics.Canvas canvas, android.graphics.Rect bounds, android.icu.util.Calendar calendar, androidx.wear.watchface.RenderParameters renderParameters);
     method public final void setDrawable(androidx.wear.watchface.complications.rendering.ComplicationDrawable value);
-    method @UiThread public void setIdAndData(androidx.wear.complications.data.IdAndComplicationData? value);
-    method public void setIdComplicationDataSync(androidx.wear.complications.data.IdAndComplicationData? idAndComplicationData);
+    method public void setIdAndData(androidx.wear.complications.data.IdAndComplicationData? idAndComplicationData, boolean loadDrawablesAsynchronous);
     method @UiThread public void setIsHighlighted(boolean value);
     property public final androidx.wear.watchface.complications.rendering.ComplicationDrawable drawable;
-    property @UiThread public androidx.wear.complications.data.IdAndComplicationData? idAndData;
     property @UiThread public boolean isHighlighted;
   }
 
diff --git a/wear/wear-watchface/api/restricted_current.txt b/wear/wear-watchface/api/restricted_current.txt
index 1866acb..f4dbcf9 100644
--- a/wear/wear-watchface/api/restricted_current.txt
+++ b/wear/wear-watchface/api/restricted_current.txt
@@ -7,9 +7,8 @@
     method @UiThread public void onAttach(androidx.wear.watchface.Complication complication);
     method @UiThread public void onDetach();
     method @UiThread public void render(android.graphics.Canvas canvas, android.graphics.Rect bounds, android.icu.util.Calendar calendar, androidx.wear.watchface.RenderParameters renderParameters);
-    method public void setIdAndData(androidx.wear.complications.data.IdAndComplicationData? p);
+    method public void setIdAndData(androidx.wear.complications.data.IdAndComplicationData? idAndComplicationData, boolean loadDrawablesAsynchronous);
     method public void setIsHighlighted(boolean p);
-    property public abstract androidx.wear.complications.data.IdAndComplicationData? idAndData;
     property public abstract boolean isHighlighted;
   }
 
@@ -17,17 +16,15 @@
     ctor public CanvasComplicationDrawable(androidx.wear.watchface.complications.rendering.ComplicationDrawable drawable, androidx.wear.watchface.WatchState watchState);
     method public void drawOutline(android.graphics.Canvas canvas, android.graphics.Rect bounds, android.icu.util.Calendar calendar, @ColorInt int color);
     method public final androidx.wear.watchface.complications.rendering.ComplicationDrawable getDrawable();
-    method @UiThread public androidx.wear.complications.data.IdAndComplicationData? getIdAndData();
+    method public androidx.wear.complications.data.IdAndComplicationData? getIdAndData();
     method @UiThread public boolean isHighlighted();
     method public void onAttach(androidx.wear.watchface.Complication complication);
     method public void onDetach();
     method public void render(android.graphics.Canvas canvas, android.graphics.Rect bounds, android.icu.util.Calendar calendar, androidx.wear.watchface.RenderParameters renderParameters);
     method public final void setDrawable(androidx.wear.watchface.complications.rendering.ComplicationDrawable value);
-    method @UiThread public void setIdAndData(androidx.wear.complications.data.IdAndComplicationData? value);
-    method public void setIdComplicationDataSync(androidx.wear.complications.data.IdAndComplicationData? idAndComplicationData);
+    method public void setIdAndData(androidx.wear.complications.data.IdAndComplicationData? idAndComplicationData, boolean loadDrawablesAsynchronous);
     method @UiThread public void setIsHighlighted(boolean value);
     property public final androidx.wear.watchface.complications.rendering.ComplicationDrawable drawable;
-    property @UiThread public androidx.wear.complications.data.IdAndComplicationData? idAndData;
     property @UiThread public boolean isHighlighted;
   }
 
diff --git a/wear/wear-watchface/samples/src/main/java/androidx/wear/watchface/samples/ExampleCanvasAnalogWatchFaceService.kt b/wear/wear-watchface/samples/src/main/java/androidx/wear/watchface/samples/ExampleCanvasAnalogWatchFaceService.kt
index cb651ed..90b7e51 100644
--- a/wear/wear-watchface/samples/src/main/java/androidx/wear/watchface/samples/ExampleCanvasAnalogWatchFaceService.kt
+++ b/wear/wear-watchface/samples/src/main/java/androidx/wear/watchface/samples/ExampleCanvasAnalogWatchFaceService.kt
@@ -137,8 +137,8 @@
         context.getString(R.string.watchface_pips_setting),
         context.getString(R.string.watchface_pips_setting_description),
         null,
-        true,
-        listOf(Layer.BASE_LAYER)
+        listOf(Layer.BASE_LAYER),
+        true
     )
     val watchHandLengthStyleSetting = DoubleRangeUserStyleSetting(
         WATCH_HAND_LENGTH_STYLE_SETTING,
@@ -147,8 +147,8 @@
         null,
         0.25,
         1.0,
-        0.75,
-        listOf(Layer.TOP_LAYER)
+        listOf(Layer.TOP_LAYER),
+        0.75
     )
     // These are style overrides applied on top of the complications passed into
     // complicationsManager below.
diff --git a/wear/wear-watchface/src/androidTest/java/androidx/wear/watchface/test/TestCanvasAnalogWatchFaceService.kt b/wear/wear-watchface/src/androidTest/java/androidx/wear/watchface/test/TestCanvasAnalogWatchFaceService.kt
index 88e7c04..faec639 100644
--- a/wear/wear-watchface/src/androidTest/java/androidx/wear/watchface/test/TestCanvasAnalogWatchFaceService.kt
+++ b/wear/wear-watchface/src/androidTest/java/androidx/wear/watchface/test/TestCanvasAnalogWatchFaceService.kt
@@ -23,6 +23,7 @@
 import androidx.wear.watchface.WatchFace
 import androidx.wear.watchface.WatchFaceService
 import androidx.wear.watchface.WatchState
+import androidx.wear.watchface.control.data.WallpaperInteractiveWatchFaceInstanceParams
 import androidx.wear.watchface.samples.createExampleCanvasAnalogWatchFaceBuilder
 
 /** A simple canvas test analog watch face for integration tests. */
@@ -31,7 +32,8 @@
     private val handler: Handler,
     var mockSystemTimeMillis: Long,
     var surfaceHolderOverride: SurfaceHolder,
-    var preRInitFlow: Boolean
+    var preRInitFlow: Boolean,
+    var directBootParams: WallpaperInteractiveWatchFaceInstanceParams?
 ) : WatchFaceService() {
 
     private val mutableWatchState = MutableWatchState()
@@ -67,4 +69,15 @@
     override fun getWallpaperSurfaceHolderOverride() = surfaceHolderOverride
 
     override fun expectPreRInitFlow() = preRInitFlow
+
+    override fun readDirectBootPrefs(
+        context: Context,
+        fileName: String
+    ) = directBootParams
+
+    override fun writeDirectBootPrefs(
+        context: Context,
+        fileName: String,
+        prefs: WallpaperInteractiveWatchFaceInstanceParams
+    ) {}
 }
diff --git a/wear/wear-watchface/src/androidTest/java/androidx/wear/watchface/test/TestGlesWatchFaceService.kt b/wear/wear-watchface/src/androidTest/java/androidx/wear/watchface/test/TestGlesWatchFaceService.kt
index 9cc1d57..6c32f27 100644
--- a/wear/wear-watchface/src/androidTest/java/androidx/wear/watchface/test/TestGlesWatchFaceService.kt
+++ b/wear/wear-watchface/src/androidTest/java/androidx/wear/watchface/test/TestGlesWatchFaceService.kt
@@ -23,6 +23,7 @@
 import androidx.wear.watchface.WatchFace
 import androidx.wear.watchface.WatchFaceService
 import androidx.wear.watchface.WatchState
+import androidx.wear.watchface.control.data.WallpaperInteractiveWatchFaceInstanceParams
 import androidx.wear.watchface.samples.createExampleOpenGLWatchFaceBuilder
 
 /** A simple OpenGL test watch face for integration tests. */
@@ -30,7 +31,8 @@
     testContext: Context,
     private val handler: Handler,
     var mockSystemTimeMillis: Long,
-    var surfacHolderOverride: SurfaceHolder?
+    var surfacHolderOverride: SurfaceHolder?,
+    var directBootParams: WallpaperInteractiveWatchFaceInstanceParams?
 ) : WatchFaceService() {
 
     private val mutableWatchState = MutableWatchState()
@@ -64,4 +66,15 @@
     override fun allowWatchFaceToAnimate() = false
 
     override fun getWallpaperSurfaceHolderOverride() = surfacHolderOverride
+
+    override fun readDirectBootPrefs(
+        context: Context,
+        fileName: String
+    ) = directBootParams
+
+    override fun writeDirectBootPrefs(
+        context: Context,
+        fileName: String,
+        prefs: WallpaperInteractiveWatchFaceInstanceParams
+    ) {}
 }
diff --git a/wear/wear-watchface/src/androidTest/java/androidx/wear/watchface/test/WatchFaceServiceImageTest.kt b/wear/wear-watchface/src/androidTest/java/androidx/wear/watchface/test/WatchFaceServiceImageTest.kt
index 85d8f9b..5d8e57d 100644
--- a/wear/wear-watchface/src/androidTest/java/androidx/wear/watchface/test/WatchFaceServiceImageTest.kt
+++ b/wear/wear-watchface/src/androidTest/java/androidx/wear/watchface/test/WatchFaceServiceImageTest.kt
@@ -22,6 +22,7 @@
 import android.graphics.Color
 import android.graphics.Rect
 import android.graphics.SurfaceTexture
+import android.icu.util.TimeZone
 import android.os.Handler
 import android.os.Looper
 import android.support.wearable.watchface.SharedMemoryImage
@@ -114,7 +115,9 @@
 
     @After
     fun shutDown() {
-        interactiveWatchFaceInstanceWCS.release()
+        if (this::interactiveWatchFaceInstanceWCS.isInitialized) {
+            interactiveWatchFaceInstanceWCS.release()
+        }
     }
 
     private fun initCanvasWatchFace() {
@@ -123,7 +126,8 @@
             handler,
             100000,
             surfaceHolder,
-            true // Not direct boot.
+            true, // Not direct boot.
+            null
         )
 
         Mockito.`when`(surfaceHolder.surfaceFrame)
@@ -144,7 +148,8 @@
             ApplicationProvider.getApplicationContext<Context>(),
             handler,
             100000,
-            surfaceHolder
+            surfaceHolder,
+            null
         )
 
         surfaceTexture.setDefaultBufferSize(BITMAP_WIDTH, BITMAP_HEIGHT)
@@ -183,6 +188,9 @@
                         ) {
                             interactiveWatchFaceInstanceWCS = iInteractiveWatchFaceWcs
                             sendComplications()
+                            // Set the timezone so it doesn't matter where the bots are running.
+                            engineWrapper.watchFaceImpl.calendar.timeZone =
+                                TimeZone.getTimeZone("UTC")
                             initLatch.countDown()
                         }
                     }
@@ -456,33 +464,51 @@
 
     @Test
     fun directBoot() {
-        handler.post(this::initCanvasWatchFace)
-        initLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)
+        Mockito.`when`(surfaceHolder.surfaceFrame)
+            .thenReturn(Rect(0, 0, BITMAP_WIDTH, BITMAP_HEIGHT))
+        Mockito.`when`(surfaceHolder.lockHardwareCanvas()).thenReturn(canvas)
+        Mockito.`when`(surfaceHolder.unlockCanvasAndPost(canvas)).then {
+            renderDoneLatch.countDown()
+        }
+
+        lateinit var engineWrapper: WatchFaceService.EngineWrapper
+
         handler.post {
-            // Change the style
-            interactiveWatchFaceInstanceWCS.setCurrentUserStyle(
-                UserStyleWireFormat(mapOf(COLOR_STYLE_SETTING to GREEN_STYLE))
-            )
-
-            // Simulate device shutting down.
-            InteractiveInstanceManager.deleteInstance(INTERACTIVE_INSTANCE_ID)
-
             // Simulate a R style direct boot scenario where a new service is created but there's no
-            // pending PendingWallpaperInteractiveWatchFaceInstance and no wallpaper command. This
-            // should load the direct boot parameters which get saved.
-            val service2 = TestCanvasAnalogWatchFaceService(
+            // pending PendingWallpaperInteractiveWatchFaceInstance and no wallpaper command. It
+            // instead uses the WallpaperInteractiveWatchFaceInstanceParams which normally would be
+            // read from disk, but provided directly in this test.
+            val service = TestCanvasAnalogWatchFaceService(
                 ApplicationProvider.getApplicationContext<Context>(),
                 handler,
                 100000,
                 surfaceHolder,
-                false // Direct boot.
+                false, // Direct boot.
+                WallpaperInteractiveWatchFaceInstanceParams(
+                    INTERACTIVE_INSTANCE_ID,
+                    DeviceConfig(
+                        false,
+                        false,
+                        0,
+                        0
+                    ),
+                    SystemState(false, 0),
+                    UserStyleWireFormat(
+                        mapOf(COLOR_STYLE_SETTING to GREEN_STYLE)
+                    ),
+                    null
+                )
             )
 
-            val engineWrapper2 = service2.onCreateEngine() as WatchFaceService.EngineWrapper
-            handler.post { engineWrapper2.draw() }
+            engineWrapper = service.onCreateEngine() as WatchFaceService.EngineWrapper
+            handler.post { engineWrapper.draw() }
         }
 
         renderDoneLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)
-        bitmap.assertAgainstGolden(screenshotRule, "direct_boot")
+        try {
+            bitmap.assertAgainstGolden(screenshotRule, "direct_boot")
+        } finally {
+            engineWrapper.onDestroy()
+        }
     }
 }
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/Complication.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/Complication.kt
index 396e26e..1a83c6e 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/Complication.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/Complication.kt
@@ -55,8 +55,8 @@
     public fun onDetach()
 
     /**
-     * Draws the complication defined by [idAndData] into the canvas with the specified bounds. This
-     * will usually be called by user watch face drawing code, but the system may also call it
+     * Draws the complication defined by [getIdAndData] into the canvas with the specified bounds.
+     * This will usually be called by user watch face drawing code, but the system may also call it
      * for complication selection UI rendering. The width and height will be the same as that
      * computed by computeBounds but the translation and canvas size may differ.
      *
@@ -82,11 +82,18 @@
     @set:JvmName("setIsHighlighted")
     public var isHighlighted: Boolean
 
-    /** The [IdAndComplicationData] to render. */
-    public var idAndData: IdAndComplicationData?
+    /** Returns the [IdAndComplicationData] to render with. */
+    public fun getIdAndData(): IdAndComplicationData?
 
-    /** @hide */
-    public fun setIdComplicationDataSync(idAndComplicationData: IdAndComplicationData?)
+    /**
+     * Sets the [IdAndComplicationData] to render with.
+     *
+     * @param loadDrawablesAsynchronous Whether or not any drawables should be loaded asynchronously
+     **/
+    public fun setIdAndData(
+        idAndComplicationData: IdAndComplicationData?,
+        loadDrawablesAsynchronous: Boolean
+    )
 }
 
 /**
@@ -165,7 +172,7 @@
                 drawable.currentTimeMillis = calendar.timeInMillis
                 val wasHighlighted = drawable.isHighlighted
                 drawable.isHighlighted =
-                    renderParameters.selectedComplicationId == idAndData?.complicationId
+                    renderParameters.selectedComplicationId == getIdAndData()?.complicationId
                 drawable.draw(canvas)
                 drawable.isHighlighted = wasHighlighted
 
@@ -215,24 +222,16 @@
 
     private var _idAndData: IdAndComplicationData? = null
 
-    /** The [IdAndComplicationData] to use when rendering the complication. */
-    override var idAndData: IdAndComplicationData?
-        @UiThread
-        get() = _idAndData
-        @UiThread
-        set(value) {
-            drawable.setComplicationData(
-                value?.complicationData?.asWireComplicationData(),
-                true
-            )
-            _idAndData = value
-        }
+    override fun getIdAndData(): IdAndComplicationData? = _idAndData
 
-    override fun setIdComplicationDataSync(idAndComplicationData: IdAndComplicationData?) {
+    override fun setIdAndData(
+        idAndComplicationData: IdAndComplicationData?,
+        loadDrawablesAsynchronous: Boolean
+    ) {
         _idAndData = idAndComplicationData
         drawable.setComplicationData(
             idAndComplicationData?.complicationData?.asWireComplicationData(),
-            false
+            loadDrawablesAsynchronous
         )
     }
 }
@@ -490,7 +489,7 @@
                 return
             }
             renderer.onDetach()
-            value.idAndData = renderer.idAndData
+            value.setIdAndData(renderer.getIdAndData(), true)
             field = value
             value.onAttach(this)
         }
@@ -645,7 +644,7 @@
         // Try the current type if there is one, otherwise fall back to the bounds for the default
         // provider type.
         val unitSquareBounds =
-            renderer.idAndData?.let {
+            renderer.getIdAndData()?.let {
                 complicationBounds.perComplicationTypeBounds[it.complicationData.type]
             } ?: complicationBounds.perComplicationTypeBounds[defaultProviderType]!!
         unitSquareBounds.intersect(unitSquare)
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/ComplicationsManager.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/ComplicationsManager.kt
index cfdec0e..38aec04 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/ComplicationsManager.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/ComplicationsManager.kt
@@ -207,7 +207,7 @@
                 if (complication.boundsType == ComplicationBoundsType.BACKGROUND) {
                     ComplicationBoundsType.BACKGROUND
                 } else {
-                    complication.renderer.idAndData?.let {
+                    complication.renderer.getIdAndData()?.let {
                         labels.add(
                             ContentDescriptionLabel(
                                 watchFaceHostApi.getContext(),
@@ -238,8 +238,7 @@
                 activeKeys.add(id)
 
                 labelsDirty =
-                    labelsDirty || complication.dataDirty ||
-                    complication.complicationBoundsDirty
+                    labelsDirty || complication.dataDirty || complication.complicationBoundsDirty
 
                 if (complication.defaultProviderPolicyDirty ||
                     complication.defaultProviderTypeDirty
@@ -286,9 +285,12 @@
     @UiThread
     internal fun onComplicationDataUpdate(watchFaceComplicationId: Int, data: ComplicationData) {
         val complication = complications[watchFaceComplicationId] ?: return
-        complication.dataDirty =
-            complication.dataDirty || (complication.renderer.idAndData?.complicationData != data)
-        complication.renderer.idAndData = IdAndComplicationData(watchFaceComplicationId, data)
+        complication.dataDirty = complication.dataDirty ||
+            (complication.renderer.getIdAndData()?.complicationData != data)
+        complication.renderer.setIdAndData(
+            IdAndComplicationData(watchFaceComplicationId, data),
+            true
+        )
         (complication.complicationData as MutableObservableWatchData<ComplicationData>).value =
             data
     }
@@ -351,7 +353,7 @@
     @UiThread
     internal fun onComplicationSingleTapped(complicationId: Int) {
         // Check if the complication is missing permissions.
-        val data = complications[complicationId]?.renderer?.idAndData ?: return
+        val data = complications[complicationId]?.renderer?.getIdAndData() ?: return
         if (data.complicationData.type == ComplicationType.NO_PERMISSION) {
             watchFaceHostApi.getContext().startActivity(
                 ComplicationHelperActivity.createPermissionRequestHelperIntent(
@@ -383,7 +385,7 @@
         if (complication.fixedComplicationProvider) {
             return
         }
-        val data = complication.renderer.idAndData ?: return
+        val data = complication.renderer.getIdAndData() ?: return
         if (data.complicationData.type == ComplicationType.NO_PERMISSION) {
             watchFaceHostApi.getContext().startActivity(
                 ComplicationHelperActivity.createPermissionRequestHelperIntent(
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFace.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFace.kt
index 52a52b7..118497d 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFace.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFace.kt
@@ -657,7 +657,7 @@
         ): Bitmap {
             val oldComplicationData =
                 complicationsManager.complications.values.map {
-                    it.renderer.idAndData ?: IdAndComplicationData(
+                    it.renderer.getIdAndData() ?: IdAndComplicationData(
                         it.id,
                         NoDataComplicationData()
                     )
@@ -665,8 +665,9 @@
 
             idToComplicationData?.let {
                 for ((id, complicationData) in it) {
-                    complicationsManager[id]!!.renderer.setIdComplicationDataSync(
-                        IdAndComplicationData(id, complicationData)
+                    complicationsManager[id]!!.renderer.setIdAndData(
+                        IdAndComplicationData(id, complicationData),
+                        false
                     )
                 }
             }
@@ -679,7 +680,7 @@
             if (idToComplicationData != null) {
                 for (idAndData in oldComplicationData) {
                     complicationsManager[idAndData.complicationId]!!.renderer
-                        .setIdComplicationDataSync(idAndData)
+                        .setIdAndData(idAndData, false)
                 }
             }
             return screenShot
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFaceService.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFaceService.kt
index 7618adc..e9c4b6e 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFaceService.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFaceService.kt
@@ -252,10 +252,34 @@
         attachBaseContext(context)
     }
 
+    internal open fun readDirectBootPrefs(
+        context: Context,
+        fileName: String
+    ): WallpaperInteractiveWatchFaceInstanceParams? =
+        try {
+            val reader = context.openFileInput(fileName)
+            val result =
+                ParcelUtils.fromInputStream<WallpaperInteractiveWatchFaceInstanceParams>(reader)
+            reader.close()
+            result
+        } catch (e: FileNotFoundException) {
+            null
+        }
+
+    internal open fun writeDirectBootPrefs(
+        context: Context,
+        fileName: String,
+        prefs: WallpaperInteractiveWatchFaceInstanceParams
+    ) {
+        val writer = context.openFileOutput(fileName, Context.MODE_PRIVATE)
+        ParcelUtils.toOutputStream(prefs, writer)
+        writer.close()
+    }
+
     internal inner class EngineWrapper(
         private val uiThreadHandler: Handler
     ) : WallpaperService.Engine(), WatchFaceHostApi {
-        private val coroutineScope = CoroutineScope(getHandler().asCoroutineDispatcher())
+        internal val coroutineScope = CoroutineScope(getHandler().asCoroutineDispatcher())
         private val _context = this@WatchFaceService as Context
 
         internal lateinit var iWatchFaceService: IWatchFaceService
@@ -322,6 +346,7 @@
         internal var lastA11yLabels: Array<ContentDescriptionLabel>? = null
 
         private var watchFaceInitStarted = false
+        private var asyncWatchFaceConstructionPending = false
 
         private var initialUserStyle: UserStyleWireFormat? = null
         private lateinit var interactiveInstanceId: String
@@ -341,7 +366,7 @@
                 if (params != null) {
                     coroutineScope.launch {
                         // In tests a watchface may already have been created.
-                        if (!watchFaceCreated()) {
+                        if (!watchFaceCreatedOrPending()) {
                             createInteractiveInstance(params).createWCSApi()
                         }
                         keepSerializedDirectBootParamsUpdated(params)
@@ -357,8 +382,6 @@
                     )
                     keepSerializedDirectBootParamsUpdated(pendingWallpaperInstance.params)
                 }
-
-                interactiveInstanceId = pendingWallpaperInstance.params.instanceId
             }
         }
 
@@ -456,7 +479,7 @@
                             it.value.defaultProviderPolicy.systemProviderFallback,
                             it.value.defaultProviderType.asWireComplicationType(),
                             it.value.enabled,
-                            it.value.renderer.idAndData?.complicationData?.type
+                            it.value.renderer.getIdAndData()?.complicationData?.type
                                 ?.asWireComplicationType()
                                 ?: ComplicationType.NO_DATA.asWireComplicationType(),
                             it.value.fixedComplicationProvider
@@ -518,15 +541,19 @@
 
             val oldComplicationData =
                 watchFaceImpl.complicationsManager.complications.values.map {
-                    it.renderer.idAndData ?: IdAndComplicationData(it.id, NoDataComplicationData())
+                    it.renderer.getIdAndData() ?: IdAndComplicationData(
+                        it.id,
+                        NoDataComplicationData()
+                    )
                 }
             params.idAndComplicationDatumWireFormats?.let {
                 for (idAndData in it) {
                     watchFaceImpl.complicationsManager[idAndData.id]!!.renderer
-                        .setIdComplicationDataSync(
+                        .setIdAndData(
                             IdAndComplicationData(
                                 idAndData.id, idAndData.complicationData.asApiComplicationData()
-                            )
+                            ),
+                            false
                         )
                 }
             }
@@ -546,7 +573,7 @@
             if (params.idAndComplicationDatumWireFormats != null) {
                 for (idAndData in oldComplicationData) {
                     watchFaceImpl.complicationsManager[idAndData.complicationId]!!.renderer
-                        .setIdComplicationDataSync(idAndData)
+                        .setIdAndData(idAndData, false)
                 }
             }
 
@@ -581,12 +608,13 @@
                 var prevIdAndComplicationData: IdAndComplicationData? = null
                 var screenshotComplicationData = params.complicationData
                 if (screenshotComplicationData != null) {
-                    prevIdAndComplicationData = it.renderer.idAndData
-                    it.renderer.setIdComplicationDataSync(
+                    prevIdAndComplicationData = it.renderer.getIdAndData()
+                    it.renderer.setIdAndData(
                         IdAndComplicationData(
                             params.complicationId,
                             screenshotComplicationData
-                        )
+                        ),
+                        false
                     )
                 }
 
@@ -599,7 +627,7 @@
 
                 // Restore previous ComplicationData & style if required.
                 if (params.complicationData != null) {
-                    it.renderer.setIdComplicationDataSync(prevIdAndComplicationData)
+                    it.renderer.setIdAndData(prevIdAndComplicationData, false)
                 }
 
                 if (newStyle != null) {
@@ -761,7 +789,7 @@
         suspend fun createHeadlessInstance(
             params: HeadlessWatchFaceInstanceParams
         ): HeadlessWatchFaceImpl {
-            require(!watchFaceCreated()) { "WatchFace already exists!" }
+            require(!watchFaceCreatedOrPending()) { "WatchFace already exists!" }
             setImmutableSystemState(params.deviceConfig)
 
             // Fake SurfaceHolder with just enough methods implemented for headless rendering.
@@ -822,11 +850,13 @@
             allowWatchfaceToAnimate = false
             mutableWatchState.isHeadless = true
             val watchState = mutableWatchState.asWatchState()
+            asyncWatchFaceConstructionPending = true
             watchFaceImpl = WatchFaceImpl(
                 createWatchFace(fakeSurfaceHolder, watchState),
                 this,
                 watchState
             )
+            asyncWatchFaceConstructionPending = false
 
             mutableWatchState.isVisible.value = true
             mutableWatchState.isAmbient.value = false
@@ -840,18 +870,20 @@
         suspend fun createInteractiveInstance(
             params: WallpaperInteractiveWatchFaceInstanceParams
         ): InteractiveWatchFaceImpl {
-            require(!watchFaceCreated()) { "WatchFace already exists!" }
+            require(!watchFaceCreatedOrPending()) { "WatchFace already exists!" }
 
             setImmutableSystemState(params.deviceConfig)
             setSystemState(params.systemState)
             initialUserStyle = params.userStyle
 
             val watchState = mutableWatchState.asWatchState()
+            asyncWatchFaceConstructionPending = true
             watchFaceImpl = WatchFaceImpl(
                 createWatchFace(getWallpaperSurfaceHolderOverride() ?: surfaceHolder, watchState),
                 this,
                 watchState
             )
+            asyncWatchFaceConstructionPending = false
 
             params.idAndComplicationDataWireFormats?.let { setComplicationDataList(it) }
 
@@ -864,6 +896,18 @@
 
             val instance = InteractiveWatchFaceImpl(this, params.instanceId, uiThreadHandler)
             InteractiveInstanceManager.addInstance(instance)
+            interactiveInstanceId = params.instanceId
+
+            // WatchFace init is async so its possible we have a pending
+            // WallpaperInteractiveWatchFaceInstance request.
+            InteractiveInstanceManager.takePendingWallpaperInteractiveWatchFaceInstance()?.let {
+                require(it.params.instanceId == params.instanceId) {
+                    "Miss match between pendingWallpaperInstance id $it.params.instanceId and " +
+                        "constructed instance id $params.instanceId"
+                }
+                it.callback.onInteractiveWatchFaceWcsCreated(instance.createWCSApi())
+            }
+
             return instance
         }
 
@@ -877,7 +921,7 @@
             // To simplify handling of watch face state, we only construct the [WatchFaceImpl]
             // once iWatchFaceService have been initialized and pending properties sent.
             if (this::iWatchFaceService.isInitialized && pendingProperties != null &&
-                !watchFaceCreated()
+                !watchFaceCreatedOrPending()
             ) {
                 watchFaceInitStarted = true
 
@@ -886,11 +930,13 @@
                 pendingProperties = null
 
                 val watchState = mutableWatchState.asWatchState()
+                asyncWatchFaceConstructionPending = true
                 watchFaceImpl = WatchFaceImpl(
                     createWatchFace(surfaceHolder, watchState),
                     this,
                     watchState
                 )
+                asyncWatchFaceConstructionPending = false
                 watchFaceImpl.renderer.onPostCreate()
 
                 val backgroundAction = pendingBackgroundAction
@@ -1015,6 +1061,9 @@
 
         internal fun watchFaceCreated() = this::watchFaceImpl.isInitialized
 
+        internal fun watchFaceCreatedOrPending() =
+            watchFaceCreated() || asyncWatchFaceConstructionPending
+
         override fun setDefaultComplicationProviderWithFallbacks(
             watchFaceComplicationId: Int,
             providers: List<ComponentName>?,
@@ -1125,27 +1174,3 @@
         @Suppress("UNCHECKED_CAST")
         returnVal as R
     }
-
-internal fun readDirectBootPrefs(
-    context: Context,
-    fileName: String
-): WallpaperInteractiveWatchFaceInstanceParams? =
-    try {
-        val reader = context.openFileInput(fileName)
-        val result =
-            ParcelUtils.fromInputStream<WallpaperInteractiveWatchFaceInstanceParams>(reader)
-        reader.close()
-        result
-    } catch (e: FileNotFoundException) {
-        null
-    }
-
-internal fun writeDirectBootPrefs(
-    context: Context,
-    fileName: String,
-    prefs: WallpaperInteractiveWatchFaceInstanceParams
-) {
-    val writer = context.openFileOutput(fileName, Context.MODE_PRIVATE)
-    ParcelUtils.toOutputStream(prefs, writer)
-    writer.close()
-}
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/control/InteractiveInstanceManager.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/control/InteractiveInstanceManager.kt
index a0f2f30..ed13e05 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/control/InteractiveInstanceManager.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/control/InteractiveInstanceManager.kt
@@ -43,7 +43,9 @@
         @SuppressLint("SyntheticAccessor")
         fun addInstance(impl: InteractiveWatchFaceImpl) {
             synchronized(pendingWallpaperInteractiveWatchFaceInstanceLock) {
-                require(!instances.containsKey(impl.instanceId))
+                require(!instances.containsKey(impl.instanceId)) {
+                    "Already have an InteractiveWatchFaceImpl with id " + impl.instanceId
+                }
                 instances[impl.instanceId] = RefCountedInteractiveWatchFaceInstance(impl, 1)
             }
         }
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/control/InteractiveWatchFaceImpl.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/control/InteractiveWatchFaceImpl.kt
index 28a81c3..909adf1 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/control/InteractiveWatchFaceImpl.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/control/InteractiveWatchFaceImpl.kt
@@ -121,4 +121,4 @@
             engine.watchFaceImpl.complicationsManager.bringAttentionToComplication(id)
         }
     }
-}
\ No newline at end of file
+}
diff --git a/wear/wear-watchface/src/test/java/androidx/wear/watchface/AsyncWatchFaceInitTest.kt b/wear/wear-watchface/src/test/java/androidx/wear/watchface/AsyncWatchFaceInitTest.kt
new file mode 100644
index 0000000..8e36c8e
--- /dev/null
+++ b/wear/wear-watchface/src/test/java/androidx/wear/watchface/AsyncWatchFaceInitTest.kt
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.watchface
+
+import android.content.Context
+import android.os.Handler
+import android.os.Looper
+import android.view.SurfaceHolder
+import androidx.test.core.app.ApplicationProvider
+import androidx.wear.watchface.control.IInteractiveWatchFaceWCS
+import androidx.wear.watchface.control.IPendingInteractiveWatchFaceWCS
+import androidx.wear.watchface.control.InteractiveInstanceManager
+import androidx.wear.watchface.control.data.WallpaperInteractiveWatchFaceInstanceParams
+import androidx.wear.watchface.data.DeviceConfig
+import androidx.wear.watchface.data.SystemState
+import androidx.wear.watchface.style.UserStyle
+import androidx.wear.watchface.style.UserStyleRepository
+import androidx.wear.watchface.style.UserStyleSchema
+import com.google.common.truth.Truth.assertThat
+import com.nhaarman.mockitokotlin2.mock
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.launch
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertNull
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers
+import org.mockito.Mockito
+import org.robolectric.annotation.Config
+import java.util.ArrayDeque
+import java.util.PriorityQueue
+
+internal class TestAsyncWatchFaceService(
+    private val handler: Handler,
+    private val factory: AsyncWatchFaceFactory,
+    private val watchState: MutableWatchState,
+    private val directBootParams: WallpaperInteractiveWatchFaceInstanceParams?
+) : WatchFaceService() {
+    init {
+        attachBaseContext(ApplicationProvider.getApplicationContext())
+    }
+
+    abstract class AsyncWatchFaceFactory {
+        abstract fun createWatchFaceAsync(
+            surfaceHolder: SurfaceHolder,
+            watchState: WatchState
+        ): Deferred<WatchFace>
+    }
+
+    override suspend fun createWatchFace(
+        surfaceHolder: SurfaceHolder,
+        watchState: WatchState
+    ) = factory.createWatchFaceAsync(surfaceHolder, watchState).await()
+
+    override fun getHandler() = handler
+
+    override fun getMutableWatchState() = watchState
+
+    override fun readDirectBootPrefs(
+        context: Context,
+        fileName: String
+    ) = directBootParams
+
+    override fun writeDirectBootPrefs(
+        context: Context,
+        fileName: String,
+        prefs: WallpaperInteractiveWatchFaceInstanceParams
+    ) {
+    }
+
+    override fun expectPreRInitFlow() = false
+}
+
+@Config(manifest = Config.NONE)
+@RunWith(WatchFaceTestRunner::class)
+public class AsyncWatchFaceInitTest {
+    private val handler = mock<Handler>()
+    private var looperTimeMillis = 0L
+    private val pendingTasks = PriorityQueue<Task>()
+    private val userStyleRepository = UserStyleRepository(UserStyleSchema(emptyList()))
+    private val initParams = WallpaperInteractiveWatchFaceInstanceParams(
+        "instanceId",
+        DeviceConfig(
+            false,
+            false,
+            0,
+            0
+        ),
+        SystemState(false, 0),
+        UserStyle(emptyMap()).toWireFormat(),
+        null
+    )
+
+    private class Task(val runTimeMillis: Long, val runnable: Runnable) : Comparable<Task> {
+        override fun compareTo(other: Task) = runTimeMillis.compareTo(other.runTimeMillis)
+    }
+
+    private fun runPostedTasksFor(durationMillis: Long) {
+        looperTimeMillis += durationMillis
+        while (pendingTasks.isNotEmpty() &&
+            pendingTasks.peek()!!.runTimeMillis <= looperTimeMillis
+        ) {
+            pendingTasks.remove().runnable.run()
+        }
+    }
+
+    @Before
+    public fun setUp() {
+        Mockito.`when`(handler.getLooper()).thenReturn(Looper.myLooper())
+
+        // Capture tasks posted to mHandler and insert in mPendingTasks which is under our control.
+        Mockito.doAnswer {
+            pendingTasks.add(
+                Task(
+                    looperTimeMillis,
+                    it.arguments[0] as Runnable
+                )
+            )
+        }.`when`(handler).post(ArgumentMatchers.any())
+
+        Mockito.doAnswer {
+            pendingTasks.add(
+                Task(
+                    looperTimeMillis + it.arguments[1] as Long,
+                    it.arguments[0] as Runnable
+                )
+            )
+        }.`when`(handler).postDelayed(ArgumentMatchers.any(), ArgumentMatchers.anyLong())
+
+        Mockito.doAnswer {
+            // Remove task from the priority queue.  There's no good way of doing this quickly.
+            val queue = ArrayDeque<Task>()
+            while (pendingTasks.isNotEmpty()) {
+                val task = pendingTasks.remove()
+                if (task.runnable != it.arguments[0]) {
+                    queue.add(task)
+                }
+            }
+
+            // Push filtered tasks back on the queue.
+            while (queue.isNotEmpty()) {
+                pendingTasks.add(queue.remove())
+            }
+        }.`when`(handler).removeCallbacks(ArgumentMatchers.any())
+    }
+
+    @Test
+    public fun createInteractiveInstanceFailsIfDirectBootWatchFaceCreationIsInProgress() {
+        val completableWatchFace = CompletableDeferred<WatchFace>()
+        val service = TestAsyncWatchFaceService(
+            handler,
+            object : TestAsyncWatchFaceService.AsyncWatchFaceFactory() {
+                override fun createWatchFaceAsync(
+                    surfaceHolder: SurfaceHolder,
+                    watchState: WatchState
+                ) = completableWatchFace
+            },
+            MutableWatchState(),
+            initParams
+        )
+
+        val engineWrapper = service.onCreateEngine() as WatchFaceService.EngineWrapper
+
+        runPostedTasksFor(0)
+
+        lateinit var pendingException: Exception
+        engineWrapper.coroutineScope.launch {
+            try {
+                // This should fail because the direct boot instance is being constructed.
+                engineWrapper.createInteractiveInstance(initParams)
+            } catch (e: Exception) {
+                pendingException = e
+            }
+        }
+
+        runPostedTasksFor(0)
+
+        assertThat(pendingException.message).startsWith("WatchFace already exists!")
+    }
+
+    @Test
+    public fun directBootAndGetExistingInstanceOrSetPendingWallpaperInteractiveWatchFaceInstance() {
+        val completableDirectBootWatchFace = CompletableDeferred<WatchFace>()
+        lateinit var pendingSurfaceHolder: SurfaceHolder
+        lateinit var pendingWatchState: WatchState
+        val service = TestAsyncWatchFaceService(
+            handler,
+            object : TestAsyncWatchFaceService.AsyncWatchFaceFactory() {
+                override fun createWatchFaceAsync(
+                    surfaceHolder: SurfaceHolder,
+                    watchState: WatchState
+                ): Deferred<WatchFace> {
+                    pendingSurfaceHolder = surfaceHolder
+                    pendingWatchState = watchState
+                    return completableDirectBootWatchFace
+                }
+            },
+            MutableWatchState(),
+            initParams
+        )
+
+        service.onCreateEngine() as WatchFaceService.EngineWrapper
+        runPostedTasksFor(0)
+
+        var pendingInteractiveWatchFaceWcs: IInteractiveWatchFaceWCS? = null
+
+        // There shouldn't be an existing instance, so we expect null.
+        assertNull(
+            InteractiveInstanceManager
+                .getExistingInstanceOrSetPendingWallpaperInteractiveWatchFaceInstance(
+                    InteractiveInstanceManager.PendingWallpaperInteractiveWatchFaceInstance(
+                        initParams,
+                        object : IPendingInteractiveWatchFaceWCS.Stub() {
+                            override fun getApiVersion() =
+                                IPendingInteractiveWatchFaceWCS.API_VERSION
+
+                            override fun onInteractiveWatchFaceWcsCreated(
+                                iInteractiveWatchFaceWcs: IInteractiveWatchFaceWCS?
+                            ) {
+                                pendingInteractiveWatchFaceWcs = iInteractiveWatchFaceWcs
+                            }
+                        }
+                    )
+                )
+        )
+
+        runPostedTasksFor(0)
+
+        // Complete the direct boot watch face which should trigger the callback which sets
+        // pendingInteractiveWatchFaceWcs.
+        completableDirectBootWatchFace.complete(
+            WatchFace(
+                WatchFaceType.ANALOG,
+                userStyleRepository,
+                TestRenderer(pendingSurfaceHolder, userStyleRepository, pendingWatchState, 16L)
+            )
+        )
+
+        runPostedTasksFor(0)
+
+        assertNotNull(pendingInteractiveWatchFaceWcs)
+    }
+}
\ No newline at end of file
diff --git a/wear/wear-watchface/src/test/java/androidx/wear/watchface/TestCommon.kt b/wear/wear-watchface/src/test/java/androidx/wear/watchface/TestCommon.kt
index cf00ca8..657398d 100644
--- a/wear/wear-watchface/src/test/java/androidx/wear/watchface/TestCommon.kt
+++ b/wear/wear-watchface/src/test/java/androidx/wear/watchface/TestCommon.kt
@@ -18,6 +18,7 @@
 
 import android.app.PendingIntent
 import android.content.ComponentName
+import android.content.Context
 import android.content.Intent
 import android.graphics.Canvas
 import android.graphics.Rect
@@ -31,6 +32,7 @@
 import android.view.SurfaceHolder
 import androidx.test.core.app.ApplicationProvider
 import androidx.wear.complications.data.IdAndComplicationData
+import androidx.wear.watchface.control.data.WallpaperInteractiveWatchFaceInstanceParams
 import androidx.wear.watchface.style.UserStyle
 import androidx.wear.watchface.style.UserStyleRepository
 import org.junit.runners.model.FrameworkMethod
@@ -110,6 +112,17 @@
     fun setIsVisible(isVisible: Boolean) {
         watchState.isVisible.value = isVisible
     }
+
+    override fun readDirectBootPrefs(
+        context: Context,
+        fileName: String
+    ) = null
+
+    override fun writeDirectBootPrefs(
+        context: Context,
+        fileName: String,
+        prefs: WallpaperInteractiveWatchFaceInstanceParams
+    ) {}
 }
 
 /**
diff --git a/wear/wear-watchface/src/test/java/androidx/wear/watchface/WatchFaceServiceTest.kt b/wear/wear-watchface/src/test/java/androidx/wear/watchface/WatchFaceServiceTest.kt
index 6b0c3ea..6ad5e06 100644
--- a/wear/wear-watchface/src/test/java/androidx/wear/watchface/WatchFaceServiceTest.kt
+++ b/wear/wear-watchface/src/test/java/androidx/wear/watchface/WatchFaceServiceTest.kt
@@ -60,6 +60,7 @@
 import com.nhaarman.mockitokotlin2.mock
 import org.junit.After
 import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNull
 import org.junit.Assert.assertTrue
 import org.junit.Before
 import org.junit.Test
@@ -161,7 +162,7 @@
                 complicationDrawableLeft,
                 watchState.asWatchState()
             ).apply {
-                idAndData = createIdAndComplicationData(LEFT_COMPLICATION_ID)
+                setIdAndData(createIdAndComplicationData(LEFT_COMPLICATION_ID), false)
             },
             listOf(
                 ComplicationType.RANGED_VALUE,
@@ -182,7 +183,7 @@
                 complicationDrawableRight,
                 watchState.asWatchState()
             ).apply {
-                idAndData = createIdAndComplicationData(RIGHT_COMPLICATION_ID)
+                setIdAndData(createIdAndComplicationData(RIGHT_COMPLICATION_ID), false)
             },
             listOf(
                 ComplicationType.RANGED_VALUE,
@@ -203,7 +204,7 @@
                 complicationDrawableBackground,
                 watchState.asWatchState()
             ).apply {
-                idAndData = createIdAndComplicationData(BACKGROUND_COMPLICATION_ID)
+                setIdAndData(createIdAndComplicationData(BACKGROUND_COMPLICATION_ID), false)
             },
             listOf(
                 ComplicationType.PHOTO_IMAGE
@@ -723,7 +724,7 @@
                     complicationDrawableLeft,
                     watchState.asWatchState()
                 ).apply {
-                    idAndData = createIdAndComplicationData(LEFT_COMPLICATION_ID)
+                    setIdAndData(createIdAndComplicationData(LEFT_COMPLICATION_ID), false)
                 },
                 listOf(
                     ComplicationType.RANGED_VALUE,
@@ -2141,4 +2142,29 @@
         // initialized to false (as opposed to null).
         assertThat(watchState.isAmbient.value).isFalse()
     }
+
+    @Test
+    fun onDestroy_clearsInstanceRecord() {
+        val instanceId = "interactiveInstanceId"
+        initWallpaperInteractiveWatchFaceInstance(
+            WatchFaceType.ANALOG,
+            emptyList(),
+            UserStyleSchema(listOf(colorStyleSetting, watchHandStyleSetting)),
+            WallpaperInteractiveWatchFaceInstanceParams(
+                instanceId,
+                DeviceConfig(
+                    false,
+                    false,
+                    0,
+                    0
+                ),
+                SystemState(false, 0),
+                UserStyle(hashMapOf(colorStyleSetting to blueStyleOption)).toWireFormat(),
+                null
+            )
+        )
+        engineWrapper.onDestroy()
+
+        assertNull(InteractiveInstanceManager.getAndRetainInstance(instanceId))
+    }
 }
diff --git a/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/Proxy.java b/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/Proxy.java
index 679b233..aecb050 100644
--- a/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/Proxy.java
+++ b/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/Proxy.java
@@ -57,6 +57,7 @@
      * @param port port number
      * @param callback callback run when this proxy serves a request
      */
+    @SuppressWarnings("CatchAndPrintStackTrace")
     public Proxy(int port, ProxyRequestCallback callback) {
         mRequestCount = 0;
         mCallback = callback;
@@ -111,6 +112,7 @@
         }).start();
     }
 
+    @SuppressWarnings("CatchAndPrintStackTrace")
     private void listen() {
         try {
             Socket socket = mServerSocket.accept();
@@ -129,6 +131,7 @@
     /**
      * Shutdown.
      */
+    @SuppressWarnings("CatchAndPrintStackTrace")
     public void shutdown() {
         if (!mRunning) return;
         mRunning = false;
@@ -154,6 +157,7 @@
         private BufferedReader mReader;
         private BufferedWriter mWriter;
 
+        @SuppressWarnings("CatchAndPrintStackTrace")
         RequestHandler(Socket socket) {
             mSocket = socket;
             try {
@@ -168,6 +172,7 @@
         }
 
         @Override
+        @SuppressWarnings("CatchAndPrintStackTrace")
         public void run() {
             try {
                 StringBuilder sb = new StringBuilder();
diff --git a/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/TracingControllerActivity.java b/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/TracingControllerActivity.java
index 07e6147..97af732 100644
--- a/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/TracingControllerActivity.java
+++ b/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/TracingControllerActivity.java
@@ -60,6 +60,7 @@
     private String mLogPath;
 
     @Override
+    @SuppressWarnings("CatchAndPrintStackTrace")
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_tracing_controller);
diff --git a/work/integration-tests/testapp/src/main/java/androidx/work/integration/testapp/imageprocessing/ImageProcessingWorker.java b/work/integration-tests/testapp/src/main/java/androidx/work/integration/testapp/imageprocessing/ImageProcessingWorker.java
index a9eaabd..e4c7cd3 100644
--- a/work/integration-tests/testapp/src/main/java/androidx/work/integration/testapp/imageprocessing/ImageProcessingWorker.java
+++ b/work/integration-tests/testapp/src/main/java/androidx/work/integration/testapp/imageprocessing/ImageProcessingWorker.java
@@ -87,6 +87,7 @@
         return Result.success();
     }
 
+    @SuppressWarnings("CatchAndPrintStackTrace")
     private Bitmap retrieveImage(String uriString) {
         Uri uri = Uri.parse(uriString);
         InputStream inputStream = null;
@@ -123,6 +124,7 @@
         }
     }
 
+    @SuppressWarnings("CatchAndPrintStackTrace")
     private String compressImage(Bitmap bitmap) {
         FileOutputStream os = null;
         try {
diff --git a/work/workmanager/src/main/java/androidx/work/impl/model/WorkTypeConverters.java b/work/workmanager/src/main/java/androidx/work/impl/model/WorkTypeConverters.java
index be044f6..2cdd930 100644
--- a/work/workmanager/src/main/java/androidx/work/impl/model/WorkTypeConverters.java
+++ b/work/workmanager/src/main/java/androidx/work/impl/model/WorkTypeConverters.java
@@ -252,6 +252,7 @@
      * @return corresponding byte array representation
      */
     @TypeConverter
+    @SuppressWarnings("CatchAndPrintStackTrace")
     public static byte[] contentUriTriggersToByteArray(ContentUriTriggers triggers) {
         if (triggers.size() == 0) {
             return null;
@@ -290,6 +291,7 @@
      * @return list of {@link ContentUriTriggers.Trigger}s
      */
     @TypeConverter
+    @SuppressWarnings("CatchAndPrintStackTrace")
     public static ContentUriTriggers byteArrayToContentUriTriggers(byte[] bytes) {
         ContentUriTriggers triggers = new ContentUriTriggers();
         if (bytes == null) {