Merge changes I0571008f,I83929941 into androidx-main

* changes:
  useDefaultMaxWidth -> usePlatformDefaultWidth
  Alow Dialogs to use the entire screen width
diff --git a/.github/workflows/presubmit.yml b/.github/workflows/presubmit.yml
index d292755..c41d950 100644
--- a/.github/workflows/presubmit.yml
+++ b/.github/workflows/presubmit.yml
@@ -56,29 +56,10 @@
           echo "ANDROID_SDK_ROOT=$HOME/Library/Android/sdk" >> $GITHUB_ENV
           echo "DIST_DIR=$HOME/dist" >> $GITHUB_ENV
 
-      - name: "Compute actions/checkout arguments"
-        id: checkout-args
-        run: |
-          set -x
-
-          REF=${{ github.event.pull_request.head.ref }}
-          if [ -z "$REF" ]; then
-            REF=${{ github.event.ref }}
-          fi
-          echo "::set-output name=ref::$REF"
-
-          REPOSITORY=${{ github.event.pull_request.head.repo.full_name }}
-          if [ -z "$REPOSITORY" ]; then
-            REPOSITORY=${{ github.repository }}
-          fi
-          echo "::set-output name=repository::$REPOSITORY"
-
       - name: "Checkout androidx repo"
         uses: actions/checkout@v2
         with:
-          ref: ${{ steps.checkout-args.outputs.ref }}
-          repository: ${{ steps.checkout-args.outputs.repository }}
-          fetch-depth: 0 # Need full depth for changed-files-action
+          fetch-depth: 1
 
       - name: "Get changed files in push or pull_request"
         id: changed-files
@@ -102,7 +83,7 @@
           JAVA_HOME: ${{ steps.setup-java.outputs.path }}
         with:
           arguments: -q :ktlintCheckFile ${{ steps.ktlint-file-args.outputs.ktlint-file-args }} ${{ needs.setup.outputs.gradlew_flags }}
-          build-root-directory: activity
+          build-root-directory: room
           configuration-cache-enabled: true
           dependencies-cache-enabled: true
           gradle-executable: activity/gradlew
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatBaseImageViewTest.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatBaseImageViewTest.java
index 18f7ef7..44ce501 100755
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatBaseImageViewTest.java
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatBaseImageViewTest.java
@@ -20,6 +20,8 @@
 import static androidx.test.espresso.Espresso.onView;
 import static androidx.test.espresso.matcher.ViewMatchers.withId;
 
+import static org.junit.Assert.assertEquals;
+
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.PorterDuff;
@@ -35,6 +37,7 @@
 import androidx.appcompat.testutils.TestUtils;
 import androidx.core.content.res.ResourcesCompat;
 import androidx.core.graphics.ColorUtils;
+import androidx.test.annotation.UiThreadTest;
 import androidx.test.filters.MediumTest;
 
 import org.junit.Test;
@@ -459,4 +462,30 @@
         verifyImageSourceIsColoredAs("New lilac image tinting", view,
                 lilacDefault, 0);
     }
+
+    @Test
+    @UiThreadTest
+    public void testLevelOnSetImageDrawable() {
+        final @IdRes int viewId = R.id.view_without_level;
+        final Resources res = mActivity.getResources();
+        final ImageView imageView = mContainer.findViewById(viewId);
+        final Drawable drawable = res.getDrawable(R.drawable.test_level_drawable);
+        drawable.setLevel(5);
+        imageView.setImageDrawable(drawable);
+        assertEquals(5, imageView.getDrawable().getLevel());
+    }
+
+    @Test
+    @UiThreadTest
+    public void testSetImageLevel() {
+        final @IdRes int viewId = R.id.view_without_level;
+        final Resources res = mActivity.getResources();
+        final ImageView imageView = mContainer.findViewById(viewId);
+        imageView.setImageLevel(5);
+        final Drawable drawable = res.getDrawable(R.drawable.test_level_drawable);
+        drawable.setLevel(1);
+        imageView.setImageDrawable(drawable);
+        assertEquals(5, imageView.getDrawable().getLevel());
+    }
+
 }
diff --git a/appcompat/appcompat/src/androidTest/res/layout/appcompat_imagebutton_activity.xml b/appcompat/appcompat/src/androidTest/res/layout/appcompat_imagebutton_activity.xml
index e8733b2..3007988 100755
--- a/appcompat/appcompat/src/androidTest/res/layout/appcompat_imagebutton_activity.xml
+++ b/appcompat/appcompat/src/androidTest/res/layout/appcompat_imagebutton_activity.xml
@@ -96,6 +96,11 @@
             android:layout_height="wrap_content"
             android:focusable="false"/>
 
+        <androidx.appcompat.widget.AppCompatImageButton
+            android:id="@+id/view_without_level"
+            android:layout_width="30dp"
+            android:layout_height="30dp" />
+
     </LinearLayout>
 
 </ScrollView>
diff --git a/appcompat/appcompat/src/androidTest/res/layout/appcompat_imageview_activity.xml b/appcompat/appcompat/src/androidTest/res/layout/appcompat_imageview_activity.xml
index 2ccd325..fbb8459 100644
--- a/appcompat/appcompat/src/androidTest/res/layout/appcompat_imageview_activity.xml
+++ b/appcompat/appcompat/src/androidTest/res/layout/appcompat_imageview_activity.xml
@@ -95,6 +95,11 @@
             android:src="@drawable/test_drawable_blue"
             app:srcCompat="@drawable/test_drawable_red" />
 
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/view_without_level"
+            android:layout_width="30dp"
+            android:layout_height="30dp" />
+
     </LinearLayout>
 
 </ScrollView>
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageButton.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageButton.java
index 1ea6667..39072be 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageButton.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageButton.java
@@ -63,6 +63,7 @@
 
     private final AppCompatBackgroundHelper mBackgroundTintHelper;
     private final AppCompatImageHelper mImageHelper;
+    private boolean mHasLevel = false;
 
     public AppCompatImageButton(@NonNull Context context) {
         this(context, null);
@@ -93,9 +94,17 @@
 
     @Override
     public void setImageDrawable(@Nullable Drawable drawable) {
+        if (mImageHelper != null && drawable != null && !mHasLevel) {
+            // If there is no level set already then obtain the level from the drawable
+            mImageHelper.obtainLevelFromDrawable(drawable);
+        }
         super.setImageDrawable(drawable);
         if (mImageHelper != null) {
             mImageHelper.applySupportImageTint();
+            if (!mHasLevel) {
+                // Apply the level from drawable
+                mImageHelper.applyImageLevel();
+            }
         }
     }
 
@@ -257,4 +266,10 @@
     public boolean hasOverlappingRendering() {
         return mImageHelper.hasOverlappingRendering() && super.hasOverlappingRendering();
     }
+
+    @Override
+    public void setImageLevel(int level) {
+        super.setImageLevel(level);
+        mHasLevel = true;
+    }
 }
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageHelper.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageHelper.java
index 27e9118..0c7a123 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageHelper.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageHelper.java
@@ -43,6 +43,7 @@
     private TintInfo mInternalImageTint;
     private TintInfo mImageTint;
     private TintInfo mTmpInfo;
+    private int mLevel = 0;
 
     public AppCompatImageHelper(@NonNull ImageView view) {
         mView = view;
@@ -221,4 +222,21 @@
 
         return false;
     }
+
+    /**
+     * Extracts the level from the drawable parameter and save it for the future use in
+     * {@link #applyImageLevel()}
+     */
+    void obtainLevelFromDrawable(@NonNull Drawable drawable) {
+        mLevel = drawable.getLevel();
+    }
+
+    /**
+     * Applies the level previously set through {@link #obtainLevelFromDrawable}
+     */
+    void applyImageLevel() {
+        if (mView.getDrawable() != null) {
+            mView.getDrawable().setLevel(mLevel);
+        }
+    }
 }
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageView.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageView.java
index c5bf0f8..78ffeb4 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageView.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatImageView.java
@@ -63,6 +63,8 @@
     private final AppCompatBackgroundHelper mBackgroundTintHelper;
     private final AppCompatImageHelper mImageHelper;
 
+    private boolean mHasLevel = false;
+
     public AppCompatImageView(@NonNull Context context) {
         this(context, null);
     }
@@ -103,9 +105,17 @@
 
     @Override
     public void setImageDrawable(@Nullable Drawable drawable) {
+        if (mImageHelper != null && drawable != null && !mHasLevel) {
+            // If there is no level set already then obtain the level from the drawable
+            mImageHelper.obtainLevelFromDrawable(drawable);
+        }
         super.setImageDrawable(drawable);
         if (mImageHelper != null) {
             mImageHelper.applySupportImageTint();
+            if (!mHasLevel) {
+                // Apply the level from drawable
+                mImageHelper.applyImageLevel();
+            }
         }
     }
 
@@ -268,4 +278,10 @@
     public boolean hasOverlappingRendering() {
         return mImageHelper.hasOverlappingRendering() && super.hasOverlappingRendering();
     }
+
+    @Override
+    public void setImageLevel(int level) {
+        super.setImageLevel(level);
+        mHasLevel = true;
+    }
 }
diff --git a/appcompat/appcompat/src/main/res/drawable/test_level_drawable.xml b/appcompat/appcompat/src/main/res/drawable/test_level_drawable.xml
new file mode 100644
index 0000000..41dadfd
--- /dev/null
+++ b/appcompat/appcompat/src/main/res/drawable/test_level_drawable.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/primary_dark_material_dark"/>
+    <corners android:radius="10dp"/>
+</shape>
\ No newline at end of file
diff --git a/appcompat/appcompat/src/main/res/values-or/strings.xml b/appcompat/appcompat/src/main/res/values-or/strings.xml
index 6f29662..edb0e65 100644
--- a/appcompat/appcompat/src/main/res/values-or/strings.xml
+++ b/appcompat/appcompat/src/main/res/values-or/strings.xml
@@ -31,7 +31,7 @@
     <string name="abc_activity_chooser_view_see_all" msgid="1189761859438369441">"ସବୁ ଦେଖନ୍ତୁ"</string>
     <string name="abc_shareactionprovider_share_with_application" msgid="9055268688411532828">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ସହ ସେୟାର୍‍ କରନ୍ତୁ"</string>
     <string name="abc_shareactionprovider_share_with" msgid="8875138169939072951">"ଏହାଙ୍କ ସହ ସେୟାର୍‌ କରନ୍ତୁ"</string>
-    <string name="abc_capital_on" msgid="884982626291842264">"ଅନ୍"</string>
+    <string name="abc_capital_on" msgid="884982626291842264">"ଚାଲୁ ଅଛି"</string>
     <string name="abc_capital_off" msgid="4215997306490295099">"ବନ୍ଦ"</string>
     <string name="search_menu_title" msgid="6264217191555673260">"Search"</string>
     <string name="abc_prepend_shortcut_label" msgid="5520303668377388990">"ମେନୁ"</string>
@@ -43,5 +43,5 @@
     <string name="abc_menu_function_shortcut_label" msgid="375214403600139847">"Function+"</string>
     <string name="abc_menu_space_shortcut_label" msgid="5473865519181928982">"ସ୍ପେସ୍‍"</string>
     <string name="abc_menu_enter_shortcut_label" msgid="7986526966204849475">"ଏଣ୍ଟର୍"</string>
-    <string name="abc_menu_delete_shortcut_label" msgid="838001238306846836">"ଡିଲିଟ୍‍"</string>
+    <string name="abc_menu_delete_shortcut_label" msgid="838001238306846836">"ଡିଲିଟ୍‌ କରନ୍ତୁ"</string>
 </resources>
diff --git a/buildSrc/src/main/kotlin/androidx/build/checkapi/ApiTasks.kt b/buildSrc/src/main/kotlin/androidx/build/checkapi/ApiTasks.kt
index 4f521ef..46c5574 100644
--- a/buildSrc/src/main/kotlin/androidx/build/checkapi/ApiTasks.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/checkapi/ApiTasks.kt
@@ -163,7 +163,10 @@
 
                 javaInputs = JavaCompileInputs.fromLibraryVariant(
                     variant,
-                    project
+                    project,
+                    // Note, in addition to androidx, bootClasspath will also include stub jars
+                    // from android { useLibrary "android.foo" } block.
+                    files(config.library.bootClasspath)
                 )
                 processManifest = config.library.buildOutputs.getByName(variant.name)
                     .processManifestProvider.get() as ProcessLibraryManifest
diff --git a/buildSrc/src/main/kotlin/androidx/build/java/JavaCompileInputs.kt b/buildSrc/src/main/kotlin/androidx/build/java/JavaCompileInputs.kt
index 98740fa..2693218 100644
--- a/buildSrc/src/main/kotlin/androidx/build/java/JavaCompileInputs.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/java/JavaCompileInputs.kt
@@ -40,7 +40,8 @@
         // Constructs a JavaCompileInputs from a library and its variant
         fun fromLibraryVariant(
             variant: BaseVariant,
-            project: Project
+            project: Project,
+            bootClasspath: FileCollection
         ): JavaCompileInputs {
             val sourceCollection = getSourceCollection(variant, project)
 
@@ -51,7 +52,7 @@
             return JavaCompileInputs(
                 sourceCollection,
                 dependencyClasspath,
-                androidJarFile(project)
+                bootClasspath
             )
         }
 
diff --git a/camera/camera-camera2-pipe-integration/build.gradle b/camera/camera-camera2-pipe-integration/build.gradle
index 09c1751..97e9f89 100644
--- a/camera/camera-camera2-pipe-integration/build.gradle
+++ b/camera/camera-camera2-pipe-integration/build.gradle
@@ -64,6 +64,8 @@
     testImplementation(libs.robolectric)
     testImplementation(libs.kotlinCoroutinesTest)
     testImplementation(project(":camera:camera-camera2-pipe-testing"))
+    testImplementation(project(":camera:camera-testing"))
+    testImplementation(project(":internal-testutils-ktx"))
     testImplementation(project(":internal-testutils-truth"))
 
     androidTestImplementation(libs.testExtJunit)
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/SessionConfigAdapter.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/SessionConfigAdapter.kt
new file mode 100644
index 0000000..6da648c
--- /dev/null
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/SessionConfigAdapter.kt
@@ -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.camera.camera2.pipe.integration.adapter
+
+import android.hardware.camera2.CaptureRequest
+import android.view.Surface
+import androidx.camera.camera2.pipe.CameraGraph
+import androidx.camera.camera2.pipe.StreamId
+import androidx.camera.camera2.pipe.core.Log
+import androidx.camera.camera2.pipe.core.Log.debug
+import androidx.camera.camera2.pipe.integration.impl.UseCaseThreads
+import androidx.camera.core.UseCase
+import androidx.camera.core.impl.DeferrableSurface
+import androidx.camera.core.impl.SessionConfig
+import androidx.camera.core.impl.utils.futures.Futures
+import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.async
+import kotlinx.coroutines.guava.await
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.withContext
+import kotlinx.coroutines.withTimeoutOrNull
+
+private const val TIMEOUT_GET_SURFACE_IN_MS = 5_000L
+
+/**
+ * Aggregate the SessionConfig from a List of [UseCase]s, and provide a validated SessionConfig for
+ * operation.
+ */
+class SessionConfigAdapter(
+    private val useCases: List<UseCase>,
+    private val threads: UseCaseThreads,
+) {
+    private val validatingBuilder: SessionConfig.ValidatingBuilder by lazy {
+        val validatingBuilder = SessionConfig.ValidatingBuilder()
+        useCases.forEach {
+            it.sessionConfig?.let { sessionConfig -> validatingBuilder.add(sessionConfig) }
+                ?: Log.debug { "Failed to add use case: $it" }
+        }
+        validatingBuilder
+    }
+
+    private val deferrableSurfaces: List<DeferrableSurface> by lazy {
+        sessionConfig.surfaces
+    }
+
+    private val sessionConfig: SessionConfig by lazy {
+        check(validatingBuilder.isValid)
+
+        validatingBuilder.build()
+    }
+
+    fun getValidSessionConfigOrNull(): SessionConfig? {
+        return if (isSessionConfigValid()) sessionConfig else null
+    }
+
+    fun isSessionConfigValid(): Boolean {
+        return validatingBuilder.isValid
+    }
+
+    fun setupSurfaceAsync(
+        graph: CameraGraph,
+        surfaceToStreamMap: Map<DeferrableSurface, StreamId>
+    ): Deferred<Unit> =
+        threads.scope.async {
+            val surfaces = getSurfaces(deferrableSurfaces)
+
+            if (!isActive) return@async
+
+            if (surfaces.isEmpty()) {
+                Log.debug { "Surface list is empty" }
+                return@async
+            }
+
+            if (areSurfacesValid(surfaces)) {
+                surfaceToStreamMap.forEach {
+                    val stream = it.value
+                    val surface = surfaces[deferrableSurfaces.indexOf(it.key)]
+                    debug { "Configured $surface for $stream" }
+                    graph.setSurface(
+                        stream = stream,
+                        surface = surface
+                    )
+                }
+            } else {
+                Log.debug { "Surface contains failed, notify SessionConfig invalid" }
+
+                // Only handle the first failed Surface since subsequent calls to
+                // CameraInternal#onUseCaseReset() will handle the other failed Surfaces if there
+                // are any.
+                val deferrableSurface = deferrableSurfaces[surfaces.indexOf(null)]
+                val sessionConfig =
+                    useCases.firstOrNull { useCase ->
+                        useCase.sessionConfig?.surfaces?.contains(deferrableSurface) ?: false
+                    }?.sessionConfig
+
+                withContext(Dispatchers.Main) {
+                    // The error listener is used to notify the UseCase to recreate the pipeline,
+                    // and the create pipeline task would be executed on the main thread.
+                    sessionConfig?.errorListeners?.forEach {
+                        it.onError(
+                            sessionConfig,
+                            SessionConfig.SessionError.SESSION_ERROR_SURFACE_NEEDS_RESET
+                        )
+                    }
+                }
+            }
+        }
+
+    private suspend fun getSurfaces(deferrableSurfaces: List<DeferrableSurface>): List<Surface?> {
+        return withTimeoutOrNull(timeMillis = TIMEOUT_GET_SURFACE_IN_MS) {
+            Futures.successfulAsList(
+                deferrableSurfaces.map {
+                    it.surface
+                }
+            ).await()
+        }.orEmpty()
+    }
+
+    private fun areSurfacesValid(surfaces: List<Surface?>): Boolean {
+        // If a Surface in configuredSurfaces is null it means the
+        // Surface was not retrieved from the ListenableFuture.
+        return surfaces.isNotEmpty() && !surfaces.contains(null)
+    }
+}
+
+/**
+ * Convert the implementation options to the CaptureRequest key-value map.
+ */
+fun SessionConfig.getImplementationOptionParameters(): Map<CaptureRequest.Key<*>, Any> {
+    val parameters = mutableMapOf<CaptureRequest.Key<*>, Any>()
+    for (configOption in implementationOptions.listOptions()) {
+        val requestKey = configOption.token as? CaptureRequest.Key<*> ?: continue
+        val value = implementationOptions.retrieveOption(configOption) ?: continue
+        parameters[requestKey] = value
+    }
+
+    return parameters
+}
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCamera.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCamera.kt
index bf7a093..5f44be3 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCamera.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCamera.kt
@@ -18,7 +18,6 @@
 
 import android.hardware.camera2.CaptureRequest
 import android.hardware.camera2.params.MeteringRectangle
-import android.view.Surface
 import androidx.camera.camera2.pipe.CameraGraph
 import androidx.camera.camera2.pipe.CameraPipe
 import androidx.camera.camera2.pipe.CameraStream
@@ -29,13 +28,13 @@
 import androidx.camera.camera2.pipe.TorchState
 import androidx.camera.camera2.pipe.core.Log.debug
 import androidx.camera.camera2.pipe.integration.adapter.CaptureConfigAdapter
+import androidx.camera.camera2.pipe.integration.adapter.SessionConfigAdapter
+import androidx.camera.camera2.pipe.integration.adapter.getImplementationOptionParameters
 import androidx.camera.camera2.pipe.integration.config.CameraConfig
 import androidx.camera.camera2.pipe.integration.config.UseCaseCameraScope
 import androidx.camera.core.UseCase
 import androidx.camera.core.impl.CaptureConfig
 import androidx.camera.core.impl.DeferrableSurface
-import androidx.camera.core.impl.utils.futures.FutureCallback
-import androidx.camera.core.impl.utils.futures.Futures
 import dagger.Module
 import dagger.Provides
 import kotlinx.atomicfu.atomic
@@ -81,6 +80,7 @@
 ) : UseCaseCamera {
     private val debugId = useCaseCameraIds.incrementAndGet()
     private val currentParameters = mutableMapOf<CaptureRequest.Key<*>, Any>()
+    private var activeSessionConfigAdapter: SessionConfigAdapter? = null
 
     private var _activeUseCases = setOf<UseCase>()
     override var activeUseCases: Set<UseCase>
@@ -89,6 +89,7 @@
             // Note: This may be called with the same set of values that was previously set. This
             // is used as a signal to indicate the properties of the UseCase may have changed.
             _activeUseCases = value
+            activeSessionConfigAdapter = SessionConfigAdapter(_activeUseCases.toList(), threads)
             updateUseCases()
         }
 
@@ -166,14 +167,26 @@
                     }
                 }
             }
-
-            val repeatingCallbacks = useCase.sessionConfig?.repeatingCameraCaptureCallbacks
-            repeatingCallbacks?.forEach {
-                repeatingListeners.addCaptureCallback(it, threads.backgroundExecutor)
-            }
         }
 
-        state.update(streams = repeatingStreamIds, listeners = setOf(repeatingListeners))
+        activeSessionConfigAdapter?.getValidSessionConfigOrNull()?.let { sessionConfig ->
+            sessionConfig.repeatingCameraCaptureCallbacks.forEach { callback ->
+                repeatingListeners.addCaptureCallback(
+                    callback,
+                    threads.backgroundExecutor
+                )
+            }
+
+            // Only update the state when the SessionConfig is valid
+            state.update(
+                parameters = sessionConfig.getImplementationOptionParameters(),
+                streams = repeatingStreamIds,
+                listeners = setOf(repeatingListeners)
+            )
+        } ?: run {
+            debug { "Unable to reset the session due to invalid config" }
+            // TODO: Consider to reset the session if there is no valid config.
+        }
     }
 
     override fun toString(): String = "UseCaseCamera-$debugId"
@@ -226,25 +239,16 @@
                     if (stream != null && deferredSurfaces != null && deferredSurfaces.size == 1) {
                         val deferredSurface = deferredSurfaces.first()
                         surfaceToStreamMap[deferredSurface] = stream.id
-
-                        Futures.addCallback(
-                            deferredSurface.surface,
-                            object : FutureCallback<Surface?> {
-                                override fun onSuccess(result: Surface?) {
-                                    debug { "Configured $result for $stream" }
-                                    graph.setSurface(stream.id, result)
-                                }
-
-                                override fun onFailure(t: Throwable) {
-                                    debug(t) { "Surface for $deferredSurface failed to arrive!" }
-                                    graph.setSurface(stream.id, null)
-                                }
-                            },
-                            threads.backgroundExecutor
-                        )
                     }
                 }
 
+                val adapter = SessionConfigAdapter(useCases, threads)
+                if (adapter.isSessionConfigValid()) {
+                    adapter.setupSurfaceAsync(graph, surfaceToStreamMap)
+                } else {
+                    debug { "Unable to create capture session due to conflicting configurations" }
+                }
+
                 val state = UseCaseCameraState(graph, threads)
                 val configAdapter =
                     CaptureConfigAdapter(surfaceToStreamMap, threads.backgroundExecutor)
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/SessionConfigAdapterTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/SessionConfigAdapterTest.kt
new file mode 100644
index 0000000..0d46290
--- /dev/null
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/SessionConfigAdapterTest.kt
@@ -0,0 +1,280 @@
+/*
+ * 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.camera2.pipe.integration.adapter
+
+import android.graphics.SurfaceTexture
+import android.hardware.camera2.CameraDevice
+import android.os.Build
+import android.view.Surface
+import androidx.camera.camera2.pipe.CameraGraph
+import androidx.camera.camera2.pipe.StreamGraph
+import androidx.camera.camera2.pipe.StreamId
+import androidx.camera.camera2.pipe.integration.impl.UseCaseThreads
+import androidx.camera.core.impl.DeferrableSurface
+import androidx.camera.core.impl.SessionConfig
+import androidx.camera.core.impl.utils.futures.Futures
+import androidx.camera.testing.fakes.FakeUseCase
+import androidx.camera.testing.fakes.FakeUseCaseConfig
+import androidx.testutils.MainDispatcherRule
+import com.google.common.truth.Truth.assertThat
+import com.google.common.util.concurrent.ListenableFuture
+import kotlinx.coroutines.CoroutineName
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.asCoroutineDispatcher
+import kotlinx.coroutines.runBlocking
+import org.junit.AfterClass
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.internal.DoNotInstrument
+import java.util.concurrent.Executors
+
+@RunWith(RobolectricCameraPipeTestRunner::class)
+@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
+@DoNotInstrument
+class SessionConfigAdapterTest {
+
+    @get:Rule
+    val dispatcherRule = MainDispatcherRule(useCaseThreads.backgroundDispatcher)
+
+    companion object {
+        private val executor = Executors.newSingleThreadExecutor()
+        private val useCaseThreads by lazy {
+            val dispatcher = executor.asCoroutineDispatcher()
+            val cameraScope = CoroutineScope(
+                Job() +
+                    dispatcher +
+                    CoroutineName("SessionConfigAdapterTest")
+            )
+
+            UseCaseThreads(
+                cameraScope,
+                executor,
+                dispatcher
+            )
+        }
+
+        @JvmStatic
+        @AfterClass
+        fun close() {
+            executor.shutdown()
+        }
+    }
+
+    @Test
+    fun setupSurface_deferrableSurfaceClosed_notifyError() = runBlocking {
+        // Arrange, create DeferrableSurface and invoke DeferrableSurface#close() immediately to
+        // close the Surface and we expect the DeferrableSurface.getSurface() will return a
+        // {@link SurfaceClosedException}.
+        val testDeferrableSurface1 = createTestDeferrableSurface().also { it.close() }
+        val testDeferrableSurface2 = createTestDeferrableSurface().also { it.close() }
+
+        val errorListener = object : SessionConfig.ErrorListener {
+            val results = mutableListOf<Pair<SessionConfig, SessionConfig.SessionError>>()
+            override fun onError(sessionConfig: SessionConfig, error: SessionConfig.SessionError) {
+                results.add(Pair(sessionConfig, error))
+            }
+        }
+
+        val fakeTestUseCase1 = createFakeTestUseCase {
+            it.setupSessionConfig(
+                SessionConfig.Builder().also { sessionConfigBuilder ->
+                    sessionConfigBuilder.setTemplateType(CameraDevice.TEMPLATE_PREVIEW)
+                    sessionConfigBuilder.addSurface(testDeferrableSurface1)
+                    sessionConfigBuilder.addErrorListener(errorListener)
+                }
+            )
+        }
+        val fakeTestUseCase2 = createFakeTestUseCase {
+            it.setupSessionConfig(
+                SessionConfig.Builder().also { sessionConfigBuilder ->
+                    sessionConfigBuilder.setTemplateType(CameraDevice.TEMPLATE_PREVIEW)
+                    sessionConfigBuilder.addSurface(testDeferrableSurface2)
+                    sessionConfigBuilder.addErrorListener(errorListener)
+                }
+            )
+        }
+
+        val fakeGraph = FakeCameraGraph()
+
+        // Act
+        SessionConfigAdapter(
+            useCases = listOf(fakeTestUseCase1, fakeTestUseCase2), threads = useCaseThreads
+        ).setupSurfaceAsync(
+            fakeGraph,
+            mapOf(
+                testDeferrableSurface1 to StreamId(0),
+                testDeferrableSurface2 to StreamId(1)
+            )
+        ).await()
+
+        // Assert, verify it only reports the SURFACE_NEEDS_RESET error on one SessionConfig
+        // at a time.
+        assertThat(fakeGraph.setSurfaceResults.size).isEqualTo(0)
+        assertThat(errorListener.results.size).isEqualTo(1)
+        assertThat(errorListener.results[0].second).isEqualTo(
+            SessionConfig.SessionError.SESSION_ERROR_SURFACE_NEEDS_RESET
+        )
+    }
+
+    @Test
+    fun setupSurface_surfacesShouldSetToGraph() = runBlocking {
+        // Arrange
+        val testDeferrableSurface1 = createTestDeferrableSurface()
+        val testDeferrableSurface2 = createTestDeferrableSurface()
+        val fakeTestUseCase1 = createFakeTestUseCase {
+            it.setupSessionConfig(
+                SessionConfig.Builder().also { sessionConfigBuilder ->
+                    sessionConfigBuilder.setTemplateType(CameraDevice.TEMPLATE_PREVIEW)
+                    sessionConfigBuilder.addSurface(testDeferrableSurface1)
+                }
+            )
+        }
+        val fakeTestUseCase2 = createFakeTestUseCase {
+            it.setupSessionConfig(
+                SessionConfig.Builder().also { sessionConfigBuilder ->
+                    sessionConfigBuilder.setTemplateType(CameraDevice.TEMPLATE_PREVIEW)
+                    sessionConfigBuilder.addSurface(testDeferrableSurface2)
+                }
+            )
+        }
+
+        val fakeGraph = FakeCameraGraph()
+        val deferrableSurfaceToStreamId: Map<DeferrableSurface, StreamId> = mapOf(
+            testDeferrableSurface1 to StreamId(0),
+            testDeferrableSurface2 to StreamId(1)
+        )
+
+        // Act
+        SessionConfigAdapter(
+            useCases = listOf(fakeTestUseCase1, fakeTestUseCase2), threads = useCaseThreads
+        ).setupSurfaceAsync(
+            fakeGraph, deferrableSurfaceToStreamId
+        ).await()
+
+        // Assert, 2 surfaces from the fakeTestUseCase1 and fakeTestUseCase2 should be set to the
+        // Graph
+        assertThat(fakeGraph.setSurfaceResults).isEqualTo(
+            deferrableSurfaceToStreamId.map {
+                it.value to (it.key as TestDeferrableSurface).testSurface
+            }.toMap()
+        )
+
+        // Clean up
+        testDeferrableSurface1.close()
+        testDeferrableSurface2.close()
+    }
+
+    @Test
+    fun invalidSessionConfig() {
+        // Arrange
+        val testDeferrableSurface = createTestDeferrableSurface()
+
+        // Create an invalid SessionConfig which doesn't set the template
+        val fakeTestUseCase = createFakeTestUseCase {
+            it.setupSessionConfig(
+                SessionConfig.Builder().also { sessionConfigBuilder ->
+                    sessionConfigBuilder.addSurface(testDeferrableSurface)
+                }
+            )
+        }
+
+        // Act
+        val sessionConfigAdapter = SessionConfigAdapter(
+            useCases = listOf(fakeTestUseCase), threads = useCaseThreads
+        )
+
+        // Assert
+        assertThat(sessionConfigAdapter.isSessionConfigValid()).isFalse()
+        assertThat(sessionConfigAdapter.getValidSessionConfigOrNull()).isNull()
+
+        // Clean up
+        testDeferrableSurface.close()
+    }
+
+    private fun createFakeTestUseCase(block: (FakeTestUseCase) -> Unit): FakeTestUseCase = run {
+        val configBuilder = FakeUseCaseConfig.Builder().setTargetName("UseCase")
+        FakeTestUseCase(configBuilder.useCaseConfig).also {
+            block(it)
+        }
+    }
+
+    private fun createTestDeferrableSurface(): TestDeferrableSurface = run {
+        TestDeferrableSurface().also {
+            it.terminationFuture.addListener({ it.cleanUp() }, useCaseThreads.backgroundExecutor)
+        }
+    }
+}
+
+private class FakeTestUseCase(
+    config: FakeUseCaseConfig,
+) : FakeUseCase(config) {
+
+    fun setupSessionConfig(sessionConfigBuilder: SessionConfig.Builder) {
+        updateSessionConfig(sessionConfigBuilder.build())
+        notifyActive()
+    }
+}
+
+private class TestDeferrableSurface : DeferrableSurface() {
+    private val surfaceTexture = SurfaceTexture(0).also {
+        it.setDefaultBufferSize(0, 0)
+    }
+    val testSurface = Surface(surfaceTexture)
+
+    override fun provideSurface(): ListenableFuture<Surface> {
+        return Futures.immediateFuture(testSurface)
+    }
+
+    fun cleanUp() {
+        testSurface.release()
+        surfaceTexture.release()
+    }
+}
+
+private class FakeCameraGraph : CameraGraph {
+    val setSurfaceResults = mutableMapOf<StreamId, Surface?>()
+
+    override val streams: StreamGraph
+        get() = throw NotImplementedError("Not used in testing")
+
+    override suspend fun acquireSession(): CameraGraph.Session {
+        throw NotImplementedError("Not used in testing")
+    }
+
+    override fun acquireSessionOrNull(): CameraGraph.Session? {
+        throw NotImplementedError("Not used in testing")
+    }
+
+    override fun close() {
+        throw NotImplementedError("Not used in testing")
+    }
+
+    override fun setSurface(stream: StreamId, surface: Surface?) {
+        setSurfaceResults[stream] = surface
+    }
+
+    override fun start() {
+        throw NotImplementedError("Not used in testing")
+    }
+
+    override fun stop() {
+        throw NotImplementedError("Not used in testing")
+    }
+}
diff --git a/car/app/app-projected/src/main/aidl/androidx/car/app/hardware/ICarHardwareHost.aidl b/car/app/app-projected/src/main/aidl/androidx/car/app/hardware/ICarHardwareHost.aidl
index 35fc908..c366c06 100644
--- a/car/app/app-projected/src/main/aidl/androidx/car/app/hardware/ICarHardwareHost.aidl
+++ b/car/app/app-projected/src/main/aidl/androidx/car/app/hardware/ICarHardwareHost.aidl
@@ -37,6 +37,6 @@
    * Indicates to the host that the app wants to unsubscribe from a vehicle result that changes
    * over time.
    */
-  void unsubscribeCarHardwareResult(in int resultType) = 3;
+  void unsubscribeCarHardwareResult(in int resultType, in @nullable Bundleable params) = 3;
 
 }
diff --git a/car/app/app-projected/src/test/java/androidx/car/app/hardware/common/CarHardwareHostDispatcherTest.java b/car/app/app-projected/src/test/java/androidx/car/app/hardware/common/CarHardwareHostDispatcherTest.java
index 6c9644d..d963035 100644
--- a/car/app/app-projected/src/test/java/androidx/car/app/hardware/common/CarHardwareHostDispatcherTest.java
+++ b/car/app/app-projected/src/test/java/androidx/car/app/hardware/common/CarHardwareHostDispatcherTest.java
@@ -123,7 +123,7 @@
         }
 
         @Override
-        public void getCarHardwareResult(int resultType, Bundleable params,
+        public void getCarHardwareResult(int resultType, @Nullable Bundleable params,
                 ICarHardwareResult callback) throws RemoteException {
             mCallback = callback;
             // Record the call in the mock
@@ -135,12 +135,13 @@
         }
 
         @Override
-        public void subscribeCarHardwareResult(int resultType, Bundleable params,
+        public void subscribeCarHardwareResult(int resultType, @Nullable Bundleable params,
                 ICarHardwareResult callback) throws RemoteException {
         }
 
         @Override
-        public void unsubscribeCarHardwareResult(int resultType) throws RemoteException {
+        public void unsubscribeCarHardwareResult(int resultType, @Nullable Bundleable params)
+                throws RemoteException {
         }
     }
 }
diff --git a/car/app/app-projected/src/test/java/androidx/car/app/hardware/common/CarResultStubTest.java b/car/app/app-projected/src/test/java/androidx/car/app/hardware/common/CarResultStubTest.java
index fb4f66f..7e7347c 100644
--- a/car/app/app-projected/src/test/java/androidx/car/app/hardware/common/CarResultStubTest.java
+++ b/car/app/app-projected/src/test/java/androidx/car/app/hardware/common/CarResultStubTest.java
@@ -145,7 +145,7 @@
         }
 
         @Override
-        public void getCarHardwareResult(int resultType, Bundleable params,
+        public void getCarHardwareResult(int resultType, @Nullable Bundleable params,
                 ICarHardwareResult callback) throws RemoteException {
             mCallback = callback;
             // Record the call in the mock
@@ -157,7 +157,7 @@
         }
 
         @Override
-        public void subscribeCarHardwareResult(int resultType, Bundleable params,
+        public void subscribeCarHardwareResult(int resultType, @Nullable Bundleable params,
                 ICarHardwareResult callback) throws RemoteException {
             mCallback = callback;
             mMockCarHardwareHost.subscribeCarHardwareResult(resultType, params, callback);
@@ -167,8 +167,9 @@
         }
 
         @Override
-        public void unsubscribeCarHardwareResult(int resultType) throws RemoteException {
-            mMockCarHardwareHost.unsubscribeCarHardwareResult(resultType);
+        public void unsubscribeCarHardwareResult(int resultType, @Nullable Bundleable params)
+                throws RemoteException {
+            mMockCarHardwareHost.unsubscribeCarHardwareResult(resultType, params);
         }
     }
 }
diff --git a/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/navigation/SurfaceRenderer.java b/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/navigation/SurfaceRenderer.java
index 878d2ca..d0285b9 100644
--- a/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/navigation/SurfaceRenderer.java
+++ b/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/navigation/SurfaceRenderer.java
@@ -34,13 +34,19 @@
 import androidx.car.app.hardware.CarHardwareManager;
 import androidx.car.app.hardware.common.CarValue;
 import androidx.car.app.hardware.common.OnCarDataListener;
+import androidx.car.app.hardware.info.Accelerometer;
+import androidx.car.app.hardware.info.CarHardwareLocation;
 import androidx.car.app.hardware.info.CarInfo;
+import androidx.car.app.hardware.info.CarSensors;
+import androidx.car.app.hardware.info.Compass;
+import androidx.car.app.hardware.info.Gyroscope;
 import androidx.car.app.hardware.info.Model;
 import androidx.core.content.ContextCompat;
 import androidx.lifecycle.DefaultLifecycleObserver;
 import androidx.lifecycle.Lifecycle;
 import androidx.lifecycle.LifecycleOwner;
 
+import java.util.List;
 import java.util.concurrent.Executor;
 
 /** A very simple implementation of a renderer for the app's background surface. */
@@ -65,8 +71,11 @@
     private final Paint mCarInfoPaint = new Paint();
     private boolean mShowCarHardwareSurfaceInfo;
 
-    @Nullable
-    Model mModel;
+    @Nullable Model mModel;
+    @Nullable Accelerometer mAccelerometer;
+    @Nullable Gyroscope mGyroscope;
+    @Nullable Compass mCompass;
+    @Nullable CarHardwareLocation mCarHardwareLocation;
 
     private OnCarDataListener<Model> mModelListener = new OnCarDataListener<Model>() {
         @Override
@@ -79,6 +88,38 @@
         }
     };
 
+    private OnCarDataListener<Accelerometer> mAccelerometerListener = data -> {
+        synchronized (SurfaceRenderer.this) {
+            Log.i(TAG, String.format("Received accelerometer %s", data));
+            mAccelerometer = data;
+            renderFrame();
+        }
+    };
+
+    private OnCarDataListener<Gyroscope> mGyroscopeListener = data -> {
+        synchronized (SurfaceRenderer.this) {
+            Log.i(TAG, String.format("Received gyroscope %s", data));
+            mGyroscope = data;
+            renderFrame();
+        }
+    };
+
+    private OnCarDataListener<Compass> mCompassListener = data -> {
+        synchronized (SurfaceRenderer.this) {
+            Log.i(TAG, String.format("Received compass %s", data));
+            mCompass = data;
+            renderFrame();
+        }
+    };
+
+    private OnCarDataListener<CarHardwareLocation> mCarLocationListener = data -> {
+        synchronized (SurfaceRenderer.this) {
+            Log.i(TAG, String.format("Received car location %s", data));
+            mCarHardwareLocation = data;
+            renderFrame();
+        }
+    };
+
     private final SurfaceCallback mSurfaceCallback =
             new SurfaceCallback() {
                 @Override
@@ -142,7 +183,6 @@
         mCarInfoPaint.setAntiAlias(true);
         mCarInfoPaint.setStyle(Style.STROKE);
         mCarInfoPaint.setTextAlign(Align.CENTER);
-
         mCarHardwareExecutor = ContextCompat.getMainExecutor(mCarContext);
 
         lifecycle.addObserver(this);
@@ -158,14 +198,39 @@
         if (isEnabled == mShowCarHardwareSurfaceInfo) {
             return;
         }
+        CarHardwareManager carHardwareManager =
+                mCarContext.getCarService(CarHardwareManager.class);
         if (isEnabled) {
-            CarHardwareManager carHardwareManager =
-                    mCarContext.getCarService(CarHardwareManager.class);
-
             // Request any single shot values.
             CarInfo carInfo = carHardwareManager.getCarInfo();
             mModel = null;
             carInfo.getModel(mCarHardwareExecutor, mModelListener);
+
+            // Request sensors
+            CarSensors carSensors = carHardwareManager.getCarSensors();
+            mCompass = null;
+            carSensors.addCompassListener(CarSensors.UPDATE_RATE_NORMAL, mCarHardwareExecutor,
+                    mCompassListener);
+            mGyroscope = null;
+            carSensors.addGyroscopeListener(CarSensors.UPDATE_RATE_NORMAL, mCarHardwareExecutor,
+                    mGyroscopeListener);
+            mAccelerometer = null;
+            carSensors.addAccelerometerListener(CarSensors.UPDATE_RATE_NORMAL, mCarHardwareExecutor,
+                    mAccelerometerListener);
+            mCarHardwareLocation = null;
+            carSensors.addCarHardwareLocationListener(CarSensors.UPDATE_RATE_NORMAL,
+                    mCarHardwareExecutor, mCarLocationListener);
+        } else {
+            // Unsubscribe sensors
+            CarSensors carSensors = carHardwareManager.getCarSensors();
+            mCompass = null;
+            carSensors.removeCompassListener(mCompassListener);
+            mGyroscope = null;
+            carSensors.removeGyroscopeListener(mGyroscopeListener);
+            mAccelerometer = null;
+            carSensors.removeAccelerometerListener(mAccelerometerListener);
+            mCarHardwareLocation = null;
+            carSensors.removeCarHardwareLocationListener(mCarLocationListener);
         }
         mShowCarHardwareSurfaceInfo = isEnabled;
         renderFrame();
@@ -204,6 +269,10 @@
                 visibleArea.set(0, 0, canvas.getWidth() - 1, canvas.getHeight() - 1);
             }
 
+            Paint.FontMetrics fm = mCarInfoPaint.getFontMetrics();
+            float height = fm.descent - fm.ascent;
+            float verticalPos = visibleArea.top + VERTICAL_TEXT_MARGIN_FROM_TOP;
+
             StringBuilder info = new StringBuilder();
             if (mModel == null) {
                 info.append("Fetching model info.");
@@ -226,11 +295,71 @@
                     info.append(mModel.getYear());
                 }
             }
-            canvas.drawText(info.toString(), visibleArea.centerX(),
-                    visibleArea.top + VERTICAL_TEXT_MARGIN_FROM_TOP, mCarInfoPaint);
+            canvas.drawText(info.toString(), visibleArea.centerX(), verticalPos, mCarInfoPaint);
+            verticalPos += height;
+            info = new StringBuilder();
+            if (mAccelerometer == null) {
+                info.append("Fetching accelerometer");
+            } else {
+                if (mAccelerometer.getForces().getStatus() != CarValue.STATUS_SUCCESS) {
+                    info.append("Accelerometer unavailable.");
+                } else {
+                    info.append("Accelerometer: ");
+                    appendFloatList(info, mAccelerometer.getForces().getValue());
+                }
+            }
+            canvas.drawText(info.toString(), visibleArea.centerX(), verticalPos, mCarInfoPaint);
+            verticalPos += height;
+            info = new StringBuilder();
+            if (mGyroscope == null) {
+                info.append("Fetching gyroscope");
+            } else {
+                if (mGyroscope.getRotations().getStatus() != CarValue.STATUS_SUCCESS) {
+                    info.append("Gyroscope unavailable.");
+                } else {
+                    info.append("Gyroscope: ");
+                    appendFloatList(info, mGyroscope.getRotations().getValue());
+                }
+            }
+            canvas.drawText(info.toString(), visibleArea.centerX(), verticalPos, mCarInfoPaint);
+            verticalPos += height;
+            info = new StringBuilder();
+            if (mCompass == null) {
+                info.append("Fetching compass");
+            } else {
+                if (mCompass.getOrientations().getStatus() != CarValue.STATUS_SUCCESS) {
+                    info.append("Compass unavailable.");
+                } else {
+                    info.append("Compass: ");
+                    appendFloatList(info, mCompass.getOrientations().getValue());
+                }
+            }
+            canvas.drawText(info.toString(), visibleArea.centerX(), verticalPos, mCarInfoPaint);
+            verticalPos += height;
+            info = new StringBuilder();
+            if (mCarHardwareLocation == null) {
+                info.append("Fetching location");
+            } else {
+                if (mCarHardwareLocation.getLocation().getStatus() != CarValue.STATUS_SUCCESS) {
+                    info.append("Car Hardware Location unavailable");
+                } else {
+                    info.append("Car Hardware location: ");
+                    info.append(mCarHardwareLocation.getLocation().getValue().toString());
+                }
+            }
+            canvas.drawText(info.toString(), visibleArea.centerX(), verticalPos, mCarInfoPaint);
         }
     }
 
+    private void appendFloatList(StringBuilder builder, List<Float> values) {
+        builder.append("[ ");
+        for (Float value : values) {
+            builder.append(value);
+            builder.append(" ");
+        }
+        builder.append("]");
+    }
+
     private void renderStandardFrame(Canvas canvas) {
 
         // Draw a rectangle showing the inset.
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 91b6a8b..0a9dad9 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
@@ -22,7 +22,7 @@
 enum class AnimationEndReason {
     /**
      * Animation will be forced to end when its value reaches upper/lower bound (if they have
-     * been defined, e.g via [Animatable.updateBounds])
+     * been defined, e.g. via [Animatable.updateBounds])
      *
      * Unlike [Finished], when an animation ends due to [BoundReached], it often falls short
      * from its initial target, and the remaining velocity is often non-zero. Both the end value
diff --git a/compose/animation/animation/api/public_plus_experimental_1.0.0-beta10.txt b/compose/animation/animation/api/public_plus_experimental_1.0.0-beta10.txt
index 3ca024e..20da353 100644
--- a/compose/animation/animation/api/public_plus_experimental_1.0.0-beta10.txt
+++ b/compose/animation/animation/api/public_plus_experimental_1.0.0-beta10.txt
@@ -50,7 +50,7 @@
     method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(boolean visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.RowScope, boolean visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.ColumnScope, boolean visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
-    method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, androidx.compose.animation.EnterTransition enter, androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
+    method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.RowScope, androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.ColumnScope, androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static <T> void AnimatedVisibility(androidx.compose.animation.core.Transition<T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
diff --git a/compose/animation/animation/api/public_plus_experimental_current.txt b/compose/animation/animation/api/public_plus_experimental_current.txt
index 3ca024e..20da353 100644
--- a/compose/animation/animation/api/public_plus_experimental_current.txt
+++ b/compose/animation/animation/api/public_plus_experimental_current.txt
@@ -50,7 +50,7 @@
     method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(boolean visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.RowScope, boolean visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.ColumnScope, boolean visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
-    method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, androidx.compose.animation.EnterTransition enter, androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
+    method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.RowScope, androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.ColumnScope, androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static <T> void AnimatedVisibility(androidx.compose.animation.core.Transition<T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
diff --git a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedVisibility.kt b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedVisibility.kt
index c1b5784..f5beb63 100644
--- a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedVisibility.kt
+++ b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedVisibility.kt
@@ -345,10 +345,10 @@
  *
  * @param visibleState defines whether the content should be visible
  * @param modifier modifier for the [Layout] created to contain the [content]
- * @param enter EnterTransition(s) used for the appearing animation, fading in while expanding
- *              vertically by default
+ * @param enter EnterTransition(s) used for the appearing animation, fading in while expanding by
+ *              default
  * @param exit ExitTransition(s) used for the disappearing animation, fading out while
- *             shrinking vertically by default
+ *             shrinking by default
  * @param content Content to appear or disappear based on the value of [visibleState]
  *
  * @see EnterTransition
@@ -366,8 +366,8 @@
 fun AnimatedVisibility(
     visibleState: MutableTransitionState<Boolean>,
     modifier: Modifier = Modifier,
-    enter: EnterTransition,
-    exit: ExitTransition,
+    enter: EnterTransition = fadeIn() + expandIn(),
+    exit: ExitTransition = fadeOut() + shrinkOut(),
     content: @Composable() AnimatedVisibilityScope.() -> Unit
 ) {
     val transition = updateTransition(visibleState)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/ForEachGestureTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/ForEachGestureTest.kt
new file mode 100644
index 0000000..544f512
--- /dev/null
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/ForEachGestureTest.kt
@@ -0,0 +1,71 @@
+/*
+ * 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.gesture
+
+import androidx.compose.foundation.gestures.forEachGesture
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.size
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import org.junit.Assert.assertTrue
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import java.util.concurrent.CancellationException
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class ForEachGestureTest {
+    @get:Rule
+    val rule = createComposeRule()
+
+    /**
+     * Make sure that an empty `forEachGesture` block does not cause a crash.
+     */
+    @Test
+    fun testEmptyForEachGesture() {
+        val latch1 = CountDownLatch(2)
+        val latch2 = CountDownLatch(1)
+        rule.setContent {
+            Box(
+                Modifier.pointerInput(Unit) {
+                    forEachGesture {
+                        if (latch1.count == 0L) {
+                            // forEachGesture will loop infinitely with nothing in the middle
+                            // so cancel this before it becomes a problem
+                            throw CancellationException()
+                        }
+                        latch1.countDown()
+                    }
+                }.pointerInput(Unit) {
+                    awaitPointerEventScope {
+                        assertTrue(currentEvent.changes.isEmpty())
+                        latch2.countDown()
+                    }
+                }.size(10.dp)
+            )
+        }
+        assertTrue(latch1.await(1, TimeUnit.SECONDS))
+        assertTrue(latch2.await(1, TimeUnit.SECONDS))
+    }
+}
\ No newline at end of file
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 4e484f4..7bcb55a 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
@@ -82,7 +82,7 @@
      * [draggable].
      *
      * This method is used internally for low level operations, allowing implementers of
-     * [DraggableState] influence the consumption as suits them, e.g introduce nested scrolling.
+     * [DraggableState] influence the consumption as suits them, e.g. introduce nested scrolling.
      * Manually dispatching delta via this method will likely result in a bad user experience,
      * you must prefer [drag] method over this one.
      *
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformGestureDetector.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformGestureDetector.kt
index 3755604..725334c 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformGestureDetector.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformGestureDetector.kt
@@ -32,7 +32,7 @@
 import kotlin.math.atan2
 
 /**
- * A gesture detector for rotationg, panning, and zoom. Once touch slop has been reached, the
+ * A gesture detector for rotation, panning, and zoom. Once touch slop has been reached, the
  * user can use rotation, panning and zoom gestures. [onGesture] will be called when any of the
  * rotation, zoom or pan occurs, passing the rotation angle in degrees, zoom in scale factor and
  * pan as an offset in pixels. Each of these changes is a difference between the previous call
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazySemantics.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazySemantics.kt
index a460b39..8f697eb 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazySemantics.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazySemantics.kt
@@ -16,13 +16,19 @@
 
 package androidx.compose.foundation.lazy
 
+import androidx.compose.foundation.gestures.ScrollableState
+import androidx.compose.foundation.gestures.scrollBy
 import androidx.compose.runtime.State
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.semantics.CollectionInfo
+import androidx.compose.ui.semantics.ScrollAxisRange
 import androidx.compose.ui.semantics.collectionInfo
+import androidx.compose.ui.semantics.horizontalScrollAxisRange
 import androidx.compose.ui.semantics.indexForKey
+import androidx.compose.ui.semantics.scrollBy
 import androidx.compose.ui.semantics.scrollToIndex
 import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.verticalScrollAxisRange
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
 
@@ -43,6 +49,31 @@
             -1
         }
 
+        val accessibilityScrollState = ScrollAxisRange(
+            value = {
+                // This is a simple way of representing the current position without
+                // needing any lazy items to be measured. It's good enough so far, because
+                // screen-readers care mostly about whether scroll position changed or not
+                // rather than the actual offset in pixels.
+                state.firstVisibleItemIndex + state.firstVisibleItemScrollOffset / 100_000f
+            },
+            maxValue = { Float.POSITIVE_INFINITY }
+        )
+        if (isVertical) {
+            verticalScrollAxisRange = accessibilityScrollState
+        } else {
+            horizontalScrollAxisRange = accessibilityScrollState
+        }
+
+        scrollBy { x, y ->
+            val delta = if (isVertical) { y } else { x }
+            coroutineScope.launch {
+                (state as ScrollableState).scrollBy(delta)
+            }
+            // TODO(aelias): is it important to return false if we know in advance we cannot scroll?
+            true
+        }
+
         scrollToIndex { index ->
             require(index >= 0 && index < stateOfItemsProvider.value.itemsCount) {
                 "Can't scroll to index $index, it is out of bounds [0, ${stateOfItemsProvider
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/animation/Animation.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/animation/Animation.kt
index f674d16..ccf28a0 100644
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/animation/Animation.kt
+++ b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/animation/Animation.kt
@@ -15,7 +15,10 @@
  */
 
 // Ignore lint warnings in documentation snippets
-@file:Suppress("CanBeVal", "UNUSED_VARIABLE", "RemoveExplicitTypeArguments", "unused")
+@file:Suppress(
+    "CanBeVal", "UNUSED_VARIABLE", "RemoveExplicitTypeArguments", "unused",
+    "MemberVisibilityCanBePrivate"
+)
 @file:SuppressLint("ModifierInspectorInfo", "NewApi")
 
 package androidx.compose.integration.docs.animation
@@ -95,6 +98,7 @@
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.input.pointer.positionChange
 import androidx.compose.ui.input.pointer.util.VelocityTracker
+import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.test.captureToImage
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onRoot
@@ -128,11 +132,12 @@
 @Composable
 fun AnimatedVisibilityWithEnterAndExit() {
     var visible by remember { mutableStateOf(true) }
+    val density = LocalDensity.current
     AnimatedVisibility(
         visible = visible,
         enter = slideInVertically(
-            // Slide in from 40 px from the top.
-            initialOffsetY = { -40 }
+            // Slide in from 40 dp from the top.
+            initialOffsetY = { with(density) { -40.dp.roundToPx() } }
         ) + expandVertically(
             // Expand from the top.
             expandFrom = Alignment.Top
@@ -477,13 +482,15 @@
     ): Modifier = composed {
         val offsetX = remember { Animatable(0f) }
         pointerInput(Unit) {
+            // Used to calculate fling decay.
             val decay = splineBasedDecay<Float>(this)
+            // Use suspend functions for touch events and the Animatable.
             coroutineScope {
                 while (true) {
                     // Detect a touch down event.
                     val pointerId = awaitPointerEventScope { awaitFirstDown().id }
                     val velocityTracker = VelocityTracker()
-                    // Intercept an ongoing animation (if there's one).
+                    // Stop any ongoing animation.
                     offsetX.stop()
                     awaitPointerEventScope {
                         horizontalDrag(pointerId) { change ->
@@ -499,6 +506,7 @@
                             )
                         }
                     }
+                    // No longer receiving touch events. Prepare the animation.
                     val velocity = velocityTracker.calculateVelocity().x
                     val targetOffsetX = decay.calculateTargetValue(
                         offsetX.value,
diff --git a/compose/material/material/api/public_plus_experimental_1.0.0-beta10.txt b/compose/material/material/api/public_plus_experimental_1.0.0-beta10.txt
index a7a2c2d..aa65079 100644
--- a/compose/material/material/api/public_plus_experimental_1.0.0-beta10.txt
+++ b/compose/material/material/api/public_plus_experimental_1.0.0-beta10.txt
@@ -560,6 +560,7 @@
   }
 
   public final class SliderKt {
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> values, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material.SliderColors colors);
     method @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.SliderColors colors);
   }
 
diff --git a/compose/material/material/api/public_plus_experimental_current.txt b/compose/material/material/api/public_plus_experimental_current.txt
index a7a2c2d..aa65079 100644
--- a/compose/material/material/api/public_plus_experimental_current.txt
+++ b/compose/material/material/api/public_plus_experimental_current.txt
@@ -560,6 +560,7 @@
   }
 
   public final class SliderKt {
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> values, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material.SliderColors colors);
     method @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.SliderColors colors);
   }
 
diff --git a/compose/material/material/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/model/Examples.kt b/compose/material/material/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/model/Examples.kt
index 6f76c9c..6f787a5 100644
--- a/compose/material/material/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/model/Examples.kt
+++ b/compose/material/material/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/model/Examples.kt
@@ -49,6 +49,7 @@
 import androidx.compose.material.samples.PasswordTextField
 import androidx.compose.material.samples.RadioButtonSample
 import androidx.compose.material.samples.RadioGroupSample
+import androidx.compose.material.samples.RangeSliderSample
 import androidx.compose.material.samples.ScaffoldWithCoroutinesSnackbar
 import androidx.compose.material.samples.ScaffoldWithCustomSnackbar
 import androidx.compose.material.samples.ScaffoldWithSimpleSnackbar
@@ -62,6 +63,7 @@
 import androidx.compose.material.samples.SimpleTextFieldSample
 import androidx.compose.material.samples.SimpleTopAppBar
 import androidx.compose.material.samples.SliderSample
+import androidx.compose.material.samples.StepRangeSliderSample
 import androidx.compose.material.samples.StepsSliderSample
 import androidx.compose.material.samples.SwitchSample
 import androidx.compose.material.samples.TextAndIconTabs
@@ -424,7 +426,21 @@
         sourceUrl = SlidersExampleSourceUrl
     ) {
         StepsSliderSample()
-    }
+    },
+    Example(
+        name = ::RangeSliderSample.name,
+        description = SlidersExampleDescription,
+        sourceUrl = SlidersExampleSourceUrl
+    ) {
+        RangeSliderSample()
+    },
+    Example(
+        name = ::StepRangeSliderSample.name,
+        description = SlidersExampleDescription,
+        sourceUrl = SlidersExampleSourceUrl
+    ) {
+        StepRangeSliderSample()
+    },
 )
 
 private const val SnackbarsExampleDescription = "Snackbars examples"
diff --git a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/SliderDemo.kt b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/SliderDemo.kt
index 8e974cf9..774f44c 100644
--- a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/SliderDemo.kt
+++ b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/SliderDemo.kt
@@ -18,11 +18,13 @@
 
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.requiredHeight
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.requiredHeight
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Text
+import androidx.compose.material.samples.RangeSliderSample
 import androidx.compose.material.samples.SliderSample
+import androidx.compose.material.samples.StepRangeSliderSample
 import androidx.compose.material.samples.StepsSliderSample
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
@@ -39,5 +41,11 @@
         Text(text = "Discrete Slider with custom color", style = headerStyle)
         Spacer(Modifier.requiredHeight(16.dp))
         StepsSliderSample()
+        Text(text = "Range Continuous Slider", style = headerStyle)
+        Spacer(Modifier.requiredHeight(16.dp))
+        RangeSliderSample()
+        Text(text = "Range Discrete Slider", style = headerStyle)
+        Spacer(Modifier.requiredHeight(16.dp))
+        StepRangeSliderSample()
     }
 }
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 98211d5..e68c665 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
@@ -17,7 +17,9 @@
 package androidx.compose.material.samples
 
 import androidx.annotation.Sampled
+import androidx.compose.material.ExperimentalMaterialApi
 import androidx.compose.material.MaterialTheme
+import androidx.compose.material.RangeSlider
 import androidx.compose.material.Slider
 import androidx.compose.material.SliderDefaults
 import androidx.compose.material.Text
@@ -54,4 +56,43 @@
             activeTrackColor = MaterialTheme.colors.secondary
         )
     )
+}
+
+@Sampled
+@Composable
+@OptIn(ExperimentalMaterialApi::class)
+fun RangeSliderSample() {
+    var sliderPosition by remember { mutableStateOf(0f..100f) }
+    Text(text = sliderPosition.toString())
+    RangeSlider(
+        values = sliderPosition,
+        onValueChange = { sliderPosition = it },
+        valueRange = 0f..100f,
+        onValueChangeFinished = {
+            // launch some business logic update with the state you hold
+            // viewModel.updateSelectedSliderValue(sliderPosition)
+        },
+    )
+}
+
+@Sampled
+@Composable
+@OptIn(ExperimentalMaterialApi::class)
+fun StepRangeSliderSample() {
+    var sliderPosition by remember { mutableStateOf(0f..100f) }
+    Text(text = sliderPosition.toString())
+    RangeSlider(
+        steps = 5,
+        values = sliderPosition,
+        onValueChange = { sliderPosition = it },
+        valueRange = 0f..100f,
+        onValueChangeFinished = {
+            // launch some business logic update with the state you hold
+            // viewModel.updateSelectedSliderValue(sliderPosition)
+        },
+        colors = SliderDefaults.colors(
+            thumbColor = MaterialTheme.colors.secondary,
+            activeTrackColor = MaterialTheme.colors.secondary
+        )
+    )
 }
\ No newline at end of file
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 e73e6c7..85a1e8f 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
@@ -36,6 +36,7 @@
 import androidx.compose.ui.text.input.TextFieldValue
 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
@@ -85,6 +86,7 @@
             .isEqualTo(darkPrimary.copy(alpha = 0.375f))
     }
 
+    @FlakyTest(bugId = 191141357)
     @Test
     fun text_lightThemeSelectionColors() {
         rule.setContent {
@@ -103,6 +105,7 @@
             .assertAgainstGolden(screenshotRule, "text_lightThemeSelectionColors")
     }
 
+    @FlakyTest(bugId = 191141357)
     @Test
     fun text_darkThemeSelectionColors() {
         rule.setContent {
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 80e0fbf..dfbdacc 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
@@ -175,4 +175,52 @@
             .captureToImage()
             .assertAgainstGolden(screenshotRule, goldenName)
     }
+
+    @Test
+    @ExperimentalMaterialApi
+    fun rangeSliderTest_middle_steps_disabled() {
+        rule.setMaterialContent {
+            Box(wrap.testTag(wrapperTestTag)) {
+                var position by remember { mutableStateOf(0.5f..1f) }
+                RangeSlider(position, { position = it }, steps = 5, enabled = false)
+            }
+        }
+        assertSliderAgainstGolden("rangeSlider_middle_steps_disabled")
+    }
+
+    @Test
+    @ExperimentalMaterialApi
+    fun rangeSliderTest_middle_steps_enabled() {
+        rule.setMaterialContent {
+            Box(wrap.testTag(wrapperTestTag)) {
+                var position by remember { mutableStateOf(0.5f..1f) }
+                RangeSlider(position, { position = it }, steps = 5)
+            }
+        }
+        assertSliderAgainstGolden("rangeSlider_middle_steps_enabled")
+    }
+
+    @Test
+    @ExperimentalMaterialApi
+    fun rangeSliderTest_overlapingThumbs() {
+        rule.setMaterialContent {
+            Box(wrap.testTag(wrapperTestTag)) {
+                var position by remember { mutableStateOf(0.5f..0.51f) }
+                RangeSlider(position, { position = it })
+            }
+        }
+        assertSliderAgainstGolden("rangeSlider_overlapingThumbs")
+    }
+
+    @Test
+    @ExperimentalMaterialApi
+    fun rangeSliderTest_fullRange() {
+        rule.setMaterialContent {
+            Box(wrap.testTag(wrapperTestTag)) {
+                var position by remember { mutableStateOf(0f..1f) }
+                RangeSlider(position, { position = it })
+            }
+        }
+        assertSliderAgainstGolden("rangeSlider_fullRange")
+    }
 }
\ No newline at end of file
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 998ebaf..339d051 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
@@ -62,7 +62,6 @@
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
-import kotlin.math.abs
 
 @MediumTest
 @RunWith(AndroidJUnit4::class)
@@ -207,7 +206,7 @@
                 expected = calculateFraction(left, right, centerX + 100 - slop)
             }
         rule.runOnIdle {
-            Truth.assertThat(abs(state.value - expected)).isLessThan(0.001f)
+            Truth.assertThat(state.value).isWithin(0.001f).of(expected)
         }
     }
 
@@ -236,7 +235,7 @@
                 expected = calculateFraction(left, right, centerX + 50)
             }
         rule.runOnIdle {
-            Truth.assertThat(abs(state.value - expected)).isLessThan(0.001f)
+            Truth.assertThat(state.value).isWithin(0.001f).of(expected)
         }
     }
 
@@ -268,7 +267,7 @@
             }
 
         rule.runOnIdle {
-            Truth.assertThat(abs(state.value - expected)).isLessThan(0.001f)
+            Truth.assertThat(state.value).isWithin(0.001f).of(expected)
         }
     }
 
@@ -303,7 +302,7 @@
                 expected = calculateFraction(left, right, centerX - 100 + slop)
             }
         rule.runOnIdle {
-            Truth.assertThat(abs(state.value - expected)).isLessThan(0.001f)
+            Truth.assertThat(state.value).isWithin(0.001f).of(expected)
         }
     }
 
@@ -334,7 +333,38 @@
                 expected = calculateFraction(left, right, centerX - 50)
             }
         rule.runOnIdle {
-            Truth.assertThat(abs(state.value - expected)).isLessThan(0.001f)
+            Truth.assertThat(state.value).isWithin(0.001f).of(expected)
+        }
+    }
+
+    @Test
+    fun rangeSlider_tap_rtl() {
+        val state = mutableStateOf(0f)
+
+        rule.setMaterialContent {
+            CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
+                Slider(
+                    modifier = Modifier.testTag(tag),
+                    value = state.value,
+                    onValueChange = { state.value = it }
+                )
+            }
+        }
+
+        rule.runOnUiThread {
+            Truth.assertThat(state.value).isEqualTo(0f)
+        }
+
+        var expected = 0f
+
+        rule.onNodeWithTag(tag)
+            .performGesture {
+                down(Offset(centerX + 50, centerY))
+                up()
+                expected = calculateFraction(left, right, centerX - 50)
+            }
+        rule.runOnIdle {
+            Truth.assertThat(state.value).isWithin(0.001f).of(expected)
         }
     }
 
@@ -473,4 +503,211 @@
                 .isEqualTo(interactions[0])
         }
     }
+
+    @ExperimentalMaterialApi
+    @Test
+    fun rangeSlider_dragThumb() {
+        val state = mutableStateOf(0f..1f)
+        var slop = 0f
+
+        rule.setMaterialContent {
+            slop = LocalViewConfiguration.current.touchSlop
+            RangeSlider(
+                modifier = Modifier.testTag(tag),
+                values = state.value,
+                onValueChange = { state.value = it }
+            )
+        }
+
+        rule.runOnUiThread {
+            Truth.assertThat(state.value).isEqualTo(0f..1f)
+        }
+
+        var expected = 0f
+
+        rule.onNodeWithTag(tag)
+            .performGesture {
+                down(center)
+                moveBy(Offset(100f, 0f))
+                up()
+                expected = calculateFraction(left, right, centerX + 100 - slop)
+            }
+        rule.runOnIdle {
+            Truth.assertThat(state.value.start).isEqualTo(0f)
+            Truth.assertThat(state.value.endInclusive).isWithin(0.001f).of(expected)
+        }
+    }
+
+    @ExperimentalMaterialApi
+    @Test
+    fun rangeSlider_tap() {
+        val state = mutableStateOf(0f..1f)
+
+        rule.setMaterialContent {
+            RangeSlider(
+                modifier = Modifier.testTag(tag),
+                values = state.value,
+                onValueChange = { state.value = it }
+            )
+        }
+
+        rule.runOnUiThread {
+            Truth.assertThat(state.value).isEqualTo(0f..1f)
+        }
+
+        var expected = 0f
+
+        rule.onNodeWithTag(tag)
+            .performGesture {
+                down(Offset(centerX + 50, centerY))
+                up()
+                expected = calculateFraction(left, right, centerX + 50)
+            }
+        rule.runOnIdle {
+            Truth.assertThat(state.value.endInclusive).isWithin(0.001f).of(expected)
+            Truth.assertThat(state.value.start).isEqualTo(0f)
+        }
+    }
+
+    @ExperimentalMaterialApi
+    @Test
+    fun rangeSlider_tap_rangeChange() {
+        val state = mutableStateOf(0f..25f)
+        val rangeEnd = mutableStateOf(.25f)
+
+        rule.setMaterialContent {
+            RangeSlider(
+                modifier = Modifier.testTag(tag),
+                values = state.value,
+                onValueChange = { state.value = it },
+                valueRange = 0f..rangeEnd.value
+            )
+        }
+        // change to 1 since [calculateFraction] coerces between 0..1
+        rule.runOnUiThread {
+            rangeEnd.value = 1f
+        }
+
+        var expected = 0f
+
+        rule.onNodeWithTag(tag)
+            .performGesture {
+                down(Offset(centerX + 50, centerY))
+                up()
+                expected = calculateFraction(left, right, centerX + 50)
+            }
+
+        rule.runOnIdle {
+            Truth.assertThat(state.value.endInclusive).isWithin(0.001f).of(expected)
+        }
+    }
+
+    @ExperimentalMaterialApi
+    @Test
+    fun rangeSlider_drag_rtl() {
+        val state = mutableStateOf(0f..1f)
+        var slop = 0f
+
+        rule.setMaterialContent {
+            CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
+                slop = LocalViewConfiguration.current.touchSlop
+                RangeSlider(
+                    modifier = Modifier.testTag(tag),
+                    values = state.value,
+                    onValueChange = { state.value = it }
+                )
+            }
+        }
+
+        rule.runOnUiThread {
+            Truth.assertThat(state.value).isEqualTo(0f..1f)
+        }
+
+        var expected = 0f
+
+        rule.onNodeWithTag(tag)
+            .performGesture {
+                down(center)
+                moveBy(Offset(100f, 0f))
+                up()
+                // subtract here as we're in rtl and going in the opposite direction
+                expected = calculateFraction(left, right, centerX - 100 + slop)
+            }
+        rule.runOnIdle {
+            Truth.assertThat(state.value.start).isEqualTo(0f)
+            Truth.assertThat(state.value.endInclusive).isWithin(0.001f).of(expected)
+        }
+    }
+
+    @ExperimentalMaterialApi
+    @Test
+    fun rangeSlider_closeThumbs_dragRight() {
+        val state = mutableStateOf(0.5f..0.5f)
+        var slop = 0f
+
+        rule.setMaterialContent {
+            slop = LocalViewConfiguration.current.touchSlop
+            RangeSlider(
+                modifier = Modifier.testTag(tag),
+                values = state.value,
+                onValueChange = { state.value = it }
+            )
+        }
+
+        rule.runOnUiThread {
+            Truth.assertThat(state.value).isEqualTo(0.5f..0.5f)
+        }
+
+        var expected = 0f
+
+        rule.onNodeWithTag(tag)
+            .performGesture {
+                down(center)
+                moveBy(Offset(slop, 0f))
+                moveBy(Offset(100f, 0f))
+                up()
+                // subtract here as we're in rtl and going in the opposite direction
+                expected = calculateFraction(left, right, centerX + 100)
+            }
+        rule.runOnIdle {
+            Truth.assertThat(state.value.start).isEqualTo(0.5f)
+            Truth.assertThat(state.value.endInclusive).isWithin(0.001f).of(expected)
+        }
+    }
+
+    @ExperimentalMaterialApi
+    @Test
+    fun rangeSlider_closeThumbs_dragLeft() {
+        val state = mutableStateOf(0.5f..0.5f)
+        var slop = 0f
+
+        rule.setMaterialContent {
+            slop = LocalViewConfiguration.current.touchSlop
+            RangeSlider(
+                modifier = Modifier.testTag(tag),
+                values = state.value,
+                onValueChange = { state.value = it }
+            )
+        }
+
+        rule.runOnUiThread {
+            Truth.assertThat(state.value).isEqualTo(0.5f..0.5f)
+        }
+
+        var expected = 0f
+
+        rule.onNodeWithTag(tag)
+            .performGesture {
+                down(center)
+                moveBy(Offset(-slop - 1, 0f))
+                moveBy(Offset(-100f, 0f))
+                up()
+                // subtract here as we're in rtl and going in the opposite direction
+                expected = calculateFraction(left, right, centerX - 100)
+            }
+        rule.runOnIdle {
+            Truth.assertThat(state.value.start).isWithin(0.001f).of(expected)
+            Truth.assertThat(state.value.endInclusive).isEqualTo(0.5f)
+        }
+    }
 }
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 4805fb8..a5e1b53 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
@@ -479,15 +479,15 @@
         // on top we offset either by default padding or by label's half height if its too big
         // minWidth must not be set to 0 due to how foundation TextField treats zero minWidth
         val topPadding = max(heightOrZero(labelPlaceable) / 2, bottomPadding)
-        val textContraints = incomingConstraints.offset(
+        val textConstraints = incomingConstraints.offset(
             horizontal = -occupiedSpaceHorizontally,
             vertical = -bottomPadding - topPadding
         ).copy(minHeight = 0)
         val textFieldPlaceable =
-            measurables.first { it.layoutId == TextFieldId }.measure(textContraints)
+            measurables.first { it.layoutId == TextFieldId }.measure(textConstraints)
 
         // measure placeholder
-        val placeholderConstraints = textContraints.copy(minWidth = 0)
+        val placeholderConstraints = textConstraints.copy(minWidth = 0)
         val placeholderPlaceable =
             measurables.find { it.layoutId == PlaceholderId }?.measure(placeholderConstraints)
 
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 054d49f..a45ce5c 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
@@ -26,8 +26,12 @@
 import androidx.compose.foundation.gestures.DragScope
 import androidx.compose.foundation.gestures.DraggableState
 import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.awaitFirstDown
+import androidx.compose.foundation.gestures.awaitHorizontalTouchSlopOrCancellation
 import androidx.compose.foundation.gestures.detectTapGestures
 import androidx.compose.foundation.gestures.draggable
+import androidx.compose.foundation.gestures.forEachGesture
+import androidx.compose.foundation.gestures.horizontalDrag
 import androidx.compose.foundation.indication
 import androidx.compose.foundation.interaction.DragInteraction
 import androidx.compose.foundation.interaction.Interaction
@@ -48,6 +52,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.State
@@ -67,16 +72,23 @@
 import androidx.compose.ui.graphics.PointMode
 import androidx.compose.ui.graphics.StrokeCap
 import androidx.compose.ui.graphics.compositeOver
+import androidx.compose.ui.input.pointer.AwaitPointerEventScope
+import androidx.compose.ui.input.pointer.PointerId
+import androidx.compose.ui.input.pointer.PointerInputChange
+import androidx.compose.ui.input.pointer.consumePositionChange
 import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.input.pointer.positionChange
 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.Dp
 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.CoroutineScope
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.launch
@@ -138,7 +150,7 @@
     require(steps >= 0) { "steps should be >= 0" }
     val onValueChangeState = rememberUpdatedState(onValueChange)
     val tickFractions = remember(steps) {
-        if (steps == 0) emptyList() else List(steps + 2) { it.toFloat() / (steps + 1) }
+        stepsToTickFractions(steps)
     }
     BoxWithConstraints(
         modifier
@@ -163,20 +175,12 @@
                 onValueChangeState.value.invoke(scaleToUserValue(rawOffset.value))
             }
         }
-        SideEffect {
-            val newOffset = scaleToOffset(value)
-            // floating point error due to rescaling
-            val error = (valueRange.endInclusive - valueRange.start) / 1000
-            if (abs(newOffset - rawOffset.value) > error) rawOffset.value = newOffset
-        }
+
+        CorrectValueSideEffect(::scaleToOffset, valueRange, rawOffset, value)
 
         val gestureEndAction = rememberUpdatedState<(Float) -> Unit> { velocity: Float ->
             val current = rawOffset.value
-            // target is a closest anchor to the `current`, if exists
-            val target = tickFractions
-                .minByOrNull { abs(lerp(minPx, maxPx, it) - current) }
-                ?.run { lerp(minPx, maxPx, this) }
-                ?: current
+            val target = snapValueToTick(current, tickFractions, minPx, maxPx)
             if (current != target) {
                 scope.launch {
                     animateToTarget(draggableState, current, target, velocity)
@@ -201,6 +205,7 @@
             startDragImmediately = draggableState.isDragging,
             state = draggableState
         )
+
         val coerced = value.coerceIn(valueRange.start, valueRange.endInclusive)
         val fraction = calcFraction(valueRange.start, valueRange.endInclusive, coerced)
         SliderImpl(
@@ -216,6 +221,147 @@
 }
 
 /**
+ * <a href="https://material.io/components/sliders" class="external" target="_blank">Material Design slider</a>.
+ *
+ * Range Sliders expand upon [Slider] using the same concepts but allow the user to select 2 values.
+ *
+ * The two values are still bounded by the value range but they also cannot cross each other.
+ *
+ * Use continuous Range Sliders to allow users to make meaningful selections that don’t
+ * require a specific values:
+ *
+ * @sample androidx.compose.material.samples.RangeSliderSample
+ *
+ * You can allow the user to choose only between predefined set of values by specifying the amount
+ * of steps between min and max values:
+ *
+ * @sample androidx.compose.material.samples.StepRangeSliderSample
+ *
+ * @param values current values of the RangeSlider. If either value is outside of [valueRange]
+ * provided, it will be coerced to this range.
+ * @param onValueChange lambda in which values should be updated
+ * @param modifier modifiers for the Range Slider layout
+ * @param enabled whether or not component is enabled and can we interacted with or not
+ * @param valueRange range of values that Range Slider values can take. Passed [values] will be
+ * coerced to this range
+ * @param steps if greater than 0, specifies the amounts of discrete values, evenly distributed
+ * between across the whole value range. If 0, range slider will behave as a continuous slider and
+ * allow to choose any values from the range specified. Must not be negative.
+ * @param onValueChangeFinished lambda to be invoked when value change has ended. This callback
+ * shouldn't be used to update the range slider values (use [onValueChange] for that), but rather to
+ * know when the user has completed selecting a new value by ending a drag or a click.
+ * @param colors [SliderColors] that will be used to determine the color of the Range Slider
+ * parts in different state. See [SliderDefaults.colors] to customize.
+ */
+@Composable
+@ExperimentalMaterialApi
+fun RangeSlider(
+    values: ClosedFloatingPointRange<Float>,
+    onValueChange: (ClosedFloatingPointRange<Float>) -> Unit,
+    modifier: Modifier = Modifier,
+    enabled: Boolean = true,
+    valueRange: ClosedFloatingPointRange<Float> = 0f..1f,
+    /*@IntRange(from = 0)*/
+    steps: Int = 0,
+    onValueChangeFinished: (() -> Unit)? = null,
+    colors: SliderColors = SliderDefaults.colors()
+) {
+    val startInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+    val endInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+
+    require(steps >= 0) { "steps should be >= 0" }
+    val onValueChangeState = rememberUpdatedState(onValueChange)
+    val tickFractions = remember(steps) {
+        stepsToTickFractions(steps)
+    }
+
+    BoxWithConstraints {
+        val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
+        val maxPx = constraints.maxWidth.toFloat()
+        val minPx = 0f
+
+        fun scaleToUserValue(offset: ClosedFloatingPointRange<Float>) =
+            scale(minPx, maxPx, offset, valueRange.start, valueRange.endInclusive)
+
+        fun scaleToOffset(userValue: Float) =
+            scale(valueRange.start, valueRange.endInclusive, userValue, minPx, maxPx)
+
+        val rawOffsetStart = remember { mutableStateOf(scaleToOffset(values.start)) }
+        val rawOffsetEnd = remember { mutableStateOf(scaleToOffset(values.endInclusive)) }
+
+        CorrectValueSideEffect(::scaleToOffset, valueRange, rawOffsetStart, values.start)
+        CorrectValueSideEffect(::scaleToOffset, valueRange, rawOffsetEnd, values.endInclusive)
+
+        val scope = rememberCoroutineScope()
+        val gestureEndAction = rememberUpdatedState<(Boolean) -> Unit> { isStart ->
+            val current = (if (isStart) rawOffsetStart else rawOffsetEnd).value
+            // target is a closest anchor to the `current`, if exists
+            val target = snapValueToTick(current, tickFractions, minPx, maxPx)
+            if (current == target) {
+                onValueChangeFinished?.invoke()
+                return@rememberUpdatedState
+            }
+
+            scope.launch {
+                Animatable(initialValue = current).animateTo(
+                    target, SliderToTickAnimation,
+                    0f
+                ) {
+                    (if (isStart) rawOffsetStart else rawOffsetEnd).value = this.value
+                    onValueChangeState.value.invoke(
+                        scaleToUserValue(rawOffsetStart.value..rawOffsetEnd.value)
+                    )
+                }
+
+                onValueChangeFinished?.invoke()
+            }
+        }
+
+        val pressDrag = modifier.rangeSliderPressDragModifier(
+            startInteractionSource,
+            endInteractionSource,
+            rawOffsetStart,
+            rawOffsetEnd,
+            enabled,
+            isRtl,
+            maxPx,
+            valueRange,
+            gestureEndAction,
+        ) { isStart, offset ->
+            if (isStart) {
+                rawOffsetStart.value = (rawOffsetStart.value + offset)
+                    .coerceIn(minPx, rawOffsetEnd.value)
+            } else {
+                rawOffsetEnd.value = (rawOffsetEnd.value + offset)
+                    .coerceIn(rawOffsetStart.value, maxPx)
+            }
+
+            onValueChangeState.value.invoke(
+                scaleToUserValue(rawOffsetStart.value..rawOffsetEnd.value)
+            )
+        }
+
+        // The positions of the thumbs are dependant on each other.
+        val coercedStart = values.start.coerceIn(valueRange.start, values.endInclusive)
+        val coercedEnd = values.endInclusive.coerceIn(values.start, valueRange.endInclusive)
+        val fractionStart = calcFraction(valueRange.start, valueRange.endInclusive, coercedStart)
+        val fractionEnd = calcFraction(valueRange.start, valueRange.endInclusive, coercedEnd)
+
+        RangeSliderImpl(
+            enabled,
+            fractionStart,
+            fractionEnd,
+            tickFractions,
+            colors,
+            maxPx,
+            startInteractionSource,
+            endInteractionSource,
+            modifier = pressDrag.then(modifier),
+        )
+    }
+}
+
+/**
  * Object to hold defaults used by [Slider]
  */
 object SliderDefaults {
@@ -357,63 +503,130 @@
     interactionSource: MutableInteractionSource,
     modifier: Modifier
 ) {
-    val widthDp = with(LocalDensity.current) {
-        width.toDp()
-    }
     Box(modifier.then(DefaultSliderConstraints)) {
+        val trackStrokeWidth: Float
+        val thumbPx: Float
+        val widthDp: Dp
+        with(LocalDensity.current) {
+            trackStrokeWidth = TrackHeight.toPx()
+            thumbPx = ThumbRadius.toPx()
+            widthDp = width.toDp()
+        }
+
         val thumbSize = ThumbRadius * 2
         val offset = (widthDp - thumbSize) * positionFraction
         val center = Modifier.align(Alignment.CenterStart)
 
-        val trackStrokeWidth: Float
-        val thumbPx: Float
-        with(LocalDensity.current) {
-            trackStrokeWidth = TrackHeight.toPx()
-            thumbPx = ThumbRadius.toPx()
-        }
         Track(
             center.fillMaxSize(),
             colors,
             enabled,
+            0f,
             positionFraction,
             tickFractions,
             thumbPx,
             trackStrokeWidth
         )
-        Box(center.padding(start = offset)) {
-            val interactions = remember { mutableStateListOf<Interaction>() }
+        SliderThumb(center, offset, interactionSource, colors, enabled, thumbSize)
+    }
+}
 
-            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)
-                    }
+@Composable
+private fun RangeSliderImpl(
+    enabled: Boolean,
+    positionFractionStart: Float,
+    positionFractionEnd: Float,
+    tickFractions: List<Float>,
+    colors: SliderColors,
+    width: Float,
+    startInteractionSource: MutableInteractionSource,
+    endInteractionSource: MutableInteractionSource,
+    modifier: Modifier
+) {
+
+    Box(modifier.then(DefaultSliderConstraints)) {
+        val trackStrokeWidth: Float
+        val thumbPx: Float
+        val widthDp: Dp
+        with(LocalDensity.current) {
+            trackStrokeWidth = TrackHeight.toPx()
+            thumbPx = ThumbRadius.toPx()
+            widthDp = width.toDp()
+        }
+
+        val thumbSize = ThumbRadius * 2
+        val offsetStart = (widthDp - thumbSize) * positionFractionStart
+        val offsetEnd = (widthDp - thumbSize) * positionFractionEnd
+        Track(
+            Modifier.align(Alignment.CenterStart).fillMaxSize(),
+            colors,
+            enabled,
+            positionFractionStart,
+            positionFractionEnd,
+            tickFractions,
+            thumbPx,
+            trackStrokeWidth
+        )
+
+        SliderThumb(
+            Modifier.align(Alignment.CenterStart),
+            offsetStart,
+            startInteractionSource,
+            colors,
+            enabled,
+            thumbSize
+        )
+        SliderThumb(
+            Modifier.align(Alignment.CenterStart),
+            offsetEnd,
+            endInteractionSource,
+            colors,
+            enabled,
+            thumbSize
+        )
+    }
+}
+
+@Composable
+private fun SliderThumb(
+    modifier: Modifier,
+    offset: Dp,
+    interactionSource: MutableInteractionSource,
+    colors: SliderColors,
+    enabled: Boolean,
+    thumbSize: Dp
+) {
+    Box(modifier.padding(start = offset)) {
+        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)
+                    is DragInteraction.Start -> interactions.add(interaction)
+                    is DragInteraction.Stop -> interactions.remove(interaction.start)
+                    is DragInteraction.Cancel -> interactions.remove(interaction.start)
                 }
             }
-
-            val hasInteraction = interactions.isNotEmpty()
-            val elevation = if (hasInteraction) {
-                ThumbPressedElevation
-            } else {
-                ThumbDefaultElevation
-            }
-            Spacer(
-                Modifier
-                    .size(thumbSize, thumbSize)
-                    .focusable(interactionSource = interactionSource)
-                    .indication(
-                        interactionSource = interactionSource,
-                        indication = rememberRipple(bounded = false, radius = ThumbRippleRadius)
-                    )
-                    .shadow(if (enabled) elevation else 0.dp, CircleShape, clip = false)
-                    .background(colors.thumbColor(enabled).value, CircleShape)
-            )
         }
+
+        val elevation = if (interactions.isNotEmpty()) {
+            ThumbPressedElevation
+        } else {
+            ThumbDefaultElevation
+        }
+        Spacer(
+            Modifier
+                .size(thumbSize, thumbSize)
+                .focusable(interactionSource = interactionSource)
+                .indication(
+                    interactionSource = interactionSource,
+                    indication = rememberRipple(bounded = false, radius = ThumbRippleRadius)
+                )
+                .shadow(if (enabled) elevation else 0.dp, CircleShape, clip = false)
+                .background(colors.thumbColor(enabled).value, CircleShape)
+        )
     }
 }
 
@@ -422,7 +635,8 @@
     modifier: Modifier,
     colors: SliderColors,
     enabled: Boolean,
-    positionFraction: Float,
+    positionFractionStart: Float,
+    positionFractionEnd: Float,
     tickFractions: List<Float>,
     thumbPx: Float,
     trackStrokeWidth: Float
@@ -444,19 +658,24 @@
             trackStrokeWidth,
             StrokeCap.Round
         )
-        val sliderValue = Offset(
-            sliderStart.x + (sliderEnd.x - sliderStart.x) * positionFraction,
+        val sliderValueEnd = Offset(
+            sliderStart.x + (sliderEnd.x - sliderStart.x) * positionFractionEnd,
+            center.y
+        )
+
+        val sliderValueStart = Offset(
+            sliderStart.x + (sliderEnd.x - sliderStart.x) * positionFractionStart,
             center.y
         )
 
         drawLine(
             activeTrackColor.value,
-            sliderStart,
-            sliderValue,
+            sliderValueStart,
+            sliderValueEnd,
             trackStrokeWidth,
             StrokeCap.Round
         )
-        tickFractions.groupBy { it > positionFraction }.forEach { (afterFraction, list) ->
+        tickFractions.groupBy { it > positionFractionEnd }.forEach { (afterFraction, list) ->
             drawPoints(
                 list.map {
                     Offset(lerp(sliderStart, sliderEnd, it).x, center.y)
@@ -470,14 +689,62 @@
     }
 }
 
+private fun snapValueToTick(
+    current: Float,
+    tickFractions: List<Float>,
+    minPx: Float,
+    maxPx: Float
+): Float {
+    // target is a closest anchor to the `current`, if exists
+    return tickFractions
+        .minByOrNull { abs(lerp(minPx, maxPx, it) - current) }
+        ?.run { lerp(minPx, maxPx, this) }
+        ?: current
+}
+
+private suspend fun AwaitPointerEventScope.awaitSlop(
+    id: PointerId
+): Pair<PointerInputChange, Float>? {
+    var initialDelta = 0f
+    val postTouchSlop = { pointerInput: PointerInputChange, offset: Float ->
+        pointerInput.consumePositionChange()
+        initialDelta = offset
+    }
+    val afterSlopResult = awaitHorizontalTouchSlopOrCancellation(id, postTouchSlop)
+    return if (afterSlopResult != null) afterSlopResult to initialDelta else null
+}
+
+private fun stepsToTickFractions(steps: Int): List<Float> {
+    return if (steps == 0) emptyList() else List(steps + 2) { it.toFloat() / (steps + 1) }
+}
+
 // Scale x1 from a1..b1 range to a2..b2 range
 private fun scale(a1: Float, b1: Float, x1: Float, a2: Float, b2: Float) =
     lerp(a2, b2, calcFraction(a1, b1, x1))
 
+// Scale x.start, x.endInclusive from a1..b1 range to a2..b2 range
+private fun scale(a1: Float, b1: Float, x: ClosedFloatingPointRange<Float>, a2: Float, b2: Float) =
+    scale(a1, b1, x.start, a2, b2)..scale(a1, b1, x.endInclusive, a2, b2)
+
 // Calculate the 0..1 fraction that `pos` value represents between `a` and `b`
 private fun calcFraction(a: Float, b: Float, pos: Float) =
     (if (b - a == 0f) 0f else (pos - a) / (b - a)).coerceIn(0f, 1f)
 
+@Composable
+private fun CorrectValueSideEffect(
+    scaleToOffset: (Float) -> Float,
+    valueRange: ClosedFloatingPointRange<Float>,
+    valueState: MutableState<Float>,
+    value: Float
+) {
+    SideEffect {
+        val error = (valueRange.endInclusive - valueRange.start) / 1000
+        val newOffset = scaleToOffset(value)
+        if (abs(newOffset - valueState.value) > error)
+            valueState.value = newOffset
+    }
+}
+
 private fun Modifier.sliderSemantics(
     value: Float,
     tickFractions: List<Float>,
@@ -566,6 +833,137 @@
     }
 }
 
+private fun Modifier.rangeSliderPressDragModifier(
+    startInteractionSource: MutableInteractionSource,
+    endInteractionSource: MutableInteractionSource,
+    rawOffsetStart: State<Float>,
+    rawOffsetEnd: State<Float>,
+    enabled: Boolean,
+    isRtl: Boolean,
+    maxPx: Float,
+    valueRange: ClosedFloatingPointRange<Float>,
+    gestureEndAction: State<(Boolean) -> Unit>,
+    onDrag: (Boolean, Float) -> Unit,
+): Modifier =
+    if (enabled) {
+        pointerInput(startInteractionSource, endInteractionSource, maxPx, isRtl, valueRange) {
+            val rangeSliderLogic = RangeSliderLogic(
+                startInteractionSource,
+                endInteractionSource,
+                rawOffsetStart,
+                rawOffsetEnd,
+                onDrag
+            )
+            coroutineScope {
+                forEachGesture {
+                    awaitPointerEventScope {
+                        var thumbCaptured = false
+                        // If we are dragging the start thumb, false if we are dragging end thumb.
+                        var draggingStart = true
+                        val pointerEvent = awaitFirstDown(requireUnconsumed = false)
+                        val interaction = PressInteraction.Press(pointerEvent.position)
+                        val slop = viewConfiguration.touchSlop
+                        val posX =
+                            if (isRtl) maxPx - pointerEvent.position.x else pointerEvent.position.x
+
+                        if (abs(rawOffsetEnd.value - posX) > slop ||
+                            abs(rawOffsetStart.value - posX) > slop
+                        ) {
+                            // We have enough distance we can start dragging right away
+                            draggingStart = rangeSliderLogic.shouldCaptureStartThumb(posX)
+                            rangeSliderLogic.captureThumb(
+                                draggingStart,
+                                posX,
+                                interaction,
+                                this@coroutineScope
+                            )
+                            thumbCaptured = true
+                        }
+
+                        awaitSlop(pointerEvent.id)?.let {
+                            if (thumbCaptured) {
+                                onDrag(draggingStart, if (isRtl) -it.second else it.second)
+                            } else {
+                                // Determine which thumb to drag based on the direction the user
+                                // is dragging
+                                val dir = it.second
+                                draggingStart = if (isRtl) dir >= 0f else dir < 0f
+                            }
+                        }
+
+                        if (!thumbCaptured) {
+                            rangeSliderLogic.captureThumb(
+                                draggingStart,
+                                posX,
+                                interaction,
+                                this@coroutineScope
+                            )
+                        }
+
+                        val finishInteraction = try {
+                            val success = horizontalDrag(pointerId = pointerEvent.id) {
+                                val deltaX = it.positionChange().x
+                                onDrag(draggingStart, if (isRtl) -deltaX else deltaX)
+                            }
+                            if (success) {
+                                PressInteraction.Release(interaction)
+                            } else {
+                                PressInteraction.Cancel(interaction)
+                            }
+                        } catch (e: CancellationException) {
+                            PressInteraction.Cancel(interaction)
+                        }
+
+                        gestureEndAction.value.invoke(draggingStart)
+                        launch {
+                            rangeSliderLogic
+                                .activeInteraction(draggingStart)
+                                .emit(finishInteraction)
+                        }
+                    }
+                }
+            }
+        }
+    } else {
+        this
+    }
+
+private class RangeSliderLogic(
+    val startInteractionSource: MutableInteractionSource,
+    val endInteractionSource: MutableInteractionSource,
+    val rawOffsetStart: State<Float>,
+    val rawOffsetEnd: State<Float>,
+    val onDrag: (Boolean, Float) -> Unit,
+) {
+    fun activeInteraction(draggingStart: Boolean): MutableInteractionSource =
+        if (draggingStart) startInteractionSource else endInteractionSource
+
+    fun shouldCaptureStartThumb(eventX: Float): Boolean {
+        val diffStart = abs(rawOffsetStart.value - eventX)
+        val diffEnd = abs(rawOffsetEnd.value - eventX)
+        return if (diffEnd == diffStart)
+            rawOffsetStart.value > eventX
+        else diffStart < diffEnd
+    }
+
+    fun captureThumb(
+        draggingStart: Boolean,
+        posX: Float,
+        interaction: Interaction,
+        scope: CoroutineScope
+    ) {
+        // TODO() interaction sources are not exposed in the public API so
+        //  we only emit press events
+        onDrag(
+            draggingStart,
+            posX - if (draggingStart) rawOffsetStart.value else rawOffsetEnd.value
+        )
+        scope.launch {
+            activeInteraction(draggingStart).emit(interaction)
+        }
+    }
+}
+
 @Immutable
 private class DefaultSliderColors(
     private val thumbColor: Color,
@@ -683,4 +1081,4 @@
     override fun dispatchRawDelta(delta: Float) {
         return onDelta(delta)
     }
-}
+}
\ No newline at end of file
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Snackbar.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Snackbar.kt
index a7e4097..5f0854d 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Snackbar.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Snackbar.kt
@@ -61,7 +61,7 @@
  * of the [SnackbarHost] to the [Scaffold]:
  * @sample androidx.compose.material.samples.ScaffoldWithCustomSnackbar
  *
- * @param modifier modifiers for the the Snackbar layout
+ * @param modifier modifiers for the Snackbar layout
  * @param action action / button component to add as an action to the snackbar. Consider using
  * [SnackbarDefaults.primaryActionColor] as the color for the action, if you do not
  * have a predefined color you wish to use instead.
@@ -205,7 +205,7 @@
 
     /**
      * Provides a best-effort 'primary' color to be used as the primary color inside a [Snackbar].
-     * Given that [Snackbar]s have an 'inverted' theme, i.e in a light theme they appear dark, and
+     * Given that [Snackbar]s have an 'inverted' theme, i.e. in a light theme they appear dark, and
      * in a dark theme they appear light, just using [Colors.primary] will not work, and has
      * incorrect contrast.
      *
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 dec32d4..acd0a8a 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
@@ -485,7 +485,7 @@
 }
 
 /**
- * Create and [remember] a [SwipeableState] which is kept in sync with another state, i.e:
+ * Create and [remember] a [SwipeableState] which is kept in sync with another state, i.e.:
  *  1. Whenever the [value] changes, the [SwipeableState] will be animated to that new value.
  *  2. Whenever the value of the [SwipeableState] changes (e.g. after a swipe), the owner of the
  *  [value] will be notified to update their state to the new value of the [SwipeableState] by
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 1e0658eb..d676337 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
@@ -1176,7 +1176,7 @@
     override fun dispose() {
         // Disposing the global snapshot is a no-op.
 
-        // The dispose behavior is preformed by advancing the global snapshot. This method is
+        // The dispose behavior is performed by advancing the global snapshot. This method is
         // squelched so  calling it from `currentSnapshot` doesn't cause incorrect behavior
     }
 }
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotIdSet.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotIdSet.kt
index 8c5502f..19a2458 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotIdSet.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotIdSet.kt
@@ -50,7 +50,7 @@
 ) : Iterable<Int> {
 
     /**
-     * The the value of the bit at index [bit]
+     * The value of the bit at index [bit]
      */
     fun get(bit: Int): Boolean {
         val offset = bit - lowerBound
diff --git a/compose/ui/ui-graphics/api/public_plus_experimental_1.0.0-beta10.txt b/compose/ui/ui-graphics/api/public_plus_experimental_1.0.0-beta10.txt
index 587aad3..39b20cc 100644
--- a/compose/ui/ui-graphics/api/public_plus_experimental_1.0.0-beta10.txt
+++ b/compose/ui/ui-graphics/api/public_plus_experimental_1.0.0-beta10.txt
@@ -332,6 +332,8 @@
     method public long getUnspecified-0d7_KjU();
     method public long getWhite-0d7_KjU();
     method public long getYellow-0d7_KjU();
+    method @androidx.compose.ui.graphics.ExperimentalGraphicsApi public long hsl-0d7_KjU(float hue, float saturation, float lightness, optional float alpha, optional androidx.compose.ui.graphics.colorspace.Rgb colorSpace);
+    method @androidx.compose.ui.graphics.ExperimentalGraphicsApi public long hsv-0d7_KjU(float hue, float saturation, float value, optional float alpha, optional androidx.compose.ui.graphics.colorspace.Rgb colorSpace);
     property public final long Black;
     property public final long Blue;
     property public final long Cyan;
@@ -397,6 +399,9 @@
   public final class DegreesKt {
   }
 
+  @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") public @interface ExperimentalGraphicsApi {
+  }
+
   @androidx.compose.runtime.Immutable public final inline class FilterQuality {
     ctor public FilterQuality();
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(int p, Object? p1);
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 587aad3..39b20cc 100644
--- a/compose/ui/ui-graphics/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-graphics/api/public_plus_experimental_current.txt
@@ -332,6 +332,8 @@
     method public long getUnspecified-0d7_KjU();
     method public long getWhite-0d7_KjU();
     method public long getYellow-0d7_KjU();
+    method @androidx.compose.ui.graphics.ExperimentalGraphicsApi public long hsl-0d7_KjU(float hue, float saturation, float lightness, optional float alpha, optional androidx.compose.ui.graphics.colorspace.Rgb colorSpace);
+    method @androidx.compose.ui.graphics.ExperimentalGraphicsApi public long hsv-0d7_KjU(float hue, float saturation, float value, optional float alpha, optional androidx.compose.ui.graphics.colorspace.Rgb colorSpace);
     property public final long Black;
     property public final long Blue;
     property public final long Cyan;
@@ -397,6 +399,9 @@
   public final class DegreesKt {
   }
 
+  @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") public @interface ExperimentalGraphicsApi {
+  }
+
   @androidx.compose.runtime.Immutable public final inline class FilterQuality {
     ctor public FilterQuality();
     method @androidx.compose.runtime.Immutable public static inline boolean equals-impl(int p, Object? p1);
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Color.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Color.kt
index 5524df22..c987420 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Color.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Color.kt
@@ -319,6 +319,72 @@
          */
         @Stable
         val Unspecified = Color(0f, 0f, 0f, 0f, ColorSpaces.Unspecified)
+
+        /**
+         * Return a [Color] from [hue], [saturation], and [value] (HSV representation).
+         *
+         * @param hue The color value in the range (0..360), where 0 is red, 120 is green, and
+         * 240 is blue
+         * @param saturation The amount of [hue] represented in the color in the range (0..1),
+         * where 0 has no color and 1 is fully saturated.
+         * @param value The strength of the color, where 0 is black.
+         * @param colorSpace The RGB color space used to calculate the Color from the HSV values.
+         */
+        @ExperimentalGraphicsApi
+        fun hsv(
+            hue: Float,
+            saturation: Float,
+            value: Float,
+            alpha: Float = 1f,
+            colorSpace: Rgb = ColorSpaces.Srgb
+        ): Color {
+            require(hue in 0f..360f && saturation in 0f..1f && value in 0f..1f) {
+                "HSV ($hue, $saturation, $value) must be in range (0..360, 0..1, 0..1)"
+            }
+            val red = hsvToRgbComponent(5, hue, saturation, value)
+            val green = hsvToRgbComponent(3, hue, saturation, value)
+            val blue = hsvToRgbComponent(1, hue, saturation, value)
+            return Color(red, green, blue, alpha, colorSpace)
+        }
+
+        private fun hsvToRgbComponent(n: Int, h: Float, s: Float, v: Float): Float {
+            val k = (n.toFloat() + h / 60f) % 6f
+            return v - (v * s * max(0f, minOf(k, 4 - k, 1f)))
+        }
+
+        /**
+         * Return a [Color] from [hue], [saturation], and [lightness] (HSL representation).
+         *
+         * @param hue The color value in the range (0..360), where 0 is red, 120 is green, and
+         * 240 is blue
+         * @param saturation The amount of [hue] represented in the color in the range (0..1),
+         * where 0 has no color and 1 is fully saturated.
+         * @param lightness A range of (0..1) where 0 is black, 0.5 is fully colored, and 1 is
+         * white.
+         * @param colorSpace The RGB color space used to calculate the Color from the HSL values.
+         */
+        @ExperimentalGraphicsApi
+        fun hsl(
+            hue: Float,
+            saturation: Float,
+            lightness: Float,
+            alpha: Float = 1f,
+            colorSpace: Rgb = ColorSpaces.Srgb
+        ): Color {
+            require(hue in 0f..360f && saturation in 0f..1f && lightness in 0f..1f) {
+                "HSL ($hue, $saturation, $lightness) must be in range (0..360, 0..1, 0..1)"
+            }
+            val red = hslToRgbComponent(0, hue, saturation, lightness)
+            val green = hslToRgbComponent(8, hue, saturation, lightness)
+            val blue = hslToRgbComponent(4, hue, saturation, lightness)
+            return Color(red, green, blue, alpha, colorSpace)
+        }
+
+        private fun hslToRgbComponent(n: Int, h: Float, s: Float, l: Float): Float {
+            val k = (n.toFloat() + h / 30f) % 12f
+            val a = s * min(l, 1f - l)
+            return l - a * max(-1f, minOf(k - 3, 9 - k, 1f))
+        }
     }
 }
 
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/ExperimentalGraphicsApi.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/ExperimentalGraphicsApi.kt
new file mode 100644
index 0000000..aa38621
--- /dev/null
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/ExperimentalGraphicsApi.kt
@@ -0,0 +1,20 @@
+/*
+ * 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.graphics
+
+@RequiresOptIn("This API is experimental and is likely to change in the future.")
+annotation class ExperimentalGraphicsApi
\ No newline at end of file
diff --git a/compose/ui/ui-graphics/src/test/java/androidx/compose/ui/graphics/ColorTest.kt b/compose/ui/ui-graphics/src/test/java/androidx/compose/ui/graphics/ColorTest.kt
index eaa0c4f..c87b11c 100644
--- a/compose/ui/ui-graphics/src/test/java/androidx/compose/ui/graphics/ColorTest.kt
+++ b/compose/ui/ui-graphics/src/test/java/androidx/compose/ui/graphics/ColorTest.kt
@@ -285,6 +285,104 @@
         assertEquals(0.6f, alpha, epsilon)
     }
 
+    @OptIn(ExperimentalGraphicsApi::class)
+    @Test
+    fun testHsvInSrgb() {
+        assertEquals(Color.Transparent, Color.hsv(0f, 0f, 0f, 0f))
+        assertEquals(Color.Black, Color.hsv(0f, 0f, 0f))
+        assertEquals(Color.Black, Color.hsv(120f, 0f, 0f))
+        assertEquals(Color.Black, Color.hsv(120f, 1f, 0f))
+        assertEquals(Color.White, Color.hsv(0f, 0f, 1f))
+        assertEquals(Color.White, Color.hsv(120f, 0f, 1f))
+        assertEquals(Color.White, Color.hsv(240f, 0f, 1f))
+        val gray = Color(0xFF808080)
+        assertEquals(gray, Color.hsv(0f, 0f, 0.5f))
+        assertEquals(gray, Color.hsv(120f, 0f, 0.5f))
+        assertEquals(gray, Color.hsv(240f, 0f, 0.5f))
+
+        assertEquals(Color.Red, Color.hsv(0f, 1f, 1f))
+        assertEquals(Color.Yellow, Color.hsv(60f, 1f, 1f))
+        assertEquals(Color.Green, Color.hsv(120f, 1f, 1f))
+        assertEquals(Color.Cyan, Color.hsv(180f, 1f, 1f))
+        assertEquals(Color.Blue, Color.hsv(240f, 1f, 1f))
+        assertEquals(Color.Magenta, Color.hsv(300f, 1f, 1f))
+        assertEquals(Color.Red, Color.hsv(360f, 1f, 1f))
+    }
+
+    @OptIn(ExperimentalGraphicsApi::class)
+    @Test
+    fun testHsvInLinearSrgb() {
+        val lrgb = ColorSpaces.LinearSrgb
+        val srgb = ColorSpaces.Srgb
+        assertEquals(Color.Black, Color.hsv(0f, 0f, 0f, 1f, lrgb).convert(srgb))
+        assertEquals(Color.Black, Color.hsv(120f, 0f, 0f, 1f, lrgb).convert(srgb))
+        assertEquals(Color.Black, Color.hsv(120f, 1f, 0f, 1f, lrgb).convert(srgb))
+        assertEquals(Color.White, Color.hsv(0f, 0f, 1f, 1f, lrgb).convert(srgb))
+        assertEquals(Color.White, Color.hsv(120f, 0f, 1f, 1f, lrgb).convert(srgb))
+        assertEquals(Color.White, Color.hsv(240f, 0f, 1f, 1f, lrgb).convert(srgb))
+        val gray = Color(0.5f, 0.5f, 0.5f, 1f, lrgb)
+        assertEquals(gray, Color.hsv(0f, 0f, 0.5f, 1f, lrgb))
+        assertEquals(gray, Color.hsv(120f, 0f, 0.5f, 1f, lrgb))
+        assertEquals(gray, Color.hsv(240f, 0f, 0.5f, 1f, lrgb))
+
+        assertEquals(Color(1f, 0f, 0f, 1f, lrgb), Color.hsv(0f, 1f, 1f, 1f, lrgb))
+        assertEquals(Color(1f, 1f, 0f, 1f, lrgb), Color.hsv(60f, 1f, 1f, 1f, lrgb))
+        assertEquals(Color(0f, 1f, 0f, 1f, lrgb), Color.hsv(120f, 1f, 1f, 1f, lrgb))
+        assertEquals(Color(0f, 1f, 1f, 1f, lrgb), Color.hsv(180f, 1f, 1f, 1f, lrgb))
+        assertEquals(Color(0f, 0f, 1f, 1f, lrgb), Color.hsv(240f, 1f, 1f, 1f, lrgb))
+        assertEquals(Color(1f, 0f, 1f, 1f, lrgb), Color.hsv(300f, 1f, 1f, 1f, lrgb))
+        assertEquals(Color(1f, 0f, 0f, 1f, lrgb), Color.hsv(360f, 1f, 1f, 1f, lrgb))
+    }
+
+    @OptIn(ExperimentalGraphicsApi::class)
+    @Test
+    fun testHslInSrgb() {
+        assertEquals(Color.Transparent, Color.hsl(0f, 0f, 0f, 0f))
+        assertEquals(Color.Black, Color.hsl(0f, 0f, 0f))
+        assertEquals(Color.Black, Color.hsl(120f, 0f, 0f))
+        assertEquals(Color.Black, Color.hsl(120f, 1f, 0f))
+        assertEquals(Color.White, Color.hsl(0f, 0f, 1f))
+        assertEquals(Color.White, Color.hsl(120f, 1f, 1f))
+        assertEquals(Color.White, Color.hsl(240f, 0.5f, 1f))
+        val gray = Color(0xFF808080)
+        assertEquals(gray, Color.hsl(0f, 0f, 0.5f))
+        assertEquals(gray, Color.hsl(120f, 0f, 0.5f))
+        assertEquals(gray, Color.hsl(240f, 0f, 0.5f))
+
+        assertEquals(Color.Red, Color.hsl(0f, 1f, 0.5f))
+        assertEquals(Color.Yellow, Color.hsl(60f, 1f, 0.5f))
+        assertEquals(Color.Green, Color.hsl(120f, 1f, 0.5f))
+        assertEquals(Color.Cyan, Color.hsl(180f, 1f, 0.5f))
+        assertEquals(Color.Blue, Color.hsl(240f, 1f, 0.5f))
+        assertEquals(Color.Magenta, Color.hsl(300f, 1f, 0.5f))
+        assertEquals(Color.Red, Color.hsl(360f, 1f, 0.5f))
+    }
+
+    @OptIn(ExperimentalGraphicsApi::class)
+    @Test
+    fun testHslInLinearSrgb() {
+        val lrgb = ColorSpaces.LinearSrgb
+        val srgb = ColorSpaces.Srgb
+        assertEquals(Color.Black, Color.hsl(0f, 0f, 0f, 1f, lrgb).convert(srgb))
+        assertEquals(Color.Black, Color.hsl(120f, 0f, 0f, 1f, lrgb).convert(srgb))
+        assertEquals(Color.Black, Color.hsl(120f, 1f, 0f, 1f, lrgb).convert(srgb))
+        assertEquals(Color.White, Color.hsl(0f, 0f, 1f, 1f, lrgb).convert(srgb))
+        assertEquals(Color.White, Color.hsl(120f, 0f, 1f, 1f, lrgb).convert(srgb))
+        assertEquals(Color.White, Color.hsl(240f, 0f, 1f, 1f, lrgb).convert(srgb))
+        val gray = Color(0.5f, 0.5f, 0.5f, 1f, lrgb)
+        assertEquals(gray, Color.hsl(0f, 0f, 0.5f, 1f, lrgb))
+        assertEquals(gray, Color.hsl(120f, 0f, 0.5f, 1f, lrgb))
+        assertEquals(gray, Color.hsl(240f, 0f, 0.5f, 1f, lrgb))
+
+        assertEquals(Color(1f, 0f, 0f, 1f, lrgb), Color.hsl(0f, 1f, 0.5f, 1f, lrgb))
+        assertEquals(Color(1f, 1f, 0f, 1f, lrgb), Color.hsl(60f, 1f, 0.5f, 1f, lrgb))
+        assertEquals(Color(0f, 1f, 0f, 1f, lrgb), Color.hsl(120f, 1f, 0.5f, 1f, lrgb))
+        assertEquals(Color(0f, 1f, 1f, 1f, lrgb), Color.hsl(180f, 1f, 0.5f, 1f, lrgb))
+        assertEquals(Color(0f, 0f, 1f, 1f, lrgb), Color.hsl(240f, 1f, 0.5f, 1f, lrgb))
+        assertEquals(Color(1f, 0f, 1f, 1f, lrgb), Color.hsl(300f, 1f, 0.5f, 1f, lrgb))
+        assertEquals(Color(1f, 0f, 0f, 1f, lrgb), Color.hsl(360f, 1f, 0.5f, 1f, lrgb))
+    }
+
     companion object {
         @OptIn(kotlin.ExperimentalUnsignedTypes::class)
         fun Int.toHexString() = "0x${toUInt().toString(16).padStart(8, '0')}"
diff --git a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/SimpleComposablePreview.kt b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/SimpleComposablePreview.kt
index 679b4a1..c4098c8 100644
--- a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/SimpleComposablePreview.kt
+++ b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/SimpleComposablePreview.kt
@@ -16,6 +16,8 @@
 
 package androidx.compose.ui.tooling
 
+import androidx.activity.compose.LocalActivityResultRegistryOwner
+import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
 import androidx.compose.material.Surface
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
@@ -86,6 +88,24 @@
     Text("SaveableStateRegistry preview")
 }
 
+@Preview
+@Composable
+private fun OnBackPressedDispatcherPreview() {
+    if (LocalOnBackPressedDispatcherOwner.current == null) throw IllegalArgumentException(
+        "OnBackPressedDispatcher is not provided"
+    )
+    Text("OnBackPressedDispatcher preview")
+}
+
+@Preview
+@Composable
+private fun ActivityResultRegistryPreview() {
+    if (LocalActivityResultRegistryOwner.current == null) throw IllegalArgumentException(
+        "ActivityResultRegistry is not provided"
+    )
+    Text("ActivityResultRegistry preview")
+}
+
 class TestGroup {
     @Preview
     @Composable
diff --git a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/preview/ComposeViewAdapterTest.kt b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/preview/ComposeViewAdapterTest.kt
index 7a66e0d..a8c2933 100644
--- a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/preview/ComposeViewAdapterTest.kt
+++ b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/preview/ComposeViewAdapterTest.kt
@@ -265,6 +265,22 @@
         )
     }
 
+    @Test
+    fun onBackPressedDispatcherUsedInsidePreview() {
+        assertRendersCorrectly(
+            "androidx.compose.ui.tooling.SimpleComposablePreviewKt",
+            "OnBackPressedDispatcherPreview"
+        )
+    }
+
+    @Test
+    fun activityResultRegistryUsedInsidePreview() {
+        assertRendersCorrectly(
+            "androidx.compose.ui.tooling.SimpleComposablePreviewKt",
+            "ActivityResultRegistryPreview"
+        )
+    }
+
     /**
      * Check that no re-composition happens without forcing it.
      */
diff --git a/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/preview/ComposeViewAdapter.kt b/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/preview/ComposeViewAdapter.kt
index d20854c..4dabeea 100644
--- a/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/preview/ComposeViewAdapter.kt
+++ b/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/preview/ComposeViewAdapter.kt
@@ -25,6 +25,13 @@
 import android.util.AttributeSet
 import android.util.Log
 import android.widget.FrameLayout
+import androidx.activity.OnBackPressedDispatcher
+import androidx.activity.OnBackPressedDispatcherOwner
+import androidx.activity.compose.LocalActivityResultRegistryOwner
+import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
+import androidx.activity.result.ActivityResultRegistry
+import androidx.activity.result.ActivityResultRegistryOwner
+import androidx.activity.result.contract.ActivityResultContract
 import androidx.annotation.VisibleForTesting
 import androidx.compose.animation.core.InternalAnimationApi
 import androidx.compose.animation.core.Transition
@@ -49,6 +56,7 @@
 import androidx.compose.ui.tooling.preview.animation.PreviewAnimationClock
 import androidx.compose.ui.tooling.preview.CommonPreviewUtils.invokeComposableViaReflection
 import androidx.compose.ui.unit.IntRect
+import androidx.core.app.ActivityOptionsCompat
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleRegistry
 import androidx.lifecycle.ViewModelStoreOwner
@@ -479,7 +487,11 @@
         // We need to replace the FontResourceLoader to avoid using ResourcesCompat.
         // ResourcesCompat can not load fonts within Layoutlib and, since Layoutlib always runs
         // the latest version, we do not need it.
-        CompositionLocalProvider(LocalFontLoader provides LayoutlibFontResourceLoader(context)) {
+        CompositionLocalProvider(
+            LocalFontLoader provides LayoutlibFontResourceLoader(context),
+            LocalOnBackPressedDispatcherOwner provides FakeOnBackPressedDispatcherOwner,
+            LocalActivityResultRegistryOwner provides FakeActivityResultRegistryOwner,
+        ) {
             Inspectable(slotTableRecord, content)
         }
     }
@@ -678,4 +690,26 @@
     private val FakeViewModelStoreOwner = ViewModelStoreOwner {
         throw IllegalStateException("ViewModels creation is not supported in Preview")
     }
+
+    private val FakeOnBackPressedDispatcherOwner = object : OnBackPressedDispatcherOwner {
+        private val onBackPressedDispatcher = OnBackPressedDispatcher()
+
+        override fun getOnBackPressedDispatcher() = onBackPressedDispatcher
+        override fun getLifecycle() = FakeSavedStateRegistryOwner.lifecycle
+    }
+
+    private val FakeActivityResultRegistryOwner = object : ActivityResultRegistryOwner {
+        private val activityResultRegistry = object : ActivityResultRegistry() {
+            override fun <I : Any?, O : Any?> onLaunch(
+                requestCode: Int,
+                contract: ActivityResultContract<I, O>,
+                input: I,
+                options: ActivityOptionsCompat?
+            ) {
+                throw IllegalStateException("Calling launch() is not supported in Preview")
+            }
+        }
+
+        override fun getActivityResultRegistry(): ActivityResultRegistry = activityResultRegistry
+    }
 }
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 d134ee9..cdf94ae 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
@@ -38,6 +38,7 @@
 import android.widget.LinearLayout
 import android.widget.TextView
 import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.ScrollState
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
@@ -47,11 +48,15 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.LazyRow
+import androidx.compose.foundation.lazy.LazyListState
 import androidx.compose.foundation.progressSemantics
 import androidx.compose.foundation.selection.selectable
 import androidx.compose.foundation.selection.toggleable
 import androidx.compose.foundation.text.BasicText
 import androidx.compose.foundation.text.BasicTextField
+import androidx.compose.foundation.verticalScroll
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
@@ -104,6 +109,7 @@
 import androidx.test.filters.LargeTest
 import androidx.test.filters.SdkSuppress
 import androidx.test.platform.app.InstrumentationRegistry
+import com.google.common.truth.Truth.assertThat
 import com.nhaarman.mockitokotlin2.argThat
 import com.nhaarman.mockitokotlin2.atLeastOnce
 import com.nhaarman.mockitokotlin2.doReturn
@@ -495,6 +501,147 @@
     }
 
     @Test
+    fun testPerformAction_showOnScreen() {
+        val scrollState = ScrollState(initial = 0)
+        val target1Tag = "target1"
+        val target2Tag = "target2"
+        container.setContent {
+            Box {
+                Column(
+                    Modifier
+                        .size(200.dp)
+                        .verticalScroll(scrollState)
+                ) {
+                    BasicText("Backward", Modifier.testTag(target2Tag).size(150.dp))
+                    BasicText("Forward", Modifier.testTag(target1Tag).size(150.dp))
+                }
+            }
+        }
+
+        waitForSubtreeEventToSend()
+        assertThat(scrollState.value).isEqualTo(0)
+
+        val showOnScreen = android.R.id.accessibilityActionShowOnScreen
+        val targetNode1 = rule.onNodeWithTag(target1Tag)
+            .fetchSemanticsNode("couldn't find node with tag $target1Tag")
+        rule.runOnUiThread {
+            assertTrue(provider.performAction(targetNode1.id, showOnScreen, null))
+        }
+        with(rule.density) {
+            assertThat(scrollState.value).isGreaterThan(99.dp.toPx().toInt())
+        }
+
+        val targetNode2 = rule.onNodeWithTag(target2Tag)
+            .fetchSemanticsNode("couldn't find node with tag $target2Tag")
+        rule.runOnUiThread {
+            assertTrue(provider.performAction(targetNode2.id, showOnScreen, null))
+        }
+        assertThat(scrollState.value).isEqualTo(0)
+    }
+
+    @Test
+    fun testPerformAction_showOnScreen_lazy() {
+        val lazyState = LazyListState()
+        val target1Tag = "target1"
+        val target2Tag = "target2"
+        container.setContent {
+            Box {
+                LazyColumn(
+                    modifier = Modifier.size(200.dp),
+                    state = lazyState
+                ) {
+                    item {
+                        BasicText("Backward", Modifier.testTag(target2Tag).size(150.dp))
+                    }
+                    item {
+                        BasicText("Forward", Modifier.testTag(target1Tag).size(150.dp))
+                    }
+                }
+            }
+        }
+
+        waitForSubtreeEventToSend()
+        assertThat(lazyState.firstVisibleItemScrollOffset).isEqualTo(0)
+
+        val showOnScreen = android.R.id.accessibilityActionShowOnScreen
+        val targetNode1 = rule.onNodeWithTag(target1Tag)
+            .fetchSemanticsNode("couldn't find node with tag $target1Tag")
+        rule.runOnUiThread {
+            assertTrue(provider.performAction(targetNode1.id, showOnScreen, null))
+        }
+        with(rule.density) {
+            assertThat(lazyState.firstVisibleItemIndex).isEqualTo(0)
+            assertThat(lazyState.firstVisibleItemScrollOffset).isGreaterThan(99.dp.toPx().toInt())
+        }
+
+        val targetNode2 = rule.onNodeWithTag(target2Tag)
+            .fetchSemanticsNode("couldn't find node with tag $target2Tag")
+        rule.runOnUiThread {
+            assertTrue(provider.performAction(targetNode2.id, showOnScreen, null))
+        }
+        assertThat(lazyState.firstVisibleItemIndex).isEqualTo(0)
+        assertThat(lazyState.firstVisibleItemScrollOffset).isEqualTo(0)
+    }
+
+    @Test
+    fun testPerformAction_showOnScreen_lazynested() {
+        val parentLazyState = LazyListState()
+        val lazyState = LazyListState()
+        val target1Tag = "target1"
+        val target2Tag = "target2"
+        container.setContent {
+            Box {
+                LazyRow(
+                    modifier = Modifier.size(250.dp),
+                    state = parentLazyState
+                ) {
+                    item {
+                        LazyColumn(
+                            modifier = Modifier.size(200.dp),
+                            state = lazyState
+                        ) {
+                            item {
+                                BasicText("Backward", Modifier.testTag(target2Tag).size(150.dp))
+                            }
+                            item {
+                                BasicText("Forward", Modifier.testTag(target1Tag).size(150.dp))
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        waitForSubtreeEventToSend()
+        assertThat(lazyState.firstVisibleItemIndex).isEqualTo(0)
+        assertThat(lazyState.firstVisibleItemScrollOffset).isEqualTo(0)
+
+        // Test that child column scrolls to make it fully visible in its context, without being
+        // influenced by or influencing the parent row.
+        // TODO(b/190865803): Is this the ultimate right behavior we want?
+        val showOnScreen = android.R.id.accessibilityActionShowOnScreen
+        val targetNode1 = rule.onNodeWithTag(target1Tag)
+            .fetchSemanticsNode("couldn't find node with tag $target1Tag")
+        rule.runOnUiThread {
+            assertTrue(provider.performAction(targetNode1.id, showOnScreen, null))
+        }
+        with(rule.density) {
+            assertThat(lazyState.firstVisibleItemIndex).isEqualTo(0)
+            assertThat(lazyState.firstVisibleItemScrollOffset).isGreaterThan(99.dp.toPx().toInt())
+        }
+        assertThat(parentLazyState.firstVisibleItemScrollOffset).isEqualTo(0)
+
+        val targetNode2 = rule.onNodeWithTag(target2Tag)
+            .fetchSemanticsNode("couldn't find node with tag $target2Tag")
+        rule.runOnUiThread {
+            assertTrue(provider.performAction(targetNode2.id, showOnScreen, null))
+        }
+        assertThat(lazyState.firstVisibleItemIndex).isEqualTo(0)
+        assertThat(lazyState.firstVisibleItemScrollOffset).isEqualTo(0)
+        assertThat(parentLazyState.firstVisibleItemScrollOffset).isEqualTo(0)
+    }
+
+    @Test
     fun testPerformAction_succeedOnEnabledNodes() {
         val tag = "Toggleable"
         container.setContent {
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 fea1c50..6663e6c 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
@@ -25,9 +25,11 @@
 import android.widget.FrameLayout
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.snapshots.Snapshot
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
+import androidx.compose.runtime.structuralEqualityPolicy
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.node.InnerPlaceable
@@ -597,55 +599,46 @@
     }
 
     @Test
-    fun notSendScrollEvent_whenOnlyScrollAxisRangeMaxValueChanges() {
-        val oldSemanticsNode = createSemanticsNodeWithProperties(1, true) {
-            this.verticalScrollAxisRange = ScrollAxisRange({ 0f }, { 0f }, false)
+    fun sendScrollEvent_byStateObservation() {
+        var scrollValue by mutableStateOf(0f, structuralEqualityPolicy())
+        var scrollMaxValue by mutableStateOf(100f, structuralEqualityPolicy())
+
+        val semanticsNode = createSemanticsNodeWithProperties(1, false) {
+            verticalScrollAxisRange = ScrollAxisRange({ scrollValue }, { scrollMaxValue })
         }
+
         accessibilityDelegate.previousSemanticsNodes[1] =
             AndroidComposeViewAccessibilityDelegateCompat.SemanticsNodeCopy(
-                oldSemanticsNode,
+                semanticsNode,
                 mapOf()
             )
         val newNodes = mutableMapOf<Int, SemanticsNodeWithAdjustedBounds>()
-        newNodes[1] = createSemanticsNodeWithAdjustedBoundsWithProperties(1, true) {
-            this.verticalScrollAxisRange = ScrollAxisRange({ 0f }, { 5f }, false)
-        }
-        accessibilityDelegate.sendSemanticsPropertyChangeEvents(newNodes)
-
-        verify(container, never()).requestSendAccessibilityEvent(
-            eq(androidComposeView),
-            argThat(
-                ArgumentMatcher {
-                    it.eventType == AccessibilityEvent.TYPE_VIEW_SCROLLED
-                }
-            )
+        newNodes[1] = SemanticsNodeWithAdjustedBounds(
+            semanticsNode,
+            android.graphics.Rect()
         )
-    }
 
-    @Test
-    fun sendScrollEvent_whenScrollAxisRangeValueChanges() {
-        val oldSemanticsNode = createSemanticsNodeWithProperties(2, false) {
-            this.verticalScrollAxisRange = ScrollAxisRange({ 0f }, { 5f }, false)
+        try {
+            accessibilityDelegate.view.snapshotObserver.startObserving()
+
+            accessibilityDelegate.sendSemanticsPropertyChangeEvents(newNodes)
+
+            Snapshot.notifyObjectsInitialized()
+            scrollValue = 1f
+            Snapshot.sendApplyNotifications()
+        } finally {
+            accessibilityDelegate.view.snapshotObserver.stopObserving()
         }
-        accessibilityDelegate.previousSemanticsNodes[2] =
-            AndroidComposeViewAccessibilityDelegateCompat.SemanticsNodeCopy(
-                oldSemanticsNode,
-                mapOf()
-            )
-        val newNodes = mutableMapOf<Int, SemanticsNodeWithAdjustedBounds>()
-        newNodes[2] = createSemanticsNodeWithAdjustedBoundsWithProperties(2, false) {
-            this.verticalScrollAxisRange = ScrollAxisRange({ 2f }, { 5f }, false)
-        }
-        accessibilityDelegate.sendSemanticsPropertyChangeEvents(newNodes)
 
         verify(container, times(1)).requestSendAccessibilityEvent(
             eq(androidComposeView),
             argThat(
                 ArgumentMatcher {
-                    it.eventType == AccessibilityEvent.TYPE_VIEW_SCROLLED && it.scrollY == 2 &&
-                        it.maxScrollY == 5 &&
+                    it.eventType == AccessibilityEvent.TYPE_VIEW_SCROLLED &&
+                        it.scrollY == 1 &&
+                        it.maxScrollY == 100 &&
                         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
-                            it.scrollDeltaY == 2
+                            it.scrollDeltaY == 1
                         } else {
                             true
                         }
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 b441e23..fe177ce 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
@@ -45,8 +45,10 @@
 import androidx.compose.ui.graphics.toAndroidRect
 import androidx.compose.ui.layout.boundsInParent
 import androidx.compose.ui.node.LayoutNode
+import androidx.compose.ui.node.OwnerScope
 import androidx.compose.ui.semantics.CustomAccessibilityAction
 import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.ScrollAxisRange
 import androidx.compose.ui.semantics.SemanticsActions
 import androidx.compose.ui.semantics.SemanticsActions.CustomActions
 import androidx.compose.ui.semantics.SemanticsNode
@@ -1198,6 +1200,33 @@
             AccessibilityNodeInfoCompat.ACTION_DISMISS -> {
                 return node.config.getOrNull(SemanticsActions.Dismiss)?.action?.invoke() ?: false
             }
+            android.R.id.accessibilityActionShowOnScreen -> {
+                // TODO(b/190865803): Consider scrolling nested containers instead of only the first one.
+                var scrollableAncestor: SemanticsNode? = node.parent
+                var scrollAction = scrollableAncestor?.config?.getOrNull(SemanticsActions.ScrollBy)
+                while (scrollableAncestor != null) {
+                    if (scrollAction != null) {
+                        break
+                    }
+                    scrollableAncestor = scrollableAncestor.parent
+                    scrollAction = scrollableAncestor?.config?.getOrNull(SemanticsActions.ScrollBy)
+                }
+                if (scrollableAncestor == null) {
+                    return false
+                }
+
+                // TalkBack expects the minimum amount of movement to fully reveal the node.
+                var xDelta = node.size.width - node.boundsInWindow.width
+                if (node.boundsInWindow.left == scrollableAncestor.positionInWindow.x) {
+                    xDelta = -xDelta
+                }
+                var yDelta = node.size.height - node.boundsInWindow.height
+                if (node.boundsInWindow.top == scrollableAncestor.positionInWindow.y) {
+                    yDelta = -yDelta
+                }
+
+                return scrollAction?.action?.invoke(xDelta, yDelta) ?: false
+            }
             // TODO: handling for other system actions
             else -> {
                 val label = actionIdToLabel[virtualViewId]?.get(action) ?: return false
@@ -1601,14 +1630,23 @@
     internal fun sendSemanticsPropertyChangeEvents(
         newSemanticsNodes: Map<Int, SemanticsNodeWithAdjustedBounds>
     ) {
+        val oldScrollObservationScopes = ArrayList(scrollObservationScopes)
+        scrollObservationScopes.clear()
         for (id in newSemanticsNodes.keys) {
             // We do doing this search because the new configuration is set as a whole, so we
             // can't indicate which property is changed when setting the new configuration.
             val oldNode = previousSemanticsNodes[id] ?: continue
             val newNode = newSemanticsNodes[id]?.semanticsNode
             var propertyChanged = false
+
             for (entry in newNode!!.config) {
-                if (entry.value == oldNode.config.getOrNull(entry.key)) {
+                var newlyObservingScroll = false
+                if (entry.key == SemanticsProperties.HorizontalScrollAxisRange ||
+                    entry.key == SemanticsProperties.VerticalScrollAxisRange
+                ) {
+                    newlyObservingScroll = registerScrollingId(id, oldScrollObservationScopes)
+                }
+                if (!newlyObservingScroll && entry.value == oldNode.config.getOrNull(entry.key)) {
                     continue
                 }
                 @Suppress("UNCHECKED_CAST")
@@ -1707,47 +1745,16 @@
                     SemanticsProperties.HorizontalScrollAxisRange,
                     SemanticsProperties.VerticalScrollAxisRange -> {
                         // TODO(yingleiw): Add throttling for scroll/state events.
-                        val newXState = newNode.config.getOrNull(
-                            SemanticsProperties.HorizontalScrollAxisRange
-                        )
-                        val oldXState = oldNode.config.getOrNull(
-                            SemanticsProperties.HorizontalScrollAxisRange
-                        )
-                        val newYState = newNode.config.getOrNull(
-                            SemanticsProperties.VerticalScrollAxisRange
-                        )
-                        val oldYState = oldNode.config.getOrNull(
-                            SemanticsProperties.VerticalScrollAxisRange
-                        )
                         notifySubtreeAccessibilityStateChangedIfNeeded(newNode.layoutNode)
-                        val deltaX = if (newXState != null && oldXState != null) {
-                            newXState.value() - oldXState.value()
-                        } else {
-                            0f
-                        }
-                        val deltaY = if (newYState != null && oldYState != null) {
-                            newYState.value() - oldYState.value()
-                        } else {
-                            0f
-                        }
-                        if (deltaX != 0f || deltaY != 0f) {
-                            val event = createEvent(
-                                semanticsNodeIdToAccessibilityVirtualNodeId(id),
-                                AccessibilityEvent.TYPE_VIEW_SCROLLED
-                            )
-                            if (newXState != null) {
-                                event.scrollX = newXState.value().toInt()
-                                event.maxScrollX = newXState.maxValue().toInt()
-                            }
-                            if (newYState != null) {
-                                event.scrollY = newYState.value().toInt()
-                                event.maxScrollY = newYState.maxValue().toInt()
-                            }
-                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
-                                Api28Impl.setScrollEventDelta(event, deltaX.toInt(), deltaY.toInt())
-                            }
-                            sendEvent(event)
-                        }
+
+                        val scope = scrollObservationScopes.findById(id)!!
+                        scope.horizontalScrollAxisRange = newNode.config.getOrNull(
+                            SemanticsProperties.HorizontalScrollAxisRange
+                        )
+                        scope.verticalScrollAxisRange = newNode.config.getOrNull(
+                            SemanticsProperties.VerticalScrollAxisRange
+                        )
+                        sendScrollEventIfNeeded(scope)
                     }
                     SemanticsProperties.Focused -> {
                         if (entry.value as Boolean) {
@@ -1814,6 +1821,93 @@
         }
     }
 
+    // List of visible scrollable nodes (which are observing scroll state snapshot writes).
+    private val scrollObservationScopes = mutableListOf<ScrollObservationScope>()
+
+    /*
+     * Lambda to store in scrolling snapshot observer, which must never be recreated because
+     * the snapshot system makes use of lambda reference comparisons.
+     * (Note that recent versions of the Kotlin compiler do maintain a persistent
+     * object for most lambda expressions, so this is just for the purpose of explicitness.)
+     */
+    private val sendScrollEventIfNeededLambda: (ScrollObservationScope) -> Unit = {
+        this.sendScrollEventIfNeeded(it)
+    }
+
+    private fun registerScrollingId(
+        id: Int,
+        oldScrollObservationScopes: List<ScrollObservationScope>
+    ): Boolean {
+        var newlyObservingScroll = false
+        val oldScope = oldScrollObservationScopes.findById(id)
+        val newScope = if (oldScope != null) {
+            oldScope
+        } else {
+            newlyObservingScroll = true
+            ScrollObservationScope(
+                semanticsNodeId = id,
+                allScopes = scrollObservationScopes,
+                oldXValue = null,
+                oldYValue = null,
+                horizontalScrollAxisRange = null,
+                verticalScrollAxisRange = null
+            )
+        }
+        scrollObservationScopes.add(newScope)
+        return newlyObservingScroll
+    }
+
+    private fun sendScrollEventIfNeeded(scrollObservationScope: ScrollObservationScope) {
+        if (!scrollObservationScope.isValid) {
+            return
+        }
+        view.snapshotObserver.observeReads(scrollObservationScope, sendScrollEventIfNeededLambda) {
+            val newXState = scrollObservationScope.horizontalScrollAxisRange
+            val newYState = scrollObservationScope.verticalScrollAxisRange
+            val oldXValue = scrollObservationScope.oldXValue
+            val oldYValue = scrollObservationScope.oldYValue
+
+            val deltaX = if (newXState != null && oldXValue != null) {
+                newXState.value() - oldXValue
+            } else {
+                0f
+            }
+            val deltaY = if (newYState != null && oldYValue != null) {
+                newYState.value() - oldYValue
+            } else {
+                0f
+            }
+
+            if (deltaX != 0f || deltaY != 0f) {
+                val event = createEvent(
+                    semanticsNodeIdToAccessibilityVirtualNodeId(
+                        scrollObservationScope.semanticsNodeId
+                    ),
+                    AccessibilityEvent.TYPE_VIEW_SCROLLED
+                )
+                if (newXState != null) {
+                    event.scrollX = newXState.value().toInt()
+                    event.maxScrollX = newXState.maxValue().toInt()
+                }
+                if (newYState != null) {
+                    event.scrollY = newYState.value().toInt()
+                    event.maxScrollY = newYState.maxValue().toInt()
+                }
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+                    Api28Impl.setScrollEventDelta(event, deltaX.toInt(), deltaY.toInt())
+                }
+                sendEvent(event)
+            }
+
+            if (newXState != null) {
+                scrollObservationScope.oldXValue = newXState.value()
+            }
+            if (newYState != null) {
+                scrollObservationScope.oldYValue = newYState.value()
+            }
+        }
+    }
+
     private fun sendPaneChangeEvents(
         semanticsNodeId: Int,
         contentChangeType: Int,
@@ -2341,4 +2435,27 @@
     fun setAvailableExtraData(node: AccessibilityNodeInfo, data: List<String>) {
         node.availableExtraData = data
     }
+}
+
+// These objects are used as snapshot observation scopes for the purpose of sending accessibility
+// scroll events whenever the scroll offset changes.  There is one per scroller and their lifecycle
+// is the same as the scroller's lifecycle in the semantics tree.
+internal class ScrollObservationScope(
+    val semanticsNodeId: Int,
+    val allScopes: List<ScrollObservationScope>,
+    var oldXValue: Float?,
+    var oldYValue: Float?,
+    var horizontalScrollAxisRange: ScrollAxisRange?,
+    var verticalScrollAxisRange: ScrollAxisRange?
+) : OwnerScope {
+    override val isValid get() = allScopes.contains(this)
+}
+
+internal fun List<ScrollObservationScope>.findById(id: Int): ScrollObservationScope? {
+    for (index in indices) {
+        if (this[index].semanticsNodeId == id) {
+            return this[index]
+        }
+    }
+    return null
 }
\ No newline at end of file
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroid.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroid.android.kt
index e61215c..333a055 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroid.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroid.android.kt
@@ -70,7 +70,11 @@
     private val layoutListener = ViewTreeObserver.OnGlobalLayoutListener {
         // focusedRect is null if there is not ongoing text input session. So safe to request
         // latest focused rectangle whenever global layout has changed.
-        focusedRect?.let { view.requestRectangleOnScreen(it) }
+        focusedRect?.let {
+            // Notice that view.requestRectangleOnScreen may modify the input Rect, we have to
+            // create another Rect and then pass it.
+            view.requestRectangleOnScreen(android.graphics.Rect(it))
+        }
     }
 
     internal constructor(view: View) : this(view, InputMethodManagerImpl(view.context))
@@ -236,7 +240,11 @@
         // Even if we miss all the timing of requesting rectangle during initial text field focus,
         // focused rectangle will be requested when software keyboard has shown.
         if (ic == null) {
-            view.requestRectangleOnScreen(focusedRect)
+            focusedRect?.let {
+                // Notice that view.requestRectangleOnScreen may modify the input Rect, we have to
+                // create another Rect and then pass it.
+                view.requestRectangleOnScreen(android.graphics.Rect(it))
+            }
         }
     }
 }
diff --git a/compose/ui/ui/src/androidMain/res/values-af/strings.xml b/compose/ui/ui/src/androidMain/res/values-af/strings.xml
new file mode 100644
index 0000000..0a70b81
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-af/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Nie gemerk of ontmerk nie"</string>
+    <string name="on" msgid="8655164131929253426">"Aan"</string>
+    <string name="off" msgid="875452955155264703">"Af"</string>
+    <string name="selected" msgid="6043586758067023">"Gekies"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Nie gekies nie"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> persent."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Besig"</string>
+    <string name="tab" msgid="1672349317127674378">"Oortjie"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigasiekieslys"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Maak navigasiekieslys toe"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Maak sigblad toe"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Ongeldige invoer"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-am/strings.xml b/compose/ui/ui/src/androidMain/res/values-am/strings.xml
new file mode 100644
index 0000000..45c14ea
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-am/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"ምልክት የተደረገበትም ያልተደረገበትም"</string>
+    <string name="on" msgid="8655164131929253426">"በርቷል"</string>
+    <string name="off" msgid="875452955155264703">"ጠፍቷል"</string>
+    <string name="selected" msgid="6043586758067023">"ተመርጧል"</string>
+    <string name="not_selected" msgid="6610465462668679431">"ያልተመረጡ"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> በመቶ።"</string>
+    <string name="in_progress" msgid="6827826412747255547">"በሂደት ላይ"</string>
+    <string name="tab" msgid="1672349317127674378">"ትር"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"የዳሰሳ ምናሌ"</string>
+    <string name="close_drawer" msgid="406453423630273620">"የዳሰሳ ምናሌን ዝጋ"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"ሉህን ዝጋ"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"ልክ ያልሆነ ግቤት"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ar/strings.xml b/compose/ui/ui/src/androidMain/res/values-ar/strings.xml
new file mode 100644
index 0000000..760e115
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-ar/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"لم يتم وضع علامة أو إزالتها"</string>
+    <string name="on" msgid="8655164131929253426">"مفعّل"</string>
+    <string name="off" msgid="875452955155264703">"غير مفعّل"</string>
+    <string name="selected" msgid="6043586758067023">"محدّد"</string>
+    <string name="not_selected" msgid="6610465462668679431">"غير محدّد"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> في المئة."</string>
+    <string name="in_progress" msgid="6827826412747255547">"قيد التقدم"</string>
+    <string name="tab" msgid="1672349317127674378">"علامة تبويب"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"قائمة تنقل"</string>
+    <string name="close_drawer" msgid="406453423630273620">"إغلاق قائمة التنقل"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"إغلاق الورقة"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"إدخال غير صالح"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-as/strings.xml b/compose/ui/ui/src/androidMain/res/values-as/strings.xml
new file mode 100644
index 0000000..f1eed51
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-as/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"টিক চিহ্ন দিয়াও নাই আঁতৰোৱাও নাই"</string>
+    <string name="on" msgid="8655164131929253426">"অন কৰা আছে"</string>
+    <string name="off" msgid="875452955155264703">"অফ আছে"</string>
+    <string name="selected" msgid="6043586758067023">"বাছনি কৰা হৈছে"</string>
+    <string name="not_selected" msgid="6610465462668679431">"বাছনি কৰা হোৱা নাই"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> শতাংশ।"</string>
+    <string name="in_progress" msgid="6827826412747255547">"প্ৰক্ৰিয়াকৰণ কৰি থকা হৈছে"</string>
+    <string name="tab" msgid="1672349317127674378">"টেব"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"নেভিগেশ্বন মেনু"</string>
+    <string name="close_drawer" msgid="406453423630273620">"নেভিগেশ্বন মেনু বন্ধ কৰক"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"শ্বীট বন্ধ কৰক"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"অমান্য ইনপুট"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-az/strings.xml b/compose/ui/ui/src/androidMain/res/values-az/strings.xml
new file mode 100644
index 0000000..549f325
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-az/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Nə seçilməyib, nə də seçim ləğv edilməyib"</string>
+    <string name="on" msgid="8655164131929253426">"Aktiv"</string>
+    <string name="off" msgid="875452955155264703">"Deaktiv"</string>
+    <string name="selected" msgid="6043586758067023">"Seçilib"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Seçilməyib"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> faiz."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Davam edir"</string>
+    <string name="tab" msgid="1672349317127674378">"Tab"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Naviqasiya menyusu"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Naviqasiya menyusunu bağlayın"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Səhifəni bağlayın"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Yanlış daxiletmə"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-b+sr+Latn/strings.xml b/compose/ui/ui/src/androidMain/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..5b6e403
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Nije označeno niti poništeno"</string>
+    <string name="on" msgid="8655164131929253426">"Uključeno"</string>
+    <string name="off" msgid="875452955155264703">"Isključeno"</string>
+    <string name="selected" msgid="6043586758067023">"Izabrano"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Nije izabrano"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> posto."</string>
+    <string name="in_progress" msgid="6827826412747255547">"U toku"</string>
+    <string name="tab" msgid="1672349317127674378">"Kartica"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Meni za navigaciju"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Zatvori meni za navigaciju"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Zatvorite tabelu"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Unos je nevažeći"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-be/strings.xml b/compose/ui/ui/src/androidMain/res/values-be/strings.xml
new file mode 100644
index 0000000..db26c43
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-be/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Птушка не пастаўлена і не знята"</string>
+    <string name="on" msgid="8655164131929253426">"Уключана"</string>
+    <string name="off" msgid="875452955155264703">"Выключана"</string>
+    <string name="selected" msgid="6043586758067023">"Выбрана"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Не выбрана"</string>
+    <string name="template_percent" msgid="5946805113151406391">"Працэнтаў: <xliff:g id="PERCENTAGE">%1$d</xliff:g>."</string>
+    <string name="in_progress" msgid="6827826412747255547">"У працэсе"</string>
+    <string name="tab" msgid="1672349317127674378">"Укладка"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Меню навігацыі"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Закрыць меню навігацыі"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Закрыць аркуш"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Памылка ўводу"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-bg/strings.xml b/compose/ui/ui/src/androidMain/res/values-bg/strings.xml
new file mode 100644
index 0000000..ee7ab18
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-bg/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Няма поставена или премахната отметка"</string>
+    <string name="on" msgid="8655164131929253426">"Вкл."</string>
+    <string name="off" msgid="875452955155264703">"Изкл."</string>
+    <string name="selected" msgid="6043586758067023">"Избрано"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Не е избрано"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> процента."</string>
+    <string name="in_progress" msgid="6827826412747255547">"В ход"</string>
+    <string name="tab" msgid="1672349317127674378">"Раздел"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Меню за навигация"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Затваряне на менюто за навигация"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Затваряне на таблицата"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Въведеното е невалидно"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-bs/strings.xml b/compose/ui/ui/src/androidMain/res/values-bs/strings.xml
new file mode 100644
index 0000000..529ef91
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-bs/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Nije odabrano ni poništeno"</string>
+    <string name="on" msgid="8655164131929253426">"Uključeno"</string>
+    <string name="off" msgid="875452955155264703">"Isključeno"</string>
+    <string name="selected" msgid="6043586758067023">"Odabrano"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Nije odabrano"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> posto."</string>
+    <string name="in_progress" msgid="6827826412747255547">"U toku"</string>
+    <string name="tab" msgid="1672349317127674378">"Kartica"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Meni za navigaciju"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Zatvaranje navigacionog menija"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Zatvaranje tabele"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Pogrešan unos"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ca/strings.xml b/compose/ui/ui/src/androidMain/res/values-ca/strings.xml
new file mode 100644
index 0000000..21f81fb
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-ca/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Ni marcada ni desmarcada"</string>
+    <string name="on" msgid="8655164131929253426">"Activat"</string>
+    <string name="off" msgid="875452955155264703">"Desactivat"</string>
+    <string name="selected" msgid="6043586758067023">"Seleccionat"</string>
+    <string name="not_selected" msgid="6610465462668679431">"No seleccionat"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> per cent"</string>
+    <string name="in_progress" msgid="6827826412747255547">"En curs"</string>
+    <string name="tab" msgid="1672349317127674378">"Pestanya"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Menú de navegació"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Tanca el menú de navegació"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Tanca el full"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"L\'entrada no és vàlida"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-cs/strings.xml b/compose/ui/ui/src/androidMain/res/values-cs/strings.xml
new file mode 100644
index 0000000..48ba4f2
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-cs/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Ani zaškrtnuto, ani nezaškrtnuto"</string>
+    <string name="on" msgid="8655164131929253426">"Zap"</string>
+    <string name="off" msgid="875452955155264703">"Vyp"</string>
+    <string name="selected" msgid="6043586758067023">"Vybráno"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Nevybráno"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> procent."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Probíhá"</string>
+    <string name="tab" msgid="1672349317127674378">"Karta"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigační nabídka"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Zavřít navigační panel"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Zavřít sešit"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Neplatný údaj"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-da/strings.xml b/compose/ui/ui/src/androidMain/res/values-da/strings.xml
new file mode 100644
index 0000000..7ff8daff
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-da/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Hverken tilvalgt eller fravalgt"</string>
+    <string name="on" msgid="8655164131929253426">"Til"</string>
+    <string name="off" msgid="875452955155264703">"Fra"</string>
+    <string name="selected" msgid="6043586758067023">"Valgt"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Ikke valgt"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> procent."</string>
+    <string name="in_progress" msgid="6827826412747255547">"I gang"</string>
+    <string name="tab" msgid="1672349317127674378">"Fane"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigationsmenu"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Luk navigationsmenuen"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Luk arket"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Ugyldigt input"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-de/strings.xml b/compose/ui/ui/src/androidMain/res/values-de/strings.xml
new file mode 100644
index 0000000..b716e53
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-de/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Häkchen weder gesetzt noch entfernt"</string>
+    <string name="on" msgid="8655164131929253426">"An"</string>
+    <string name="off" msgid="875452955155264703">"Aus"</string>
+    <string name="selected" msgid="6043586758067023">"Ausgewählt"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Nicht ausgewählt"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> Prozent."</string>
+    <string name="in_progress" msgid="6827826412747255547">"In Bearbeitung"</string>
+    <string name="tab" msgid="1672349317127674378">"Tab"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigationsmenü"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Navigationsmenü schließen"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Tabelle schließen"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Ungültige Eingabe"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-el/strings.xml b/compose/ui/ui/src/androidMain/res/values-el/strings.xml
new file mode 100644
index 0000000..69dcbd3
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-el/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Ούτε επιλεγμένο ούτε μη επιλεγμένο"</string>
+    <string name="on" msgid="8655164131929253426">"Ενεργό"</string>
+    <string name="off" msgid="875452955155264703">"Ανενεργό"</string>
+    <string name="selected" msgid="6043586758067023">"Επιλεγμένο"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Δεν έχει επιλεχθεί"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> τοις εκατό."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Σε εξέλιξη"</string>
+    <string name="tab" msgid="1672349317127674378">"Καρτέλα"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Μενού πλοήγησης"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Κλείσιμο του μενού πλοήγησης"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Κλείσιμο φύλλου"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Μη έγκυρη καταχώριση"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-en-rAU/strings.xml b/compose/ui/ui/src/androidMain/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..0bcdf21
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-en-rAU/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Neither ticked nor unticked"</string>
+    <string name="on" msgid="8655164131929253426">"On"</string>
+    <string name="off" msgid="875452955155264703">"Off"</string>
+    <string name="selected" msgid="6043586758067023">"Selected"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Not selected"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> per cent."</string>
+    <string name="in_progress" msgid="6827826412747255547">"In progress"</string>
+    <string name="tab" msgid="1672349317127674378">"Tab"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigation menu"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Close navigation menu"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Close sheet"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Invalid input"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-en-rCA/strings.xml b/compose/ui/ui/src/androidMain/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..0bcdf21
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-en-rCA/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Neither ticked nor unticked"</string>
+    <string name="on" msgid="8655164131929253426">"On"</string>
+    <string name="off" msgid="875452955155264703">"Off"</string>
+    <string name="selected" msgid="6043586758067023">"Selected"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Not selected"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> per cent."</string>
+    <string name="in_progress" msgid="6827826412747255547">"In progress"</string>
+    <string name="tab" msgid="1672349317127674378">"Tab"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigation menu"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Close navigation menu"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Close sheet"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Invalid input"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-en-rGB/strings.xml b/compose/ui/ui/src/androidMain/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..0bcdf21
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-en-rGB/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Neither ticked nor unticked"</string>
+    <string name="on" msgid="8655164131929253426">"On"</string>
+    <string name="off" msgid="875452955155264703">"Off"</string>
+    <string name="selected" msgid="6043586758067023">"Selected"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Not selected"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> per cent."</string>
+    <string name="in_progress" msgid="6827826412747255547">"In progress"</string>
+    <string name="tab" msgid="1672349317127674378">"Tab"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigation menu"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Close navigation menu"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Close sheet"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Invalid input"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-en-rIN/strings.xml b/compose/ui/ui/src/androidMain/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..0bcdf21
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-en-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Neither ticked nor unticked"</string>
+    <string name="on" msgid="8655164131929253426">"On"</string>
+    <string name="off" msgid="875452955155264703">"Off"</string>
+    <string name="selected" msgid="6043586758067023">"Selected"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Not selected"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> per cent."</string>
+    <string name="in_progress" msgid="6827826412747255547">"In progress"</string>
+    <string name="tab" msgid="1672349317127674378">"Tab"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigation menu"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Close navigation menu"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Close sheet"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Invalid input"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-en-rXC/strings.xml b/compose/ui/ui/src/androidMain/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..c08a8ca
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-en-rXC/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎‎‏‎‎Neither checked nor unchecked‎‏‎‎‏‎"</string>
+    <string name="on" msgid="8655164131929253426">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‎‎‎‎‏‏‎‎‏‏‎‎‎‏‏‎‎‏‎‎On‎‏‎‎‏‎"</string>
+    <string name="off" msgid="875452955155264703">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎‎‎‏‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‎Off‎‏‎‎‏‎"</string>
+    <string name="selected" msgid="6043586758067023">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‏‏‎‎‎‏‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‏‎‎‎‎‏‏‎‏‎‎‏‏‏‏‎Selected‎‏‎‎‏‎"</string>
+    <string name="not_selected" msgid="6610465462668679431">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‏‎‎‎‎‏‎‎‎‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‏‏‏‎Not selected‎‏‎‎‏‎"</string>
+    <string name="template_percent" msgid="5946805113151406391">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‎‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‎‏‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%1$d</xliff:g>‎‏‎‎‏‏‏‎ percent.‎‏‎‎‏‎"</string>
+    <string name="in_progress" msgid="6827826412747255547">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‏‏‏‎‏‏‎In progress‎‏‎‎‏‎"</string>
+    <string name="tab" msgid="1672349317127674378">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‎‏‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‎‏‎‏‎‎Tab‎‏‎‎‏‎"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‏‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‎Navigation menu‎‏‎‎‏‎"</string>
+    <string name="close_drawer" msgid="406453423630273620">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‎‎‎‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‏‎‏‎‏‎‎‎Close navigation menu‎‏‎‎‏‎"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎Close sheet‎‏‎‎‏‎"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‎‏‏‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎Invalid input‎‏‎‎‏‎"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-es-rUS/strings.xml b/compose/ui/ui/src/androidMain/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..878c0d6
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-es-rUS/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Ni marcada ni desmarcada"</string>
+    <string name="on" msgid="8655164131929253426">"Sí"</string>
+    <string name="off" msgid="875452955155264703">"No"</string>
+    <string name="selected" msgid="6043586758067023">"Seleccionado"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Sin seleccionar"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> por ciento."</string>
+    <string name="in_progress" msgid="6827826412747255547">"En curso"</string>
+    <string name="tab" msgid="1672349317127674378">"Pestaña"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Menú de navegación"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Cerrar el menú de navegación"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Cerrar hoja"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Entrada no válida"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-es/strings.xml b/compose/ui/ui/src/androidMain/res/values-es/strings.xml
new file mode 100644
index 0000000..1c59f02
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-es/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Ni marcada ni desmarcada"</string>
+    <string name="on" msgid="8655164131929253426">"Activado"</string>
+    <string name="off" msgid="875452955155264703">"Desactivado"</string>
+    <string name="selected" msgid="6043586758067023">"Seleccionado"</string>
+    <string name="not_selected" msgid="6610465462668679431">"No seleccionado"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> por cien."</string>
+    <string name="in_progress" msgid="6827826412747255547">"En curso"</string>
+    <string name="tab" msgid="1672349317127674378">"Pestaña"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Menú de navegación"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Cerrar menú de navegación"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Cerrar hoja"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Entrada no válida"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-et/strings.xml b/compose/ui/ui/src/androidMain/res/values-et/strings.xml
new file mode 100644
index 0000000..36a1d50
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-et/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Ei märgitud ega märkimata"</string>
+    <string name="on" msgid="8655164131929253426">"Sees"</string>
+    <string name="off" msgid="875452955155264703">"Väljas"</string>
+    <string name="selected" msgid="6043586758067023">"Valitud"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Pole valitud"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> protsenti."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Pooleli"</string>
+    <string name="tab" msgid="1672349317127674378">"Vaheleht"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigeerimismenüü"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Sule navigeerimismenüü"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Sule leht"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Sobimatu sisend"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-eu/strings.xml b/compose/ui/ui/src/androidMain/res/values-eu/strings.xml
new file mode 100644
index 0000000..821ca0b
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-eu/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Ez markatuta eta ez markatu gabe"</string>
+    <string name="on" msgid="8655164131929253426">"Aktibatuta"</string>
+    <string name="off" msgid="875452955155264703">"Desaktibatuta"</string>
+    <string name="selected" msgid="6043586758067023">"Hautatuta"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Hautatu gabe"</string>
+    <string name="template_percent" msgid="5946805113151406391">"Ehuneko <xliff:g id="PERCENTAGE">%1$d</xliff:g>."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Abian"</string>
+    <string name="tab" msgid="1672349317127674378">"Fitxa"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Nabigazio-menua"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Itxi nabigazio-menua"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Itxi orria"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Sarrerak ez du balio"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-fa/strings.xml b/compose/ui/ui/src/androidMain/res/values-fa/strings.xml
new file mode 100644
index 0000000..079c362
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-fa/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"نه علامت‌گذاری شده و نه علامت‌گذاری آن لغو شده"</string>
+    <string name="on" msgid="8655164131929253426">"روشن"</string>
+    <string name="off" msgid="875452955155264703">"خاموش"</string>
+    <string name="selected" msgid="6043586758067023">"انتخاب شد"</string>
+    <string name="not_selected" msgid="6610465462668679431">"انتخاب‌نشده"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> درصد."</string>
+    <string name="in_progress" msgid="6827826412747255547">"درحال انجام"</string>
+    <string name="tab" msgid="1672349317127674378">"برگه"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"منوی پیمایش"</string>
+    <string name="close_drawer" msgid="406453423630273620">"بستن منوی پیمایش"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"بستن برگ"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"ورودی نامعتبر"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-fi/strings.xml b/compose/ui/ui/src/androidMain/res/values-fi/strings.xml
new file mode 100644
index 0000000..d606a79
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-fi/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Ei valittu eikä valitsematta"</string>
+    <string name="on" msgid="8655164131929253426">"Päällä"</string>
+    <string name="off" msgid="875452955155264703">"Pois"</string>
+    <string name="selected" msgid="6043586758067023">"Valittu"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Ei valittu"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> prosenttia"</string>
+    <string name="in_progress" msgid="6827826412747255547">"Kesken"</string>
+    <string name="tab" msgid="1672349317127674378">"Välilehti"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigointivalikko"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Sulje navigointivalikko"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Sulje taulukko"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Virheellinen syöte"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-fr-rCA/strings.xml b/compose/ui/ui/src/androidMain/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..fcd13b9
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-fr-rCA/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Ni cochée ni décochée"</string>
+    <string name="on" msgid="8655164131929253426">"Activé"</string>
+    <string name="off" msgid="875452955155264703">"Désactivé"</string>
+    <string name="selected" msgid="6043586758067023">"Sélectionné"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Non sélectionné"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> pour cent."</string>
+    <string name="in_progress" msgid="6827826412747255547">"En cours…"</string>
+    <string name="tab" msgid="1672349317127674378">"Onglet"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Menu de navigation"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Fermer le menu de navigation"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Fermer la feuille"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Entrée incorrecte"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-fr/strings.xml b/compose/ui/ui/src/androidMain/res/values-fr/strings.xml
new file mode 100644
index 0000000..47a728f
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-fr/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Ni cochée, ni décochée"</string>
+    <string name="on" msgid="8655164131929253426">"Activé"</string>
+    <string name="off" msgid="875452955155264703">"Désactivé"</string>
+    <string name="selected" msgid="6043586758067023">"Sélectionné"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Non sélectionné"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> pour cent."</string>
+    <string name="in_progress" msgid="6827826412747255547">"En cours"</string>
+    <string name="tab" msgid="1672349317127674378">"Onglet"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Menu de navigation"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Fermer le menu de navigation"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Fermer la feuille"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Données incorrectes"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-gl/strings.xml b/compose/ui/ui/src/androidMain/res/values-gl/strings.xml
new file mode 100644
index 0000000..d3505c6
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-gl/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Non marcada nin desmarcada"</string>
+    <string name="on" msgid="8655164131929253426">"Activado"</string>
+    <string name="off" msgid="875452955155264703">"Desactivado"</string>
+    <string name="selected" msgid="6043586758067023">"Seleccionado"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Non seleccionado"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> por cento."</string>
+    <string name="in_progress" msgid="6827826412747255547">"En curso"</string>
+    <string name="tab" msgid="1672349317127674378">"Tabulador"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Menú de navegación"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Pechar menú de navegación"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Pechar folla"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"O texto escrito non é válido"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-hi/strings.xml b/compose/ui/ui/src/androidMain/res/values-hi/strings.xml
new file mode 100644
index 0000000..8562884
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-hi/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"चेकबॉक्स पर न तो सही का निशान लगाया गया, न ही पहले से लगा सही का निशान हटाया गया"</string>
+    <string name="on" msgid="8655164131929253426">"चालू है"</string>
+    <string name="off" msgid="875452955155264703">"बंद है"</string>
+    <string name="selected" msgid="6043586758067023">"चुना गया"</string>
+    <string name="not_selected" msgid="6610465462668679431">"नहीं चुना गया"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> प्रतिशत."</string>
+    <string name="in_progress" msgid="6827826412747255547">"जारी है"</string>
+    <string name="tab" msgid="1672349317127674378">"टैब"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"नेविगेशन मेन्यू"</string>
+    <string name="close_drawer" msgid="406453423630273620">"नेविगेशन मेन्यू बंद करें"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"शीट बंद करें"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"अमान्य इनपुट"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-hr/strings.xml b/compose/ui/ui/src/androidMain/res/values-hr/strings.xml
new file mode 100644
index 0000000..c786212
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-hr/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Nije označeno ni poništeno"</string>
+    <string name="on" msgid="8655164131929253426">"Uključeno"</string>
+    <string name="off" msgid="875452955155264703">"Isključeno"</string>
+    <string name="selected" msgid="6043586758067023">"Odabrano"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Nije odabrano"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> posto."</string>
+    <string name="in_progress" msgid="6827826412747255547">"U tijeku"</string>
+    <string name="tab" msgid="1672349317127674378">"Kartica"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigacijski izbornik"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Zatvaranje izbornika za navigaciju"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Zatvaranje lista"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Nevažeći unos"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-hu/strings.xml b/compose/ui/ui/src/androidMain/res/values-hu/strings.xml
new file mode 100644
index 0000000..9bfc7f9
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-hu/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Sem bejelöléssel, sem bejelölés nélkül"</string>
+    <string name="on" msgid="8655164131929253426">"Be"</string>
+    <string name="off" msgid="875452955155264703">"Ki"</string>
+    <string name="selected" msgid="6043586758067023">"Kijelölve"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Nincs kijelölve"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> százalék."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Folyamatban"</string>
+    <string name="tab" msgid="1672349317127674378">"Lap"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigációs menü"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Navigációs menü bezárása"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Munkalap bezárása"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Érvénytelen adat"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-in/strings.xml b/compose/ui/ui/src/androidMain/res/values-in/strings.xml
new file mode 100644
index 0000000..4651485
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-in/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Tidak dicentang atau dihapus centangnya"</string>
+    <string name="on" msgid="8655164131929253426">"Aktif"</string>
+    <string name="off" msgid="875452955155264703">"Nonaktif"</string>
+    <string name="selected" msgid="6043586758067023">"Dipilih"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Tidak dipilih"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> persen."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Dalam proses"</string>
+    <string name="tab" msgid="1672349317127674378">"Tab"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Menu navigasi"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Tutup menu navigasi"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Tutup sheet"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Input tidak valid"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-is/strings.xml b/compose/ui/ui/src/androidMain/res/values-is/strings.xml
new file mode 100644
index 0000000..f8ff962
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-is/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Hvorki merkt né afmerkt"</string>
+    <string name="on" msgid="8655164131929253426">"Kveikt"</string>
+    <string name="off" msgid="875452955155264703">"Slökkt"</string>
+    <string name="selected" msgid="6043586758067023">"Valið"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Ekki valið"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> prósent."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Í vinnslu"</string>
+    <string name="tab" msgid="1672349317127674378">"Flipi"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Yfirlitsvalmynd"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Loka yfirlitsvalmynd"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Loka blaði"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Ógildur innsláttur"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-it/strings.xml b/compose/ui/ui/src/androidMain/res/values-it/strings.xml
new file mode 100644
index 0000000..97f5387
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-it/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Casella di controllo né selezionata né deselezionata"</string>
+    <string name="on" msgid="8655164131929253426">"On"</string>
+    <string name="off" msgid="875452955155264703">"Off"</string>
+    <string name="selected" msgid="6043586758067023">"Elemento selezionato"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Opzione non selezionata"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> percento."</string>
+    <string name="in_progress" msgid="6827826412747255547">"In corso"</string>
+    <string name="tab" msgid="1672349317127674378">"Scheda"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Menu di navigazione"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Chiudi il menu di navigazione"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Chiudi il foglio"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Valore non valido"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ja/strings.xml b/compose/ui/ui/src/androidMain/res/values-ja/strings.xml
new file mode 100644
index 0000000..58574d5
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-ja/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"オンでもオフでもありません"</string>
+    <string name="on" msgid="8655164131929253426">"オン"</string>
+    <string name="off" msgid="875452955155264703">"オフ"</string>
+    <string name="selected" msgid="6043586758067023">"選択済み"</string>
+    <string name="not_selected" msgid="6610465462668679431">"未選択"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>パーセント。"</string>
+    <string name="in_progress" msgid="6827826412747255547">"処理しています"</string>
+    <string name="tab" msgid="1672349317127674378">"タブ"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"ナビゲーションメニュー"</string>
+    <string name="close_drawer" msgid="406453423630273620">"ナビゲーションメニューを閉じる"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"シートを閉じる"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"入力値が無効です"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ka/strings.xml b/compose/ui/ui/src/androidMain/res/values-ka/strings.xml
new file mode 100644
index 0000000..16f9b79
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-ka/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"არც მონიშნულია და არც მოუნიშნავი"</string>
+    <string name="on" msgid="8655164131929253426">"ჩართული"</string>
+    <string name="off" msgid="875452955155264703">"გამორთული"</string>
+    <string name="selected" msgid="6043586758067023">"არჩეული"</string>
+    <string name="not_selected" msgid="6610465462668679431">"არ არის არჩეული"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> პროცენტი."</string>
+    <string name="in_progress" msgid="6827826412747255547">"მუშავდება"</string>
+    <string name="tab" msgid="1672349317127674378">"ჩანართი"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"ნავიგაციის მენიუ"</string>
+    <string name="close_drawer" msgid="406453423630273620">"ნავიგაციის მენიუს დახურვა"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"ფურცლის დახურვა"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"შენატანი არასწორია"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-kk/strings.xml b/compose/ui/ui/src/androidMain/res/values-kk/strings.xml
new file mode 100644
index 0000000..ceeb61f
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-kk/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Белгіленбеді немесе белгісі алынбады"</string>
+    <string name="on" msgid="8655164131929253426">"Қосулы"</string>
+    <string name="off" msgid="875452955155264703">"Өшірулі"</string>
+    <string name="selected" msgid="6043586758067023">"Таңдалды"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Таңдалмады"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> пайыз."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Орындалуда"</string>
+    <string name="tab" msgid="1672349317127674378">"Қойынды"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Навигация мәзірі"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Навигация мәзірін жабу"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Парақты жабу"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Енгізілген мән жарамсыз."</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-km/strings.xml b/compose/ui/ui/src/androidMain/res/values-km/strings.xml
new file mode 100644
index 0000000..7c77db5
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-km/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"មិនបានធីក ហើយក៏មិន​បានដោះធីកដែរ"</string>
+    <string name="on" msgid="8655164131929253426">"បើក"</string>
+    <string name="off" msgid="875452955155264703">"បិទ"</string>
+    <string name="selected" msgid="6043586758067023">"បានជ្រើសរើស"</string>
+    <string name="not_selected" msgid="6610465462668679431">"មិនបាន​ជ្រើសរើស"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> ភាគរយ។"</string>
+    <string name="in_progress" msgid="6827826412747255547">"កំពុងដំណើរការ"</string>
+    <string name="tab" msgid="1672349317127674378">"Tab"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"ម៉ឺនុយរុករក"</string>
+    <string name="close_drawer" msgid="406453423630273620">"បិទម៉ឺនុយរុករក"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"បិទសន្លឹក"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"ការបញ្ចូល​មិនត្រឹមត្រូវ"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ko/strings.xml b/compose/ui/ui/src/androidMain/res/values-ko/strings.xml
new file mode 100644
index 0000000..6a2688a
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-ko/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"선택 또는 선택 해제되지 않음"</string>
+    <string name="on" msgid="8655164131929253426">"켜짐"</string>
+    <string name="off" msgid="875452955155264703">"꺼짐"</string>
+    <string name="selected" msgid="6043586758067023">"선택됨"</string>
+    <string name="not_selected" msgid="6610465462668679431">"선택되지 않음"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>퍼센트"</string>
+    <string name="in_progress" msgid="6827826412747255547">"진행 중"</string>
+    <string name="tab" msgid="1672349317127674378">"탭"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"탐색 메뉴"</string>
+    <string name="close_drawer" msgid="406453423630273620">"탐색 메뉴 닫기"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"시트 닫기"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"입력이 잘못됨"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ky/strings.xml b/compose/ui/ui/src/androidMain/res/values-ky/strings.xml
new file mode 100644
index 0000000..636d1d3
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-ky/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Белгиленген же белгиленбеген эмес"</string>
+    <string name="on" msgid="8655164131929253426">"Күйүк"</string>
+    <string name="off" msgid="875452955155264703">"Өчүк"</string>
+    <string name="selected" msgid="6043586758067023">"Тандалды"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Тандалган жок"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> пайыз."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Аткарылууда"</string>
+    <string name="tab" msgid="1672349317127674378">"Өтмөк"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Чабыттоо менюсу"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Чабыттоо менюсун жабуу"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Баракты жабуу"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Киргизилген маалымат жараксыз"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-lt/strings.xml b/compose/ui/ui/src/androidMain/res/values-lt/strings.xml
new file mode 100644
index 0000000..9bc393d
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-lt/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Nei pažymėta, nei nepažymėta"</string>
+    <string name="on" msgid="8655164131929253426">"Įjungta"</string>
+    <string name="off" msgid="875452955155264703">"Išjungta"</string>
+    <string name="selected" msgid="6043586758067023">"Pasirinkta"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Nepasirinkta"</string>
+    <string name="template_percent" msgid="5946805113151406391">"Procentų: <xliff:g id="PERCENTAGE">%1$d</xliff:g>."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Vyksta"</string>
+    <string name="tab" msgid="1672349317127674378">"Tabuliavimo klavišas"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Naršymo meniu"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Uždaryti naršymo meniu"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Uždaryti lapą"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Netinkama įvestis"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-lv/strings.xml b/compose/ui/ui/src/androidMain/res/values-lv/strings.xml
new file mode 100644
index 0000000..46a596d
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-lv/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Nav ne atzīmēta, ne neatzīmēta"</string>
+    <string name="on" msgid="8655164131929253426">"Ieslēgts"</string>
+    <string name="off" msgid="875452955155264703">"Izslēgts"</string>
+    <string name="selected" msgid="6043586758067023">"Atlasīts"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Nav atlasīts"</string>
+    <string name="template_percent" msgid="5946805113151406391">"Procenti: <xliff:g id="PERCENTAGE">%1$d</xliff:g>."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Notiek apstrāde"</string>
+    <string name="tab" msgid="1672349317127674378">"Cilne"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigācijas izvēlne"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Aizvērt navigācijas izvēlni"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Aizvērt izklājlapu"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Nederīga ievade"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-mk/strings.xml b/compose/ui/ui/src/androidMain/res/values-mk/strings.xml
new file mode 100644
index 0000000..13e7bd1
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-mk/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Ниту штиклирано, ниту отштиклирано"</string>
+    <string name="on" msgid="8655164131929253426">"Вклучено"</string>
+    <string name="off" msgid="875452955155264703">"Исклучено"</string>
+    <string name="selected" msgid="6043586758067023">"Избрано"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Не е избрано"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> проценти."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Во тек"</string>
+    <string name="tab" msgid="1672349317127674378">"Картичка"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Мени за навигација"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Затворете го менито за навигација"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Затворете го листот"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Неважечки запис"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-mn/strings.xml b/compose/ui/ui/src/androidMain/res/values-mn/strings.xml
new file mode 100644
index 0000000..dcc5796
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-mn/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Тэмдэглэсэн, сонголтыг болиулаагүйн аль нь ч биш"</string>
+    <string name="on" msgid="8655164131929253426">"Асаалттай"</string>
+    <string name="off" msgid="875452955155264703">"Унтраалттай"</string>
+    <string name="selected" msgid="6043586758067023">"Сонгосон"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Сонгоогүй"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> хувь."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Үргэлжилж байна"</string>
+    <string name="tab" msgid="1672349317127674378">"Таб"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Навигацын цэс"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Навигацын цэсийг хаах"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Хүснэгтийг хаах"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Буруу оролт"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ms/strings.xml b/compose/ui/ui/src/androidMain/res/values-ms/strings.xml
new file mode 100644
index 0000000..399fce6
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-ms/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Berkecuali"</string>
+    <string name="on" msgid="8655164131929253426">"Hidup"</string>
+    <string name="off" msgid="875452955155264703">"Mati"</string>
+    <string name="selected" msgid="6043586758067023">"Dipilih"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Tidak dipilih"</string>
+    <string name="template_percent" msgid="5946805113151406391">"Peratus <xliff:g id="PERCENTAGE">%1$d</xliff:g>."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Dalam proses"</string>
+    <string name="tab" msgid="1672349317127674378">"Tab"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Menu navigasi"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Tutup menu navigasi"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Tutup helaian"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Input tidak sah"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-my/strings.xml b/compose/ui/ui/src/androidMain/res/values-my/strings.xml
new file mode 100644
index 0000000..72d22c7
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-my/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"အမှတ်ခြစ်မထားပါ (သို့) အမှတ်ခြစ်ပြီး"</string>
+    <string name="on" msgid="8655164131929253426">"ဖွင့်"</string>
+    <string name="off" msgid="875452955155264703">"ပိတ်"</string>
+    <string name="selected" msgid="6043586758067023">"ရွေးထားသည်"</string>
+    <string name="not_selected" msgid="6610465462668679431">"ရွေးမထားပါ"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> ရာခိုင်နှုန်း။"</string>
+    <string name="in_progress" msgid="6827826412747255547">"ဆောင်ရွက်နေဆဲ"</string>
+    <string name="tab" msgid="1672349317127674378">"တဘ်"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"လမ်းညွှန် မီနူး"</string>
+    <string name="close_drawer" msgid="406453423630273620">"လမ်းညွှန် မီနူး ပိတ်ရန်"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"စာမျက်နှာ ပိတ်ရန်"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"ထည့်သွင်းမှု မမှန်ကန်ပါ"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-nb/strings.xml b/compose/ui/ui/src/androidMain/res/values-nb/strings.xml
new file mode 100644
index 0000000..2b8314b
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-nb/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Verken avmerket eller ikke avmerket"</string>
+    <string name="on" msgid="8655164131929253426">"På"</string>
+    <string name="off" msgid="875452955155264703">"Av"</string>
+    <string name="selected" msgid="6043586758067023">"Valgt"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Ikke valgt"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> prosent."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Pågår"</string>
+    <string name="tab" msgid="1672349317127674378">"Fane"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigasjonsmeny"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Lukk navigasjonsmenyen"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Lukk arket"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Ugyldige inndata"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-nl/strings.xml b/compose/ui/ui/src/androidMain/res/values-nl/strings.xml
new file mode 100644
index 0000000..667814b
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-nl/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Niet aangevinkt of uitgevinkt"</string>
+    <string name="on" msgid="8655164131929253426">"Aan"</string>
+    <string name="off" msgid="875452955155264703">"Uit"</string>
+    <string name="selected" msgid="6043586758067023">"Geselecteerd"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Niet geselecteerd"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> procent."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Bezig"</string>
+    <string name="tab" msgid="1672349317127674378">"Tabblad"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigatiemenu"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Navigatiemenu sluiten"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Blad sluiten"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Ongeldige invoer"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-pl/strings.xml b/compose/ui/ui/src/androidMain/res/values-pl/strings.xml
new file mode 100644
index 0000000..812531b
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-pl/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Ani nie zaznaczono, ani nie odznaczono"</string>
+    <string name="on" msgid="8655164131929253426">"Włączono"</string>
+    <string name="off" msgid="875452955155264703">"Wyłączono"</string>
+    <string name="selected" msgid="6043586758067023">"Wybrano"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Nie wybrano"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> procent."</string>
+    <string name="in_progress" msgid="6827826412747255547">"W toku"</string>
+    <string name="tab" msgid="1672349317127674378">"Karta"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Menu nawigacyjne"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Zamknij menu nawigacyjne"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Zamknij arkusz"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Nieprawidłowe dane wejściowe"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-pt-rBR/strings.xml b/compose/ui/ui/src/androidMain/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..d687d4b
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-pt-rBR/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Nem marcada nem desmarcada"</string>
+    <string name="on" msgid="8655164131929253426">"Ativado"</string>
+    <string name="off" msgid="875452955155264703">"Desativado"</string>
+    <string name="selected" msgid="6043586758067023">"Selecionado"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Não selecionado"</string>
+    <!-- String.format failed for translation -->
+    <!-- no translation found for template_percent (5946805113151406391) -->
+    <skip />
+    <string name="in_progress" msgid="6827826412747255547">"Em andamento"</string>
+    <string name="tab" msgid="1672349317127674378">"Guia"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Menu de navegação"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Fechar menu de navegação"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Fechar planilha"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Entrada inválida"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-pt-rPT/strings.xml b/compose/ui/ui/src/androidMain/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..b7fb8a6
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-pt-rPT/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Nem selecionada nem desselecionada"</string>
+    <string name="on" msgid="8655164131929253426">"Ativado"</string>
+    <string name="off" msgid="875452955155264703">"Desativado"</string>
+    <string name="selected" msgid="6043586758067023">"Selecionado"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Não selecionado"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> por cento."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Em curso"</string>
+    <string name="tab" msgid="1672349317127674378">"Separador"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Menu de navegação"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Fechar menu de navegação"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Fechar folha"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Entrada inválida"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-pt/strings.xml b/compose/ui/ui/src/androidMain/res/values-pt/strings.xml
new file mode 100644
index 0000000..d687d4b
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-pt/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Nem marcada nem desmarcada"</string>
+    <string name="on" msgid="8655164131929253426">"Ativado"</string>
+    <string name="off" msgid="875452955155264703">"Desativado"</string>
+    <string name="selected" msgid="6043586758067023">"Selecionado"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Não selecionado"</string>
+    <!-- String.format failed for translation -->
+    <!-- no translation found for template_percent (5946805113151406391) -->
+    <skip />
+    <string name="in_progress" msgid="6827826412747255547">"Em andamento"</string>
+    <string name="tab" msgid="1672349317127674378">"Guia"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Menu de navegação"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Fechar menu de navegação"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Fechar planilha"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Entrada inválida"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ro/strings.xml b/compose/ui/ui/src/androidMain/res/values-ro/strings.xml
new file mode 100644
index 0000000..ad20c72
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-ro/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Nici bifată, nici debifată"</string>
+    <string name="on" msgid="8655164131929253426">"Activat"</string>
+    <string name="off" msgid="875452955155264703">"Dezactivat"</string>
+    <string name="selected" msgid="6043586758067023">"Selectat"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Neselectat"</string>
+    <!-- String.format failed for translation -->
+    <!-- no translation found for template_percent (5946805113151406391) -->
+    <skip />
+    <string name="in_progress" msgid="6827826412747255547">"În curs"</string>
+    <string name="tab" msgid="1672349317127674378">"Filă"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Meniu de navigare"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Închideți meniul de navigare"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Închideți foaia"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Intrare nevalidă"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ru/strings.xml b/compose/ui/ui/src/androidMain/res/values-ru/strings.xml
new file mode 100644
index 0000000..65c7bfe
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-ru/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Флажок не установлен и не снят"</string>
+    <string name="on" msgid="8655164131929253426">"Включено"</string>
+    <string name="off" msgid="875452955155264703">"Выключено"</string>
+    <string name="selected" msgid="6043586758067023">"Выбрано"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Не выбрано"</string>
+    <string name="template_percent" msgid="5946805113151406391">"Процентов: <xliff:g id="PERCENTAGE">%1$d</xliff:g>."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Выполняется"</string>
+    <string name="tab" msgid="1672349317127674378">"Вкладка"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Меню навигации"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Закрыть меню навигации"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Закрыть лист"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Неправильный ввод"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-si/strings.xml b/compose/ui/ui/src/androidMain/res/values-si/strings.xml
new file mode 100644
index 0000000..1d0294a
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-si/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"හරි ලකුණු යොදා හෝ හරි ලකුණු යෙදීම ඉවත් කර නැත"</string>
+    <string name="on" msgid="8655164131929253426">"ක්‍රියාත්මකයි"</string>
+    <string name="off" msgid="875452955155264703">"ක්‍රියාවිරහිතයි"</string>
+    <string name="selected" msgid="6043586758067023">"තෝරන ලදි"</string>
+    <string name="not_selected" msgid="6610465462668679431">"තෝරා නැත"</string>
+    <string name="template_percent" msgid="5946805113151406391">"සියයට <xliff:g id="PERCENTAGE">%1$d</xliff:g>."</string>
+    <string name="in_progress" msgid="6827826412747255547">"ප්‍රගතියේ පවතී"</string>
+    <string name="tab" msgid="1672349317127674378">"ටැබය"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"සංචාලන මෙනුව"</string>
+    <string name="close_drawer" msgid="406453423630273620">"සංචාලන මෙනුව වසන්න"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"පත්‍රය වසන්න"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"වලංගු නොවන ආදානයකි"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-sk/strings.xml b/compose/ui/ui/src/androidMain/res/values-sk/strings.xml
new file mode 100644
index 0000000..b912997
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-sk/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Ani začiarknuté ani nezačiarknuté"</string>
+    <string name="on" msgid="8655164131929253426">"Zapnuté"</string>
+    <string name="off" msgid="875452955155264703">"Vypnuté"</string>
+    <string name="selected" msgid="6043586758067023">"Vybrané"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Nevybrané"</string>
+    <!-- String.format failed for translation -->
+    <!-- no translation found for template_percent (5946805113151406391) -->
+    <skip />
+    <string name="in_progress" msgid="6827826412747255547">"Prebieha"</string>
+    <string name="tab" msgid="1672349317127674378">"Karta"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigačná ponuka"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Zavrieť navigačnú ponuku"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Zavrieť hárok"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Neplatný vstup"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-sl/strings.xml b/compose/ui/ui/src/androidMain/res/values-sl/strings.xml
new file mode 100644
index 0000000..e30acad
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-sl/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Niti potrjeno niti nepotrjeno"</string>
+    <string name="on" msgid="8655164131929253426">"Vklopljeno"</string>
+    <string name="off" msgid="875452955155264703">"Izklopljeno"</string>
+    <string name="selected" msgid="6043586758067023">"Izbrano"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Ni izbrano"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> odstotkov"</string>
+    <string name="in_progress" msgid="6827826412747255547">"Poteka"</string>
+    <string name="tab" msgid="1672349317127674378">"Zavihek"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Meni za krmarjenje"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Zapri meni za krmarjenje"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Zapri list"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Neveljaven vnos"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-sr/strings.xml b/compose/ui/ui/src/androidMain/res/values-sr/strings.xml
new file mode 100644
index 0000000..485493f
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-sr/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Није означено нити поништено"</string>
+    <string name="on" msgid="8655164131929253426">"Укључено"</string>
+    <string name="off" msgid="875452955155264703">"Искључено"</string>
+    <string name="selected" msgid="6043586758067023">"Изабрано"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Није изабрано"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> посто."</string>
+    <string name="in_progress" msgid="6827826412747255547">"У току"</string>
+    <string name="tab" msgid="1672349317127674378">"Картица"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Мени за навигацију"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Затвори мени за навигацију"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Затворите табелу"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Унос је неважећи"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-sv/strings.xml b/compose/ui/ui/src/androidMain/res/values-sv/strings.xml
new file mode 100644
index 0000000..bb491c8
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-sv/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Varken markerad eller avmarkerad"</string>
+    <string name="on" msgid="8655164131929253426">"På"</string>
+    <string name="off" msgid="875452955155264703">"Av"</string>
+    <string name="selected" msgid="6043586758067023">"Valt"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Inte vald"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> procent."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Pågår"</string>
+    <string name="tab" msgid="1672349317127674378">"Flik"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Navigeringsmeny"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Stäng navigeringsmenyn"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Stäng kalkylarket"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Ogiltiga indata"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-sw/strings.xml b/compose/ui/ui/src/androidMain/res/values-sw/strings.xml
new file mode 100644
index 0000000..1f8eec8
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-sw/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Hujateua wala kubatilisha uteuzi"</string>
+    <string name="on" msgid="8655164131929253426">"Imewashwa"</string>
+    <string name="off" msgid="875452955155264703">"Imezimwa"</string>
+    <string name="selected" msgid="6043586758067023">"Umechagua"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Hujachagua"</string>
+    <string name="template_percent" msgid="5946805113151406391">"Asilimia <xliff:g id="PERCENTAGE">%1$d</xliff:g>."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Inaendelea"</string>
+    <string name="tab" msgid="1672349317127674378">"Kichupo"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Menyu ya kusogeza"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Funga menyu ya kusogeza"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Funga laha"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Ulichoweka si sahihi"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ta/strings.xml b/compose/ui/ui/src/androidMain/res/values-ta/strings.xml
new file mode 100644
index 0000000..ed3b4a2
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-ta/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"தேர்வுசெய்யப்பட்டது மற்றும் தேர்வுசெய்யப்படாதது"</string>
+    <string name="on" msgid="8655164131929253426">"இயக்கப்பட்டுள்ளது"</string>
+    <string name="off" msgid="875452955155264703">"முடக்கப்பட்டுள்ளது"</string>
+    <string name="selected" msgid="6043586758067023">"தேர்ந்தெடுக்கப்பட்டுள்ளது"</string>
+    <string name="not_selected" msgid="6610465462668679431">"தேர்ந்தெடுக்கப்படவில்லை"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> சதவீதம்."</string>
+    <string name="in_progress" msgid="6827826412747255547">"செயலிலுள்ளது"</string>
+    <string name="tab" msgid="1672349317127674378">"பிரிவு"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"வழிசெலுத்தல் மெனு"</string>
+    <string name="close_drawer" msgid="406453423630273620">"வழிசெலுத்தல் மெனுவை மூடும்"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"ஷீட்டை மூடும்"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"தவறான உள்ளீடு"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-th/strings.xml b/compose/ui/ui/src/androidMain/res/values-th/strings.xml
new file mode 100644
index 0000000..43a3761
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-th/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"ไม่ได้เลือกหรือยกเลิกการเลือก"</string>
+    <string name="on" msgid="8655164131929253426">"เปิด"</string>
+    <string name="off" msgid="875452955155264703">"ปิด"</string>
+    <string name="selected" msgid="6043586758067023">"เลือกไว้"</string>
+    <string name="not_selected" msgid="6610465462668679431">"ไม่ได้เลือก"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> เปอร์เซ็นต์"</string>
+    <string name="in_progress" msgid="6827826412747255547">"กำลังดำเนินการ"</string>
+    <string name="tab" msgid="1672349317127674378">"แท็บ"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"เมนูการนำทาง"</string>
+    <string name="close_drawer" msgid="406453423630273620">"ปิดเมนูการนำทาง"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"ปิดชีต"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"อินพุตไม่ถูกต้อง"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-tl/strings.xml b/compose/ui/ui/src/androidMain/res/values-tl/strings.xml
new file mode 100644
index 0000000..f0700fb
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-tl/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Hindi may check o walang check"</string>
+    <string name="on" msgid="8655164131929253426">"Naka-on"</string>
+    <string name="off" msgid="875452955155264703">"Naka-off"</string>
+    <string name="selected" msgid="6043586758067023">"Napili"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Hindi napili"</string>
+    <string name="template_percent" msgid="5946805113151406391">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> (na) porsyento."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Isinasagawa"</string>
+    <string name="tab" msgid="1672349317127674378">"Tab"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Menu ng navigation"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Isara ang menu ng navigation"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Isara ang sheet"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Invalid na input"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-tr/strings.xml b/compose/ui/ui/src/androidMain/res/values-tr/strings.xml
new file mode 100644
index 0000000..edb132d
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-tr/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Ne işaretlendi ne de işareti kaldırıldı"</string>
+    <string name="on" msgid="8655164131929253426">"Açık"</string>
+    <string name="off" msgid="875452955155264703">"Kapalı"</string>
+    <string name="selected" msgid="6043586758067023">"Seçili"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Seçilmedi"</string>
+    <string name="template_percent" msgid="5946805113151406391">"Yüzde <xliff:g id="PERCENTAGE">%1$d</xliff:g>."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Devam ediyor"</string>
+    <string name="tab" msgid="1672349317127674378">"Sekme"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Gezinme menüsü"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Gezinme menüsünü kapat"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Sayfayı kapat"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Geçersiz giriş"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-uk/strings.xml b/compose/ui/ui/src/androidMain/res/values-uk/strings.xml
new file mode 100644
index 0000000..1e73c6e
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-uk/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Прапорець ані поставлено, ані знято"</string>
+    <string name="on" msgid="8655164131929253426">"Увімкнено"</string>
+    <string name="off" msgid="875452955155264703">"Вимкнено"</string>
+    <string name="selected" msgid="6043586758067023">"Вибрано"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Не вибрано"</string>
+    <string name="template_percent" msgid="5946805113151406391">"Відсотків: <xliff:g id="PERCENTAGE">%1$d</xliff:g>."</string>
+    <string name="in_progress" msgid="6827826412747255547">"Виконується"</string>
+    <string name="tab" msgid="1672349317127674378">"Вкладка"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Меню навігації"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Закрити меню навігації"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Закрити аркуш"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Введено недійсні дані"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-vi/strings.xml b/compose/ui/ui/src/androidMain/res/values-vi/strings.xml
new file mode 100644
index 0000000..5dd316f
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-vi/strings.xml
@@ -0,0 +1,34 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"Không đánh dấu cũng không bỏ đánh dấu"</string>
+    <string name="on" msgid="8655164131929253426">"Đang bật"</string>
+    <string name="off" msgid="875452955155264703">"Đang tắt"</string>
+    <string name="selected" msgid="6043586758067023">"Đã chọn"</string>
+    <string name="not_selected" msgid="6610465462668679431">"Chưa chọn"</string>
+    <!-- String.format failed for translation -->
+    <!-- no translation found for template_percent (5946805113151406391) -->
+    <skip />
+    <string name="in_progress" msgid="6827826412747255547">"Đang thực hiện"</string>
+    <string name="tab" msgid="1672349317127674378">"Thẻ"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"Trình đơn điều hướng"</string>
+    <string name="close_drawer" msgid="406453423630273620">"Đóng trình đơn điều hướng"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"Đóng trang tính"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"Giá trị nhập không hợp lệ"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-zh-rCN/strings.xml b/compose/ui/ui/src/androidMain/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..6392b8b
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-zh-rCN/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"既没有勾选也没有取消选中"</string>
+    <string name="on" msgid="8655164131929253426">"开启"</string>
+    <string name="off" msgid="875452955155264703">"关闭"</string>
+    <string name="selected" msgid="6043586758067023">"已选择"</string>
+    <string name="not_selected" msgid="6610465462668679431">"未选择"</string>
+    <string name="template_percent" msgid="5946805113151406391">"百分之 <xliff:g id="PERCENTAGE">%1$d</xliff:g>。"</string>
+    <string name="in_progress" msgid="6827826412747255547">"进行中"</string>
+    <string name="tab" msgid="1672349317127674378">"标签页"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"导航菜单"</string>
+    <string name="close_drawer" msgid="406453423630273620">"关闭导航菜单"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"关闭工作表"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"输入无效"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-zh-rHK/strings.xml b/compose/ui/ui/src/androidMain/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..5b4e62b
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-zh-rHK/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"未勾選或者未取消勾選"</string>
+    <string name="on" msgid="8655164131929253426">"開"</string>
+    <string name="off" msgid="875452955155264703">"閂"</string>
+    <string name="selected" msgid="6043586758067023">"揀咗"</string>
+    <string name="not_selected" msgid="6610465462668679431">"未揀"</string>
+    <string name="template_percent" msgid="5946805113151406391">"百分之 <xliff:g id="PERCENTAGE">%1$d</xliff:g>。"</string>
+    <string name="in_progress" msgid="6827826412747255547">"進行中"</string>
+    <string name="tab" msgid="1672349317127674378">"分頁"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"導覽選單"</string>
+    <string name="close_drawer" msgid="406453423630273620">"閂導覽選單"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"閂表單"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"輸入嘅資料無效"</string>
+</resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-zh-rTW/strings.xml b/compose/ui/ui/src/androidMain/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..8f47f69
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/res/values-zh-rTW/strings.xml
@@ -0,0 +1,32 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="indeterminate" msgid="2486394087603402002">"沒有勾選也沒有取消勾選"</string>
+    <string name="on" msgid="8655164131929253426">"已開啟"</string>
+    <string name="off" msgid="875452955155264703">"已關閉"</string>
+    <string name="selected" msgid="6043586758067023">"已選取"</string>
+    <string name="not_selected" msgid="6610465462668679431">"未選取"</string>
+    <string name="template_percent" msgid="5946805113151406391">"百分之 <xliff:g id="PERCENTAGE">%1$d</xliff:g>。"</string>
+    <string name="in_progress" msgid="6827826412747255547">"處理中"</string>
+    <string name="tab" msgid="1672349317127674378">"Tab 鍵"</string>
+    <string name="navigation_menu" msgid="542007171693138492">"導覽選單"</string>
+    <string name="close_drawer" msgid="406453423630273620">"關閉導覽選單"</string>
+    <string name="close_sheet" msgid="7573152094250666567">"關閉功能表"</string>
+    <string name="default_error_message" msgid="8038256446254964252">"輸入內容無效"</string>
+</resources>
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 53cccdb..d8909b8 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
@@ -230,6 +230,8 @@
 
 private val DownChangeConsumed = ConsumedData(downChange = true)
 
+private val EmptyPointerEvent = PointerEvent(emptyList())
+
 /**
  * Implementation notes:
  * This class does a lot of lifting. It is both a [PointerInputModifier] and that modifier's
@@ -256,7 +258,7 @@
     override val pointerInputFilter: PointerInputFilter
         get() = this
 
-    private var currentEvent: PointerEvent? = null
+    private var currentEvent: PointerEvent = EmptyPointerEvent
 
     /**
      * Actively registered input handlers from currently ongoing calls to [awaitPointerEventScope].
@@ -416,9 +418,7 @@
         private var awaitPass: PointerEventPass = PointerEventPass.Main
 
         override val currentEvent: PointerEvent
-            get() = checkNotNull(this@SuspendingPointerInputFilter.currentEvent) {
-                "cannot access currentEvent outside of input dispatch"
-            }
+            get() = this@SuspendingPointerInputFilter.currentEvent
         override val size: IntSize
             get() = this@SuspendingPointerInputFilter.boundsSize
         override val viewConfiguration: ViewConfiguration
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/SaveRestoreBackStackTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/SaveRestoreBackStackTest.kt
index 42ad4dc..f14d650 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/SaveRestoreBackStackTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/SaveRestoreBackStackTest.kt
@@ -16,12 +16,9 @@
 
 package androidx.fragment.app
 
-import android.os.Bundle
 import androidx.fragment.app.test.FragmentTestActivity
-import androidx.fragment.app.test.TestViewModel
 import androidx.fragment.test.R
 import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.ViewModelProvider
 import androidx.test.core.app.ActivityScenario
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
@@ -43,7 +40,7 @@
                 supportFragmentManager
             }
             val fragmentBase = StrictFragment()
-            val fragmentReplacement = ViewModelStrictFragment()
+            val fragmentReplacement = StateSaveFragment()
 
             fm.beginTransaction()
                 .add(R.id.content, fragmentBase)
@@ -433,32 +430,4 @@
             assertThat(fm.backStackEntryCount).isEqualTo(1)
         }
     }
-
-    public open class ViewModelStrictFragment : StrictFragment() {
-        public val viewModel: TestViewModel by lazy {
-            ViewModelProvider(this).get(TestViewModel::class.java)
-        }
-    }
-
-    public class StateSaveFragment(
-        public var savedState: String? = null,
-        public val unsavedState: String? = null
-    ) : ViewModelStrictFragment() {
-
-        override fun onCreate(savedInstanceState: Bundle?) {
-            super.onCreate(savedInstanceState)
-            if (savedInstanceState != null) {
-                savedState = savedInstanceState.getString(STATE_KEY)
-            }
-        }
-
-        override fun onSaveInstanceState(outState: Bundle) {
-            super.onSaveInstanceState(outState)
-            outState.putString(STATE_KEY, savedState)
-        }
-
-        private companion object {
-            private const val STATE_KEY = "state"
-        }
-    }
 }
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/test/StateSaveFragment.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/test/StateSaveFragment.kt
index 0ab9d0d..1edd340 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/test/StateSaveFragment.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/test/StateSaveFragment.kt
@@ -17,6 +17,8 @@
 package androidx.fragment.app
 
 import android.os.Bundle
+import androidx.fragment.app.test.TestViewModel
+import androidx.lifecycle.ViewModelProvider
 
 class StateSaveFragment(
     var savedState: String? = null,
@@ -40,6 +42,10 @@
         outState.putString(STATE_KEY, savedState)
     }
 
+    public val viewModel: TestViewModel by lazy {
+        ViewModelProvider(this).get(TestViewModel::class.java)
+    }
+
     companion object {
         private const val STATE_KEY = "state"
     }
diff --git a/leanback/leanback/src/main/res/values-bs/strings.xml b/leanback/leanback/src/main/res/values-bs/strings.xml
index 68aa6f3..0421ed7 100644
--- a/leanback/leanback/src/main/res/values-bs/strings.xml
+++ b/leanback/leanback/src/main/res/values-bs/strings.xml
@@ -47,7 +47,7 @@
     <string name="lb_playback_controls_high_quality_disable" msgid="1209119371486219736">"Isključi visoki kvalitet"</string>
     <string name="lb_playback_controls_closed_captioning_enable" msgid="2346334170216706076">"Uključi titlove"</string>
     <string name="lb_playback_controls_closed_captioning_disable" msgid="8691966842977635128">"Isključi titlove"</string>
-    <string name="lb_playback_controls_picture_in_picture" msgid="5770668162543767702">"Uđi u način rada Slika u slici"</string>
+    <string name="lb_playback_controls_picture_in_picture" msgid="5770668162543767702">"Uđi u način rada slike u slici"</string>
     <string name="lb_playback_time_separator" msgid="1471121602610716654">"/"</string>
     <string name="lb_playback_controls_shown" msgid="8690223891515602822">"Kontrole za medije su prikazane"</string>
     <string name="lb_playback_controls_hidden" msgid="5859666950961624736">"Kontrole za medije su skrivene. Pritisnite d-pad da ih prikažete"</string>
diff --git a/leanback/leanback/src/main/res/values-ky/strings.xml b/leanback/leanback/src/main/res/values-ky/strings.xml
index 3eee16b..4d12f12 100644
--- a/leanback/leanback/src/main/res/values-ky/strings.xml
+++ b/leanback/leanback/src/main/res/values-ky/strings.xml
@@ -50,7 +50,7 @@
     <string name="lb_playback_controls_picture_in_picture" msgid="5770668162543767702">"Сүрөт режиминде сүрөт киргизүү"</string>
     <string name="lb_playback_time_separator" msgid="1471121602610716654">"/"</string>
     <string name="lb_playback_controls_shown" msgid="8690223891515602822">"Медиа файлды башкаруу көрсөтүлдү"</string>
-    <string name="lb_playback_controls_hidden" msgid="5859666950961624736">"Медиа файлды башкаруу жашырылган, көрүү үчүн d-pad көзөмөлдөө каражатын басыңыз"</string>
+    <string name="lb_playback_controls_hidden" msgid="5859666950961624736">"Медиа файлды башкаруу жашырылган, көрүү үчүн d-pad башкаруу элементин басыңыз"</string>
     <string name="lb_guidedaction_finish_title" msgid="3330958750346333890">"Бүттү"</string>
     <string name="lb_guidedaction_continue_title" msgid="893619591225519922">"Улантуу"</string>
     <string name="lb_media_player_error" msgid="3228326776757666747">"MediaPlayer\'деги катанын коду: %1$d, кошумча: %2$d"</string>
diff --git a/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt b/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt
index 8360616..f3dfe69 100644
--- a/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt
+++ b/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt
@@ -18,7 +18,6 @@
 
 package androidx.build.lint
 
-import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
@@ -34,7 +33,6 @@
 ) {
 
     @Test
-    @Ignore("b/190726182")
     fun `Detection of unsafe references in Java sources`() {
         val input = arrayOf(
             javaSample("androidx.ClassVerificationFailureFromJava"),
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/AddInDefaultArgsTest.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/AddInDefaultArgsTest.kt
index 78d1f94..6cd431e 100644
--- a/navigation/navigation-common/src/androidTest/java/androidx/navigation/AddInDefaultArgsTest.kt
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/AddInDefaultArgsTest.kt
@@ -22,6 +22,7 @@
 import androidx.navigation.test.longArgument
 import androidx.navigation.test.referenceArgument
 import androidx.navigation.test.stringArgument
+import androidx.navigation.test.stringArrayArgument
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
@@ -35,6 +36,7 @@
 private val longArgumentWithDefault = "longArg" to longArgument(123L)
 private val floatArgumentWithDefault = "floatArg" to floatArgument(123f)
 private val referenceArgumentWithDefault = "referenceArg" to referenceArgument(123)
+private val stringArrayArgumentWithDefault = "stringArrayArg" to stringArrayArgument(null)
 
 @SmallTest
 @RunWith(Parameterized::class)
@@ -60,7 +62,9 @@
                 // Test with arguments that have default values (long)
                 mapOf(stringArgumentWithDefault, floatArgumentWithDefault),
                 // Test with arguments that have default values (reference)
-                mapOf(stringArgumentWithDefault, referenceArgumentWithDefault)
+                mapOf(stringArgumentWithDefault, referenceArgumentWithDefault),
+                // Test with arguments that have default values (string array)
+                mapOf(stringArgumentWithDefault, stringArrayArgumentWithDefault)
 
             ).forEach { arguments: Map<String, NavArgument> ->
                 // Run with a null Bundle
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/test/NavArgument.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/test/NavArgument.kt
index 71a36750..760817c 100644
--- a/navigation/navigation-common/src/androidTest/java/androidx/navigation/test/NavArgument.kt
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/test/NavArgument.kt
@@ -21,6 +21,7 @@
 import androidx.navigation.NavType.Companion.IntType
 import androidx.navigation.NavType.Companion.LongType
 import androidx.navigation.NavType.Companion.ReferenceType
+import androidx.navigation.NavType.Companion.StringArrayType
 import androidx.navigation.NavType.Companion.StringType
 
 // region IntType
@@ -80,3 +81,12 @@
     .setIsNullable(true)
     .build()
 // endregion
+
+// region StringArrayType
+fun stringArrayArgument(
+    defaultValue: Array<String>?
+) = NavArgument.Builder().setType(StringArrayType)
+    .setIsNullable(true)
+    .setDefaultValue(defaultValue)
+    .build()
+// endregion
\ No newline at end of file
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/NavType.kt b/navigation/navigation-common/src/main/java/androidx/navigation/NavType.kt
index 401f880..48618f9 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/NavType.kt
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/NavType.kt
@@ -527,20 +527,22 @@
          * Default values in Navigation XML files are not supported.
          */
         @JvmField
-        public val StringArrayType: NavType<Array<String>> = object : NavType<Array<String>>(true) {
+        public val StringArrayType: NavType<Array<String>?> = object : NavType<Array<String>?>(
+            true
+        ) {
             override val name: String
                 get() = "string[]"
 
-            override fun put(bundle: Bundle, key: String, value: Array<String>) {
+            override fun put(bundle: Bundle, key: String, value: Array<String>?) {
                 bundle.putStringArray(key, value)
             }
 
             @Suppress("UNCHECKED_CAST")
-            override fun get(bundle: Bundle, key: String): Array<String> {
-                return bundle[key] as Array<String>
+            override fun get(bundle: Bundle, key: String): Array<String>? {
+                return bundle[key] as Array<String>?
             }
 
-            override fun parseValue(value: String): Array<String> {
+            override fun parseValue(value: String): Array<String>? {
                 throw UnsupportedOperationException("Arrays don't support default values.")
             }
         }
diff --git a/navigation/navigation-dynamic-features-runtime/api/current.ignore b/navigation/navigation-dynamic-features-runtime/api/current.ignore
index fdf7759..2d8ef14 100644
--- a/navigation/navigation-dynamic-features-runtime/api/current.ignore
+++ b/navigation/navigation-dynamic-features-runtime/api/current.ignore
@@ -1,5 +1,7 @@
 // Baseline format: 1.0
 RemovedMethod: androidx.navigation.dynamicfeatures.DynamicExtras#DynamicExtras():
     Removed constructor androidx.navigation.dynamicfeatures.DynamicExtras()
+RemovedMethod: androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator#navigate(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph, android.os.Bundle, androidx.navigation.NavOptions, androidx.navigation.Navigator.Extras):
+    Removed method androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.navigate(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph,android.os.Bundle,androidx.navigation.NavOptions,androidx.navigation.Navigator.Extras)
 RemovedMethod: androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator#popBackStack():
     Removed method androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.popBackStack()
diff --git a/navigation/navigation-dynamic-features-runtime/api/current.txt b/navigation/navigation-dynamic-features-runtime/api/current.txt
index 6d9572f..85b8d16 100644
--- a/navigation/navigation-dynamic-features-runtime/api/current.txt
+++ b/navigation/navigation-dynamic-features-runtime/api/current.txt
@@ -71,7 +71,6 @@
   @androidx.navigation.Navigator.Name("include-dynamic") public final class DynamicIncludeGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
     ctor public DynamicIncludeGraphNavigator(android.content.Context context, androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.NavInflater navInflater, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
     method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph createDestination();
-    method @Deprecated public androidx.navigation.NavDestination? navigate(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
   }
 
   public static final class DynamicIncludeGraphNavigator.DynamicIncludeNavGraph extends androidx.navigation.NavDestination {
diff --git a/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_current.txt b/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_current.txt
index 6d9572f..85b8d16 100644
--- a/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_current.txt
+++ b/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_current.txt
@@ -71,7 +71,6 @@
   @androidx.navigation.Navigator.Name("include-dynamic") public final class DynamicIncludeGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
     ctor public DynamicIncludeGraphNavigator(android.content.Context context, androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.NavInflater navInflater, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
     method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph createDestination();
-    method @Deprecated public androidx.navigation.NavDestination? navigate(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
   }
 
   public static final class DynamicIncludeGraphNavigator.DynamicIncludeNavGraph extends androidx.navigation.NavDestination {
diff --git a/navigation/navigation-dynamic-features-runtime/api/restricted_current.ignore b/navigation/navigation-dynamic-features-runtime/api/restricted_current.ignore
index fdf7759..2d8ef14 100644
--- a/navigation/navigation-dynamic-features-runtime/api/restricted_current.ignore
+++ b/navigation/navigation-dynamic-features-runtime/api/restricted_current.ignore
@@ -1,5 +1,7 @@
 // Baseline format: 1.0
 RemovedMethod: androidx.navigation.dynamicfeatures.DynamicExtras#DynamicExtras():
     Removed constructor androidx.navigation.dynamicfeatures.DynamicExtras()
+RemovedMethod: androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator#navigate(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph, android.os.Bundle, androidx.navigation.NavOptions, androidx.navigation.Navigator.Extras):
+    Removed method androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.navigate(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph,android.os.Bundle,androidx.navigation.NavOptions,androidx.navigation.Navigator.Extras)
 RemovedMethod: androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator#popBackStack():
     Removed method androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.popBackStack()
diff --git a/navigation/navigation-dynamic-features-runtime/api/restricted_current.txt b/navigation/navigation-dynamic-features-runtime/api/restricted_current.txt
index 6d9572f..85b8d16 100644
--- a/navigation/navigation-dynamic-features-runtime/api/restricted_current.txt
+++ b/navigation/navigation-dynamic-features-runtime/api/restricted_current.txt
@@ -71,7 +71,6 @@
   @androidx.navigation.Navigator.Name("include-dynamic") public final class DynamicIncludeGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
     ctor public DynamicIncludeGraphNavigator(android.content.Context context, androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.NavInflater navInflater, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
     method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph createDestination();
-    method @Deprecated public androidx.navigation.NavDestination? navigate(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
   }
 
   public static final class DynamicIncludeGraphNavigator.DynamicIncludeNavGraph extends androidx.navigation.NavDestination {
diff --git a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicIncludeGraphNavigator.kt b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicIncludeGraphNavigator.kt
index a8a9a22..8db61ba 100644
--- a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicIncludeGraphNavigator.kt
+++ b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicIncludeGraphNavigator.kt
@@ -24,6 +24,7 @@
 import androidx.core.content.withStyledAttributes
 import androidx.navigation.NavBackStackEntry
 import androidx.navigation.NavDestination
+import androidx.navigation.NavGraph
 import androidx.navigation.NavInflater
 import androidx.navigation.NavInflater.Companion.APPLICATION_ID_PLACEHOLDER
 import androidx.navigation.NavOptions
@@ -59,9 +60,17 @@
     }
 
     /**
+     * Navigates to a dynamically included graph from a `com.android.dynamic-feature` module.
+     *
+     * @param entries destination(s) to navigate to
+     * @param navOptions additional options for navigation
+     * @param navigatorExtras extras unique to your Navigator.
+     *
      * @throws Resources.NotFoundException if one of the [entries] does not have a valid
      * `graphResourceName` and `graphPackage`.
      * @throws IllegalStateException if one of the [entries] does not have a parent.
+
+     * @see Navigator.navigate
      */
     override fun navigate(
         entries: List<NavBackStackEntry>,
@@ -74,23 +83,6 @@
     }
 
     /**
-     * @throws Resources.NotFoundException if the [destination] does not have a valid
-     * `graphResourceName` and `graphPackage`.
-     * @throws IllegalStateException if the [destination] does not have a parent.
-     */
-    @Deprecated("Use NavBackStackEntry version of this method instead")
-    override fun navigate(
-        destination: DynamicIncludeNavGraph,
-        args: Bundle?,
-        navOptions: NavOptions?,
-        navigatorExtras: Extras?
-    ): NavDestination? {
-        val entry = NavBackStackEntry.create(null, destination, args)
-        navigate(entry, navOptions, navigatorExtras)
-        return null
-    }
-
-    /**
      * @throws Resources.NotFoundException if the [entry] does not have a valid
      * `graphResourceName` and `graphPackage`.
      * @throws IllegalStateException if the [entry] does not have a parent.
@@ -109,10 +101,9 @@
             installManager.performInstall(entry, extras, moduleName)
         } else {
             val includedNav = replaceWithIncludedNav(destination)
-            val navigator: Navigator<NavDestination> = navigatorProvider[
-                includedNav.destination.navigatorName
-            ]
-            navigator.navigate(listOf(includedNav), navOptions, navigatorExtras)
+            val navigator: Navigator<NavDestination> = navigatorProvider[includedNav.navigatorName]
+            val newGraphEntry = state.createBackStackEntry(includedNav, entry.arguments)
+            navigator.navigate(listOf(newGraphEntry), navOptions, navigatorExtras)
         }
     }
 
@@ -121,7 +112,7 @@
      *
      * @return the newly inflated included navigation graph
      */
-    private fun replaceWithIncludedNav(destination: DynamicIncludeNavGraph): NavBackStackEntry {
+    private fun replaceWithIncludedNav(destination: DynamicIncludeNavGraph): NavGraph {
         val graphId = context.resources.getIdentifier(
             destination.graphResourceName, "navigation",
             destination.graphPackage
@@ -146,11 +137,9 @@
         outerNav.addDestination(includedNav)
         // Avoid calling replaceWithIncludedNav() on the same destination more than once
         createdDestinations.remove(destination)
-        return NavBackStackEntry.create(context, includedNav)
+        return includedNav
     }
 
-    override fun popBackStack(): Boolean = true
-
     override fun onSaveState(): Bundle? {
         // Return a non-null Bundle to get a callback to onRestoreState
         return Bundle.EMPTY
diff --git a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/FragmentNavigatorDestinationBuilderTest.kt b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/FragmentNavigatorDestinationBuilderTest.kt
index 616174b..233e23e 100644
--- a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/FragmentNavigatorDestinationBuilderTest.kt
+++ b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/FragmentNavigatorDestinationBuilderTest.kt
@@ -23,8 +23,7 @@
 import androidx.test.annotation.UiThreadTest
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
+import com.google.common.truth.Truth.assertWithMessage
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -47,15 +46,12 @@
         val graph = navHostFragment.createGraph(startDestination = DESTINATION_ID) {
             fragment<BuilderTestFragment>(DESTINATION_ID)
         }
-        assertTrue(
-            "Destination should be added to the graph",
-            DESTINATION_ID in graph
-        )
-        assertEquals(
-            "Fragment class should be set to BuilderTestFragment",
-            BuilderTestFragment::class.java.name,
-            (graph[DESTINATION_ID] as FragmentNavigator.Destination).className
-        )
+        assertWithMessage("Destination should be added to the graph")
+            .that(DESTINATION_ID in graph)
+            .isTrue()
+        assertWithMessage("Fragment class should be set to BuilderTestFragment")
+            .that((graph[DESTINATION_ID] as FragmentNavigator.Destination).className)
+            .isEqualTo(BuilderTestFragment::class.java.name)
     }
 
     @Suppress("DEPRECATION")
@@ -70,19 +66,15 @@
                 label = LABEL
             }
         }
-        assertTrue(
-            "Destination should be added to the graph",
-            DESTINATION_ID in graph
-        )
-        assertEquals(
-            "Fragment class should be set to BuilderTestFragment",
-            BuilderTestFragment::class.java.name,
-            (graph[DESTINATION_ID] as FragmentNavigator.Destination).className
-        )
-        assertEquals(
-            "Fragment should have label set",
-            LABEL, graph[DESTINATION_ID].label
-        )
+        assertWithMessage("Destination should be added to the graph")
+            .that(DESTINATION_ID in graph)
+            .isTrue()
+        assertWithMessage("Fragment class should be set to BuilderTestFragment")
+            .that((graph[DESTINATION_ID] as FragmentNavigator.Destination).className)
+            .isEqualTo(BuilderTestFragment::class.java.name)
+        assertWithMessage("Fragment should have label set")
+            .that(graph[DESTINATION_ID].label)
+            .isEqualTo(LABEL)
     }
 
     @UiThreadTest
@@ -94,15 +86,12 @@
         val graph = navHostFragment.createGraph(startDestination = DESTINATION_ROUTE) {
             fragment<BuilderTestFragment>(DESTINATION_ROUTE)
         }
-        assertTrue(
-            "Destination should be added to the graph",
-            DESTINATION_ROUTE in graph
-        )
-        assertEquals(
-            "Fragment class should be set to BuilderTestFragment",
-            BuilderTestFragment::class.java.name,
-            (graph[DESTINATION_ROUTE] as FragmentNavigator.Destination).className
-        )
+        assertWithMessage("Destination should be added to the graph")
+            .that(DESTINATION_ROUTE in graph)
+            .isTrue()
+        assertWithMessage("Fragment class should be set to BuilderTestFragment")
+            .that((graph[DESTINATION_ROUTE] as FragmentNavigator.Destination).className)
+            .isEqualTo(BuilderTestFragment::class.java.name)
     }
 
     @UiThreadTest
@@ -116,19 +105,15 @@
                 label = LABEL
             }
         }
-        assertTrue(
-            "Destination should be added to the graph",
-            DESTINATION_ROUTE in graph
-        )
-        assertEquals(
-            "Fragment class should be set to BuilderTestFragment",
-            BuilderTestFragment::class.java.name,
-            (graph[DESTINATION_ROUTE] as FragmentNavigator.Destination).className
-        )
-        assertEquals(
-            "Fragment should have label set",
-            LABEL, graph[DESTINATION_ROUTE].label
-        )
+        assertWithMessage("Destination should be added to the graph")
+            .that(DESTINATION_ROUTE in graph)
+            .isTrue()
+        assertWithMessage("Fragment class should be set to BuilderTestFragment")
+            .that((graph[DESTINATION_ROUTE] as FragmentNavigator.Destination).className)
+            .isEqualTo(BuilderTestFragment::class.java.name)
+        assertWithMessage("Fragment should have label set")
+            .that(graph[DESTINATION_ROUTE].label)
+            .isEqualTo(LABEL)
     }
 }
 
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/ActivityNavigatorDestinationBuilderTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/ActivityNavigatorDestinationBuilderTest.kt
index 6e1ae7a..d74eef3 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/ActivityNavigatorDestinationBuilderTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/ActivityNavigatorDestinationBuilderTest.kt
@@ -21,8 +21,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertWithMessage
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -40,15 +38,12 @@
                 label = LABEL
             }
         }
-        assertTrue(
-            "Destination should be added to the graph",
-            DESTINATION_ID in graph
-        )
-        assertEquals(
-            "Destination should have label set",
-            LABEL,
-            graph[DESTINATION_ID].label
-        )
+        assertWithMessage("Destination should be added to the graph")
+            .that(DESTINATION_ID in graph)
+            .isTrue()
+        assertWithMessage("Destination should have label set")
+            .that(graph[DESTINATION_ID].label)
+            .isEqualTo(LABEL)
     }
 
     @Suppress("DEPRECATION")
@@ -75,15 +70,12 @@
                 activityClass = TestActivity::class
             }
         }
-        assertTrue(
-            "Destination should be added to the graph",
-            DESTINATION_ID in graph
-        )
-        assertEquals(
-            "Destination should have ComponentName set",
-            TestActivity::class.java.name,
-            (graph[DESTINATION_ID] as ActivityNavigator.Destination).component?.className
-        )
+        assertWithMessage("Destination should be added to the graph")
+            .that(DESTINATION_ID in graph)
+            .isTrue()
+        assertWithMessage("Destination should have ComponentName set")
+            .that((graph[DESTINATION_ID] as ActivityNavigator.Destination).component?.className)
+            .isEqualTo(TestActivity::class.java.name)
     }
 
     @Suppress("DEPRECATION")
@@ -94,15 +86,12 @@
                 action = ACTION
             }
         }
-        assertTrue(
-            "Destination should be added to the graph",
-            DESTINATION_ID in graph
-        )
-        assertEquals(
-            "Destination should have action set",
-            ACTION,
-            (graph[DESTINATION_ID] as ActivityNavigator.Destination).action
-        )
+        assertWithMessage("Destination should be added to the graph")
+            .that(DESTINATION_ID in graph)
+            .isTrue()
+        assertWithMessage("Destination should have action set")
+            .that((graph[DESTINATION_ID] as ActivityNavigator.Destination).action)
+            .isEqualTo(ACTION)
     }
 
     @Suppress("DEPRECATION")
@@ -113,15 +102,12 @@
                 data = DATA
             }
         }
-        assertTrue(
-            "Destination should be added to the graph",
-            DESTINATION_ID in graph
-        )
-        assertEquals(
-            "Destination should have data set",
-            DATA,
-            (graph[DESTINATION_ID] as ActivityNavigator.Destination).data
-        )
+        assertWithMessage("Destination should be added to the graph")
+            .that(DESTINATION_ID in graph)
+            .isTrue()
+        assertWithMessage("Destination should have data set")
+            .that((graph[DESTINATION_ID] as ActivityNavigator.Destination).data)
+            .isEqualTo(DATA)
     }
 
     @Suppress("DEPRECATION")
@@ -132,15 +118,12 @@
                 dataPattern = DATA_PATTERN
             }
         }
-        assertTrue(
-            "Destination should be added to the graph",
-            DESTINATION_ID in graph
-        )
-        assertEquals(
-            "Destination should have data pattern set",
-            DATA_PATTERN,
-            (graph[DESTINATION_ID] as ActivityNavigator.Destination).dataPattern
-        )
+        assertWithMessage("Destination should be added to the graph")
+            .that(DESTINATION_ID in graph)
+            .isTrue()
+        assertWithMessage("Destination should have data pattern set")
+            .that((graph[DESTINATION_ID] as ActivityNavigator.Destination).dataPattern)
+            .isEqualTo(DATA_PATTERN)
     }
 
     @Test
@@ -150,15 +133,12 @@
                 label = LABEL
             }
         }
-        assertTrue(
-            "Destination should be added to the graph",
-            DESTINATION_ROUTE in graph
-        )
-        assertEquals(
-            "Destination should have label set",
-            LABEL,
-            graph[DESTINATION_ROUTE].label
-        )
+        assertWithMessage("Destination should be added to the graph")
+            .that(DESTINATION_ROUTE in graph)
+            .isTrue()
+        assertWithMessage("Destination should have label set")
+            .that(graph[DESTINATION_ROUTE].label)
+            .isEqualTo(LABEL)
     }
 
     @Test
@@ -183,15 +163,12 @@
                 activityClass = TestActivity::class
             }
         }
-        assertTrue(
-            "Destination should be added to the graph",
-            DESTINATION_ROUTE in graph
-        )
-        assertEquals(
-            "Destination should have ComponentName set",
-            TestActivity::class.java.name,
-            (graph[DESTINATION_ROUTE] as ActivityNavigator.Destination).component?.className
-        )
+        assertWithMessage("Destination should be added to the graph")
+            .that(DESTINATION_ROUTE in graph)
+            .isTrue()
+        assertWithMessage("Destination should have ComponentName set")
+            .that((graph[DESTINATION_ROUTE] as ActivityNavigator.Destination).component?.className)
+            .isEqualTo(TestActivity::class.java.name)
     }
 
     @Test
@@ -201,15 +178,12 @@
                 action = ACTION
             }
         }
-        assertTrue(
-            "Destination should be added to the graph",
-            DESTINATION_ROUTE in graph
-        )
-        assertEquals(
-            "Destination should have action set",
-            ACTION,
-            (graph[DESTINATION_ROUTE] as ActivityNavigator.Destination).action
-        )
+        assertWithMessage("Destination should be added to the graph")
+            .that(DESTINATION_ROUTE in graph)
+            .isTrue()
+        assertWithMessage("Destination should have action set")
+            .that((graph[DESTINATION_ROUTE] as ActivityNavigator.Destination).action)
+            .isEqualTo(ACTION)
     }
 
     @Test
@@ -219,15 +193,12 @@
                 data = DATA
             }
         }
-        assertTrue(
-            "Destination should be added to the graph",
-            DESTINATION_ROUTE in graph
-        )
-        assertEquals(
-            "Destination should have data set",
-            DATA,
-            (graph[DESTINATION_ROUTE] as ActivityNavigator.Destination).data
-        )
+        assertWithMessage("Destination should be added to the graph")
+            .that(DESTINATION_ROUTE in graph)
+            .isTrue()
+        assertWithMessage("Destination should have data set")
+            .that((graph[DESTINATION_ROUTE] as ActivityNavigator.Destination).data)
+            .isEqualTo(DATA)
     }
 
     @Test
@@ -237,15 +208,12 @@
                 dataPattern = DATA_PATTERN
             }
         }
-        assertTrue(
-            "Destination should be added to the graph",
-            DESTINATION_ROUTE in graph
-        )
-        assertEquals(
-            "Destination should have data pattern set",
-            DATA_PATTERN,
-            (graph[DESTINATION_ROUTE] as ActivityNavigator.Destination).dataPattern
-        )
+        assertWithMessage("Destination should be added to the graph")
+            .that(DESTINATION_ROUTE in graph)
+            .isTrue()
+        assertWithMessage("Destination should have data pattern set")
+            .that((graph[DESTINATION_ROUTE] as ActivityNavigator.Destination).dataPattern)
+            .isEqualTo(DATA_PATTERN)
     }
 }
 
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavDeepLinkBuilderTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavDeepLinkBuilderTest.kt
index 0b21a08..5a6b530 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavDeepLinkBuilderTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavDeepLinkBuilderTest.kt
@@ -26,7 +26,6 @@
 import androidx.testutils.TestNavigator
 import androidx.testutils.test
 import com.google.common.truth.Truth.assertWithMessage
-import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -66,7 +65,7 @@
         deepLinkBuilder.setGraph(R.navigation.nav_simple)
         deepLinkBuilder.setDestination(R.id.second_test)
         val taskStackBuilder = deepLinkBuilder.createTaskStackBuilder()
-        assertEquals("Expected one Intent", 1, taskStackBuilder.intentCount)
+        assertWithMessage("Expected one Intent").that(taskStackBuilder.intentCount).isEqualTo(1)
     }
 
     @Test
@@ -76,7 +75,7 @@
         deepLinkBuilder.setGraph(nav_simple_route_graph)
         deepLinkBuilder.setDestination("second_test")
         val taskStackBuilder = deepLinkBuilder.createTaskStackBuilder()
-        assertEquals("Expected one Intent", 1, taskStackBuilder.intentCount)
+        assertWithMessage("Expected one Intent").that(taskStackBuilder.intentCount).isEqualTo(1)
     }
 
     @Test
@@ -92,7 +91,7 @@
         deepLinkBuilder.setGraph(navGraph)
         deepLinkBuilder.setDestination(R.id.second_test)
         val taskStackBuilder = deepLinkBuilder.createTaskStackBuilder()
-        assertEquals("Expected one Intent", 1, taskStackBuilder.intentCount)
+        assertWithMessage("Expected one Intent").that(taskStackBuilder.intentCount).isEqualTo(1)
     }
 
     @Test
@@ -102,7 +101,7 @@
         deepLinkBuilder.setGraph(nav_simple_route_graph)
         deepLinkBuilder.setDestination("second_test")
         val taskStackBuilder = deepLinkBuilder.createTaskStackBuilder()
-        assertEquals("Expected one Intent", 1, taskStackBuilder.intentCount)
+        assertWithMessage("Expected one Intent").that(taskStackBuilder.intentCount).isEqualTo(1)
     }
 
     @Suppress("DEPRECATION")
@@ -120,7 +119,7 @@
         deepLinkBuilder.setGraph(navGraph)
         deepLinkBuilder.setDestination(1)
         val taskStackBuilder = deepLinkBuilder.createTaskStackBuilder()
-        assertEquals("Expected one Intent", 1, taskStackBuilder.intentCount)
+        assertWithMessage("Expected one Intent").that(taskStackBuilder.intentCount).isEqualTo(1)
     }
 
     @Test
@@ -139,7 +138,7 @@
         deepLinkBuilder.setGraph(navGraph)
         deepLinkBuilder.setDestination("test")
         val taskStackBuilder = deepLinkBuilder.createTaskStackBuilder()
-        assertEquals("Expected one Intent", 1, taskStackBuilder.intentCount)
+        assertWithMessage("Expected one Intent").that(taskStackBuilder.intentCount).isEqualTo(1)
     }
 
     @UiThreadTest
@@ -153,7 +152,7 @@
 
         deepLinkBuilder.setDestination(R.id.second_test)
         val taskStackBuilder = deepLinkBuilder.createTaskStackBuilder()
-        assertEquals("Expected one Intent", 1, taskStackBuilder.intentCount)
+        assertWithMessage("Expected one Intent").that(taskStackBuilder.intentCount).isEqualTo(1)
     }
 
     @UiThreadTest
@@ -167,7 +166,7 @@
 
         deepLinkBuilder.setDestination("second_test")
         val taskStackBuilder = deepLinkBuilder.createTaskStackBuilder()
-        assertEquals("Expected one Intent", 1, taskStackBuilder.intentCount)
+        assertWithMessage("Expected one Intent").that(taskStackBuilder.intentCount).isEqualTo(1)
     }
 
     @Test
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavInflaterTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavInflaterTest.kt
index 9f25763..ae4d0f9 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavInflaterTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavInflaterTest.kt
@@ -233,6 +233,14 @@
     }
 
     @Test
+    fun testDefaultArgumentsStringArray() {
+        val defaultArguments = inflateDefaultArgumentsFromGraph()
+
+        assertThat(defaultArguments["test_string_array"]?.run { type to defaultValue })
+            .isEqualTo(NavType.StringArrayType to null)
+    }
+
+    @Test
     fun testDefaultArgumentsReference() {
         val defaultArguments = inflateDefaultArgumentsFromGraph()
 
diff --git a/navigation/navigation-runtime/src/androidTest/res/navigation/nav_default_arguments.xml b/navigation/navigation-runtime/src/androidTest/res/navigation/nav_default_arguments.xml
index 0b66aec..248f22f 100644
--- a/navigation/navigation-runtime/src/androidTest/res/navigation/nav_default_arguments.xml
+++ b/navigation/navigation-runtime/src/androidTest/res/navigation/nav_default_arguments.xml
@@ -90,6 +90,11 @@
             app:argType="string" />
 
         <argument
+            android:name="test_string_array"
+            android:defaultValue="@null"
+            app:argType="string[]" />
+
+        <argument
             android:name="test_long"
             android:defaultValue="456789013456L" />
         <argument
diff --git a/playground-common/playground.properties b/playground-common/playground.properties
index 76f0b30..dac9b6d 100644
--- a/playground-common/playground.properties
+++ b/playground-common/playground.properties
@@ -26,7 +26,7 @@
 kotlin.code.style=official
 # Disable docs
 androidx.enableDocumentation=false
-androidx.playground.snapshotBuildId=7440113
+androidx.playground.snapshotBuildId=7456910
 androidx.playground.metalavaBuildId=7255182
 androidx.playground.dokkaBuildId=7299536
 androidx.studio.type=playground
diff --git a/preference/preference/res/values-or/strings.xml b/preference/preference/res/values-or/strings.xml
index d3bcbc8..fc0b5e7 100644
--- a/preference/preference/res/values-or/strings.xml
+++ b/preference/preference/res/values-or/strings.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="v7_preference_on" msgid="89551595707643515">"ଅନ୍ ଅଛି"</string>
+    <string name="v7_preference_on" msgid="89551595707643515">"ଚାଲୁ ଅଛି"</string>
     <string name="v7_preference_off" msgid="3140233346420563315">"ବନ୍ଦ"</string>
     <string name="expand_button_title" msgid="2427401033573778270">"ଅଧିକ ଉନ୍ନତ"</string>
     <string name="summary_collapsed_preference_list" msgid="9167775378838880170">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XBasicAnnotationProcessor.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XBasicAnnotationProcessor.kt
new file mode 100644
index 0000000..733e5f9
--- /dev/null
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XBasicAnnotationProcessor.kt
@@ -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.room.compiler.processing
+
+/**
+ * Common interface for basic annotation processors.
+ *
+ * A processor should not implement this interface directly and instead should extend
+ * [androidx.room.compiler.processing.javac.JavacBasicAnnotationProcessor] or
+ * [androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor].
+ */
+interface XBasicAnnotationProcessor {
+
+    /**
+     * The list of processing steps to execute.
+     */
+    fun processingSteps(): Iterable<XProcessingStep>
+
+    /**
+     * Called at the end of a processing round after all [processingSteps] have been executed.
+     */
+    fun postRound(env: XProcessingEnv, round: XRoundEnv) { }
+}
\ No newline at end of file
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XProcessingStep.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XProcessingStep.kt
index b3bac7f..96f3994 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XProcessingStep.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XProcessingStep.kt
@@ -16,16 +16,6 @@
 
 package androidx.room.compiler.processing
 
-import androidx.room.compiler.processing.javac.JavacElement
-import androidx.room.compiler.processing.javac.JavacProcessingEnv
-import androidx.room.compiler.processing.ksp.KspElement
-import androidx.room.compiler.processing.ksp.KspProcessingEnv
-import com.google.auto.common.BasicAnnotationProcessor
-import com.google.common.collect.ImmutableSetMultimap
-import com.google.devtools.ksp.symbol.KSAnnotated
-import javax.annotation.processing.ProcessingEnvironment
-import javax.lang.model.element.Element
-
 /**
  * Processing step to simplify processing a set of annotations.
  */
@@ -47,59 +37,4 @@
      * The set of annotation qualified names processed by this step.
      */
     fun annotations(): Set<String>
-
-    companion object {
-
-        /**
-         * Wraps current [XProcessingStep] into an Auto Common
-         * [BasicAnnotationProcessor.ProcessingStep].
-         */
-        @JvmStatic
-        fun XProcessingStep.asAutoCommonProcessor(
-            env: ProcessingEnvironment
-        ): BasicAnnotationProcessor.Step {
-            return JavacProcessingStepDelegate(
-                env = env,
-                delegate = this
-            )
-        }
-
-        @JvmStatic
-        fun XProcessingStep.executeInKsp(env: XProcessingEnv): List<KSAnnotated> {
-            check(env is KspProcessingEnv)
-            val round = XRoundEnv.create(env)
-            val args = annotations().associateWith { annotation ->
-                round.getElementsAnnotatedWith(annotation)
-            }
-            return process(env, args)
-                .map { (it as KspElement).declaration }
-        }
-    }
-}
-
-internal class JavacProcessingStepDelegate(
-    val env: ProcessingEnvironment,
-    val delegate: XProcessingStep
-) : BasicAnnotationProcessor.Step {
-    override fun annotations(): Set<String> = delegate.annotations()
-
-    @Suppress("UnstableApiUsage")
-    override fun process(
-        elementsByAnnotation: ImmutableSetMultimap<String, Element>
-    ): Set<Element> {
-        val converted = mutableMapOf<String, Set<XElement>>()
-        // create a new x processing environment for each step to ensure it can freely cache
-        // whatever it wants and we don't keep elements references across rounds.
-        val xEnv = JavacProcessingEnv(env)
-        annotations().forEach { annotation ->
-            val elements = elementsByAnnotation[annotation].mapNotNull { element ->
-                xEnv.wrapAnnotatedElement(element, annotation)
-            }.toSet()
-            converted[annotation] = elements
-        }
-        val result = delegate.process(xEnv, converted)
-        return result.map {
-            (it as JavacElement).element
-        }.toSet()
-    }
 }
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/compat/XConverters.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/compat/XConverters.kt
index 4d5e1ee..c3cadc6 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/compat/XConverters.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/compat/XConverters.kt
@@ -19,15 +19,18 @@
 import androidx.room.compiler.processing.XElement
 import androidx.room.compiler.processing.XExecutableElement
 import androidx.room.compiler.processing.XProcessingEnv
+import androidx.room.compiler.processing.XRoundEnv
 import androidx.room.compiler.processing.XType
 import androidx.room.compiler.processing.XTypeElement
 import androidx.room.compiler.processing.XVariableElement
 import androidx.room.compiler.processing.javac.JavacElement
 import androidx.room.compiler.processing.javac.JavacExecutableElement
 import androidx.room.compiler.processing.javac.JavacProcessingEnv
+import androidx.room.compiler.processing.javac.JavacRoundEnv
 import androidx.room.compiler.processing.javac.JavacType
 import androidx.room.compiler.processing.javac.JavacTypeElement
 import androidx.room.compiler.processing.javac.JavacVariableElement
+import javax.annotation.processing.RoundEnvironment
 import javax.lang.model.element.Element
 import javax.lang.model.element.ExecutableElement
 import javax.lang.model.element.TypeElement
@@ -38,6 +41,9 @@
 object XConverters {
 
     @JvmStatic
+    fun XRoundEnv.toJavac(): RoundEnvironment = (this as JavacRoundEnv).delegate
+
+    @JvmStatic
     fun XElement.toJavac(): Element = (this as JavacElement).element
 
     @JvmStatic
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacBasicAnnotationProcessor.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacBasicAnnotationProcessor.kt
new file mode 100644
index 0000000..f8926ad
--- /dev/null
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacBasicAnnotationProcessor.kt
@@ -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.room.compiler.processing.javac
+
+import androidx.room.compiler.processing.XBasicAnnotationProcessor
+import androidx.room.compiler.processing.XElement
+import androidx.room.compiler.processing.XRoundEnv
+import com.google.auto.common.BasicAnnotationProcessor
+import com.google.common.collect.ImmutableSetMultimap
+import javax.annotation.processing.RoundEnvironment
+import javax.lang.model.element.Element
+
+/**
+ * Javac implementation of a [XBasicAnnotationProcessor] with built-in support for validating and
+ * deferring elements via auto-common's [BasicAnnotationProcessor].
+ */
+abstract class JavacBasicAnnotationProcessor :
+    BasicAnnotationProcessor(), XBasicAnnotationProcessor {
+
+    final override fun steps(): Iterable<Step> {
+        // Execute all processing steps in a single auto-common Step. This is done to share the
+        // XProcessingEnv and its cached across steps in the same round.
+        val steps = processingSteps()
+        val parentStep = object : Step {
+            override fun annotations() = steps.flatMap { it.annotations() }.toSet()
+
+            override fun process(
+                elementsByAnnotation: ImmutableSetMultimap<String, Element>
+            ): Set<Element> {
+                val xEnv = JavacProcessingEnv(processingEnv)
+                val convertedElementsByAnnotation = mutableMapOf<String, Set<XElement>>()
+                annotations().forEach { annotation ->
+                    convertedElementsByAnnotation[annotation] =
+                        elementsByAnnotation[annotation].mapNotNull { element ->
+                            xEnv.wrapAnnotatedElement(element, annotation)
+                        }.toSet()
+                }
+                val results = steps.flatMap { step ->
+                    step.process(
+                        env = xEnv,
+                        elementsByAnnotation = step.annotations().associateWith {
+                            convertedElementsByAnnotation[it] ?: emptySet()
+                        }
+                    )
+                }
+                return results.map { (it as JavacElement).element }.toSet()
+            }
+        }
+        return listOf(parentStep)
+    }
+
+    final override fun postRound(roundEnv: RoundEnvironment) {
+        // Due to BasicAnnotationProcessor taking over AbstractProcessor#process() we can't
+        // share the same XProcessingEnv from the steps, but that might be ok...
+        val xEnv = JavacProcessingEnv(processingEnv)
+        val xRound = XRoundEnv.create(xEnv, roundEnv)
+        postRound(xEnv, xRound)
+    }
+}
\ No newline at end of file
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspBasicAnnotationProcessor.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspBasicAnnotationProcessor.kt
new file mode 100644
index 0000000..9551d6d
--- /dev/null
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspBasicAnnotationProcessor.kt
@@ -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.room.compiler.processing.ksp
+
+import androidx.room.compiler.processing.XBasicAnnotationProcessor
+import androidx.room.compiler.processing.XElement
+import androidx.room.compiler.processing.XProcessingEnv
+import androidx.room.compiler.processing.XRoundEnv
+import com.google.devtools.ksp.processing.Resolver
+import com.google.devtools.ksp.processing.SymbolProcessor
+import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
+import com.google.devtools.ksp.symbol.KSAnnotated
+import com.google.devtools.ksp.validate
+
+/**
+ * KSP implementation of a [XBasicAnnotationProcessor] with built-in support for validating and
+ * deferring symbols.
+ */
+abstract class KspBasicAnnotationProcessor(
+    val symbolProcessorEnvironment: SymbolProcessorEnvironment
+) : SymbolProcessor, XBasicAnnotationProcessor {
+
+    final override fun process(resolver: Resolver): List<KSAnnotated> {
+        val processingEnv = XProcessingEnv.create(
+            symbolProcessorEnvironment.options,
+            resolver,
+            symbolProcessorEnvironment.codeGenerator,
+            symbolProcessorEnvironment.logger
+        )
+        val round = XRoundEnv.create(processingEnv)
+        val deferredElements = processingSteps().flatMap { step ->
+            val invalidElements = mutableSetOf<XElement>()
+            val elementsByAnnotation = step.annotations().associateWith { annotation ->
+                val annotatedElements = round.getElementsAnnotatedWith(annotation)
+                annotatedElements
+                    .filter { (it as KspElement).declaration.validate() }
+                    .also { invalidElements.addAll(annotatedElements - it) }
+                    .toSet()
+            }
+            invalidElements + step.process(processingEnv, elementsByAnnotation)
+        }
+        postRound(processingEnv, round)
+        return deferredElements.map { (it as KspElement).declaration }
+    }
+}
\ No newline at end of file
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingStepTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingStepTest.kt
index 004ace1..b0af4d3 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingStepTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingStepTest.kt
@@ -16,20 +16,18 @@
 
 package androidx.room.compiler.processing
 
-import androidx.room.compiler.processing.XProcessingStep.Companion.asAutoCommonProcessor
-import androidx.room.compiler.processing.XProcessingStep.Companion.executeInKsp
+import androidx.room.compiler.processing.javac.JavacBasicAnnotationProcessor
+import androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor
+import androidx.room.compiler.processing.ksp.KspElement
 import androidx.room.compiler.processing.testcode.MainAnnotation
 import androidx.room.compiler.processing.testcode.OtherAnnotation
 import androidx.room.compiler.processing.util.CompilationTestCapabilities
-import com.google.auto.common.BasicAnnotationProcessor
 import com.google.common.truth.Truth.assertAbout
 import com.google.common.truth.Truth.assertThat
-import com.google.devtools.ksp.processing.Resolver
 import com.google.devtools.ksp.processing.SymbolProcessor
 import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
 import com.google.devtools.ksp.processing.SymbolProcessorProvider
 import com.google.devtools.ksp.symbol.ClassKind
-import com.google.devtools.ksp.symbol.KSAnnotated
 import com.google.devtools.ksp.symbol.KSClassDeclaration
 import com.google.testing.compile.JavaFileObjects
 import com.google.testing.compile.JavaSourcesSubjectFactory
@@ -79,12 +77,8 @@
                 )
             }
         }
-        val mainProcessor = object : BasicAnnotationProcessor() {
-            override fun steps(): Iterable<Step> {
-                return listOf(
-                    processingStep.asAutoCommonProcessor(processingEnv)
-                )
-            }
+        val mainProcessor = object : JavacBasicAnnotationProcessor() {
+            override fun processingSteps() = listOf(processingStep)
         }
         val main = JavaFileObjects.forSourceString(
             "foo.bar.Main",
@@ -187,19 +181,8 @@
         ).that(
             listOf(main)
         ).processedWith(
-            object : BasicAnnotationProcessor() {
-                override fun steps(): Iterable<Step> {
-                    return listOf(
-                        processingStep.asAutoCommonProcessor(processingEnv)
-                    )
-                }
-
-                override fun getSupportedOptions(): Set<String> {
-                    return setOf(
-                        MainAnnotation::class.qualifiedName!!,
-                        OtherAnnotation::class.qualifiedName!!
-                    )
-                }
+            object : JavacBasicAnnotationProcessor() {
+                override fun processingSteps() = listOf(processingStep)
             }
         ).compilesWithoutError()
         assertThat(otherAnnotatedElements).containsExactly(
@@ -267,19 +250,8 @@
         ).that(
             listOf(main)
         ).processedWith(
-            object : BasicAnnotationProcessor() {
-                override fun steps(): Iterable<Step> {
-                    return listOf(
-                        processingStep.asAutoCommonProcessor(processingEnv)
-                    )
-                }
-
-                override fun getSupportedOptions(): Set<String> {
-                    return setOf(
-                        MainAnnotation::class.qualifiedName!!,
-                        OtherAnnotation::class.qualifiedName!!
-                    )
-                }
+            object : JavacBasicAnnotationProcessor() {
+                override fun processingSteps() = listOf(processingStep)
             }
         ).compilesWithoutError()
         assertThat(elementPerRound).hasSize(2)
@@ -298,6 +270,7 @@
     @Test
     fun kspReturnsUnprocessed() {
         CompilationTestCapabilities.assumeKspIsEnabled()
+        var returned: Set<XElement>? = null
         val processingStep = object : XProcessingStep {
             override fun process(
                 env: XProcessingEnv,
@@ -306,26 +279,17 @@
                 return elementsByAnnotation.values
                     .flatten()
                     .toSet()
+                    .also { returned = it }
             }
 
             override fun annotations(): Set<String> {
                 return setOf(OtherAnnotation::class.qualifiedName!!)
             }
         }
-        var returned: List<KSAnnotated>? = null
         val processorProvider = object : SymbolProcessorProvider {
             override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
-                return object : SymbolProcessor {
-                    override fun process(resolver: Resolver): List<KSAnnotated> {
-                        val env = XProcessingEnv.create(
-                            emptyMap(),
-                            resolver,
-                            environment.codeGenerator,
-                            environment.logger
-                        )
-                        return processingStep.executeInKsp(env)
-                            .also { returned = it }
-                    }
+                return object : KspBasicAnnotationProcessor(environment) {
+                    override fun processingSteps() = listOf(processingStep)
                 }
             }
         }
@@ -352,8 +316,137 @@
             isNotNull()
             isNotEmpty()
         }
-        val element = returned!!.first() as KSClassDeclaration
+        val element =
+            returned!!.map { (it as KspElement).declaration }.first() as KSClassDeclaration
         assertThat(element.classKind).isEqualTo(ClassKind.CLASS)
         assertThat(element.qualifiedName!!.asString()).isEqualTo("foo.bar.Other")
     }
+
+    @Test
+    fun javacAnnotatedElementsByStep() {
+        val main = JavaFileObjects.forSourceString(
+            "foo.bar.Main",
+            """
+            package foo.bar;
+            import androidx.room.compiler.processing.testcode.*;
+            @MainAnnotation(
+                typeList = {},
+                singleType = Object.class,
+                intMethod = 3,
+                singleOtherAnnotation = @OtherAnnotation("y")
+            )
+            class Main {
+            }
+            """.trimIndent()
+        )
+        val other = JavaFileObjects.forSourceString(
+            "foo.bar.Other",
+            """
+            package foo.bar;
+            import androidx.room.compiler.processing.testcode.*;
+            @OtherAnnotation("x")
+            class Other {
+            }
+            """.trimIndent()
+        )
+        val elementsByStep = mutableMapOf<XProcessingStep, Collection<String>>()
+        val mainStep = object : XProcessingStep {
+            override fun annotations() = setOf(MainAnnotation::class.qualifiedName!!)
+            override fun process(
+                env: XProcessingEnv,
+                elementsByAnnotation: Map<String, Set<XElement>>
+            ): Set<XElement> {
+                elementsByStep[this] = elementsByAnnotation.values.flatten()
+                    .map { (it as XTypeElement).qualifiedName }
+                return emptySet()
+            }
+        }
+        val otherStep = object : XProcessingStep {
+            override fun annotations() = setOf(OtherAnnotation::class.qualifiedName!!)
+            override fun process(
+                env: XProcessingEnv,
+                elementsByAnnotation: Map<String, Set<XElement>>
+            ): Set<XElement> {
+                elementsByStep[this] = elementsByAnnotation.values.flatten()
+                    .map { (it as XTypeElement).qualifiedName }
+                return emptySet()
+            }
+        }
+        assertAbout(
+            JavaSourcesSubjectFactory.javaSources()
+        ).that(
+            listOf(main, other)
+        ).processedWith(
+            object : JavacBasicAnnotationProcessor() {
+                override fun processingSteps() = listOf(mainStep, otherStep)
+            }
+        ).compilesWithoutError()
+        assertThat(elementsByStep[mainStep])
+            .containsExactly("foo.bar.Main")
+        assertThat(elementsByStep[otherStep])
+            .containsExactly("foo.bar.Other")
+    }
+
+    @Test
+    fun kspAnnotatedElementsByStep() {
+        val main = SourceFile.kotlin(
+            "Classes.kt",
+            """
+            package foo.bar
+            import androidx.room.compiler.processing.testcode.*
+            @MainAnnotation(
+                typeList = [],
+                singleType = Any::class,
+                intMethod = 3,
+                singleOtherAnnotation = OtherAnnotation("y")
+            )
+            class Main {
+            }
+            @OtherAnnotation("y")
+            class Other {
+            }
+            """.trimIndent()
+        )
+        val elementsByStep = mutableMapOf<XProcessingStep, Collection<String>>()
+        val mainStep = object : XProcessingStep {
+            override fun annotations() = setOf(MainAnnotation::class.qualifiedName!!)
+            override fun process(
+                env: XProcessingEnv,
+                elementsByAnnotation: Map<String, Set<XElement>>
+            ): Set<XElement> {
+                elementsByStep[this] = elementsByAnnotation.values.flatten()
+                    .map { (it as XTypeElement).qualifiedName }
+                return emptySet()
+            }
+        }
+        val otherStep = object : XProcessingStep {
+            override fun annotations() = setOf(OtherAnnotation::class.qualifiedName!!)
+            override fun process(
+                env: XProcessingEnv,
+                elementsByAnnotation: Map<String, Set<XElement>>
+            ): Set<XElement> {
+                elementsByStep[this] = elementsByAnnotation.values.flatten()
+                    .map { (it as XTypeElement).qualifiedName }
+                return emptySet()
+            }
+        }
+        val processorProvider = object : SymbolProcessorProvider {
+            override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
+                return object : KspBasicAnnotationProcessor(environment) {
+                    override fun processingSteps() = listOf(mainStep, otherStep)
+                }
+            }
+        }
+        KotlinCompilation().apply {
+            workingDir = temporaryFolder.root
+            inheritClassPath = true
+            symbolProcessorProviders = listOf(processorProvider)
+            sources = listOf(main)
+            verbose = false
+        }.compile()
+        assertThat(elementsByStep[mainStep])
+            .containsExactly("foo.bar.Main")
+        assertThat(elementsByStep[otherStep])
+            .containsExactly("foo.bar.Other")
+    }
 }
\ No newline at end of file
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/RoomKspProcessor.kt b/room/room-compiler/src/main/kotlin/androidx/room/RoomKspProcessor.kt
index fa1656b9..7437810 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/RoomKspProcessor.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/RoomKspProcessor.kt
@@ -16,44 +16,25 @@
 
 package androidx.room
 
-import androidx.room.compiler.processing.XProcessingEnv
-import androidx.room.compiler.processing.XProcessingStep.Companion.executeInKsp
-import com.google.devtools.ksp.processing.CodeGenerator
-import com.google.devtools.ksp.processing.KSPLogger
-import com.google.devtools.ksp.processing.Resolver
+import androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor
 import com.google.devtools.ksp.processing.SymbolProcessor
 import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
 import com.google.devtools.ksp.processing.SymbolProcessorProvider
-import com.google.devtools.ksp.symbol.KSAnnotated
 
 /**
  * Entry point for processing using KSP.
  */
 class RoomKspProcessor(
-    private val options: Map<String, String>,
-    private val codeGenerator: CodeGenerator,
-    private val logger: KSPLogger
-) : SymbolProcessor {
-    override fun process(resolver: Resolver): List<KSAnnotated> {
-        val processingEnv = XProcessingEnv.create(
-            options,
-            resolver,
-            codeGenerator,
-            logger
-        )
+    environment: SymbolProcessorEnvironment
+) : KspBasicAnnotationProcessor(environment) {
 
-        return DatabaseProcessingStep().executeInKsp(
-            processingEnv
-        )
-    }
+    override fun processingSteps() = listOf(
+        DatabaseProcessingStep()
+    )
 
     class Provider : SymbolProcessorProvider {
         override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
-            return RoomKspProcessor(
-                options = environment.options,
-                codeGenerator = environment.codeGenerator,
-                logger = environment.logger
-            )
+            return RoomKspProcessor(environment)
         }
     }
 }
\ No newline at end of file
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/RoomProcessor.kt b/room/room-compiler/src/main/kotlin/androidx/room/RoomProcessor.kt
index 8119102..8f6c8ac 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/RoomProcessor.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/RoomProcessor.kt
@@ -17,12 +17,11 @@
 package androidx.room
 
 import androidx.room.compiler.processing.XProcessingEnv
-import androidx.room.compiler.processing.XProcessingStep.Companion.asAutoCommonProcessor
+import androidx.room.compiler.processing.javac.JavacBasicAnnotationProcessor
 import androidx.room.processor.Context
 import androidx.room.processor.ProcessorErrors
 import androidx.room.util.SimpleJavaVersion
 import androidx.room.vo.Warning
-import com.google.auto.common.BasicAnnotationProcessor
 import javax.lang.model.SourceVersion
 
 /**
@@ -34,20 +33,18 @@
 /**
  * The annotation processor for Room.
  */
-class RoomProcessor : BasicAnnotationProcessor() {
+class RoomProcessor : JavacBasicAnnotationProcessor() {
 
     /** Helper variable to avoid reporting the warning twice. */
     private var jdkVersionHasBugReported = false
 
-    override fun steps(): MutableIterable<Step> {
-        return mutableListOf(
-            DatabaseProcessingStep().asAutoCommonProcessor(processingEnv)
-        )
-    }
+    override fun processingSteps() = listOf(
+        DatabaseProcessingStep()
+    )
 
     override fun getSupportedOptions(): MutableSet<String> {
         val supportedOptions = Context.ARG_OPTIONS.toMutableSet()
-        // x processing is a cheap wrapper so it is fine to re-create.
+        // XProcessingEnv is a cheap wrapper so it is fine to re-create.
         val xProcessing = XProcessingEnv.create(processingEnv)
         if (Context.BooleanProcessorOptions.INCREMENTAL.getValue(xProcessing)) {
             if (methodParametersVisibleInClassFiles()) {
diff --git a/settings.gradle b/settings.gradle
index 9be70e4..8e095e4 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -620,6 +620,7 @@
 includeProject(":wear:compose:compose-foundation", "wear/compose/foundation", [BuildType.COMPOSE])
 includeProject(":wear:compose:compose-material", "wear/compose/material", [BuildType.COMPOSE])
 includeProject(":wear:compose:compose-material-benchmark", "wear/compose/material/benchmark", [BuildType.COMPOSE])
+includeProject(":wear:compose:integration-tests:demos", "wear/compose/integration-tests/demos", [BuildType.COMPOSE])
 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])
diff --git a/slices/view/src/main/res/values-tr/strings.xml b/slices/view/src/main/res/values-tr/strings.xml
index 84da5fb..74de868 100644
--- a/slices/view/src/main/res/values-tr/strings.xml
+++ b/slices/view/src/main/res/values-tr/strings.xml
@@ -18,7 +18,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="abc_slice_more_content" msgid="6405516388971241142">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
-    <string name="abc_slice_more" msgid="1983560225998630901">"Diğer"</string>
+    <string name="abc_slice_more" msgid="1983560225998630901">"Daha fazla"</string>
     <string name="abc_slice_show_more" msgid="1567717014004692768">"Daha fazla göster"</string>
     <string name="abc_slice_updated" msgid="8155085405396453848">"Güncellenme zamanı: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <plurals name="abc_slice_duration_min" formatted="false" msgid="6996334305156847955">
diff --git a/testutils/testutils-espresso/build.gradle b/testutils/testutils-espresso/build.gradle
index 57507bf..8ac3572 100644
--- a/testutils/testutils-espresso/build.gradle
+++ b/testutils/testutils-espresso/build.gradle
@@ -25,6 +25,7 @@
 
     implementation(libs.espressoCore, excludes.espresso)
     implementation(libs.kotlinStdlib)
+    implementation("androidx.core:core:1.2.0")
 }
 
 android {
diff --git a/testutils/testutils-espresso/src/main/java/androidx/testutils/SwipeExclusionRects.kt b/testutils/testutils-espresso/src/main/java/androidx/testutils/SwipeExclusionRects.kt
new file mode 100644
index 0000000..e3c9b5e
--- /dev/null
+++ b/testutils/testutils-espresso/src/main/java/androidx/testutils/SwipeExclusionRects.kt
@@ -0,0 +1,57 @@
+/*
+ * 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.testutils
+
+import android.graphics.Rect
+import android.view.View
+import androidx.core.view.ViewCompat
+
+/**
+ * Sets exclusion rects for system gestures on this view that will make sure Espresso's
+ * predefined swipes (such as [swipeRight][androidx.test.espresso.action.ViewActions.swipeRight])
+ * won't be mistaken for system gestures.
+ *
+ * Set this on the view on which you will perform the swipe ViewActions.
+ */
+fun View.setSystemExclusionRectsForEspressoSwipes() {
+    addOnLayoutChangeListener(SetExclusionRectsOnLayout())
+}
+
+private class SetExclusionRectsOnLayout : View.OnLayoutChangeListener {
+    private val exclusionRects = mutableListOf<Rect>()
+
+    override fun onLayoutChange(
+        v: View?,
+        left: Int,
+        top: Int,
+        right: Int,
+        bottom: Int,
+        oldLeft: Int,
+        oldTop: Int,
+        oldRight: Int,
+        oldBottom: Int
+    ) {
+        if (v == null) return
+        exclusionRects.clear()
+        val vCenter = (bottom - top) / 2
+        val hCenter = (right - left) / 2
+        // Create an exclusion strip of 2px thick (center +/- 1) through the middle, hor and ver
+        exclusionRects += Rect(left, vCenter - 1, right, vCenter + 1)
+        exclusionRects += Rect(hCenter - 1, top, hCenter + 1, bottom)
+        ViewCompat.setSystemGestureExclusionRects(v, exclusionRects)
+    }
+}
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/LayoutIntrinsics.kt b/text/text/src/main/java/androidx/compose/ui/text/android/LayoutIntrinsics.kt
index 8773399..d9b29cd 100644
--- a/text/text/src/main/java/androidx/compose/ui/text/android/LayoutIntrinsics.kt
+++ b/text/text/src/main/java/androidx/compose/ui/text/android/LayoutIntrinsics.kt
@@ -22,7 +22,6 @@
 import android.text.TextPaint
 import androidx.compose.ui.text.android.style.LetterSpacingSpanEm
 import androidx.compose.ui.text.android.style.LetterSpacingSpanPx
-import androidx.compose.ui.text.android.style.LineHeightSpan
 import java.text.BreakIterator
 import java.util.PriorityQueue
 
@@ -139,6 +138,5 @@
         textPaint.letterSpacing != 0f ||
             charSequence.hasSpan(LetterSpacingSpanPx::class.java) ||
             charSequence.hasSpan(LetterSpacingSpanEm::class.java)
-        ) &&
-        charSequence.hasSpan(LineHeightSpan::class.java)
+        )
 }
\ No newline at end of file
diff --git a/viewpager/viewpager/src/androidTest/java/androidx/viewpager/widget/BaseViewPagerTest.java b/viewpager/viewpager/src/androidTest/java/androidx/viewpager/widget/BaseViewPagerTest.java
index ad223ff..6423be2 100644
--- a/viewpager/viewpager/src/androidTest/java/androidx/viewpager/widget/BaseViewPagerTest.java
+++ b/viewpager/viewpager/src/androidTest/java/androidx/viewpager/widget/BaseViewPagerTest.java
@@ -1068,6 +1068,7 @@
 
     @Test
     @LargeTest
+    @FlakyTest(bugId = 179887413)
     public void testPageScrollPositionChangesSwipe() {
         // Swipe one page to the left
         verifyScrollCallbacksToHigherPage(ViewPagerActions.wrap(swipeLeft()), 1);
diff --git a/viewpager2/integration-tests/testapp/build.gradle b/viewpager2/integration-tests/testapp/build.gradle
index 3c2e9d5..7aed76de 100644
--- a/viewpager2/integration-tests/testapp/build.gradle
+++ b/viewpager2/integration-tests/testapp/build.gradle
@@ -35,6 +35,7 @@
         exclude group: "androidx.viewpager2", module: "viewpager2"
     }
 
+    androidTestImplementation(project(":internal-testutils-espresso"))
     androidTestImplementation(libs.testRules)
     androidTestImplementation(libs.testExtJunit)
     androidTestImplementation(libs.espressoCore)
diff --git a/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/BaseTest.kt b/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/BaseTest.kt
index 46ef639..3ac083f 100644
--- a/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/BaseTest.kt
+++ b/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/BaseTest.kt
@@ -29,6 +29,7 @@
 import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
 import androidx.test.espresso.matcher.ViewMatchers.withId
 import androidx.test.espresso.matcher.ViewMatchers.withText
+import androidx.testutils.setSystemExclusionRectsForEspressoSwipes
 import androidx.viewpager2.integration.testapp.R
 import androidx.viewpager2.integration.testapp.test.util.ViewPagerIdleWatcher
 import androidx.viewpager2.integration.testapp.test.util.onCurrentPage
@@ -71,6 +72,7 @@
     @Before
     open fun setUp() {
         viewPager = activityTestRule.activity.findViewById(layoutId)
+        viewPager.setSystemExclusionRectsForEspressoSwipes()
         idleWatcher = ViewPagerIdleWatcher(viewPager)
         onView(withId(layoutId)).perform(waitForInjectMotionEvents())
     }
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
index c1aae40..c6668d7 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
@@ -45,6 +45,7 @@
 import androidx.test.espresso.matcher.ViewMatchers.withText
 import androidx.testutils.LocaleTestUtils
 import androidx.testutils.recreate
+import androidx.testutils.setSystemExclusionRectsForEspressoSwipes
 import androidx.testutils.waitForExecution
 import androidx.viewpager2.adapter.FragmentStateAdapter
 import androidx.viewpager2.test.R
@@ -117,7 +118,10 @@
         onView(withId(R.id.view_pager)).perform(waitForInjectMotionEvents())
 
         val viewPager: ViewPager2 = activityTestRule.activity.findViewById(R.id.view_pager)
-        activityTestRule.runOnUiThread { viewPager.orientation = orientation }
+        activityTestRule.runOnUiThread {
+            viewPager.orientation = orientation
+            viewPager.setSystemExclusionRectsForEspressoSwipes()
+        }
         onView(withId(R.id.view_pager)).check(matches(isDisplayed()))
 
         // animations getting in the way on API < 16
@@ -143,6 +147,7 @@
                 viewPager.orientation = orientation
                 viewPager.isUserInputEnabled = isUserInputEnabled
                 viewPager.adapter = adapterProvider(activity)
+                viewPager.setSystemExclusionRectsForEspressoSwipes()
                 onCreateCallback(viewPager)
             }
             activity = activityTestRule.recreate()
diff --git a/wear/compose/integration-tests/demos/build.gradle b/wear/compose/integration-tests/demos/build.gradle
new file mode 100644
index 0000000..a82173a
--- /dev/null
+++ b/wear/compose/integration-tests/demos/build.gradle
@@ -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.
+ */
+
+plugins {
+    id("AndroidXPlugin")
+    id("AndroidXComposePlugin")
+    id 'com.android.application'
+    id("org.jetbrains.kotlin.android")
+}
+
+android {
+    defaultConfig {
+        applicationId "androidx.wear.compose.integration.demos"
+        minSdk 25
+        targetSdk 30
+        versionCode 1
+        versionName "1.0"
+        // Change the APK name to match the *testapp regex we use to pick up APKs for testing as
+        // part of CI.
+        archivesBaseName = "wear-compose-demos-testapp"
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+    }
+    buildFeatures {
+        viewBinding true
+    }
+}
+
+dependencies {
+    kotlinPlugin(project(":compose:compiler:compiler"))
+
+    implementation 'androidx.wear:wear:1.1.0'
+    implementation(project(":compose:ui:ui"))
+    implementation project(path: ':compose:integration-tests:demos:common')
+    implementation project(path: ':wear:compose:compose-material')
+    implementation(project(":compose:foundation:foundation"))
+    implementation(project(":compose:foundation:foundation-layout"))
+    implementation(project(":compose:runtime:runtime"))
+
+    androidTestImplementation(project(":compose:ui:ui-test-junit4"))
+    androidTestImplementation(libs.testCore)
+    androidTestImplementation(libs.testRules)
+    androidTestImplementation(libs.testRunner)
+    androidTestImplementation(libs.espressoCore)
+    androidTestImplementation(libs.junit)
+    androidTestImplementation(libs.truth)
+}
\ No newline at end of file
diff --git a/wear/compose/integration-tests/demos/proguard-rules.pro b/wear/compose/integration-tests/demos/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/wear/compose/integration-tests/demos/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/wear/compose/integration-tests/demos/src/androidTest/AndroidManifest.xml b/wear/compose/integration-tests/demos/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..cfe8548
--- /dev/null
+++ b/wear/compose/integration-tests/demos/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<?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 package="androidx.wear.compose.integration.demos" />
diff --git a/wear/compose/integration-tests/demos/src/androidTest/java/androidx/wear/compose/integration/demos/test/DemoTest.kt b/wear/compose/integration-tests/demos/src/androidTest/java/androidx/wear/compose/integration/demos/test/DemoTest.kt
new file mode 100644
index 0000000..0ca836b
--- /dev/null
+++ b/wear/compose/integration-tests/demos/src/androidTest/java/androidx/wear/compose/integration/demos/test/DemoTest.kt
@@ -0,0 +1,203 @@
+/*
+ * 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.wear.compose.integration.demos.test
+
+import androidx.compose.integration.demos.common.Demo
+import androidx.compose.integration.demos.common.DemoCategory
+import androidx.compose.integration.demos.common.allDemos
+import androidx.compose.ui.test.ExperimentalTestApi
+import androidx.compose.ui.test.SemanticsNodeInteractionCollection
+import androidx.compose.ui.test.hasClickAction
+import androidx.compose.ui.test.hasText
+import androidx.compose.ui.test.isDialog
+import androidx.compose.ui.test.junit4.createAndroidComposeRule
+import androidx.compose.ui.test.performClick
+import androidx.compose.ui.test.performScrollTo
+import androidx.test.espresso.Espresso
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.wear.compose.integration.demos.DemoActivity
+import androidx.wear.compose.integration.demos.WearComposeDemos
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private val ignoredDemos = listOf<String>(
+    // Not ignoring any of them \o/
+)
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+@OptIn(ExperimentalTestApi::class)
+class DemoTest {
+    // We need to provide the recompose factory first to use new clock.
+    @get:Rule
+    val rule = createAndroidComposeRule<DemoActivity>()
+
+    @Test
+    fun navigateThroughAllDemos() {
+        // Compose integration-tests are split into batches due to size,
+        // but that's overkill until we have a decent population of tests.
+        navigateThroughAllDemos(AllButIgnoredDemos)
+    }
+
+    private fun navigateThroughAllDemos(root: DemoCategory, fastForwardClock: Boolean = false) {
+        // Keep track of each demo we visit.
+        val visitedDemos = mutableListOf<Demo>()
+
+        // Visit all demos.
+        root.visitDemos(
+            visitedDemos = visitedDemos,
+            path = listOf(root),
+            fastForwardClock = fastForwardClock
+        )
+
+        // Ensure that we visited all the demos we expected to, in the order we expected to.
+        assertThat(visitedDemos).isEqualTo(root.allDemos())
+    }
+
+    /**
+     * DFS traversal of each demo in a [DemoCategory] using [Demo.visit]
+     *
+     * @param path The path of categories that leads to this demo
+     */
+    private fun DemoCategory.visitDemos(
+        visitedDemos: MutableList<Demo>,
+        path: List<DemoCategory>,
+        fastForwardClock: Boolean
+    ) {
+        demos.forEach { demo ->
+            visitedDemos.add(demo)
+            demo.visit(visitedDemos, path, fastForwardClock)
+        }
+    }
+
+    /**
+     * Visits a [Demo], and then navigates back up to the [DemoCategory] it was inside.
+     *
+     * If this [Demo] is a [DemoCategory], this will visit sub-[Demo]s first before continuing
+     * in the current category.
+     *
+     * @param path The path of categories that leads to this demo
+     */
+    private fun Demo.visit(
+        visitedDemos: MutableList<Demo>,
+        path: List<DemoCategory>,
+        fastForwardClock: Boolean
+    ) {
+        val navigationTitle = path.navigationTitle
+
+        if (fastForwardClock) {
+            // Skip through the enter animation of the list screen
+            fastForwardClock()
+        }
+
+        rule.onNode(hasText(title) and hasClickAction())
+            .assertExists("Couldn't find \"$title\" in \"$navigationTitle\"")
+            .performScrollTo()
+            .performClick()
+
+        if (this is DemoCategory) {
+            visitDemos(visitedDemos, path + this, fastForwardClock)
+        }
+
+        if (fastForwardClock) {
+            // Skip through the enter animation of the visited demo
+            fastForwardClock()
+        }
+
+        rule.waitForIdle()
+        while (rule.onAllNodes(isDialog()).isNotEmpty()) {
+            Espresso.pressBack()
+            rule.waitForIdle()
+        }
+
+        clearFocusFromDemo()
+        rule.waitForIdle()
+
+        Espresso.pressBack()
+        rule.waitForIdle()
+
+        if (fastForwardClock) {
+            // Pump press back
+            fastForwardClock(2000)
+        }
+    }
+
+    private fun fastForwardClock(millis: Long = 5000) {
+        rule.waitForIdle()
+        rule.mainClock.advanceTimeBy(millis)
+    }
+
+    private fun SemanticsNodeInteractionCollection.isNotEmpty(): Boolean {
+        return fetchSemanticsNodes(atLeastOneRootRequired = false).isNotEmpty()
+    }
+
+    private fun clearFocusFromDemo() {
+        with(rule.activity) {
+            if (hostView.hasFocus()) {
+                if (hostView.isFocused) {
+                    // One of the Compose components has focus.
+                    focusManager.clearFocus(force = true)
+                } else {
+                    // A child view has focus. (View interop scenario).
+                    // We could also use hostViewGroup.focusedChild?.clearFocus(), but the
+                    // interop views might end up being focused if one of them is marked as
+                    // focusedByDefault. So we clear focus by requesting focus on the owner.
+                    rule.runOnUiThread { hostView.requestFocus() }
+                }
+            }
+        }
+    }
+}
+
+private val AllButIgnoredDemos =
+    WearComposeDemos.filter { path, demo ->
+        demo.navigationTitle(path) !in ignoredDemos
+    }
+
+private fun Demo.navigationTitle(path: List<DemoCategory>): String {
+    return path.plus(this).navigationTitle
+}
+
+private val List<Demo>.navigationTitle: String
+    get() = if (size == 1) first().title else drop(1).joinToString(" > ")
+
+/**
+ * Trims the tree of [Demo]s represented by this [DemoCategory] by cutting all leave demos for
+ * which the [predicate] returns `false` and recursively removing all empty categories as a result.
+ */
+private fun DemoCategory.filter(
+    path: List<DemoCategory> = emptyList(),
+    predicate: (path: List<DemoCategory>, demo: Demo) -> Boolean
+): DemoCategory {
+    val newPath = path + this
+    return DemoCategory(
+        title,
+        demos.mapNotNull {
+            when (it) {
+                is DemoCategory -> {
+                    it.filter(newPath, predicate).let { if (it.demos.isEmpty()) null else it }
+                }
+                else -> {
+                    if (predicate(newPath, it)) it else null
+                }
+            }
+        }
+    )
+}
diff --git a/wear/compose/integration-tests/demos/src/main/AndroidManifest.xml b/wear/compose/integration-tests/demos/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..ec8bddb
--- /dev/null
+++ b/wear/compose/integration-tests/demos/src/main/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?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.wear.compose.integration.demos">
+
+    <application
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:supportsRtl="true"
+        android:theme="@android:style/Theme.DeviceDefault">
+        <activity
+            android:name=".DemoActivity"
+            android:exported="true"
+            android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+
+</manifest>
\ No newline at end of file
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ButtonDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ButtonDemo.kt
new file mode 100644
index 0000000..757d704
--- /dev/null
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ButtonDemo.kt
@@ -0,0 +1,104 @@
+/*
+ * 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.compose.integration.demos
+
+import androidx.compose.foundation.layout.Arrangement
+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.size
+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.unit.dp
+import androidx.wear.compose.material.Button
+import androidx.wear.compose.material.ButtonDefaults
+import androidx.wear.compose.material.CompactButton
+import androidx.wear.compose.material.MaterialTheme
+import androidx.wear.compose.material.Text
+import androidx.wear.compose.material.ToggleButton
+
+@Composable
+fun ButtonDemo() {
+    var enabled by remember { mutableStateOf(true) }
+
+    Column(
+        modifier = Modifier.fillMaxSize(),
+        verticalArrangement = Arrangement.Center,
+        horizontalAlignment = Alignment.CenterHorizontally
+    ) {
+        Row(
+            horizontalArrangement = Arrangement.spacedBy(2.dp),
+            verticalAlignment = Alignment.CenterVertically
+        ) {
+            Button(
+                onClick = {},
+                enabled = enabled,
+                modifier = Modifier.size(ButtonDefaults.LargeButtonSize),
+            ) {
+                Text("Lrg")
+            }
+            Button(
+                onClick = {},
+                enabled = enabled,
+            ) {
+                // NB Leave size as default for this one.
+                Text("Def")
+            }
+            Button(
+                onClick = {},
+                enabled = enabled,
+                modifier = Modifier.size(ButtonDefaults.SmallButtonSize),
+            ) {
+                Text("Sml")
+            }
+            CompactButton(
+                onClick = {},
+                enabled = enabled,
+            ) {
+                Text("XS")
+            }
+        }
+        Spacer(modifier = Modifier.size(4.dp))
+        Row(
+            horizontalArrangement = Arrangement.Center,
+            verticalAlignment = Alignment.CenterVertically
+        ) {
+            Text(
+                text = "Enabled",
+                style = MaterialTheme.typography.caption2,
+                color = Color.White
+            )
+            Spacer(modifier = Modifier.size(4.dp))
+            ToggleButton(
+                checked = enabled,
+                onCheckedChange = {
+                    enabled = it
+                },
+                modifier = Modifier.size(ButtonDefaults.SmallButtonSize)
+            ) {
+                Text(text = if (enabled) "Yes" else "No")
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/DemoActivity.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/DemoActivity.kt
new file mode 100644
index 0000000..c74d8d8
--- /dev/null
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/DemoActivity.kt
@@ -0,0 +1,164 @@
+/*
+ * 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.compose.integration.demos
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import android.view.View
+import androidx.activity.ComponentActivity
+import androidx.activity.OnBackPressedCallback
+import androidx.activity.OnBackPressedDispatcher
+import androidx.compose.integration.demos.common.ActivityDemo
+import androidx.compose.integration.demos.common.Demo
+import androidx.compose.integration.demos.common.DemoCategory
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.Saver
+import androidx.compose.runtime.saveable.listSaver
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.focus.FocusManager
+import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.platform.LocalFocusManager
+import androidx.compose.ui.platform.LocalView
+import androidx.wear.compose.material.MaterialTheme
+
+/**
+ * Main [Activity] for Wear Compose related demos.
+ */
+class DemoActivity : ComponentActivity() {
+    lateinit var hostView: View
+    lateinit var focusManager: FocusManager
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        ComposeView(this).also {
+            setContentView(it)
+        }.setContent {
+            hostView = LocalView.current
+            focusManager = LocalFocusManager.current
+            val activityStarter = fun(demo: ActivityDemo<*>) {
+                startActivity(Intent(this, demo.activityClass.java))
+            }
+            val navigator = rememberSaveable(
+                saver = Navigator.Saver(WearComposeDemos, onBackPressedDispatcher, activityStarter)
+            ) {
+                Navigator(WearComposeDemos, onBackPressedDispatcher, activityStarter)
+            }
+            MaterialTheme {
+                DemoApp(
+                    currentDemo = navigator.currentDemo,
+                    onNavigateToDemo = { demo ->
+                        navigator.navigateTo(demo)
+                    },
+                )
+            }
+        }
+    }
+}
+
+private class Navigator private constructor(
+    private val backDispatcher: OnBackPressedDispatcher,
+    private val launchActivityDemo: (ActivityDemo<*>) -> Unit,
+    private val rootDemo: Demo,
+    initialDemo: Demo,
+    private val backStack: MutableList<Demo>
+) {
+    constructor(
+        rootDemo: Demo,
+        backDispatcher: OnBackPressedDispatcher,
+        launchActivityDemo: (ActivityDemo<*>) -> Unit
+    ) : this(backDispatcher, launchActivityDemo, rootDemo, rootDemo, mutableListOf<Demo>())
+
+    private val onBackPressed = object : OnBackPressedCallback(false) {
+        override fun handleOnBackPressed() {
+            popBackStack()
+        }
+    }.apply {
+        isEnabled = !isRoot
+        backDispatcher.addCallback(this)
+    }
+
+    private var _currentDemo by mutableStateOf(initialDemo)
+    var currentDemo: Demo
+        get() = _currentDemo
+        private set(value) {
+            _currentDemo = value
+            onBackPressed.isEnabled = !isRoot
+        }
+
+    val isRoot: Boolean get() = backStack.isEmpty()
+
+    val backStackTitle: String
+        get() =
+            (backStack.drop(1) + currentDemo).joinToString(separator = " > ") { it.title }
+
+    fun navigateTo(demo: Demo) {
+        if (demo is ActivityDemo<*>) {
+            launchActivityDemo(demo)
+        } else {
+            backStack.add(currentDemo)
+            currentDemo = demo
+        }
+    }
+
+    fun popAll() {
+        if (!isRoot) {
+            backStack.clear()
+            currentDemo = rootDemo
+        }
+    }
+
+    private fun popBackStack() {
+        currentDemo = backStack.removeAt(backStack.lastIndex)
+    }
+
+    companion object {
+        fun Saver(
+            rootDemo: DemoCategory,
+            backDispatcher: OnBackPressedDispatcher,
+            launchActivityDemo: (ActivityDemo<*>) -> Unit
+        ): Saver<Navigator, *> = listSaver<Navigator, String>(
+            save = { navigator ->
+                (navigator.backStack + navigator.currentDemo).map { it.title }
+            },
+            restore = { restored ->
+                require(restored.isNotEmpty())
+                val backStack = restored.mapTo(mutableListOf()) {
+                    requireNotNull(findDemo(rootDemo, it))
+                }
+                val initial = backStack.removeAt(backStack.lastIndex)
+                Navigator(backDispatcher, launchActivityDemo, rootDemo, initial, backStack)
+            }
+        )
+
+        private fun findDemo(demo: Demo, title: String): Demo? {
+            if (demo.title == title) {
+                return demo
+            }
+            if (demo is DemoCategory) {
+                demo.demos.forEach { child ->
+                    findDemo(child, title)
+                        ?.let { return it }
+                }
+            }
+            return null
+        }
+    }
+}
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/DemoApp.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/DemoApp.kt
new file mode 100644
index 0000000..4e8f1e6
--- /dev/null
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/DemoApp.kt
@@ -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.wear.compose.integration.demos
+
+import androidx.compose.animation.Crossfade
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.integration.demos.common.ActivityDemo
+import androidx.compose.integration.demos.common.ComposableDemo
+import androidx.compose.integration.demos.common.Demo
+import androidx.compose.integration.demos.common.DemoCategory
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.unit.dp
+import androidx.wear.compose.material.ChipDefaults
+import androidx.wear.compose.material.CompactChip
+import androidx.wear.compose.material.MaterialTheme
+import androidx.wear.compose.material.Text
+
+@Composable
+fun DemoApp(
+    currentDemo: Demo,
+    onNavigateToDemo: (Demo) -> Unit,
+) {
+    DemoContent(currentDemo, onNavigateToDemo)
+}
+
+@Composable
+private fun DemoContent(
+    currentDemo: Demo,
+    onNavigate: (Demo) -> Unit,
+) {
+    Crossfade(currentDemo) { demo ->
+        DisplayDemo(demo, onNavigate)
+    }
+}
+
+@Composable
+private fun DisplayDemo(demo: Demo, onNavigate: (Demo) -> Unit) {
+    when (demo) {
+        is ActivityDemo<*> -> {
+            /* should never get here as activity demos are not added to the backstack*/
+        }
+        is ComposableDemo -> demo.content()
+        is DemoCategory -> DisplayDemoList(demo, onNavigate)
+    }
+}
+
+@Composable
+private fun DisplayDemoList(category: DemoCategory, onNavigate: (Demo) -> Unit) {
+    Column(
+        horizontalAlignment = Alignment.CenterHorizontally,
+        modifier = Modifier.fillMaxWidth().verticalScroll(rememberScrollState())
+    ) {
+        Spacer(modifier = Modifier.size(16.dp))
+        Text(
+            text = category.title,
+            style = MaterialTheme.typography.caption1,
+            color = Color.White
+        )
+        Spacer(modifier = Modifier.size(4.dp))
+        category.demos.forEach { demo ->
+            CompactChip(
+                onClick = { onNavigate(demo) },
+                colors = ChipDefaults.secondaryChipColors(),
+                label = {
+                    Text(
+                        text = demo.title,
+                        modifier = Modifier.align(Alignment.CenterHorizontally)
+                    )
+                },
+                modifier = Modifier.width(100.dp)
+            )
+        }
+    }
+}
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/Demos.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/Demos.kt
new file mode 100644
index 0000000..125bb33
--- /dev/null
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/Demos.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.compose.integration.demos
+
+import androidx.compose.integration.demos.common.DemoCategory
+
+/**
+ * [DemoCategory] containing all the top level demo categories.
+ */
+val WearComposeDemos = DemoCategory(
+    "Wear Compose Demos",
+    listOf(
+        WearMaterialDemos,
+    )
+)
\ No newline at end of file
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/MaterialDemos.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/MaterialDemos.kt
new file mode 100644
index 0000000..34fedc1
--- /dev/null
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/MaterialDemos.kt
@@ -0,0 +1,27 @@
+/*
+ * 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.compose.integration.demos
+
+import androidx.compose.integration.demos.common.ComposableDemo
+import androidx.compose.integration.demos.common.DemoCategory
+
+val WearMaterialDemos = DemoCategory(
+    "Material",
+    listOf(
+        ComposableDemo("Button") { ButtonDemo() },
+    ),
+)
diff --git a/wear/compose/integration-tests/demos/src/main/res/mipmap-hdpi/ic_launcher.webp b/wear/compose/integration-tests/demos/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
--- /dev/null
+++ b/wear/compose/integration-tests/demos/src/main/res/mipmap-hdpi/ic_launcher.webp
Binary files differ
diff --git a/wear/compose/integration-tests/demos/src/main/res/mipmap-mdpi/ic_launcher.webp b/wear/compose/integration-tests/demos/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
--- /dev/null
+++ b/wear/compose/integration-tests/demos/src/main/res/mipmap-mdpi/ic_launcher.webp
Binary files differ
diff --git a/wear/compose/integration-tests/demos/src/main/res/mipmap-xhdpi/ic_launcher.webp b/wear/compose/integration-tests/demos/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
--- /dev/null
+++ b/wear/compose/integration-tests/demos/src/main/res/mipmap-xhdpi/ic_launcher.webp
Binary files differ
diff --git a/wear/compose/integration-tests/demos/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/wear/compose/integration-tests/demos/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
--- /dev/null
+++ b/wear/compose/integration-tests/demos/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Binary files differ
diff --git a/wear/compose/integration-tests/demos/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/wear/compose/integration-tests/demos/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
--- /dev/null
+++ b/wear/compose/integration-tests/demos/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Binary files differ
diff --git a/wear/compose/integration-tests/demos/src/main/res/values/strings.xml b/wear/compose/integration-tests/demos/src/main/res/values/strings.xml
new file mode 100644
index 0000000..8086034
--- /dev/null
+++ b/wear/compose/integration-tests/demos/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">Wear Compose Integration Demos</string>
+</resources>
\ No newline at end of file
diff --git a/wear/wear-complications-data/src/main/java/androidx/wear/complications/ComplicationHelperActivity.java b/wear/wear-complications-data/src/main/java/androidx/wear/complications/ComplicationHelperActivity.java
index 10b577e..1a66ba7 100644
--- a/wear/wear-complications-data/src/main/java/androidx/wear/complications/ComplicationHelperActivity.java
+++ b/wear/wear-complications-data/src/main/java/androidx/wear/complications/ComplicationHelperActivity.java
@@ -168,6 +168,7 @@
             int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
         if (grantResults.length == 0) {
             // Request was cancelled.
+            finish();
             return;
         }
         if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
diff --git a/wear/wear-watchface-client/api/current.txt b/wear/wear-watchface-client/api/current.txt
index 286846e..7a48103 100644
--- a/wear/wear-watchface-client/api/current.txt
+++ b/wear/wear-watchface-client/api/current.txt
@@ -72,7 +72,7 @@
   public interface HeadlessWatchFaceClient extends java.lang.AutoCloseable {
     method @AnyThread public void addClientDisconnectListener(androidx.wear.watchface.client.HeadlessWatchFaceClient.ClientDisconnectListener listener, java.util.concurrent.Executor executor);
     method public default static androidx.wear.watchface.client.HeadlessWatchFaceClient createFromBundle(android.os.Bundle bundle);
-    method public java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> getComplicationsSlotState();
+    method public java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> getComplicationSlotsState();
     method public long getPreviewReferenceTimeMillis();
     method public androidx.wear.watchface.style.UserStyleSchema getUserStyleSchema();
     method @AnyThread public boolean isConnectionAlive();
@@ -80,7 +80,7 @@
     method @RequiresApi(27) public android.graphics.Bitmap? renderComplicationToBitmap(int complicationSlotId, androidx.wear.watchface.RenderParameters renderParameters, long calendarTimeMillis, androidx.wear.complications.data.ComplicationData complicationData, androidx.wear.watchface.style.UserStyle? userStyle);
     method @RequiresApi(27) public android.graphics.Bitmap renderWatchFaceToBitmap(androidx.wear.watchface.RenderParameters renderParameters, long calendarTimeMillis, androidx.wear.watchface.style.UserStyle? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.complications.data.ComplicationData>? slotIdToComplicationData);
     method public android.os.Bundle toBundle();
-    property public abstract java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> complicationsSlotState;
+    property public abstract java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> complicationSlotsState;
     property public abstract long previewReferenceTimeMillis;
     property public abstract androidx.wear.watchface.style.UserStyleSchema userStyleSchema;
     field public static final String BINDER_KEY = "HeadlessWatchFaceClient";
@@ -99,7 +99,7 @@
     method @AnyThread public void addClientDisconnectListener(androidx.wear.watchface.client.InteractiveWatchFaceClient.ClientDisconnectListener listener, java.util.concurrent.Executor executor);
     method public void displayPressedAnimation(int complicationSlotId);
     method public default Integer? getComplicationIdAt(@Px int x, @Px int y);
-    method public java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> getComplicationsSlotState();
+    method public java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> getComplicationSlotsState();
     method public java.util.List<androidx.wear.watchface.ContentDescriptionLabel> getContentDescriptionLabels();
     method public String getInstanceId();
     method public long getPreviewReferenceTimeMillis();
@@ -113,7 +113,7 @@
     method public void updateComplicationData(java.util.Map<java.lang.Integer,? extends androidx.wear.complications.data.ComplicationData> slotIdToComplicationData);
     method public void updateWatchFaceInstance(String newInstanceId, androidx.wear.watchface.style.UserStyle userStyle);
     method public void updateWatchFaceInstance(String newInstanceId, androidx.wear.watchface.style.UserStyleData userStyle);
-    property public abstract java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> complicationsSlotState;
+    property public abstract java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> complicationSlotsState;
     property public abstract java.util.List<androidx.wear.watchface.ContentDescriptionLabel> contentDescriptionLabels;
     property public abstract String instanceId;
     property public abstract long previewReferenceTimeMillis;
diff --git a/wear/wear-watchface-client/api/public_plus_experimental_current.txt b/wear/wear-watchface-client/api/public_plus_experimental_current.txt
index 286846e..7a48103 100644
--- a/wear/wear-watchface-client/api/public_plus_experimental_current.txt
+++ b/wear/wear-watchface-client/api/public_plus_experimental_current.txt
@@ -72,7 +72,7 @@
   public interface HeadlessWatchFaceClient extends java.lang.AutoCloseable {
     method @AnyThread public void addClientDisconnectListener(androidx.wear.watchface.client.HeadlessWatchFaceClient.ClientDisconnectListener listener, java.util.concurrent.Executor executor);
     method public default static androidx.wear.watchface.client.HeadlessWatchFaceClient createFromBundle(android.os.Bundle bundle);
-    method public java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> getComplicationsSlotState();
+    method public java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> getComplicationSlotsState();
     method public long getPreviewReferenceTimeMillis();
     method public androidx.wear.watchface.style.UserStyleSchema getUserStyleSchema();
     method @AnyThread public boolean isConnectionAlive();
@@ -80,7 +80,7 @@
     method @RequiresApi(27) public android.graphics.Bitmap? renderComplicationToBitmap(int complicationSlotId, androidx.wear.watchface.RenderParameters renderParameters, long calendarTimeMillis, androidx.wear.complications.data.ComplicationData complicationData, androidx.wear.watchface.style.UserStyle? userStyle);
     method @RequiresApi(27) public android.graphics.Bitmap renderWatchFaceToBitmap(androidx.wear.watchface.RenderParameters renderParameters, long calendarTimeMillis, androidx.wear.watchface.style.UserStyle? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.complications.data.ComplicationData>? slotIdToComplicationData);
     method public android.os.Bundle toBundle();
-    property public abstract java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> complicationsSlotState;
+    property public abstract java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> complicationSlotsState;
     property public abstract long previewReferenceTimeMillis;
     property public abstract androidx.wear.watchface.style.UserStyleSchema userStyleSchema;
     field public static final String BINDER_KEY = "HeadlessWatchFaceClient";
@@ -99,7 +99,7 @@
     method @AnyThread public void addClientDisconnectListener(androidx.wear.watchface.client.InteractiveWatchFaceClient.ClientDisconnectListener listener, java.util.concurrent.Executor executor);
     method public void displayPressedAnimation(int complicationSlotId);
     method public default Integer? getComplicationIdAt(@Px int x, @Px int y);
-    method public java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> getComplicationsSlotState();
+    method public java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> getComplicationSlotsState();
     method public java.util.List<androidx.wear.watchface.ContentDescriptionLabel> getContentDescriptionLabels();
     method public String getInstanceId();
     method public long getPreviewReferenceTimeMillis();
@@ -113,7 +113,7 @@
     method public void updateComplicationData(java.util.Map<java.lang.Integer,? extends androidx.wear.complications.data.ComplicationData> slotIdToComplicationData);
     method public void updateWatchFaceInstance(String newInstanceId, androidx.wear.watchface.style.UserStyle userStyle);
     method public void updateWatchFaceInstance(String newInstanceId, androidx.wear.watchface.style.UserStyleData userStyle);
-    property public abstract java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> complicationsSlotState;
+    property public abstract java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> complicationSlotsState;
     property public abstract java.util.List<androidx.wear.watchface.ContentDescriptionLabel> contentDescriptionLabels;
     property public abstract String instanceId;
     property public abstract long previewReferenceTimeMillis;
diff --git a/wear/wear-watchface-client/api/restricted_current.txt b/wear/wear-watchface-client/api/restricted_current.txt
index 4600381..056d19d 100644
--- a/wear/wear-watchface-client/api/restricted_current.txt
+++ b/wear/wear-watchface-client/api/restricted_current.txt
@@ -74,7 +74,7 @@
   public interface HeadlessWatchFaceClient extends java.lang.AutoCloseable {
     method @AnyThread public void addClientDisconnectListener(androidx.wear.watchface.client.HeadlessWatchFaceClient.ClientDisconnectListener listener, java.util.concurrent.Executor executor);
     method public default static androidx.wear.watchface.client.HeadlessWatchFaceClient createFromBundle(android.os.Bundle bundle);
-    method public java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> getComplicationsSlotState();
+    method public java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> getComplicationSlotsState();
     method public long getPreviewReferenceTimeMillis();
     method public androidx.wear.watchface.style.UserStyleSchema getUserStyleSchema();
     method @AnyThread public boolean isConnectionAlive();
@@ -82,7 +82,7 @@
     method @RequiresApi(27) public android.graphics.Bitmap? renderComplicationToBitmap(int complicationSlotId, androidx.wear.watchface.RenderParameters renderParameters, long calendarTimeMillis, androidx.wear.complications.data.ComplicationData complicationData, androidx.wear.watchface.style.UserStyle? userStyle);
     method @RequiresApi(27) public android.graphics.Bitmap renderWatchFaceToBitmap(androidx.wear.watchface.RenderParameters renderParameters, long calendarTimeMillis, androidx.wear.watchface.style.UserStyle? userStyle, java.util.Map<java.lang.Integer,? extends androidx.wear.complications.data.ComplicationData>? slotIdToComplicationData);
     method public android.os.Bundle toBundle();
-    property public abstract java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> complicationsSlotState;
+    property public abstract java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> complicationSlotsState;
     property public abstract long previewReferenceTimeMillis;
     property public abstract androidx.wear.watchface.style.UserStyleSchema userStyleSchema;
     field public static final String BINDER_KEY = "HeadlessWatchFaceClient";
@@ -101,7 +101,7 @@
     method @AnyThread public void addClientDisconnectListener(androidx.wear.watchface.client.InteractiveWatchFaceClient.ClientDisconnectListener listener, java.util.concurrent.Executor executor);
     method public void displayPressedAnimation(int complicationSlotId);
     method public default Integer? getComplicationIdAt(@Px int x, @Px int y);
-    method public java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> getComplicationsSlotState();
+    method public java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> getComplicationSlotsState();
     method public java.util.List<androidx.wear.watchface.ContentDescriptionLabel> getContentDescriptionLabels();
     method public String getInstanceId();
     method public long getPreviewReferenceTimeMillis();
@@ -115,7 +115,7 @@
     method public void updateComplicationData(java.util.Map<java.lang.Integer,? extends androidx.wear.complications.data.ComplicationData> slotIdToComplicationData);
     method public void updateWatchFaceInstance(String newInstanceId, androidx.wear.watchface.style.UserStyle userStyle);
     method public void updateWatchFaceInstance(String newInstanceId, androidx.wear.watchface.style.UserStyleData userStyle);
-    property public abstract java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> complicationsSlotState;
+    property public abstract java.util.Map<java.lang.Integer,androidx.wear.watchface.client.ComplicationSlotState> complicationSlotsState;
     property public abstract java.util.List<androidx.wear.watchface.ContentDescriptionLabel> contentDescriptionLabels;
     property public abstract String instanceId;
     property public abstract long previewReferenceTimeMillis;
diff --git a/wear/wear-watchface-client/src/androidTest/java/androidx/wear/watchface/client/test/WatchFaceControlClientTest.kt b/wear/wear-watchface-client/src/androidTest/java/androidx/wear/watchface/client/test/WatchFaceControlClientTest.kt
index cba4daf..87c4eab 100644
--- a/wear/wear-watchface-client/src/androidTest/java/androidx/wear/watchface/client/test/WatchFaceControlClientTest.kt
+++ b/wear/wear-watchface-client/src/androidTest/java/androidx/wear/watchface/client/test/WatchFaceControlClientTest.kt
@@ -304,9 +304,9 @@
             400
         )!!
 
-        assertThat(headlessInstance.complicationsSlotState.size).isEqualTo(2)
+        assertThat(headlessInstance.complicationSlotsState.size).isEqualTo(2)
 
-        val leftComplicationDetails = headlessInstance.complicationsSlotState[
+        val leftComplicationDetails = headlessInstance.complicationSlotsState[
             EXAMPLE_CANVAS_WATCHFACE_LEFT_COMPLICATION_ID
         ]!!
         assertThat(leftComplicationDetails.bounds).isEqualTo(Rect(80, 160, 160, 240))
@@ -327,7 +327,7 @@
         )
         assertTrue(leftComplicationDetails.isEnabled)
 
-        val rightComplicationDetails = headlessInstance.complicationsSlotState[
+        val rightComplicationDetails = headlessInstance.complicationSlotsState[
             EXAMPLE_CANVAS_WATCHFACE_RIGHT_COMPLICATION_ID
         ]!!
         assertThat(rightComplicationDetails.bounds).isEqualTo(Rect(240, 160, 320, 240))
@@ -501,9 +501,9 @@
             )
         )
 
-        assertThat(interactiveInstance.complicationsSlotState.size).isEqualTo(2)
+        assertThat(interactiveInstance.complicationSlotsState.size).isEqualTo(2)
 
-        val leftComplicationDetails = interactiveInstance.complicationsSlotState[
+        val leftComplicationDetails = interactiveInstance.complicationSlotsState[
             EXAMPLE_CANVAS_WATCHFACE_LEFT_COMPLICATION_ID
         ]!!
         assertThat(leftComplicationDetails.bounds).isEqualTo(Rect(80, 160, 160, 240))
@@ -527,7 +527,7 @@
             ComplicationType.SHORT_TEXT
         )
 
-        val rightComplicationDetails = interactiveInstance.complicationsSlotState[
+        val rightComplicationDetails = interactiveInstance.complicationSlotsState[
             EXAMPLE_CANVAS_WATCHFACE_RIGHT_COMPLICATION_ID
         ]!!
         assertThat(rightComplicationDetails.bounds).isEqualTo(Rect(240, 160, 320, 240))
@@ -689,7 +689,7 @@
         // We need to wait for watch face init to have completed before lateinit
         // wallpaperService.watchFace will be assigned. To do this we issue an arbitrary API
         // call which by necessity awaits full initialization.
-        interactiveInstance.complicationsSlotState
+        interactiveInstance.complicationSlotsState
 
         // Add some additional ContentDescriptionLabels
         wallpaperService.watchFace.renderer.additionalContentDescriptionLabels = listOf(
@@ -785,10 +785,10 @@
         assertThat(interactiveInstance.instanceId).isEqualTo("testId2")
 
         // The complicationSlots should have been cleared.
-        val leftComplication = interactiveInstance.complicationsSlotState[
+        val leftComplication = interactiveInstance.complicationSlotsState[
             EXAMPLE_CANVAS_WATCHFACE_LEFT_COMPLICATION_ID
         ]!!
-        val rightComplication = interactiveInstance.complicationsSlotState[
+        val rightComplication = interactiveInstance.complicationSlotsState[
             EXAMPLE_CANVAS_WATCHFACE_RIGHT_COMPLICATION_ID
         ]!!
         assertThat(leftComplication.currentType).isEqualTo(ComplicationType.NO_DATA)
@@ -867,7 +867,7 @@
 
         try {
             // The first call on the interface should report the crash.
-            awaitWithTimeout(client).complicationsSlotState
+            awaitWithTimeout(client).complicationSlotsState
             fail("Expected an exception to be thrown because the watchface crashed on init")
         } catch (e: Exception) {
             assertThat(e.toString()).contains("Deliberately crashing")
@@ -978,7 +978,7 @@
     ): ComplicationSlotsManager {
         return ComplicationSlotsManager(
             listOf(
-                ComplicationSlot.createRoundRectComplicationBuilder(
+                ComplicationSlot.createRoundRectComplicationSlotBuilder(
                     COMPLICATION_ID,
                     { _, _ -> throw Exception("Deliberately crashing") },
                     listOf(ComplicationType.LONG_TEXT),
diff --git a/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/HeadlessWatchFaceClient.kt b/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/HeadlessWatchFaceClient.kt
index 10bb17a..6ab859e 100644
--- a/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/HeadlessWatchFaceClient.kt
+++ b/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/HeadlessWatchFaceClient.kt
@@ -67,7 +67,7 @@
      * [ComplicationSlotsUserStyleSetting]. Because the style can't change, ComplicationSlotState is
      * immutable for a headless watch face.
      */
-    public val complicationsSlotState: Map<Int, ComplicationSlotState>
+    public val complicationSlotsState: Map<Int, ComplicationSlotState>
 
     /**
      * Renders the watchface to a shared memory backed [Bitmap] with the given settings.
@@ -170,7 +170,7 @@
     override val userStyleSchema: UserStyleSchema
         get() = UserStyleSchema(iHeadlessWatchFace.userStyleSchema)
 
-    override val complicationsSlotState: Map<Int, ComplicationSlotState>
+    override val complicationSlotsState: Map<Int, ComplicationSlotState>
         get() = iHeadlessWatchFace.complicationState.associateBy(
             { it.id },
             { ComplicationSlotState(it.complicationState) }
diff --git a/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/InteractiveWatchFaceClient.kt b/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/InteractiveWatchFaceClient.kt
index 7e341e1..f3594f2 100644
--- a/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/InteractiveWatchFaceClient.kt
+++ b/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/InteractiveWatchFaceClient.kt
@@ -110,7 +110,7 @@
      * [ComplicationSlotsUserStyleSetting]. As a consequence ComplicationSlotState may update based
      * on style changes.
      */
-    public val complicationsSlotState: Map<Int, ComplicationSlotState>
+    public val complicationSlotsState: Map<Int, ComplicationSlotState>
 
     /**
      * Returns the ID of the [androidx.wear.watchface.ComplicationSlot] at the given coordinates or
@@ -118,7 +118,7 @@
      */
     @SuppressWarnings("AutoBoxing")
     public fun getComplicationIdAt(@Px x: Int, @Px y: Int): Int? =
-        complicationsSlotState.asSequence().firstOrNull {
+        complicationSlotsState.asSequence().firstOrNull {
             it.value.isEnabled && when (it.value.boundsType) {
                 ComplicationSlotBoundsType.ROUND_RECT -> it.value.bounds.contains(x, y)
                 ComplicationSlotBoundsType.BACKGROUND -> false
@@ -281,7 +281,7 @@
     override val userStyleSchema: UserStyleSchema
         get() = UserStyleSchema(iInteractiveWatchFace.userStyleSchema)
 
-    override val complicationsSlotState: Map<Int, ComplicationSlotState>
+    override val complicationSlotsState: Map<Int, ComplicationSlotState>
         get() = iInteractiveWatchFace.complicationDetails.associateBy(
             { it.id },
             { ComplicationSlotState(it.complicationState) }
diff --git a/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/WatchFaceControlClient.kt b/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/WatchFaceControlClient.kt
index ae1e00b..c95610e 100644
--- a/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/WatchFaceControlClient.kt
+++ b/wear/wear-watchface-client/src/main/java/androidx/wear/watchface/client/WatchFaceControlClient.kt
@@ -385,7 +385,7 @@
 
             // NB .use {} syntax doesn't compile here.
             try {
-                headlessClient.complicationsSlotState.mapValues {
+                headlessClient.complicationSlotsState.mapValues {
                     DefaultComplicationProviderPolicyAndType(
                         it.value.defaultProviderPolicy,
                         it.value.defaultProviderType
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 7e4fb70..9657d08 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
@@ -321,7 +321,7 @@
         mockInvalidateCallback
     )
     private val leftComplication =
-        ComplicationSlot.createRoundRectComplicationBuilder(
+        ComplicationSlot.createRoundRectComplicationSlotBuilder(
             LEFT_COMPLICATION_ID,
             { _, _ -> mockLeftCanvasComplication },
             listOf(
@@ -342,7 +342,7 @@
         mockInvalidateCallback
     )
     private val rightComplication =
-        ComplicationSlot.createRoundRectComplicationBuilder(
+        ComplicationSlot.createRoundRectComplicationSlotBuilder(
             RIGHT_COMPLICATION_ID,
             { _, _ -> mockRightCanvasComplication },
             listOf(
@@ -369,7 +369,7 @@
             mockInvalidateCallback
         )
     private val backgroundComplication =
-        ComplicationSlot.createBackgroundComplicationBuilder(
+        ComplicationSlot.createBackgroundComplicationSlotBuilder(
             BACKGROUND_COMPLICATION_ID,
             { _, _ -> mockBackgroundCanvasComplication },
             emptyList(),
@@ -624,7 +624,7 @@
                 mockInvalidateCallback
             )
         val fixedLeftComplication =
-            ComplicationSlot.createRoundRectComplicationBuilder(
+            ComplicationSlot.createRoundRectComplicationSlotBuilder(
                 LEFT_COMPLICATION_ID,
                 { _, _ -> mockLeftCanvasComplication },
                 listOf(
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 b37a4ef..ec2cdf6 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
@@ -73,7 +73,7 @@
             mockInvalidateCallback
         )
     private val leftComplication =
-        ComplicationSlot.createRoundRectComplicationBuilder(
+        ComplicationSlot.createRoundRectComplicationSlotBuilder(
             LEFT_COMPLICATION_ID,
             { _, _, -> mockLeftCanvasComplication },
             listOf(
@@ -95,7 +95,7 @@
             mockInvalidateCallback
         )
     private val rightComplication =
-        ComplicationSlot.createRoundRectComplicationBuilder(
+        ComplicationSlot.createRoundRectComplicationSlotBuilder(
             RIGHT_COMPLICATION_ID,
             { _, _, -> mockRightCanvasComplication },
             listOf(
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 00766da..d7863a8 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
@@ -738,7 +738,7 @@
 
     override val previewReferenceTimeMillis = headlessWatchFaceClient.previewReferenceTimeMillis
 
-    override val complicationSlotsState = headlessWatchFaceClient.complicationsSlotState
+    override val complicationSlotsState = headlessWatchFaceClient.complicationSlotsState
 
     override fun renderWatchFaceToBitmap(
         renderParameters: RenderParameters,
diff --git a/wear/wear-watchface/api/current.txt b/wear/wear-watchface/api/current.txt
index cb50825..e0ea586 100644
--- a/wear/wear-watchface/api/current.txt
+++ b/wear/wear-watchface/api/current.txt
@@ -27,9 +27,9 @@
 
   public final class ComplicationSlot {
     method public android.graphics.Rect computeBounds(android.graphics.Rect screen);
-    method public static androidx.wear.watchface.ComplicationSlot.Builder createBackgroundComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy);
-    method public static androidx.wear.watchface.ComplicationSlot.Builder createEdgeComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds, androidx.wear.watchface.ComplicationTapFilter complicationTapFilter);
-    method public static androidx.wear.watchface.ComplicationSlot.Builder createRoundRectComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds);
+    method public static androidx.wear.watchface.ComplicationSlot.Builder createBackgroundComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy);
+    method public static androidx.wear.watchface.ComplicationSlot.Builder createEdgeComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds, androidx.wear.watchface.ComplicationTapFilter complicationTapFilter);
+    method public static androidx.wear.watchface.ComplicationSlot.Builder createRoundRectComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds);
     method @UiThread public int getAccessibilityTraversalIndex();
     method public int getBoundsType();
     method public androidx.wear.watchface.CanvasComplicationFactory getCanvasComplicationFactory();
@@ -76,9 +76,9 @@
   }
 
   public static final class ComplicationSlot.Companion {
-    method public androidx.wear.watchface.ComplicationSlot.Builder createBackgroundComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy);
-    method public androidx.wear.watchface.ComplicationSlot.Builder createEdgeComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds, androidx.wear.watchface.ComplicationTapFilter complicationTapFilter);
-    method public androidx.wear.watchface.ComplicationSlot.Builder createRoundRectComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds);
+    method public androidx.wear.watchface.ComplicationSlot.Builder createBackgroundComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy);
+    method public androidx.wear.watchface.ComplicationSlot.Builder createEdgeComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds, androidx.wear.watchface.ComplicationTapFilter complicationTapFilter);
+    method public androidx.wear.watchface.ComplicationSlot.Builder createRoundRectComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds);
   }
 
   public final class ComplicationSlotsManager {
diff --git a/wear/wear-watchface/api/public_plus_experimental_current.txt b/wear/wear-watchface/api/public_plus_experimental_current.txt
index cb50825..e0ea586 100644
--- a/wear/wear-watchface/api/public_plus_experimental_current.txt
+++ b/wear/wear-watchface/api/public_plus_experimental_current.txt
@@ -27,9 +27,9 @@
 
   public final class ComplicationSlot {
     method public android.graphics.Rect computeBounds(android.graphics.Rect screen);
-    method public static androidx.wear.watchface.ComplicationSlot.Builder createBackgroundComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy);
-    method public static androidx.wear.watchface.ComplicationSlot.Builder createEdgeComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds, androidx.wear.watchface.ComplicationTapFilter complicationTapFilter);
-    method public static androidx.wear.watchface.ComplicationSlot.Builder createRoundRectComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds);
+    method public static androidx.wear.watchface.ComplicationSlot.Builder createBackgroundComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy);
+    method public static androidx.wear.watchface.ComplicationSlot.Builder createEdgeComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds, androidx.wear.watchface.ComplicationTapFilter complicationTapFilter);
+    method public static androidx.wear.watchface.ComplicationSlot.Builder createRoundRectComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds);
     method @UiThread public int getAccessibilityTraversalIndex();
     method public int getBoundsType();
     method public androidx.wear.watchface.CanvasComplicationFactory getCanvasComplicationFactory();
@@ -76,9 +76,9 @@
   }
 
   public static final class ComplicationSlot.Companion {
-    method public androidx.wear.watchface.ComplicationSlot.Builder createBackgroundComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy);
-    method public androidx.wear.watchface.ComplicationSlot.Builder createEdgeComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds, androidx.wear.watchface.ComplicationTapFilter complicationTapFilter);
-    method public androidx.wear.watchface.ComplicationSlot.Builder createRoundRectComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds);
+    method public androidx.wear.watchface.ComplicationSlot.Builder createBackgroundComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy);
+    method public androidx.wear.watchface.ComplicationSlot.Builder createEdgeComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds, androidx.wear.watchface.ComplicationTapFilter complicationTapFilter);
+    method public androidx.wear.watchface.ComplicationSlot.Builder createRoundRectComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds);
   }
 
   public final class ComplicationSlotsManager {
diff --git a/wear/wear-watchface/api/restricted_current.txt b/wear/wear-watchface/api/restricted_current.txt
index bc6df21..43dc248 100644
--- a/wear/wear-watchface/api/restricted_current.txt
+++ b/wear/wear-watchface/api/restricted_current.txt
@@ -53,9 +53,9 @@
 
   public final class ComplicationSlot {
     method public android.graphics.Rect computeBounds(android.graphics.Rect screen);
-    method public static androidx.wear.watchface.ComplicationSlot.Builder createBackgroundComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy);
-    method public static androidx.wear.watchface.ComplicationSlot.Builder createEdgeComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds, androidx.wear.watchface.ComplicationTapFilter complicationTapFilter);
-    method public static androidx.wear.watchface.ComplicationSlot.Builder createRoundRectComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds);
+    method public static androidx.wear.watchface.ComplicationSlot.Builder createBackgroundComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy);
+    method public static androidx.wear.watchface.ComplicationSlot.Builder createEdgeComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds, androidx.wear.watchface.ComplicationTapFilter complicationTapFilter);
+    method public static androidx.wear.watchface.ComplicationSlot.Builder createRoundRectComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds);
     method @UiThread public int getAccessibilityTraversalIndex();
     method public int getBoundsType();
     method public androidx.wear.watchface.CanvasComplicationFactory getCanvasComplicationFactory();
@@ -102,9 +102,9 @@
   }
 
   public static final class ComplicationSlot.Companion {
-    method public androidx.wear.watchface.ComplicationSlot.Builder createBackgroundComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy);
-    method public androidx.wear.watchface.ComplicationSlot.Builder createEdgeComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds, androidx.wear.watchface.ComplicationTapFilter complicationTapFilter);
-    method public androidx.wear.watchface.ComplicationSlot.Builder createRoundRectComplicationBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds);
+    method public androidx.wear.watchface.ComplicationSlot.Builder createBackgroundComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy);
+    method public androidx.wear.watchface.ComplicationSlot.Builder createEdgeComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds, androidx.wear.watchface.ComplicationTapFilter complicationTapFilter);
+    method public androidx.wear.watchface.ComplicationSlot.Builder createRoundRectComplicationSlotBuilder(int id, androidx.wear.watchface.CanvasComplicationFactory canvasComplicationFactory, java.util.List<? extends androidx.wear.complications.data.ComplicationType> supportedTypes, androidx.wear.complications.DefaultComplicationProviderPolicy defaultProviderPolicy, androidx.wear.complications.ComplicationSlotBounds bounds);
   }
 
   public final class ComplicationSlotsManager {
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 edcf7f8..a1240d2 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
@@ -231,7 +231,7 @@
                     listener
                 )
             }
-        val leftComplication = ComplicationSlot.createRoundRectComplicationBuilder(
+        val leftComplication = ComplicationSlot.createRoundRectComplicationSlotBuilder(
             EXAMPLE_CANVAS_WATCHFACE_LEFT_COMPLICATION_ID,
             canvasComplicationFactory,
             listOf(
@@ -245,7 +245,7 @@
             ComplicationSlotBounds(RectF(0.2f, 0.4f, 0.4f, 0.6f))
         ).setDefaultProviderType(ComplicationType.SHORT_TEXT)
             .build()
-        val rightComplication = ComplicationSlot.createRoundRectComplicationBuilder(
+        val rightComplication = ComplicationSlot.createRoundRectComplicationSlotBuilder(
             EXAMPLE_CANVAS_WATCHFACE_RIGHT_COMPLICATION_ID,
             canvasComplicationFactory,
             listOf(
diff --git a/wear/wear-watchface/samples/src/main/java/androidx/wear/watchface/samples/ExampleCanvasDigitalWatchFaceService.kt b/wear/wear-watchface/samples/src/main/java/androidx/wear/watchface/samples/ExampleCanvasDigitalWatchFaceService.kt
index a9367ed..2725dfb 100644
--- a/wear/wear-watchface/samples/src/main/java/androidx/wear/watchface/samples/ExampleCanvasDigitalWatchFaceService.kt
+++ b/wear/wear-watchface/samples/src/main/java/androidx/wear/watchface/samples/ExampleCanvasDigitalWatchFaceService.kt
@@ -509,7 +509,7 @@
             )
         }
 
-    private val leftComplication = ComplicationSlot.createRoundRectComplicationBuilder(
+    private val leftComplication = ComplicationSlot.createRoundRectComplicationSlotBuilder(
         ComplicationID.LEFT.ordinal,
         canvasComplicationFactory,
         listOf(
@@ -528,7 +528,7 @@
     ).setDefaultProviderType(ComplicationType.SHORT_TEXT)
         .build()
 
-    private val rightComplication = ComplicationSlot.createRoundRectComplicationBuilder(
+    private val rightComplication = ComplicationSlot.createRoundRectComplicationSlotBuilder(
         ComplicationID.RIGHT.ordinal,
         canvasComplicationFactory,
         listOf(
@@ -555,7 +555,7 @@
         ComplicationType.SMALL_IMAGE
     )
     // The upper and lower complicationSlots change shape depending on the complication's type.
-    private val upperComplication = ComplicationSlot.createRoundRectComplicationBuilder(
+    private val upperComplication = ComplicationSlot.createRoundRectComplicationSlotBuilder(
         ComplicationID.UPPER.ordinal,
         canvasComplicationFactory,
         upperAndLowerComplicationTypes,
@@ -578,7 +578,7 @@
     ).setDefaultProviderType(ComplicationType.LONG_TEXT)
         .build()
 
-    private val lowerComplication = ComplicationSlot.createRoundRectComplicationBuilder(
+    private val lowerComplication = ComplicationSlot.createRoundRectComplicationSlotBuilder(
         ComplicationID.LOWER.ordinal,
         canvasComplicationFactory,
         upperAndLowerComplicationTypes,
@@ -601,7 +601,7 @@
     ).setDefaultProviderType(ComplicationType.LONG_TEXT)
         .build()
 
-    private val backgroundComplication = ComplicationSlot.createBackgroundComplicationBuilder(
+    private val backgroundComplication = ComplicationSlot.createBackgroundComplicationSlotBuilder(
         ComplicationID.BACKGROUND.ordinal,
         canvasComplicationFactory,
         listOf(ComplicationType.PHOTO_IMAGE),
diff --git a/wear/wear-watchface/samples/src/main/java/androidx/wear/watchface/samples/ExampleOpenGLWatchFaceService.kt b/wear/wear-watchface/samples/src/main/java/androidx/wear/watchface/samples/ExampleOpenGLWatchFaceService.kt
index 0c3adf8..e131161 100644
--- a/wear/wear-watchface/samples/src/main/java/androidx/wear/watchface/samples/ExampleOpenGLWatchFaceService.kt
+++ b/wear/wear-watchface/samples/src/main/java/androidx/wear/watchface/samples/ExampleOpenGLWatchFaceService.kt
@@ -105,7 +105,7 @@
         )
     }
 
-    private val complication = ComplicationSlot.createRoundRectComplicationBuilder(
+    private val complication = ComplicationSlot.createRoundRectComplicationSlotBuilder(
         EXAMPLE_OPENGL_COMPLICATION_ID,
         { watchState, listener ->
             CanvasComplicationDrawable(
diff --git a/wear/wear-watchface/samples/src/main/java/androidx/wear/watchface/samples/KDocExampleWatchFace.kt b/wear/wear-watchface/samples/src/main/java/androidx/wear/watchface/samples/KDocExampleWatchFace.kt
index 11928a5..255993a 100644
--- a/wear/wear-watchface/samples/src/main/java/androidx/wear/watchface/samples/KDocExampleWatchFace.kt
+++ b/wear/wear-watchface/samples/src/main/java/androidx/wear/watchface/samples/KDocExampleWatchFace.kt
@@ -113,7 +113,7 @@
                 }
             return ComplicationSlotsManager(
                 listOf(
-                    ComplicationSlot.createRoundRectComplicationBuilder(
+                    ComplicationSlot.createRoundRectComplicationSlotBuilder(
                         /*id */ 0,
                         canvasComplicationFactory,
                         listOf(
@@ -127,7 +127,7 @@
                         ComplicationSlotBounds(RectF(0.15625f, 0.1875f, 0.84375f, 0.3125f))
                     ).setDefaultProviderType(ComplicationType.SHORT_TEXT)
                         .build(),
-                    ComplicationSlot.createRoundRectComplicationBuilder(
+                    ComplicationSlot.createRoundRectComplicationSlotBuilder(
                         /*id */ 1,
                         canvasComplicationFactory,
                         listOf(
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/ComplicationSlot.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/ComplicationSlot.kt
index 3b85ee5..188bd5f 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/ComplicationSlot.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/ComplicationSlot.kt
@@ -256,7 +256,7 @@
          * @param bounds The complication's [ComplicationSlotBounds].
          */
         @JvmStatic
-        public fun createRoundRectComplicationBuilder(
+        public fun createRoundRectComplicationSlotBuilder(
             id: Int,
             canvasComplicationFactory: CanvasComplicationFactory,
             supportedTypes: List<ComplicationType>,
@@ -290,7 +290,7 @@
          * the initial complication provider when the watch is first installed.
          */
         @JvmStatic
-        public fun createBackgroundComplicationBuilder(
+        public fun createBackgroundComplicationSlotBuilder(
             id: Int,
             canvasComplicationFactory: CanvasComplicationFactory,
             supportedTypes: List<ComplicationType>,
@@ -331,7 +331,7 @@
          * not a tap hit the complication.
          */
         @JvmStatic
-        public fun createEdgeComplicationBuilder(
+        public fun createEdgeComplicationSlotBuilder(
             id: Int,
             canvasComplicationFactory: CanvasComplicationFactory,
             supportedTypes: List<ComplicationType>,
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/ComplicationSlotsManager.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/ComplicationSlotsManager.kt
index 6e3b513..0e42149 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/ComplicationSlotsManager.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/ComplicationSlotsManager.kt
@@ -142,7 +142,7 @@
                             userStyle[complicationsStyleCategory]!! as ComplicationSlotsOption
                         if (previousOption != newlySelectedOption) {
                             previousOption = newlySelectedOption
-                            applyComplicationsSlotStyleCategoryOption(newlySelectedOption)
+                            applyComplicationSlotsStyleCategoryOption(newlySelectedOption)
                         }
                     }
                 }
@@ -177,7 +177,7 @@
         onComplicationsUpdated()
     }
 
-    internal fun applyComplicationsSlotStyleCategoryOption(styleOption: ComplicationSlotsOption) {
+    internal fun applyComplicationSlotsStyleCategoryOption(styleOption: ComplicationSlotsOption) {
         for ((id, complication) in complicationSlots) {
             val override = styleOption.complicationSlotOverlays.find { it.complicationSlotId == id }
             val initialConfig = initialComplicationConfigs[id]!!
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 b40aa58..5ab8463 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
@@ -666,7 +666,7 @@
         }
     }
 
-    private class RendererAndComplicationsSlotManager(
+    private class RendererAndComplicationSlotsManager(
         val renderer: Renderer,
         val complicationSlotsManager: ComplicationSlotsManager
     )
@@ -693,7 +693,7 @@
          * [deferredRendererAndComplicationManager] will complete before [deferredWatchFaceImpl].
          */
         private var deferredRendererAndComplicationManager =
-            CompletableDeferred<RendererAndComplicationsSlotManager>()
+            CompletableDeferred<RendererAndComplicationSlotsManager>()
 
         /**
          * [deferredWatchFaceImpl] will complete after [deferredRendererAndComplicationManager].
@@ -1351,7 +1351,7 @@
                         )
                     }
                     deferredRendererAndComplicationManager.complete(
-                        RendererAndComplicationsSlotManager(
+                        RendererAndComplicationSlotsManager(
                             watchFace.renderer,
                             complicationSlotsManager
                         )
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 d79e267..ba314ad 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
@@ -169,7 +169,7 @@
         ListUserStyleSetting.ListOption(Option.Id("bad_option"), "Bad", icon = null)
 
     private val leftComplication =
-        ComplicationSlot.createRoundRectComplicationBuilder(
+        ComplicationSlot.createRoundRectComplicationSlotBuilder(
             LEFT_COMPLICATION_ID,
             { watchState, listener ->
                 CanvasComplicationDrawable(
@@ -191,7 +191,7 @@
             .build()
 
     private val rightComplication =
-        ComplicationSlot.createRoundRectComplicationBuilder(
+        ComplicationSlot.createRoundRectComplicationSlotBuilder(
             RIGHT_COMPLICATION_ID,
             { watchState, listener ->
                 CanvasComplicationDrawable(
@@ -214,7 +214,7 @@
 
     private val edgeComplicationHitTester = mock<ComplicationTapFilter>()
     private val edgeComplication =
-        ComplicationSlot.createEdgeComplicationBuilder(
+        ComplicationSlot.createEdgeComplicationSlotBuilder(
             EDGE_COMPLICATION_ID,
             { watchState, listener ->
                 CanvasComplicationDrawable(
@@ -237,7 +237,7 @@
             .build()
 
     private val backgroundComplication =
-        ComplicationSlot.createBackgroundComplicationBuilder(
+        ComplicationSlot.createBackgroundComplicationSlotBuilder(
             BACKGROUND_COMPLICATION_ID,
             { watchState, listener ->
                 CanvasComplicationDrawable(
@@ -1535,7 +1535,7 @@
     public fun defaultProvidersWithFallbacks_newApi() {
         val provider1 = ComponentName("com.app1", "com.app1.App1")
         val provider2 = ComponentName("com.app2", "com.app2.App2")
-        val complication = ComplicationSlot.createRoundRectComplicationBuilder(
+        val complication = ComplicationSlot.createRoundRectComplicationSlotBuilder(
             LEFT_COMPLICATION_ID,
             { watchState, listener ->
                 CanvasComplicationDrawable(complicationDrawableLeft, watchState, listener)
@@ -1565,7 +1565,7 @@
     public fun defaultProvidersWithFallbacks_oldApi() {
         val provider1 = ComponentName("com.app1", "com.app1.App1")
         val provider2 = ComponentName("com.app2", "com.app2.App2")
-        val complication = ComplicationSlot.createRoundRectComplicationBuilder(
+        val complication = ComplicationSlot.createRoundRectComplicationSlotBuilder(
             LEFT_COMPLICATION_ID,
             { watchState, listener ->
                 CanvasComplicationDrawable(complicationDrawableLeft, watchState, listener)
@@ -1958,7 +1958,7 @@
 
         val manager = ComplicationSlotsManager(
             listOf(
-                ComplicationSlot.createRoundRectComplicationBuilder(
+                ComplicationSlot.createRoundRectComplicationSlotBuilder(
                     complicationSlotId1,
                     { watchState, listener ->
                         CanvasComplicationDrawable(complicationDrawableLeft, watchState, listener)
@@ -1972,7 +1972,7 @@
                     .setEnabled(false)
                     .build(),
 
-                ComplicationSlot.createRoundRectComplicationBuilder(
+                ComplicationSlot.createRoundRectComplicationSlotBuilder(
                     complicationSlotId2,
                     { watchState, listener ->
                         CanvasComplicationDrawable(complicationDrawableRight, watchState, listener)
@@ -2582,7 +2582,7 @@
     public fun canvasComplication_onRendererCreated() {
         val leftCanvasComplication = mock<CanvasComplication>()
         val leftComplication =
-            ComplicationSlot.createRoundRectComplicationBuilder(
+            ComplicationSlot.createRoundRectComplicationSlotBuilder(
                 LEFT_COMPLICATION_ID,
                 { _, _ -> leftCanvasComplication },
                 listOf(
@@ -2595,7 +2595,7 @@
 
         val rightCanvasComplication = mock<CanvasComplication>()
         val rightComplication =
-            ComplicationSlot.createRoundRectComplicationBuilder(
+            ComplicationSlot.createRoundRectComplicationSlotBuilder(
                 RIGHT_COMPLICATION_ID,
                 { _, _ -> rightCanvasComplication },
                 listOf(
diff --git a/webkit/webkit/src/androidTest/java/androidx/webkit/WebSettingsCompatForceDarkTest.java b/webkit/webkit/src/androidTest/java/androidx/webkit/WebSettingsCompatForceDarkTest.java
index 6975136..f278ef0 100644
--- a/webkit/webkit/src/androidTest/java/androidx/webkit/WebSettingsCompatForceDarkTest.java
+++ b/webkit/webkit/src/androidTest/java/androidx/webkit/WebSettingsCompatForceDarkTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import android.graphics.Bitmap;
@@ -238,14 +239,19 @@
     // Requires {@link WebViewFeature.OFF_SCREEN_PRERASTER} for {@link
     // WebViewOnUiThread#captureBitmap}.
     private int getWebPageColor() {
-        Map<Integer, Integer> histogram;
-        Integer[] colourValues;
-
-        histogram = getBitmapHistogram(mWebViewOnUiThread.captureBitmap(), 0, 0, 64, 64);
-        assertEquals("Bitmap should have a single colour", 1, histogram.size());
-        colourValues = histogram.keySet().toArray(new Integer[0]);
-
-        return colourValues[0];
+        Map<Integer, Integer> histogram =
+                getBitmapHistogram(mWebViewOnUiThread.captureBitmap(), 0, 0, 64, 64);
+        Map.Entry<Integer, Integer> maxEntry = null;
+        for (Map.Entry<Integer, Integer> entry : histogram.entrySet()) {
+            if (maxEntry == null || entry.getValue().compareTo(maxEntry.getValue()) > 0) {
+                maxEntry = entry;
+            }
+        }
+        assertNotNull("There must be at least one color on the screen", maxEntry);
+        assertTrue(
+                "The majority color should be at least 90% of the pixels",
+                1.0 * maxEntry.getValue() / (64 * 64) > 0.9);
+        return maxEntry.getKey();
     }
 
     private Map<Integer, Integer> getBitmapHistogram(