Merge "Remove synchronization from methods in androidx.core" into androidx-main
diff --git a/.github/workflows/presubmit.yml b/.github/workflows/presubmit.yml
index 2bd8dca..b081506a 100644
--- a/.github/workflows/presubmit.yml
+++ b/.github/workflows/presubmit.yml
@@ -557,27 +557,6 @@
           wrapper-directory: ${{ env.project-root }}/gradle/wrapper
           wrapper-cache-enabled: true
 
-      - name: Set up Cloud SDK
-        uses: google-github-actions/setup-gcloud@master
-        if: ${{ github.repository == 'androidX/androidx' }}
-        with:
-          project_id: ${{ secrets.GCP_PROJECT_ID }}
-          service_account_key: ${{ secrets.GCP_SA_KEY }}
-          export_default_credentials: true
-      - name: "Run application tests on Firebase Test Lab"
-        uses: eskatos/gradle-command-action@v1
-        if: ${{ github.repository == 'androidX/androidx' }}
-        env:
-          JAVA_HOME: ${{ steps.setup-java.outputs.path }}
-        with:
-          arguments: firebaseTestLabTests ${{ needs.setup.outputs.gradlew_flags }}
-          build-root-directory: ${{ env.project-root }}
-          configuration-cache-enabled: true
-          dependencies-cache-enabled: true
-          gradle-executable: ${{ env.project-root }}/gradlew
-          wrapper-directory: ${{ env.project-root }}/gradle/wrapper
-          wrapper-cache-enabled: true
-
       - name: "upload build artifacts"
         continue-on-error: true
         if: always()
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LayoutInflaterFactoryTestCase.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LayoutInflaterFactoryTestCase.java
index 15d4194..8b17ada 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LayoutInflaterFactoryTestCase.java
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LayoutInflaterFactoryTestCase.java
@@ -43,7 +43,6 @@
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
-import androidx.test.rule.ActivityTestRule;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -52,9 +51,11 @@
 
 @RunWith(AndroidJUnit4.class)
 public class LayoutInflaterFactoryTestCase {
+
+    @SuppressWarnings("deprecation")
     @Rule
-    public final ActivityTestRule<LayoutInflaterFactoryTestActivity> mActivityTestRule =
-            new ActivityTestRule<>(LayoutInflaterFactoryTestActivity.class);
+    public final androidx.test.rule.ActivityTestRule<LayoutInflaterFactoryTestActivity> mTestRule =
+            new androidx.test.rule.ActivityTestRule<>(LayoutInflaterFactoryTestActivity.class);
 
     @Before
     public void setup() {
@@ -66,7 +67,7 @@
     @Test
     @SmallTest
     public void testAndroidThemeInflation() {
-        final LayoutInflater inflater = LayoutInflater.from(mActivityTestRule.getActivity());
+        final LayoutInflater inflater = LayoutInflater.from(mTestRule.getActivity());
         assertThemedContext(inflater.inflate(R.layout.layout_android_theme, null));
     }
 
@@ -74,7 +75,7 @@
     @Test
     @SmallTest
     public void testAppThemeInflation() {
-        final LayoutInflater inflater = LayoutInflater.from(mActivityTestRule.getActivity());
+        final LayoutInflater inflater = LayoutInflater.from(mTestRule.getActivity());
         assertThemedContext(inflater.inflate(R.layout.layout_app_theme, null));
     }
 
@@ -83,7 +84,7 @@
     @Test
     @SmallTest
     public void testAndroidThemeWithChildrenInflation() {
-        LayoutInflater inflater = LayoutInflater.from(mActivityTestRule.getActivity());
+        LayoutInflater inflater = LayoutInflater.from(mTestRule.getActivity());
         final ViewGroup root = (ViewGroup) inflater.inflate(
                 R.layout.layout_android_theme_children, null);
         assertThemedContext(root);
@@ -93,7 +94,7 @@
     @Test
     @SmallTest
     public void testAndroidThemeWithIncludeInflation() {
-        LayoutInflater inflater = LayoutInflater.from(mActivityTestRule.getActivity());
+        LayoutInflater inflater = LayoutInflater.from(mTestRule.getActivity());
         final ViewGroup root = (ViewGroup) inflater.inflate(
                 R.layout.layout_android_theme_with_include, null);
         assertThemedContext(root.findViewById(R.id.included_view));
@@ -102,8 +103,19 @@
     @UiThreadTest
     @Test
     @SmallTest
+    public void testAndroidThemeWithMergeInflation() {
+        LayoutInflater inflater = LayoutInflater.from(mTestRule.getActivity());
+        final ViewGroup root = (ViewGroup) inflater.inflate(
+                R.layout.layout_android_theme_with_merge, null);
+        assertThemedContext(root.findViewById(R.id.merged_view));
+        assertThemedContext(root.findViewById(R.id.merged_view_2));
+    }
+
+    @UiThreadTest
+    @Test
+    @SmallTest
     public void testThemedInflationWithUnattachedParent() {
-        final Context activity = mActivityTestRule.getActivity();
+        final Context activity = mTestRule.getActivity();
 
         // Create a parent but not attached
         final LinearLayout parent = new LinearLayout(activity);
@@ -205,15 +217,15 @@
     @Test
     @SmallTest
     public void testDeclarativeOnClickWithContextWrapper() {
-        LayoutInflater inflater = LayoutInflater.from(mActivityTestRule.getActivity());
+        LayoutInflater inflater = LayoutInflater.from(mTestRule.getActivity());
         View view = inflater.inflate(R.layout.layout_button_themed_onclick, null);
 
         assertTrue(view.performClick());
-        assertTrue(mActivityTestRule.getActivity().wasDeclarativeOnClickCalled());
+        assertTrue(mTestRule.getActivity().wasDeclarativeOnClickCalled());
     }
 
     private void verifyAppCompatWidgetInflation(final int layout, final Class<?> expectedClass) {
-        LayoutInflater inflater = LayoutInflater.from(mActivityTestRule.getActivity());
+        LayoutInflater inflater = LayoutInflater.from(mTestRule.getActivity());
         View view = inflater.inflate(layout, null);
         assertSame("View is " + expectedClass.getSimpleName(), expectedClass,
                 view.getClass());
diff --git a/appcompat/appcompat/src/androidTest/res/layout/layout_android_theme_merged_views.xml b/appcompat/appcompat/src/androidTest/res/layout/layout_android_theme_merged_views.xml
new file mode 100644
index 0000000..37c5c1e
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/res/layout/layout_android_theme_merged_views.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <TextView
+        android:id="@+id/merged_view"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Test" />
+
+    <TextView
+        android:id="@+id/merged_view_2"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Test 2" />
+
+</merge>
\ No newline at end of file
diff --git a/appcompat/appcompat/src/androidTest/res/layout/layout_android_theme_with_merge.xml b/appcompat/appcompat/src/androidTest/res/layout/layout_android_theme_with_merge.xml
new file mode 100644
index 0000000..c9d3511
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/res/layout/layout_android_theme_with_merge.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:theme="@style/MagentaThemeOverlay">
+
+    <include layout="@layout/layout_android_theme_merged_views"
+        android:id="@+id/included_view" />
+
+</FrameLayout>
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/androidx/build/AndroidXPlaygroundRootPlugin.kt b/buildSrc/src/main/kotlin/androidx/build/AndroidXPlaygroundRootPlugin.kt
index e229ac9..b7b0d63 100644
--- a/buildSrc/src/main/kotlin/androidx/build/AndroidXPlaygroundRootPlugin.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/AndroidXPlaygroundRootPlugin.kt
@@ -17,7 +17,6 @@
 package androidx.build
 
 import androidx.build.AndroidXRootPlugin.Companion.PROJECT_OR_ARTIFACT_EXT_NAME
-import androidx.build.ftl.FirebaseTestLabHelper
 import androidx.build.gradle.getByType
 import androidx.build.gradle.isRoot
 import com.android.build.gradle.LibraryExtension
@@ -71,9 +70,8 @@
         config = PlaygroundProperties.load(rootProject)
         repos = PlaygroundRepositories(config)
         rootProject.repositories.addPlaygroundRepositories()
-        val ftlUtilities = FirebaseTestLabHelper(target)
         rootProject.subprojects {
-            configureSubProject(it, ftlUtilities)
+            configureSubProject(it)
         }
 
         // TODO(b/185539993): Re-enable InvalidFragmentVersionForActivityResult which was
@@ -99,10 +97,7 @@
         }
     }
 
-    private fun configureSubProject(
-        project: Project,
-        firebaseTestLabHelper: FirebaseTestLabHelper
-    ) {
+    private fun configureSubProject(project: Project) {
         project.repositories.addPlaygroundRepositories()
         project.extra.set(PROJECT_OR_ARTIFACT_EXT_NAME, projectOrArtifactClosure)
         project.configurations.all { configuration ->
@@ -110,7 +105,6 @@
                 substitution.replaceIfSnapshot()
             }
         }
-        firebaseTestLabHelper.setupFTL(project)
     }
 
     /**
diff --git a/buildSrc/src/main/kotlin/androidx/build/ftl/FirebaseTestLabHelper.kt b/buildSrc/src/main/kotlin/androidx/build/ftl/FirebaseTestLabHelper.kt
deleted file mode 100644
index 04ab48b..0000000
--- a/buildSrc/src/main/kotlin/androidx/build/ftl/FirebaseTestLabHelper.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.build.ftl
-
-import androidx.build.gradle.isRoot
-import com.android.build.gradle.TestedExtension
-import org.gradle.api.Project
-
-/**
- * Helper class to setup Firebase Test Lab for instrumentation tests
- */
-internal class FirebaseTestLabHelper(
-    private val rootProject: Project
-) {
-    init {
-        check(rootProject.isRoot) {
-            "FTL Utilities can only be created for root projects"
-        }
-    }
-
-    private val anchorTask by lazy {
-        rootProject.tasks.register(ANCHOR_TASK_NAME) {
-            it.description = "Anchor task that depends on all firebase test lab tests"
-            it.group = "Verification"
-        }
-    }
-
-    fun setupFTL(project: Project) {
-        AGP_PLUGIN_IDS.forEach { agpPluginId ->
-            // using base plugin at this stage does not work as base plugin is applied before the
-            // Android Extension is created.
-            // see the comment on [AGP_PLUGIN_IDS] for details.
-            project.pluginManager.withPlugin(agpPluginId) {
-                project.extensions.findByType(TestedExtension::class.java)?.let {
-                    configure(project, it)
-                }
-            }
-        }
-    }
-
-    private fun configure(project: Project, testedExtension: TestedExtension) {
-        testedExtension.testVariants.all { testVariant ->
-            RunTestOnFTLTask.create(project, testVariant)?.let { ftlTask ->
-                anchorTask.configure { it.dependsOn(ftlTask) }
-            }
-        }
-    }
-
-    companion object {
-        const val ANCHOR_TASK_NAME = "firebaseTestLabTests"
-
-        /**
-         * AGP base plugin is applied before the extension is created so instead we use plugin
-         * ids here.
-         * see: https://github.com/google/ksp/issues/314
-         * see: https://github.com/google/ksp/pull/318
-         */
-        private val AGP_PLUGIN_IDS = listOf(
-            "com.android.application",
-            // TODO enable library and dynamic feature when we can synthesize
-            //  an APK for them
-            //  "com.android.library",
-            //  "com.android.dynamic-feature"
-        )
-    }
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/androidx/build/ftl/GCloudCLIWrapper.kt b/buildSrc/src/main/kotlin/androidx/build/ftl/GCloudCLIWrapper.kt
deleted file mode 100644
index 385e271..0000000
--- a/buildSrc/src/main/kotlin/androidx/build/ftl/GCloudCLIWrapper.kt
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.build.ftl
-
-import androidx.build.ftl.GCloudCLIWrapper.RunTestParameters.Companion.TEST_OUTPUT_FILE_NAME
-import com.google.gson.Gson
-import com.google.gson.annotations.SerializedName
-import com.google.gson.reflect.TypeToken
-import org.gradle.api.GradleException
-import org.gradle.process.ExecOperations
-import java.io.ByteArrayOutputStream
-import java.io.File
-import java.util.Locale
-import java.util.UUID
-
-/**
- * Wrapper around GCloud CLI.
- *
- * https://cloud.google.com/sdk/gcloud
- *
- * Note that this wrapper requires gcloud to be available on the host machine.
- *
- * documentation for FTL:
- * https://cloud.google.com/sdk/gcloud/reference/firebase/test/android/run
- */
-@Suppress("UnstableApiUsage") // ExecOperations
-internal class GCloudCLIWrapper(
-    private val execOperations: ExecOperations
-) {
-    private val gson = Gson()
-
-    /**
-     * Path to the gcloud executable, derived from `which gcloud` call.
-     */
-    private val gcloud: String by lazy {
-        findExecutable("gcloud")
-    }
-
-    /**
-     * Path to the gsutil executable, derived from `which gsutil` call.
-     */
-    private val gsutil: String by lazy {
-        findExecutable("gsutil")
-    }
-
-    private inline fun <reified T> executeGcloud(
-        vararg params: String
-    ): T {
-        val output = ByteArrayOutputStream()
-        val errorOutput = ByteArrayOutputStream()
-        val execResult = execOperations.exec {
-            it.executable = gcloud
-            it.args = params.toList() + "--format=json"
-            it.standardOutput = output
-            it.errorOutput = errorOutput
-            it.isIgnoreExitValue = true
-        }
-        if (execResult.exitValue != 0) {
-            System.err.println("GCloud command failed: ${errorOutput.toString(Charsets.UTF_8)}")
-        }
-        // still try to parse the because when it fails (e.g. test failure), it returns a non-0
-        // exit code but still prints the output. We are interested in the output.
-        val commandOutput = output.toString(Charsets.UTF_8)
-        return gson.parse(commandOutput)
-    }
-
-    private fun execGsUtil(
-        vararg params: String
-    ): String {
-        val output = ByteArrayOutputStream()
-        execOperations.exec {
-            it.executable = gsutil
-            it.args = params.toList()
-            it.standardOutput = output
-        }
-        return output.toString(Charsets.UTF_8)
-    }
-
-    /**
-     * https://cloud.google.com/sdk/gcloud/reference/firebase/test/android/run
-     */
-    fun runTest(
-        params: RunTestParameters
-    ): List<TestResult> {
-        val testResults = executeGcloud<List<TestResult>>(
-            "firebase", "test", "android", "run",
-            "--type", "instrumentation",
-            "--test", params.testApk.canonicalPath,
-            "--app", params.testedApk.canonicalPath,
-            "--num-flaky-test-attempts", "2",
-            "--results-bucket=${params.bucketName}",
-            "--results-dir=${params.resultsBucketDir}",
-            "--results-history-name=${params.projectPath}"
-        )
-        // copy the test results from the bucket to the build directory
-        execGsUtil(
-            "cp", "-r", params.cloudBucketPath() + "/*", params.resultsLocalDir.canonicalPath
-        )
-        // finally, write the command response into the directory as well
-        val testResultOutput = params.resultsLocalDir.resolve(TEST_OUTPUT_FILE_NAME)
-        testResultOutput.bufferedWriter(Charsets.UTF_8).use {
-            gson.toJson(
-                testResults,
-                it
-            )
-        }
-        return testResults
-    }
-
-    /**
-     * find the given executable's path in the PATH via `which` command.
-     */
-    private fun findExecutable(name: String): String {
-        val output = ByteArrayOutputStream()
-        val result = execOperations.exec {
-            it.commandLine("which", name)
-            it.standardOutput = output
-            it.isIgnoreExitValue = true
-        }
-        if (result.exitValue != 0) {
-            throw GradleException(
-                """
-                Unable to find $name CLI executable.
-                `which $name` returned exit code ${result.exitValue}.
-                Make sure gcloud CLI is installed, authenticated and is part of your PATH.
-                See https://cloud.google.com/sdk/gcloud for installation instructions.
-                """.trimIndent()
-            )
-        }
-        return output.toString(Charsets.UTF_8).trim()
-    }
-
-    /**
-     * Data structure format for gcloud FTL command
-     */
-    internal data class TestResult(
-        @SerializedName("axis_value")
-        val axisValue: String,
-        val outcome: String,
-        @SerializedName("test_details")
-        val testDetails: String
-    ) {
-        val passed
-            get() = outcome.toLowerCase(Locale.US) in SUCCESS_OUTCOMES
-
-        companion object {
-            private val SUCCESS_OUTCOMES = listOf("passed", "flaky")
-        }
-    }
-
-    /**
-     * Parameters for invoking a test on the Firebase Test Lab
-     */
-    internal data class RunTestParameters(
-        /**
-         * The project path for which we are executing the tests for.
-         */
-        val projectPath: String,
-        /**
-         * The tested APK file
-         */
-        val testedApk: File,
-        /**
-         * The test APK file which includes the instrumentation tests
-         */
-        val testApk: File,
-        /**
-         * The name of the GS bucket to save the results
-         */
-        val bucketName: String = DEFAULT_BUCKET_NAME,
-        /**
-         * The GS Bucket directory where the results will be saved
-         */
-        val resultsBucketDir: String = buildRelativeResultDirPath(projectPath),
-        /**
-         * The local directory where we will download the test results
-         */
-        val resultsLocalDir: File,
-    ) {
-
-        /**
-         * Returns the path to the Google Cloud bucket where the test run results are saved
-         */
-        fun cloudBucketPath(): String {
-            return "gs://$bucketName/$resultsBucketDir"
-        }
-
-        companion object {
-            const val DEFAULT_BUCKET_NAME = "androidx-ftl-test-results"
-
-            /**
-             * The file into which the result of the gcloud command will be written.
-             */
-            const val TEST_OUTPUT_FILE_NAME = "testResults.json"
-
-            /**
-             * Generates a relative path for test results.
-             *
-             * If run on Github Actions CI, this method will use the environment variables to
-             * create a unique path for the action.
-             * If run locally, this will create a random UUID for the directory.
-             */
-            private fun buildRelativeResultDirPath(
-                projectPath: String
-            ): String {
-                // github action env variables:
-                // https://docs.github.com/en/actions/reference/environment-variables
-                val inGithubActions = System.getenv().containsKey("GITHUB_ACTIONS")
-                val pathValues = if (inGithubActions) {
-                    val workflowName = requireEnvValue("GITHUB_WORKFLOW")
-                    val runNumber = requireEnvValue("GITHUB_RUN_NUMBER")
-                    val runId = requireEnvValue("GITHUB_RUN_ID")
-                    val ref = System.getenv("GITHUB_REF")
-                    listOfNotNull(
-                        "github",
-                        projectPath,
-                        ref,
-                        workflowName,
-                        runNumber,
-                        runId,
-                    )
-                } else {
-                    listOf(
-                        "local",
-                        projectPath,
-                        UUID.randomUUID().toString()
-                    )
-                }
-                return pathValues.joinToString("/")
-            }
-
-            private fun requireEnvValue(name: String): String {
-                return System.getenv(name) ?: throw GradleException(
-                    "Cannot find required environment variable: $name"
-                )
-            }
-        }
-    }
-}
-
-private inline fun <reified T> Gson.parse(
-    input: String
-): T {
-    val typeToken = object : TypeToken<T>() {}.type
-    return this.fromJson(input, typeToken)
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/androidx/build/ftl/RunTestOnFTLTask.kt b/buildSrc/src/main/kotlin/androidx/build/ftl/RunTestOnFTLTask.kt
deleted file mode 100644
index 8ec207d..0000000
--- a/buildSrc/src/main/kotlin/androidx/build/ftl/RunTestOnFTLTask.kt
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.build.ftl
-
-import androidx.build.getDistributionDirectory
-import androidx.build.getSupportRootFolder
-import com.android.build.gradle.api.ApkVariant
-import com.android.build.gradle.api.ApkVariantOutput
-import com.android.build.gradle.api.TestVariant
-import org.gradle.api.DefaultTask
-import org.gradle.api.GradleException
-import org.gradle.api.Project
-import org.gradle.api.file.DirectoryProperty
-import org.gradle.api.file.RegularFileProperty
-import org.gradle.api.provider.Property
-import org.gradle.api.tasks.CacheableTask
-import org.gradle.api.tasks.Copy
-import org.gradle.api.tasks.InputFile
-import org.gradle.api.tasks.OutputDirectory
-import org.gradle.api.tasks.PathSensitive
-import org.gradle.api.tasks.PathSensitivity
-import org.gradle.api.tasks.TaskAction
-import org.gradle.api.tasks.TaskProvider
-import org.gradle.process.ExecOperations
-import org.gradle.workers.WorkAction
-import org.gradle.workers.WorkParameters
-import org.gradle.workers.WorkerExecutor
-import javax.inject.Inject
-
-/**
- * Task to run instrumentation tests on FTL.
- *
- * This task is only enabled on playground projects and requires gcloud CLI to be available on
- * the device with the right permissions.
- *
- * Due to the limitations of FTL, this task only support application instrumentation tests for now.
- */
-@Suppress("UnstableApiUsage") // for gradle property APIs
-@CacheableTask
-abstract class RunTestOnFTLTask @Inject constructor(
-    private val workerExecutor: WorkerExecutor
-) : DefaultTask() {
-    /**
-     * The test APK for the instrumentation test.
-     */
-    @get:[InputFile PathSensitive(PathSensitivity.NONE)]
-    abstract val testApk: RegularFileProperty
-
-    /**
-     * The tested application APK.
-     */
-    @get:[InputFile PathSensitive(PathSensitivity.NONE)]
-    abstract val testedApk: RegularFileProperty
-
-    /**
-     * Output file to write the results
-     */
-    @get:OutputDirectory
-    abstract val testResults: DirectoryProperty
-
-    @TaskAction
-    fun executeTest() {
-        workerExecutor.noIsolation().submit(
-            RunFTLTestWorkAction::class.java
-        ) {
-            it.testApk.set(testApk)
-            it.testedApk.set(testedApk)
-            it.testResults.set(testResults)
-            it.projectPath.set(project.relativeResultPath())
-        }
-    }
-
-    interface RunFTLTestParams : WorkParameters {
-        val projectPath: Property<String>
-        val testApk: RegularFileProperty
-        val testedApk: RegularFileProperty
-        val testResults: DirectoryProperty
-    }
-
-    abstract class RunFTLTestWorkAction @Inject constructor(
-        private val execOperations: ExecOperations
-    ) : WorkAction<RunFTLTestParams> {
-        override fun execute() {
-            val localTestResultDir = parameters.testResults.asFile.get()
-            localTestResultDir.apply {
-                deleteRecursively()
-                mkdirs()
-            }
-            val testApk = parameters.testApk.asFile.get()
-            val testedApk = parameters.testedApk.asFile.get()
-            val gcloud = GCloudCLIWrapper(execOperations)
-            val params = GCloudCLIWrapper.RunTestParameters(
-                testedApk = testedApk,
-                testApk = testApk,
-                projectPath = parameters.projectPath.get(),
-                resultsLocalDir = localTestResultDir
-
-            )
-            val result = gcloud.runTest(params)
-            val failed = result.filterNot {
-                it.passed
-            }
-            if (failed.isNotEmpty()) {
-                throw GradleException("These tests failed: $failed")
-            }
-        }
-    }
-
-    companion object {
-        private const val TASK_SUFFIX = "OnFirebaseTestLab"
-
-        /**
-         * Creates an FTL test runner task and returns it.
-         * Note that only application tests are supported hence this will return `null` for
-         * library projects.
-         */
-        fun create(project: Project, testVariant: TestVariant): TaskProvider<RunTestOnFTLTask>? {
-            // TODO add support for library project, which might require synthesizing another
-            //  APK :facepalm:
-            // see: // https://stackoverflow.com/questions/59827750/execute-instrumented-test-for-an-android-library-with-firebase-test-lab
-            val testedVariant = testVariant.testedVariant as? ApkVariant
-                ?: return null
-            val taskName = testVariant.name + TASK_SUFFIX
-            val testResultDir = project.layout.buildDirectory.dir(
-                "ftl-results"
-            )
-            // create task to copy results into dist directory
-            val copyToDistTask = project.tasks.register(
-                "copyResultsOf${taskName}ToDist",
-                Copy::class.java
-            ) {
-                it.description = "Copy test results from $taskName into DIST folder"
-                it.group = "build"
-                it.from(testResultDir)
-                it.into(
-                    project.getDistributionDirectory()
-                        .resolve("ftl-results/${project.relativeResultPath()}/$taskName")
-                )
-            }
-            return project.tasks.register(taskName, RunTestOnFTLTask::class.java) { task ->
-                task.description = "Run ${testVariant.name} tests on Firebase Test Lab"
-                task.group = "Verification"
-                task.testResults.set(testResultDir)
-                task.dependsOn(testVariant.packageApplicationProvider)
-                task.dependsOn(testedVariant.packageApplicationProvider)
-
-                task.testApk.set(
-                    testVariant.outputs
-                        .withType(ApkVariantOutput::class.java)
-                        .firstOrNull()
-                        ?.outputFile
-                )
-                task.testedApk.set(
-                    testedVariant.outputs
-                        .withType(ApkVariantOutput::class.java)
-                        .firstOrNull()
-                        ?.outputFile
-                )
-                task.finalizedBy(copyToDistTask)
-            }
-        }
-    }
-}
-
-/**
- * Returns the relative path of the project wrt the support root. This path is used for both
- * local dist path and cloud bucket paths.
- */
-private fun Project.relativeResultPath() = projectDir.relativeTo(
-    project.getSupportRootFolder()
-).path
\ No newline at end of file
diff --git a/camera/camera-view/api/current.txt b/camera/camera-view/api/current.txt
index 160857f..d9c61fc 100644
--- a/camera/camera-view/api/current.txt
+++ b/camera/camera-view/api/current.txt
@@ -75,5 +75,13 @@
     enum_constant public static final androidx.camera.view.PreviewView.StreamState STREAMING;
   }
 
+  public abstract class RotationReceiver {
+    ctor public RotationReceiver(android.content.Context);
+    method public boolean canDetectOrientation();
+    method public void disable();
+    method public void enable();
+    method public abstract void onRotationChanged(int);
+  }
+
 }
 
diff --git a/camera/camera-view/api/public_plus_experimental_current.txt b/camera/camera-view/api/public_plus_experimental_current.txt
index 2faf2d6..a02bc5e 100644
--- a/camera/camera-view/api/public_plus_experimental_current.txt
+++ b/camera/camera-view/api/public_plus_experimental_current.txt
@@ -83,6 +83,14 @@
     enum_constant public static final androidx.camera.view.PreviewView.StreamState STREAMING;
   }
 
+  public abstract class RotationReceiver {
+    ctor public RotationReceiver(android.content.Context);
+    method public boolean canDetectOrientation();
+    method public void disable();
+    method public void enable();
+    method public abstract void onRotationChanged(int);
+  }
+
 }
 
 package androidx.camera.view.transform {
diff --git a/camera/camera-view/api/restricted_current.txt b/camera/camera-view/api/restricted_current.txt
index 56cdeaa..a47bbc3 100644
--- a/camera/camera-view/api/restricted_current.txt
+++ b/camera/camera-view/api/restricted_current.txt
@@ -75,5 +75,13 @@
     enum_constant public static final androidx.camera.view.PreviewView.StreamState STREAMING;
   }
 
+  public abstract class RotationReceiver {
+    ctor public RotationReceiver(android.content.Context);
+    method public boolean canDetectOrientation();
+    method public void disable();
+    method public void enable();
+    method public abstract void onRotationChanged(int);
+  }
+
 }
 
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/CameraController.java b/camera/camera-view/src/main/java/androidx/camera/view/CameraController.java
index 2cab702..98d607f 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/CameraController.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/CameraController.java
@@ -205,7 +205,7 @@
     // Synthetic access
     @SuppressWarnings("WeakerAccess")
     @NonNull
-    final SensorRotationListener mSensorRotationListener;
+    final RotationReceiver mRotationReceiver;
 
     @Nullable
     private final DisplayRotationListener mDisplayRotationListener;
@@ -242,7 +242,7 @@
 
         // Listen to motion sensor reading and set target rotation for ImageCapture and
         // VideoCapture.
-        mSensorRotationListener = new SensorRotationListener(mAppContext) {
+        mRotationReceiver = new RotationReceiver(mAppContext) {
             @Override
             public void onRotationChanged(int rotation) {
                 mImageAnalysis.setTargetRotation(rotation);
@@ -272,7 +272,7 @@
      * Gets a {@link ListenableFuture} that completes when camera initialization completes.
      *
      * <p> This future may fail with an {@link InitializationException} and associated cause that
-     * can be retrieved by {@link Throwable#getCause()). The cause will be a
+     * can be retrieved by {@link Throwable#getCause()}. The cause will be a
      * {@link CameraUnavailableException} if it fails to access any camera during initialization.
      *
      * <p> In the rare case that the future fails with {@link CameraUnavailableException}, the
@@ -419,14 +419,14 @@
     private void startListeningToRotationEvents() {
         getDisplayManager().registerDisplayListener(mDisplayRotationListener,
                 new Handler(Looper.getMainLooper()));
-        if (mSensorRotationListener.canDetectOrientation()) {
-            mSensorRotationListener.enable();
+        if (mRotationReceiver.canDetectOrientation()) {
+            mRotationReceiver.enable();
         }
     }
 
     private void stopListeningToRotationEvents() {
         getDisplayManager().unregisterDisplayListener(mDisplayRotationListener);
-        mSensorRotationListener.disable();
+        mRotationReceiver.disable();
     }
 
     private DisplayManager getDisplayManager() {
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/RotationReceiver.java b/camera/camera-view/src/main/java/androidx/camera/view/RotationReceiver.java
new file mode 100644
index 0000000..b64fad4
--- /dev/null
+++ b/camera/camera-view/src/main/java/androidx/camera/view/RotationReceiver.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.view;
+
+import android.content.Context;
+import android.hardware.SensorManager;
+import android.view.OrientationEventListener;
+import android.view.Surface;
+
+import androidx.annotation.NonNull;
+import androidx.camera.core.UseCase;
+
+/**
+ * Helper class for receiving rotation updates from the {@link SensorManager} when the
+ * orientation of the device has changed.
+ *
+ * <p> This class is an wrapper of {@link OrientationEventListener} that notifies the app about
+ * physical orientation changes in the format of {@link Surface} rotation. It's useful when the
+ * device UI is in a fixed portrait or landscape orientation, while the app still wants to set the
+ * {@link UseCase} target rotation based on the device's physical orientation.
+ *
+ * <pre><code>
+ * rotationReceiver = new RotationReceiver(context) {
+ *         public void onRotationChanged(int rotation) {
+ *             mImageCapture.setTargetRotation(rotation);
+ *         }
+ * };
+ * if (rotationReceiver.canDetectOrientation()) {
+ *     rotationReceiver.enable();
+ * }
+ *
+ * // Disable it when it's no longer needed.
+ * rotationReceiver.disable();
+ * </code></pre>
+ *
+ * @see OrientationEventListener
+ */
+public abstract class RotationReceiver {
+
+    private static final int INVALID_SURFACE_ROTATION = -1;
+
+    // Synthetic access
+    @SuppressWarnings("WeakerAccess")
+    int mRotation = INVALID_SURFACE_ROTATION;
+
+    private final OrientationEventListener mOrientationEventListener;
+
+    public RotationReceiver(@NonNull Context context) {
+        mOrientationEventListener = new OrientationEventListener(context) {
+            @Override
+            public void onOrientationChanged(int orientation) {
+                if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) {
+                    // Short-circuit if orientation is unknown. Unknown rotation can't be handled
+                    // so it shouldn't be sent.
+                    return;
+                }
+
+                int newRotation;
+                if (orientation >= 315 || orientation < 45) {
+                    newRotation = Surface.ROTATION_0;
+                } else if (orientation >= 225) {
+                    newRotation = Surface.ROTATION_90;
+                } else if (orientation >= 135) {
+                    newRotation = Surface.ROTATION_180;
+                } else {
+                    newRotation = Surface.ROTATION_270;
+                }
+                if (mRotation != newRotation) {
+                    mRotation = newRotation;
+                    onRotationChanged(newRotation);
+                }
+            }
+        };
+    }
+
+    /**
+     * Checks if the RotationReceiver can detect orientation changes.
+     *
+     * @see OrientationEventListener#canDetectOrientation()
+     */
+    public boolean canDetectOrientation() {
+        return mOrientationEventListener.canDetectOrientation();
+    }
+
+    /**
+     * Enables the RotationReceiver so it will monitor the sensor and call onRotationChanged when
+     * the device orientation changes.
+     *
+     * <p> By default, the receiver is not enabled.
+     *
+     * @see OrientationEventListener#enable()
+     */
+    public void enable() {
+        mOrientationEventListener.enable();
+    }
+
+    /**
+     * Disables the RotationReceiver.
+     *
+     * @see OrientationEventListener#disable()
+     */
+    public void disable() {
+        mOrientationEventListener.disable();
+    }
+
+    /**
+     * Called when the physical rotation of the device changes.
+     *
+     * <p> The rotation is one of the {@link Surface} rotations mapped from orientation
+     * degrees.
+     *
+     * <table summary="Orientation degrees to Surface rotation mapping">
+     * <tr><th>Orientation degrees</th><th>Surface rotation</th></tr>
+     * <tr><td>[-45°, 45°)</td><td>{@link Surface#ROTATION_0}</td></tr>
+     * <tr><td>[45°, 135°)</td><td>{@link Surface#ROTATION_270}</td></tr>
+     * <tr><td>[135°, 225°)</td><td>{@link Surface#ROTATION_180}</td></tr>
+     * <tr><td>[225°, 315°)</td><td>{@link Surface#ROTATION_90}</td></tr>
+     * </table>
+     *
+     * @see OrientationEventListener#onOrientationChanged(int)
+     */
+    public abstract void onRotationChanged(int rotation);
+}
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/SensorRotationListener.java b/camera/camera-view/src/main/java/androidx/camera/view/SensorRotationListener.java
deleted file mode 100644
index d0919d4..0000000
--- a/camera/camera-view/src/main/java/androidx/camera/view/SensorRotationListener.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.camera.view;
-
-import android.content.Context;
-import android.view.OrientationEventListener;
-import android.view.Surface;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RestrictTo;
-
-/**
- * Listens to motion sensor reading and converts the orientation degrees to {@link Surface}
- * rotation.
- *
- * @hide
- */
-@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-public abstract class SensorRotationListener extends OrientationEventListener {
-
-    public static final int INVALID_SURFACE_ROTATION = -1;
-
-    private int mRotation = INVALID_SURFACE_ROTATION;
-
-    public SensorRotationListener(@NonNull Context context) {
-        super(context);
-    }
-
-    @Override
-    public void onOrientationChanged(int orientation) {
-        if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) {
-            // Short-circuit if orientation is unknown. Unknown rotation can't be handled so it
-            // shouldn't be sent.
-            return;
-        }
-
-        int newRotation;
-        if (orientation >= 315 || orientation < 45) {
-            newRotation = Surface.ROTATION_0;
-        } else if (orientation >= 225) {
-            newRotation = Surface.ROTATION_90;
-        } else if (orientation >= 135) {
-            newRotation = Surface.ROTATION_180;
-        } else {
-            newRotation = Surface.ROTATION_270;
-        }
-        if (mRotation != newRotation) {
-            mRotation = newRotation;
-            onRotationChanged(newRotation);
-        }
-    }
-
-    /**
-     * Invoked when rotation changes.
-     *
-     * <p> The output rotation is defined as the UI Surface rotation, or what the Surface rotation
-     * should be if the app's orientation is not locked.
-     */
-    public abstract void onRotationChanged(int rotation);
-}
diff --git a/camera/camera-view/src/test/java/androidx/camera/view/CameraControllerTest.kt b/camera/camera-view/src/test/java/androidx/camera/view/CameraControllerTest.kt
index 916d316..fe3a1c0 100644
--- a/camera/camera-view/src/test/java/androidx/camera/view/CameraControllerTest.kt
+++ b/camera/camera-view/src/test/java/androidx/camera/view/CameraControllerTest.kt
@@ -64,7 +64,7 @@
         val controller = LifecycleCameraController(context)
 
         // Act.
-        controller.mSensorRotationListener.onRotationChanged(Surface.ROTATION_180)
+        controller.mRotationReceiver.onRotationChanged(Surface.ROTATION_180)
 
         // Assert.
         assertThat(controller.mImageAnalysis.targetRotation).isEqualTo(Surface.ROTATION_180)
diff --git a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CameraControllerFragment.java b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CameraControllerFragment.java
index 46cb4308..9fab3a8f 100644
--- a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CameraControllerFragment.java
+++ b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CameraControllerFragment.java
@@ -51,7 +51,7 @@
 import androidx.camera.view.CameraController;
 import androidx.camera.view.LifecycleCameraController;
 import androidx.camera.view.PreviewView;
-import androidx.camera.view.SensorRotationListener;
+import androidx.camera.view.RotationReceiver;
 import androidx.camera.view.video.ExperimentalVideo;
 import androidx.camera.view.video.OnVideoSavedCallback;
 import androidx.camera.view.video.OutputFileOptions;
@@ -89,7 +89,7 @@
     private ToggleButton mTapToFocusToggle;
     private TextView mZoomStateText;
     private TextView mTorchStateText;
-    private RotationListener mSensorRotationListener;
+    private SensorRotationReceiver mSensorRotationReceiver;
     private TextView mLuminance;
     private boolean mIsAnalyzerSet = true;
 
@@ -123,8 +123,8 @@
             @Nullable ViewGroup container,
             @Nullable Bundle savedInstanceState) {
         mExecutorService = Executors.newSingleThreadExecutor();
-        mSensorRotationListener = new RotationListener(requireContext());
-        mSensorRotationListener.enable();
+        mSensorRotationReceiver = new SensorRotationReceiver(requireContext());
+        mSensorRotationReceiver.enable();
         mCameraController = new LifecycleCameraController(requireContext());
         checkFailedFuture(mCameraController.getInitializationFuture());
         runSafely(() -> mCameraController.bindToLifecycle(getViewLifecycleOwner()));
@@ -321,8 +321,8 @@
         if (mExecutorService != null) {
             mExecutorService.shutdown();
         }
-        if (mSensorRotationListener != null) {
-            mSensorRotationListener.disable();
+        if (mSensorRotationReceiver != null) {
+            mSensorRotationReceiver.disable();
         }
     }
 
@@ -451,11 +451,11 @@
     /**
      * Listens to accelerometer rotation change and pass it to tests.
      */
-    static class RotationListener extends SensorRotationListener {
+    static class SensorRotationReceiver extends RotationReceiver {
 
         private int mRotation;
 
-        RotationListener(@NonNull Context context) {
+        SensorRotationReceiver(@NonNull Context context) {
             super(context);
         }
 
@@ -498,7 +498,7 @@
      */
     @RestrictTo(RestrictTo.Scope.TESTS)
     int getSensorRotation() {
-        return mSensorRotationListener.getRotation();
+        return mSensorRotationReceiver.getRotation();
     }
 
     @VisibleForTesting
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ScrollTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ScrollTest.kt
index ed52e33..cd74198 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ScrollTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ScrollTest.kt
@@ -15,6 +15,7 @@
  */
 package androidx.compose.foundation
 
+import android.os.Build
 import android.os.Handler
 import android.os.Looper
 import androidx.annotation.RequiresApi
@@ -24,16 +25,23 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.text.BasicText
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.testutils.assertPixels
+import androidx.compose.testutils.assertShape
 import androidx.compose.testutils.runBlockingWithManualClock
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.drawBehind
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.RectangleShape
 import androidx.compose.ui.platform.InspectableValue
 import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.platform.isDebugInspectorInfoEnabled
@@ -822,4 +830,73 @@
             )
         }
     }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun horizontalScroller_doesNotClipVerticalOverdraw() {
+        rule.setContent {
+            Box(Modifier.size(60.dp).testTag("container").background(Color.Gray)) {
+                Row(
+                    Modifier
+                        .padding(20.dp)
+                        .fillMaxSize()
+                        .horizontalScroll(rememberScrollState(20))
+                ) {
+                    repeat(4) {
+                        Box(Modifier.size(20.dp).drawOutsideOfBounds())
+                    }
+                }
+            }
+        }
+
+        rule.onNodeWithTag("container")
+            .captureToImage()
+            .assertShape(
+                density = rule.density,
+                shape = RectangleShape,
+                shapeColor = Color.Red,
+                backgroundColor = Color.Gray,
+                horizontalPadding = 20.dp,
+                verticalPadding = 0.dp
+            )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun verticalScroller_doesNotClipHorizontalOverdraw() {
+        rule.setContent {
+            Box(Modifier.size(60.dp).testTag("container").background(Color.Gray)) {
+                Column(
+                    Modifier
+                        .padding(20.dp)
+                        .fillMaxSize()
+                        .verticalScroll(rememberScrollState(20))
+                ) {
+                    repeat(4) {
+                        Box(Modifier.size(20.dp).drawOutsideOfBounds())
+                    }
+                }
+            }
+        }
+
+        rule.onNodeWithTag("container")
+            .captureToImage()
+            .assertShape(
+                density = rule.density,
+                shape = RectangleShape,
+                shapeColor = Color.Red,
+                backgroundColor = Color.Gray,
+                horizontalPadding = 0.dp,
+                verticalPadding = 20.dp
+            )
+    }
+
+    private fun Modifier.drawOutsideOfBounds() = drawBehind {
+        val inflate = 20.dp.roundToPx().toFloat()
+        drawRect(
+            Color.Red,
+            Offset(-inflate, -inflate),
+            Size(size.width + inflate * 2, size.height + inflate * 2)
+        )
+    }
 }
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnTest.kt
index c9037c3..5803e10 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnTest.kt
@@ -29,6 +29,7 @@
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.requiredHeight
 import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.foundation.layout.requiredSizeIn
@@ -44,12 +45,15 @@
 import androidx.compose.testutils.WithTouchSlop
 import androidx.compose.testutils.assertIsEqualTo
 import androidx.compose.testutils.assertPixels
+import androidx.compose.testutils.assertShape
 import androidx.compose.testutils.runBlockingWithManualClock
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.drawBehind
 import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.RectangleShape
 import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.ExperimentalTestApi
@@ -1440,6 +1444,36 @@
             .assertTopPositionInRootIsEqualTo(containerSize - itemSizeDp)
     }
 
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun lazyColumnDoesNotClipHorizontalOverdraw() {
+        rule.setContent {
+            Box(Modifier.size(60.dp).testTag("container").background(Color.Gray)) {
+                LazyColumn(
+                    Modifier
+                        .padding(20.dp)
+                        .fillMaxSize(),
+                    rememberLazyListState(1)
+                ) {
+                    items(4) {
+                        Box(Modifier.size(20.dp).drawOutsideOfBounds())
+                    }
+                }
+            }
+        }
+
+        rule.onNodeWithTag("container")
+            .captureToImage()
+            .assertShape(
+                density = rule.density,
+                shape = RectangleShape,
+                shapeColor = Color.Red,
+                backgroundColor = Color.Gray,
+                horizontalPadding = 0.dp,
+                verticalPadding = 20.dp
+            )
+    }
+
     private fun SemanticsNodeInteraction.assertTopPositionIsAlmost(expected: Dp) {
         getUnclippedBoundsInRoot().top.assertIsEqualTo(expected, tolerance = 1.dp)
     }
@@ -1486,3 +1520,12 @@
             )
         }
     }
+
+internal fun Modifier.drawOutsideOfBounds() = drawBehind {
+    val inflate = 20.dp.roundToPx().toFloat()
+    drawRect(
+        Color.Red,
+        Offset(-inflate, -inflate),
+        Size(size.width + inflate * 2, size.height + inflate * 2)
+    )
+}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowTest.kt
index ecd3cba..e2b6fc5 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.compose.foundation.lazy
 
+import android.os.Build
 import androidx.compose.animation.core.snap
 import androidx.compose.foundation.AutoTestFrameClock
 import androidx.compose.foundation.background
@@ -24,6 +25,8 @@
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.requiredHeight
 import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.foundation.layout.requiredSizeIn
@@ -35,11 +38,13 @@
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
 import androidx.compose.testutils.assertIsEqualTo
+import androidx.compose.testutils.assertShape
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.drawBehind
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.RectangleShape
 import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.SemanticsNodeInteraction
@@ -49,6 +54,7 @@
 import androidx.compose.ui.test.assertLeftPositionInRootIsEqualTo
 import androidx.compose.ui.test.assertPositionInRootIsEqualTo
 import androidx.compose.ui.test.assertWidthIsEqualTo
+import androidx.compose.ui.test.captureToImage
 import androidx.compose.ui.test.center
 import androidx.compose.ui.test.down
 import androidx.compose.ui.test.getUnclippedBoundsInRoot
@@ -63,6 +69,7 @@
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.Dispatchers
@@ -1132,6 +1139,36 @@
             .assertLeftPositionInRootIsEqualTo(containerSize - itemSizeDp)
     }
 
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun lazyRowDoesNotClipHorizontalOverdraw() {
+        rule.setContent {
+            Box(Modifier.size(60.dp).testTag("container").background(Color.Gray)) {
+                LazyRow(
+                    Modifier
+                        .padding(20.dp)
+                        .fillMaxSize(),
+                    rememberLazyListState(1)
+                ) {
+                    items(4) {
+                        Box(Modifier.size(20.dp).drawOutsideOfBounds())
+                    }
+                }
+            }
+        }
+
+        rule.onNodeWithTag("container")
+            .captureToImage()
+            .assertShape(
+                density = rule.density,
+                shape = RectangleShape,
+                shapeColor = Color.Red,
+                backgroundColor = Color.Gray,
+                horizontalPadding = 20.dp,
+                verticalPadding = 0.dp
+            )
+    }
+
     private fun LazyListState.scrollBy(offset: Dp) {
         runBlocking(Dispatchers.Main + AutoTestFrameClock()) {
             animateScrollBy(with(rule.density) { offset.roundToPx().toFloat() }, snap())
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt
index 4720d13..4b7f5ee 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt
@@ -40,7 +40,11 @@
 import androidx.compose.runtime.structuralEqualityPolicy
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.composed
-import androidx.compose.ui.draw.clipToBounds
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.geometry.Rect
+import androidx.compose.ui.geometry.Size
+import androidx.compose.ui.graphics.Outline
+import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.layout.LayoutModifier
 import androidx.compose.ui.layout.Measurable
 import androidx.compose.ui.layout.MeasureResult
@@ -53,7 +57,9 @@
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.semantics.verticalScrollAxisRange
 import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.unit.dp
 import kotlinx.coroutines.launch
 import kotlin.math.roundToInt
 
@@ -294,7 +300,7 @@
             state = state
         )
         val layout = ScrollingLayoutModifier(state, reverseScrolling, isVertical)
-        semantics.then(scrolling).clipToBounds().then(layout)
+        semantics.then(scrolling).clipScrollableContainer(isVertical).then(layout)
     },
     inspectorInfo = debugInspectorInfo {
         name = "scroll"
@@ -356,3 +362,60 @@
         }
     }
 }
+
+/**
+ * In the scrollable containers we want to clip the main axis sides in order to not display the
+ * content which is scrolled out. But once we apply clipToBounds() modifier on such containers it
+ * causes unexpected behavior as we also clip the content on the cross axis sides. It is
+ * unexpected as Compose components are not clipping by default. The most common case how it
+ * could be reproduced is a horizontally scrolling list of Cards. Cards have the elevation by
+ * default and such Cards will be drawn with clipped shadows on top and bottom. This was harder
+ * to reproduce in the Views system as usually scrolling containers like RecyclerView didn't have
+ * an opaque background which means the ripple was drawn on the surface on the first parent with
+ * background. In Compose as we don't clip by default we draw shadows right in place.
+ * We faced similar issue in Compose already with Androids Popups and Dialogs where we decided to
+ * just predefine some constant with a maximum elevation size we are not going to clip. We are
+ * going to reuse this technique here. This will improve how it works in most common cases. If the
+ * user will need to have a larger unclipped area for some reason they can always add the needed
+ * padding inside the scrollable area.
+ */
+internal fun Modifier.clipScrollableContainer(isVertical: Boolean) =
+    then(if (isVertical) VerticalScrollableClipModifier else HorizontalScrollableClipModifier)
+
+private val MaxSupportedElevation = 30.dp
+
+private val HorizontalScrollableClipModifier = Modifier.clip(object : Shape {
+    override fun createOutline(
+        size: Size,
+        layoutDirection: LayoutDirection,
+        density: Density
+    ): Outline {
+        val inflateSize = with(density) { MaxSupportedElevation.roundToPx().toFloat() }
+        return Outline.Rectangle(
+            Rect(
+                left = 0f,
+                top = -inflateSize,
+                right = size.width,
+                bottom = size.height + inflateSize
+            )
+        )
+    }
+})
+
+private val VerticalScrollableClipModifier = Modifier.clip(object : Shape {
+    override fun createOutline(
+        size: Size,
+        layoutDirection: LayoutDirection,
+        density: Density
+    ): Outline {
+        val inflateSize = with(density) { MaxSupportedElevation.roundToPx().toFloat() }
+        return Outline.Rectangle(
+            Rect(
+                left = -inflateSize,
+                top = 0f,
+                right = size.width + inflateSize,
+                bottom = size.height
+            )
+        )
+    }
+})
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
index 141341d..f8d7ba5 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
@@ -17,6 +17,7 @@
 package androidx.compose.foundation.lazy
 
 import androidx.compose.foundation.assertNotNestingScrollableContainers
+import androidx.compose.foundation.clipScrollableContainer
 import androidx.compose.foundation.gestures.FlingBehavior
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.gestures.scrollable
@@ -31,7 +32,6 @@
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clipToBounds
 import androidx.compose.ui.layout.SubcomposeLayout
 import androidx.compose.ui.layout.SubcomposeLayoutState
 import androidx.compose.ui.platform.LocalLayoutDirection
@@ -89,7 +89,7 @@
                 flingBehavior = flingBehavior,
                 state = state
             )
-            .clipToBounds()
+            .clipScrollableContainer(isVertical)
             .padding(contentPadding)
             .then(state.remeasurementModifier)
     ) { constraints ->
diff --git a/compose/material/material/api/1.0.0-beta08.txt b/compose/material/material/api/1.0.0-beta08.txt
index 7cedeb6..ff9ea09 100644
--- a/compose/material/material/api/1.0.0-beta08.txt
+++ b/compose/material/material/api/1.0.0-beta08.txt
@@ -250,9 +250,22 @@
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ElevationOverlay> getLocalElevationOverlay();
   }
 
-  public enum FabPosition {
-    enum_constant public static final androidx.compose.material.FabPosition Center;
-    enum_constant public static final androidx.compose.material.FabPosition End;
+  public final inline class FabPosition {
+    ctor public FabPosition();
+    method public static inline boolean equals-impl(int p, Object? p1);
+    method public static boolean equals-impl0(int p1, int p2);
+    method public int getValue();
+    method public static inline int hashCode-impl(int p);
+    method public static String toString-impl(int $this);
+    property public final int value;
+    field public static final androidx.compose.material.FabPosition.Companion Companion;
+  }
+
+  public static final class FabPosition.Companion {
+    method public int getCenter-5ygKITE();
+    method public int getEnd-5ygKITE();
+    property public final int Center;
+    property public final int End;
   }
 
   public final class FloatingActionButtonDefaults {
@@ -366,7 +379,7 @@
   }
 
   public final class ScaffoldKt {
-    method @androidx.compose.runtime.Composable public static void Scaffold-axyFlp8(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional androidx.compose.material.FabPosition floatingActionButtonPosition, optional boolean isFloatingActionButtonDocked, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Scaffold-axyFlp8(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional int floatingActionButtonPosition, optional boolean isFloatingActionButtonDocked, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static androidx.compose.material.ScaffoldState rememberScaffoldState(optional androidx.compose.material.DrawerState drawerState, optional androidx.compose.material.SnackbarHostState snackbarHostState);
   }
 
diff --git a/compose/material/material/api/current.ignore b/compose/material/material/api/current.ignore
new file mode 100644
index 0000000..ae87caf
--- /dev/null
+++ b/compose/material/material/api/current.ignore
@@ -0,0 +1,13 @@
+// Baseline format: 1.0
+ChangedSuperclass: androidx.compose.material.FabPosition:
+    Class androidx.compose.material.FabPosition superclass changed from java.lang.Enum to java.lang.Object
+
+
+RemovedField: androidx.compose.material.FabPosition#Center:
+    Removed enum constant androidx.compose.material.FabPosition.Center
+RemovedField: androidx.compose.material.FabPosition#End:
+    Removed enum constant androidx.compose.material.FabPosition.End
+
+
+RemovedMethod: androidx.compose.material.ScaffoldKt#Scaffold-axyFlp8(androidx.compose.ui.Modifier, androidx.compose.material.ScaffoldState, kotlin.jvm.functions.Function0<kotlin.Unit>, kotlin.jvm.functions.Function0<kotlin.Unit>, kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit>, kotlin.jvm.functions.Function0<kotlin.Unit>, androidx.compose.material.FabPosition, boolean, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>, boolean, androidx.compose.ui.graphics.Shape, float, long, long, long, long, long, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit>):
+    Removed method androidx.compose.material.ScaffoldKt.Scaffold-axyFlp8(androidx.compose.ui.Modifier,androidx.compose.material.ScaffoldState,kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit>,kotlin.jvm.functions.Function0<kotlin.Unit>,androidx.compose.material.FabPosition,boolean,kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>,boolean,androidx.compose.ui.graphics.Shape,float,long,long,long,long,long,kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit>)
diff --git a/compose/material/material/api/current.txt b/compose/material/material/api/current.txt
index 7cedeb6..ff9ea09 100644
--- a/compose/material/material/api/current.txt
+++ b/compose/material/material/api/current.txt
@@ -250,9 +250,22 @@
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ElevationOverlay> getLocalElevationOverlay();
   }
 
-  public enum FabPosition {
-    enum_constant public static final androidx.compose.material.FabPosition Center;
-    enum_constant public static final androidx.compose.material.FabPosition End;
+  public final inline class FabPosition {
+    ctor public FabPosition();
+    method public static inline boolean equals-impl(int p, Object? p1);
+    method public static boolean equals-impl0(int p1, int p2);
+    method public int getValue();
+    method public static inline int hashCode-impl(int p);
+    method public static String toString-impl(int $this);
+    property public final int value;
+    field public static final androidx.compose.material.FabPosition.Companion Companion;
+  }
+
+  public static final class FabPosition.Companion {
+    method public int getCenter-5ygKITE();
+    method public int getEnd-5ygKITE();
+    property public final int Center;
+    property public final int End;
   }
 
   public final class FloatingActionButtonDefaults {
@@ -366,7 +379,7 @@
   }
 
   public final class ScaffoldKt {
-    method @androidx.compose.runtime.Composable public static void Scaffold-axyFlp8(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional androidx.compose.material.FabPosition floatingActionButtonPosition, optional boolean isFloatingActionButtonDocked, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Scaffold-axyFlp8(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional int floatingActionButtonPosition, optional boolean isFloatingActionButtonDocked, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static androidx.compose.material.ScaffoldState rememberScaffoldState(optional androidx.compose.material.DrawerState drawerState, optional androidx.compose.material.SnackbarHostState snackbarHostState);
   }
 
diff --git a/compose/material/material/api/public_plus_experimental_1.0.0-beta08.txt b/compose/material/material/api/public_plus_experimental_1.0.0-beta08.txt
index 5dd28c8..57df28b 100644
--- a/compose/material/material/api/public_plus_experimental_1.0.0-beta08.txt
+++ b/compose/material/material/api/public_plus_experimental_1.0.0-beta08.txt
@@ -115,7 +115,7 @@
   }
 
   public final class BottomSheetScaffoldKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BottomSheetScaffold-0Ttp7_s(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> sheetContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BottomSheetScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit>? topBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit>? floatingActionButton, optional androidx.compose.material.FabPosition floatingActionButtonPosition, optional boolean sheetGesturesEnabled, optional androidx.compose.ui.graphics.Shape sheetShape, optional float sheetElevation, optional long sheetBackgroundColor, optional long sheetContentColor, optional float sheetPeekHeight, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BottomSheetScaffold-0Ttp7_s(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> sheetContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BottomSheetScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit>? topBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit>? floatingActionButton, optional int floatingActionButtonPosition, optional boolean sheetGesturesEnabled, optional androidx.compose.ui.graphics.Shape sheetShape, optional float sheetElevation, optional long sheetBackgroundColor, optional long sheetContentColor, optional float sheetPeekHeight, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
     method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BottomSheetScaffoldState rememberBottomSheetScaffoldState(optional androidx.compose.material.DrawerState drawerState, optional androidx.compose.material.BottomSheetState bottomSheetState, optional androidx.compose.material.SnackbarHostState snackbarHostState);
     method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BottomSheetState rememberBottomSheetState(androidx.compose.material.BottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
   }
@@ -357,9 +357,22 @@
   @kotlin.RequiresOptIn(message="This material API is experimental and is likely to change or to be removed in" + " the future.") public @interface ExperimentalMaterialApi {
   }
 
-  public enum FabPosition {
-    enum_constant public static final androidx.compose.material.FabPosition Center;
-    enum_constant public static final androidx.compose.material.FabPosition End;
+  public final inline class FabPosition {
+    ctor public FabPosition();
+    method public static inline boolean equals-impl(int p, Object? p1);
+    method public static boolean equals-impl0(int p1, int p2);
+    method public int getValue();
+    method public static inline int hashCode-impl(int p);
+    method public static String toString-impl(int $this);
+    property public final int value;
+    field public static final androidx.compose.material.FabPosition.Companion Companion;
+  }
+
+  public static final class FabPosition.Companion {
+    method public int getCenter-5ygKITE();
+    method public int getEnd-5ygKITE();
+    property public final int Center;
+    property public final int End;
   }
 
   @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class FixedThreshold implements androidx.compose.material.ThresholdConfig {
@@ -506,7 +519,7 @@
   }
 
   public final class ScaffoldKt {
-    method @androidx.compose.runtime.Composable public static void Scaffold-axyFlp8(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional androidx.compose.material.FabPosition floatingActionButtonPosition, optional boolean isFloatingActionButtonDocked, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Scaffold-axyFlp8(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional int floatingActionButtonPosition, optional boolean isFloatingActionButtonDocked, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static androidx.compose.material.ScaffoldState rememberScaffoldState(optional androidx.compose.material.DrawerState drawerState, optional androidx.compose.material.SnackbarHostState snackbarHostState);
   }
 
diff --git a/compose/material/material/api/public_plus_experimental_current.txt b/compose/material/material/api/public_plus_experimental_current.txt
index 5dd28c8..57df28b 100644
--- a/compose/material/material/api/public_plus_experimental_current.txt
+++ b/compose/material/material/api/public_plus_experimental_current.txt
@@ -115,7 +115,7 @@
   }
 
   public final class BottomSheetScaffoldKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BottomSheetScaffold-0Ttp7_s(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> sheetContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BottomSheetScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit>? topBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit>? floatingActionButton, optional androidx.compose.material.FabPosition floatingActionButtonPosition, optional boolean sheetGesturesEnabled, optional androidx.compose.ui.graphics.Shape sheetShape, optional float sheetElevation, optional long sheetBackgroundColor, optional long sheetContentColor, optional float sheetPeekHeight, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BottomSheetScaffold-0Ttp7_s(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> sheetContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BottomSheetScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit>? topBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit>? floatingActionButton, optional int floatingActionButtonPosition, optional boolean sheetGesturesEnabled, optional androidx.compose.ui.graphics.Shape sheetShape, optional float sheetElevation, optional long sheetBackgroundColor, optional long sheetContentColor, optional float sheetPeekHeight, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
     method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BottomSheetScaffoldState rememberBottomSheetScaffoldState(optional androidx.compose.material.DrawerState drawerState, optional androidx.compose.material.BottomSheetState bottomSheetState, optional androidx.compose.material.SnackbarHostState snackbarHostState);
     method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BottomSheetState rememberBottomSheetState(androidx.compose.material.BottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
   }
@@ -357,9 +357,22 @@
   @kotlin.RequiresOptIn(message="This material API is experimental and is likely to change or to be removed in" + " the future.") public @interface ExperimentalMaterialApi {
   }
 
-  public enum FabPosition {
-    enum_constant public static final androidx.compose.material.FabPosition Center;
-    enum_constant public static final androidx.compose.material.FabPosition End;
+  public final inline class FabPosition {
+    ctor public FabPosition();
+    method public static inline boolean equals-impl(int p, Object? p1);
+    method public static boolean equals-impl0(int p1, int p2);
+    method public int getValue();
+    method public static inline int hashCode-impl(int p);
+    method public static String toString-impl(int $this);
+    property public final int value;
+    field public static final androidx.compose.material.FabPosition.Companion Companion;
+  }
+
+  public static final class FabPosition.Companion {
+    method public int getCenter-5ygKITE();
+    method public int getEnd-5ygKITE();
+    property public final int Center;
+    property public final int End;
   }
 
   @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class FixedThreshold implements androidx.compose.material.ThresholdConfig {
@@ -506,7 +519,7 @@
   }
 
   public final class ScaffoldKt {
-    method @androidx.compose.runtime.Composable public static void Scaffold-axyFlp8(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional androidx.compose.material.FabPosition floatingActionButtonPosition, optional boolean isFloatingActionButtonDocked, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Scaffold-axyFlp8(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional int floatingActionButtonPosition, optional boolean isFloatingActionButtonDocked, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static androidx.compose.material.ScaffoldState rememberScaffoldState(optional androidx.compose.material.DrawerState drawerState, optional androidx.compose.material.SnackbarHostState snackbarHostState);
   }
 
diff --git a/compose/material/material/api/restricted_1.0.0-beta08.txt b/compose/material/material/api/restricted_1.0.0-beta08.txt
index 7cedeb6..ff9ea09 100644
--- a/compose/material/material/api/restricted_1.0.0-beta08.txt
+++ b/compose/material/material/api/restricted_1.0.0-beta08.txt
@@ -250,9 +250,22 @@
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ElevationOverlay> getLocalElevationOverlay();
   }
 
-  public enum FabPosition {
-    enum_constant public static final androidx.compose.material.FabPosition Center;
-    enum_constant public static final androidx.compose.material.FabPosition End;
+  public final inline class FabPosition {
+    ctor public FabPosition();
+    method public static inline boolean equals-impl(int p, Object? p1);
+    method public static boolean equals-impl0(int p1, int p2);
+    method public int getValue();
+    method public static inline int hashCode-impl(int p);
+    method public static String toString-impl(int $this);
+    property public final int value;
+    field public static final androidx.compose.material.FabPosition.Companion Companion;
+  }
+
+  public static final class FabPosition.Companion {
+    method public int getCenter-5ygKITE();
+    method public int getEnd-5ygKITE();
+    property public final int Center;
+    property public final int End;
   }
 
   public final class FloatingActionButtonDefaults {
@@ -366,7 +379,7 @@
   }
 
   public final class ScaffoldKt {
-    method @androidx.compose.runtime.Composable public static void Scaffold-axyFlp8(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional androidx.compose.material.FabPosition floatingActionButtonPosition, optional boolean isFloatingActionButtonDocked, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Scaffold-axyFlp8(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional int floatingActionButtonPosition, optional boolean isFloatingActionButtonDocked, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static androidx.compose.material.ScaffoldState rememberScaffoldState(optional androidx.compose.material.DrawerState drawerState, optional androidx.compose.material.SnackbarHostState snackbarHostState);
   }
 
diff --git a/compose/material/material/api/restricted_current.ignore b/compose/material/material/api/restricted_current.ignore
new file mode 100644
index 0000000..ae87caf
--- /dev/null
+++ b/compose/material/material/api/restricted_current.ignore
@@ -0,0 +1,13 @@
+// Baseline format: 1.0
+ChangedSuperclass: androidx.compose.material.FabPosition:
+    Class androidx.compose.material.FabPosition superclass changed from java.lang.Enum to java.lang.Object
+
+
+RemovedField: androidx.compose.material.FabPosition#Center:
+    Removed enum constant androidx.compose.material.FabPosition.Center
+RemovedField: androidx.compose.material.FabPosition#End:
+    Removed enum constant androidx.compose.material.FabPosition.End
+
+
+RemovedMethod: androidx.compose.material.ScaffoldKt#Scaffold-axyFlp8(androidx.compose.ui.Modifier, androidx.compose.material.ScaffoldState, kotlin.jvm.functions.Function0<kotlin.Unit>, kotlin.jvm.functions.Function0<kotlin.Unit>, kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit>, kotlin.jvm.functions.Function0<kotlin.Unit>, androidx.compose.material.FabPosition, boolean, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>, boolean, androidx.compose.ui.graphics.Shape, float, long, long, long, long, long, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit>):
+    Removed method androidx.compose.material.ScaffoldKt.Scaffold-axyFlp8(androidx.compose.ui.Modifier,androidx.compose.material.ScaffoldState,kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit>,kotlin.jvm.functions.Function0<kotlin.Unit>,androidx.compose.material.FabPosition,boolean,kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>,boolean,androidx.compose.ui.graphics.Shape,float,long,long,long,long,long,kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit>)
diff --git a/compose/material/material/api/restricted_current.txt b/compose/material/material/api/restricted_current.txt
index 7cedeb6..ff9ea09 100644
--- a/compose/material/material/api/restricted_current.txt
+++ b/compose/material/material/api/restricted_current.txt
@@ -250,9 +250,22 @@
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ElevationOverlay> getLocalElevationOverlay();
   }
 
-  public enum FabPosition {
-    enum_constant public static final androidx.compose.material.FabPosition Center;
-    enum_constant public static final androidx.compose.material.FabPosition End;
+  public final inline class FabPosition {
+    ctor public FabPosition();
+    method public static inline boolean equals-impl(int p, Object? p1);
+    method public static boolean equals-impl0(int p1, int p2);
+    method public int getValue();
+    method public static inline int hashCode-impl(int p);
+    method public static String toString-impl(int $this);
+    property public final int value;
+    field public static final androidx.compose.material.FabPosition.Companion Companion;
+  }
+
+  public static final class FabPosition.Companion {
+    method public int getCenter-5ygKITE();
+    method public int getEnd-5ygKITE();
+    property public final int Center;
+    property public final int End;
   }
 
   public final class FloatingActionButtonDefaults {
@@ -366,7 +379,7 @@
   }
 
   public final class ScaffoldKt {
-    method @androidx.compose.runtime.Composable public static void Scaffold-axyFlp8(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional androidx.compose.material.FabPosition floatingActionButtonPosition, optional boolean isFloatingActionButtonDocked, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Scaffold-axyFlp8(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional int floatingActionButtonPosition, optional boolean isFloatingActionButtonDocked, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static androidx.compose.material.ScaffoldState rememberScaffoldState(optional androidx.compose.material.DrawerState drawerState, optional androidx.compose.material.SnackbarHostState snackbarHostState);
   }
 
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 dbda4a7..c8d1bd0 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
@@ -20,6 +20,7 @@
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
@@ -369,6 +370,23 @@
     }
 
     @Test
+    fun slider_min_size() {
+        rule.setMaterialContent {
+            Box(Modifier.requiredSize(0.dp)) {
+                Slider(
+                    modifier = Modifier.testTag(tag),
+                    value = 0f,
+                    onValueChange = { }
+                )
+            }
+        }
+
+        rule.onNodeWithTag(tag)
+            .assertWidthIsEqualTo(ThumbRadius * 2)
+            .assertHeightIsEqualTo(ThumbRadius * 2)
+    }
+
+    @Test
     fun slider_noUnwantedCallbackCalls() {
         val state = mutableStateOf(0f)
         val callCount = mutableStateOf(0f)
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
index acce578..ad8e5d9 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
@@ -406,7 +406,7 @@
 
             val fabOffsetX = when (floatingActionButtonPosition) {
                 FabPosition.Center -> (placeable.width - fabPlaceable.width) / 2
-                FabPosition.End -> placeable.width - fabPlaceable.width - FabEndSpacing.roundToPx()
+                else -> placeable.width - fabPlaceable.width - FabEndSpacing.roundToPx()
             }
             val fabOffsetY = sheetOffsetY - fabPlaceable.height / 2
 
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Scaffold.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Scaffold.kt
index c261b7d..0c38d82 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Scaffold.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Scaffold.kt
@@ -69,19 +69,28 @@
 /**
  * The possible positions for a [FloatingActionButton] attached to a [Scaffold].
  */
-enum class FabPosition {
-    /**
-     * Position FAB at the bottom of the screen in the center, above the [BottomAppBar] (if it
-     * exists)
-     */
+@Suppress("INLINE_CLASS_DEPRECATED", "EXPERIMENTAL_FEATURE_WARNING")
+inline class FabPosition internal constructor(val value: Int) {
+    companion object {
+        /**
+         * Position FAB at the bottom of the screen in the center, above the [BottomAppBar] (if it
+         * exists)
+         */
+        val Center = FabPosition(0)
 
-    Center,
+        /**
+         * Position FAB at the bottom of the screen at the end, above the [BottomAppBar] (if it
+         * exists)
+         */
+        val End = FabPosition(1)
+    }
 
-    /**
-     * Position FAB at the bottom of the screen at the end, above the [BottomAppBar] (if it
-     * exists)
-     */
-    End
+    override fun toString(): String {
+        return when (this) {
+            Center -> "FabPosition.Center"
+            else -> "FabPosition.End"
+        }
+    }
 }
 
 /**
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 f2a1a77..090084f 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
@@ -39,6 +39,7 @@
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.heightIn
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.requiredSizeIn
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.widthIn
 import androidx.compose.foundation.progressSemantics
@@ -140,7 +141,9 @@
         if (steps == 0) emptyList() else List(steps + 2) { it.toFloat() / (steps + 1) }
     }
     BoxWithConstraints(
-        modifier.sliderSemantics(value, tickFractions, enabled, onValueChange, valueRange, steps)
+        modifier
+            .requiredSizeIn(minWidth = ThumbRadius * 2, minHeight = ThumbRadius * 2)
+            .sliderSemantics(value, tickFractions, enabled, onValueChange, valueRange, steps)
     ) {
         val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
         val maxPx = constraints.maxWidth.toFloat()
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
index e8ff224..76af048 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
@@ -3081,9 +3081,10 @@
         value: Int,
         noinline block: T.(value: Int) -> Unit
     ) = with(composer) {
+        val inserting = inserting
         if (inserting || rememberedValue() != value) {
             updateRememberedValue(value)
-            composer.apply(value, block)
+            if (!inserting) apply(value, block)
         }
     }
 
@@ -3102,9 +3103,10 @@
         value: V,
         block: T.(value: V) -> Unit
     ) = with(composer) {
+        val inserting = inserting
         if (inserting || rememberedValue() != value) {
             updateRememberedValue(value)
-            composer.apply(value, block)
+            if (!inserting) apply(value, block)
         }
     }
 
diff --git a/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/CompositionTests.kt b/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/CompositionTests.kt
index 7e07357..bc34c6e 100644
--- a/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/CompositionTests.kt
+++ b/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/CompositionTests.kt
@@ -2944,6 +2944,65 @@
         stateA++
         advance()
     }
+
+    /**
+     * set should set the value every time, update should only set after initial composition.
+     */
+    @OptIn(ExperimentalCoroutinesApi::class)
+    @Test
+    fun composeNodeSetVsUpdate() = runBlockingTest {
+        localRecomposerTest { recomposer ->
+            class SetUpdateNode(property: String) {
+                var changeCount = 0
+                var property: String = property
+                    set(value) {
+                        field = value
+                        changeCount++
+                    }
+            }
+            class SetUpdateNodeApplier : AbstractApplier<SetUpdateNode>(SetUpdateNode("root")) {
+                override fun insertTopDown(index: Int, instance: SetUpdateNode) {}
+                override fun insertBottomUp(index: Int, instance: SetUpdateNode) {}
+                override fun remove(index: Int, count: Int) {}
+                override fun move(from: Int, to: Int, count: Int) {}
+                override fun onClear() {}
+            }
+            val composition = Composition(SetUpdateNodeApplier(), recomposer)
+            val nodes = mutableListOf<SetUpdateNode>()
+            fun makeNode(property: String) = SetUpdateNode(property).also { nodes += it }
+
+            var value by mutableStateOf("initial")
+
+            composition.setContent {
+                ComposeNode<SetUpdateNode, SetUpdateNodeApplier>(
+                    factory = { makeNode(value) },
+                    update = {
+                        set(value) { property = value }
+                    }
+                )
+                ComposeNode<SetUpdateNode, SetUpdateNodeApplier>(
+                    factory = { makeNode(value) },
+                    update = {
+                        update(value) { property = value }
+                    }
+                )
+            }
+
+            assertEquals("initial", nodes[0].property, "node 0 initial composition value")
+            assertEquals("initial", nodes[1].property, "node 1 initial composition value")
+            assertEquals(1, nodes[0].changeCount, "node 0 initial composition changeCount")
+            assertEquals(0, nodes[1].changeCount, "node 1 initial composition changeCount")
+
+            value = "changed"
+            Snapshot.sendApplyNotifications()
+            advanceUntilIdle()
+
+            assertEquals("changed", nodes[0].property, "node 0 recomposition value")
+            assertEquals("changed", nodes[1].property, "node 1 recomposition value")
+            assertEquals(2, nodes[0].changeCount, "node 0 recomposition changeCount")
+            assertEquals(1, nodes[1].changeCount, "node 1 recomposition changeCount")
+        }
+    }
 }
 
 var stateA by mutableStateOf(1000)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/vector/VectorTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/vector/VectorTest.kt
index 60dfe8c..383b749 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/vector/VectorTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/vector/VectorTest.kt
@@ -305,6 +305,44 @@
         rule.onNodeWithTag(testTag).captureToImage().assertPixels { Color.Blue }
     }
 
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun testVectorChangeSize() {
+        val size = mutableStateOf(200)
+        val color = mutableStateOf(Color.Magenta)
+
+        rule.setContent {
+            val background = Modifier.background(Color.Red).paint(
+                createTestVectorPainter(size.value, color.value),
+                alignment = Alignment.TopStart
+            )
+            AtLeastSize(size = 400, modifier = background) {
+            }
+        }
+
+        takeScreenShot(400).apply {
+            assertEquals(getPixel(100, 100), Color.Magenta.toArgb())
+            assertEquals(getPixel(300, 300), Color.Red.toArgb())
+        }
+
+        size.value = 400
+        color.value = Color.Cyan
+
+        takeScreenShot(400).apply {
+            assertEquals(getPixel(100, 100), Color.Cyan.toArgb())
+            assertEquals(getPixel(300, 300), Color.Cyan.toArgb())
+        }
+
+        size.value = 50
+        color.value = Color.Yellow
+
+        takeScreenShot(400).apply {
+            assertEquals(getPixel(10, 10), Color.Yellow.toArgb())
+            assertEquals(getPixel(100, 100), Color.Red.toArgb())
+            assertEquals(getPixel(300, 300), Color.Red.toArgb())
+        }
+    }
+
     @Composable
     private fun VectorTint(
         size: Int = 200,
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidViewCompatTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidViewCompatTest.kt
index 3aa73c6..b55814c 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidViewCompatTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidViewCompatTest.kt
@@ -639,6 +639,50 @@
             .assertPixels(expectedColorProvider = offsetColorProvider)
     }
 
+    @Test
+    fun testInvalidationsDuringDraw_withLayerInBetween() {
+        var view: InvalidateDuringComputeScroll? = null
+        rule.setContent {
+            val context = LocalContext.current
+            view = remember { InvalidateDuringComputeScroll(context) }
+            // Note having a graphics layer here will cause the updateDisplayList to not happen
+            // in the initial redraw traversal.
+            AndroidView(factory = { view!! }, modifier = Modifier.graphicsLayer().graphicsLayer())
+        }
+
+        val invalidatesDuringScroll = 4
+        rule.runOnIdle {
+            view!!.apply {
+                draws = 0
+                this.invalidatesDuringScroll = invalidatesDuringScroll
+                invalidate()
+            }
+        }
+
+        rule.runOnIdle { assertEquals(invalidatesDuringScroll + 1, view!!.draws) }
+    }
+
+    @Test
+    fun testInvalidationsDuringDraw_sameLayerAsAndroidComposeView() {
+        var view: InvalidateDuringComputeScroll? = null
+        rule.setContent {
+            val context = LocalContext.current
+            view = remember { InvalidateDuringComputeScroll(context) }
+            AndroidView(factory = { view!! })
+        }
+
+        val invalidatesDuringScroll = 4
+        rule.runOnIdle {
+            view!!.apply {
+                draws = 0
+                this.invalidatesDuringScroll = invalidatesDuringScroll
+                invalidate()
+            }
+        }
+
+        rule.runOnIdle { assertEquals(invalidatesDuringScroll + 1, view!!.draws) }
+    }
+
     class ColoredSquareView(context: Context) : View(context) {
         var size: Int = 100
             set(value) {
@@ -696,6 +740,23 @@
         }
     }
 
+    class InvalidateDuringComputeScroll(context: Context) : View(context) {
+        var draws = 0
+        var invalidatesDuringScroll = 0
+
+        override fun computeScroll() {
+            if (invalidatesDuringScroll > 0) {
+                --invalidatesDuringScroll
+                invalidate()
+            }
+        }
+
+        override fun onDraw(canvas: Canvas?) {
+            super.onDraw(canvas)
+            ++draws
+        }
+    }
+
     fun Modifier.layoutConstraints(childConstraints: Constraints): Modifier =
         this.then(object : LayoutModifier {
             override fun MeasureScope.measure(
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
index cdff2ff..d22435d 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
@@ -191,7 +191,12 @@
     override val autofillTree = AutofillTree()
 
     // OwnedLayers that are dirty and should be redrawn.
-    internal val dirtyLayers = mutableListOf<OwnedLayer>()
+    private val dirtyLayers = mutableListOf<OwnedLayer>()
+    // OwnerLayers that invalidated themselves during their last draw. They will be redrawn
+    // during the next AndroidComposeView dispatchDraw pass.
+    private var postponedDirtyLayers: MutableList<OwnedLayer>? = null
+
+    private var isDrawingContent = false
 
     private val motionEventAdapter = MotionEventAdapter()
     private val pointerInputEventProcessor = PointerInputEventProcessor(root)
@@ -639,6 +644,7 @@
         }
         measureAndLayout()
 
+        isDrawingContent = true
         // we don't have to observe here because the root has a layer modifier
         // that will observe all children. The AndroidComposeView has only the
         // root, so it doesn't have to invalidate itself based on model changes.
@@ -649,7 +655,6 @@
                 val layer = dirtyLayers[i]
                 layer.updateDisplayList()
             }
-            dirtyLayers.clear()
         }
 
         if (ViewLayer.shouldUseDispatchDraw) {
@@ -662,6 +667,33 @@
             super.dispatchDraw(canvas)
             canvas.restoreToCount(saveCount)
         }
+
+        dirtyLayers.clear()
+        isDrawingContent = false
+
+        // updateDisplayList operations performed above (during root.draw and during the explicit
+        // layer.updateDisplayList() calls) can result in the same layers being invalidated. These
+        // layers have been added to postponedDirtyLayers and will be redrawn during the next
+        // dispatchDraw.
+        if (postponedDirtyLayers != null) {
+            val postponed = postponedDirtyLayers!!
+            dirtyLayers.addAll(postponed)
+            postponed.clear()
+        }
+    }
+
+    internal fun notifyLayerIsDirty(layer: OwnedLayer, isDirty: Boolean) {
+        if (!isDirty) {
+            // It is correct to remove the layer here regardless of this if, but for performance
+            // we are hackily not doing the removal here in order to just do clear() a bit later.
+            if (!isDrawingContent) require(dirtyLayers.remove(layer))
+        } else if (!isDrawingContent) {
+            dirtyLayers += layer
+        } else {
+            val postponed = postponedDirtyLayers
+                ?: mutableListOf<OwnedLayer>().also { postponedDirtyLayers = it }
+            postponed += layer
+        }
     }
 
     /**
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/RenderNodeLayer.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/RenderNodeLayer.android.kt
index 061407a..94f6758 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/RenderNodeLayer.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/RenderNodeLayer.android.kt
@@ -50,6 +50,12 @@
      * True when the RenderNodeLayer has been invalidated and not yet drawn.
      */
     private var isDirty = false
+        set(value) {
+            if (value != field) {
+                field = value
+                ownerView.notifyLayerIsDirty(this, value)
+            }
+        }
     private val outlineResolver = OutlineResolver(ownerView.density)
     private var isDestroyed = false
     private var drawnWithZ = false
@@ -180,7 +186,6 @@
     override fun invalidate() {
         if (!isDirty && !isDestroyed) {
             ownerView.invalidate()
-            ownerView.dirtyLayers += this
             isDirty = true
         }
     }
@@ -213,23 +218,21 @@
             }
         } else {
             drawBlock(canvas)
+            isDirty = false
         }
-        isDirty = false
     }
 
     override fun updateDisplayList() {
         if (isDirty || !renderNode.hasDisplayList) {
-            val clipPath = if (renderNode.clipToOutline) outlineResolver.clipPath else null
-
-            renderNode.record(canvasHolder, clipPath, drawBlock)
-
             isDirty = false
+            val clipPath = if (renderNode.clipToOutline) outlineResolver.clipPath else null
+            renderNode.record(canvasHolder, clipPath, drawBlock)
         }
     }
 
     override fun destroy() {
         isDestroyed = true
-        ownerView.dirtyLayers -= this
+        isDirty = false
         ownerView.requestClearInvalidObservations()
     }
 
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ViewLayer.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ViewLayer.android.kt
index 2ce77b3..2c33801 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ViewLayer.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ViewLayer.android.kt
@@ -56,7 +56,12 @@
     private val manualClipPath: Path? get() =
         if (!clipToOutline) null else outlineResolver.clipPath
     var isInvalidated = false
-        private set
+        private set(value) {
+            if (value != field) {
+                field = value
+                ownerView.notifyLayerIsDirty(this, value)
+            }
+        }
     private var drawnWithZ = false
     private val canvasHolder = CanvasHolder()
 
@@ -225,6 +230,7 @@
     }
 
     override fun dispatchDraw(canvas: android.graphics.Canvas) {
+        isInvalidated = false
         canvasHolder.drawInto(canvas) {
             val clipPath = manualClipPath
             if (clipPath != null) {
@@ -235,7 +241,6 @@
             if (clipPath != null) {
                 restore()
             }
-            isInvalidated = false
         }
     }
 
@@ -243,7 +248,6 @@
         if (!isInvalidated) {
             isInvalidated = true
             super.invalidate()
-            ownerView.dirtyLayers += this
             ownerView.invalidate()
         }
     }
@@ -255,14 +259,14 @@
         container.postOnAnimation {
             container.removeView(this)
         }
-        ownerView.dirtyLayers -= this
+        isInvalidated = false
         ownerView.requestClearInvalidObservations()
     }
 
     override fun updateDisplayList() {
         if (isInvalidated && !shouldUseDispatchDraw) {
-            updateDisplayList(this)
             isInvalidated = false
+            updateDisplayList(this)
         }
     }
 
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/DrawCache.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/DrawCache.kt
index 99a0886..c11e511 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/DrawCache.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/DrawCache.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.ui.graphics.vector
 
-import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.BlendMode
 import androidx.compose.ui.graphics.Canvas
 import androidx.compose.ui.graphics.Color
@@ -43,6 +42,7 @@
     private var cachedCanvas: Canvas? = null
     private var scopeDensity: Density? = null
     private var layoutDirection: LayoutDirection = LayoutDirection.Ltr
+    private var size: IntSize = IntSize.Zero
 
     private val cacheScope = CanvasDrawScope()
 
@@ -72,6 +72,7 @@
             mCachedImage = targetImage
             cachedCanvas = targetCanvas
         }
+        this.size = size
         cacheScope.draw(density, layoutDirection, targetCanvas, size.toSize()) {
             clear()
             block()
@@ -92,7 +93,7 @@
             "drawCachedImage must be invoked first before attempting to draw the result " +
                 "into another destination"
         }
-        target.drawImage(targetImage, Offset.Zero, alpha = alpha, colorFilter = colorFilter)
+        target.drawImage(targetImage, srcSize = size, alpha = alpha, colorFilter = colorFilter)
     }
 
     /**
diff --git a/development/build_log_simplifier/message-flakes.ignore b/development/build_log_simplifier/message-flakes.ignore
index 843e9d4..f19cee7 100644
--- a/development/build_log_simplifier/message-flakes.ignore
+++ b/development/build_log_simplifier/message-flakes.ignore
@@ -75,3 +75,29 @@
 warning: ATTENTION!
 # b/185474400
 at org.gradle.*
+# > Task :internal-testutils-common:lintAnalyze
+Scanning .*:
+Failure reading binary cache file .*\.android\/cache\/api\-versions\-[0-9]+\-[0-9A-Z]+rev[0-9]+\.bin
+Please delete the file and restart the IDE\/lint\: .*\.android\/cache\/api\-versions\-[0-9]+\-[0-9]+rev[0-9]+\.bin
+java\.io\.FileNotFoundException\: .*\.android\/cache\/api\-versions\-[0-9]+\-[0-9]+rev[0-9]+\.bin \(No such file or directory\)
+at com\.google\.common\.io\.Files\$FileByteSource\.openStream\(Files\.java\:[0-9]+\)
+at com\.google\.common\.io\.Files\$FileByteSource\.read\(Files\.java\:[0-9]+\)
+at com\.google\.common\.io\.Files\.toByteArray\(Files\.java\:[0-9]+\)
+at com\.android\.tools\.lint\.checks\.ApiDatabase\.readData\(ApiDatabase\.java\:[0-9]+\)
+at com\.android\.tools\.lint\.checks\.ApiLookup\.\<init\>\(ApiLookup\.java\:[0-9]+\)
+at com\.android\.tools\.lint\.checks\.ApiLookup\.get\(ApiLookup\.java\:[0-9]+\)
+at com\.android\.tools\.lint\.checks\.ApiDetector\.beforeCheckRootProject\(ApiDetector\.kt\:[0-9]+\)
+at com\.android\.tools\.lint\.client\.api\.LintDriver\.checkProject\(LintDriver\.kt\:[0-9]+\)
+at com\.android\.tools\.lint\.client\.api\.LintDriver\.checkProjectRoot\(LintDriver\.kt\:[0-9]+\)
+at com\.android\.tools\.lint\.client\.api\.LintDriver\.access\$checkProjectRoot\(LintDriver\.kt\:[0-9]+\)
+at com\.android\.tools\.lint\.client\.api\.LintDriver\$analyzeOnly\$[0-9]+\.invoke\(LintDriver\.kt\:[0-9]+\)
+at com\.android\.tools\.lint\.client\.api\.LintDriver\.doAnalyze\(LintDriver\.kt\:[0-9]+\)
+at com\.android\.tools\.lint\.client\.api\.LintDriver\.analyzeOnly\(LintDriver\.kt\:[0-9]+\)
+at com\.android\.tools\.lint\.LintCliClient\$analyzeOnly\$[0-9]+\.invoke\(LintCliClient\.kt\:[0-9]+\)
+at com\.android\.tools\.lint\.LintCliClient\.run\(LintCliClient\.kt\:[0-9]+\)
+at com\.android\.tools\.lint\.LintCliClient\.run\$default\(LintCliClient\.kt\:[0-9]+\)
+at com\.android\.tools\.lint\.LintCliClient\.analyzeOnly\(LintCliClient\.kt\:[0-9]+\)
+at com\.android\.tools\.lint\.Main\.run\(Main\.java\:[0-9]+\)
+at com\.android\.build\.gradle\.internal\.lint\.AndroidLintWorkAction\.invokeLintMainRunMethod\(AndroidLintWorkAction\.kt\:[0-9]+\)
+at com\.android\.build\.gradle\.internal\.lint\.AndroidLintWorkAction\.runLint\(AndroidLintWorkAction\.kt\:[0-9]+\)
+at com\.android\.build\.gradle\.internal\.lint\.AndroidLintWorkAction\.execute\(AndroidLintWorkAction\.kt\:[0-9]+\)
diff --git a/development/referenceDocs/stageReferenceDocsWithDackka.sh b/development/referenceDocs/stageReferenceDocsWithDackka.sh
index b5689aa..cc34502 100755
--- a/development/referenceDocs/stageReferenceDocsWithDackka.sh
+++ b/development/referenceDocs/stageReferenceDocsWithDackka.sh
@@ -26,6 +26,7 @@
 #  "collection"
   "navigation"
   "paging"
+  "window"
 )
 readonly kotlinLibraryDirs=(
 #  "benchmark"
@@ -33,6 +34,7 @@
 #  "collection"
   "navigation"
 #  "paging"
+  "window"
 )
 
 
diff --git a/docs-tip-of-tree/build.gradle b/docs-tip-of-tree/build.gradle
index 69af6e3..1ffc337 100644
--- a/docs-tip-of-tree/build.gradle
+++ b/docs-tip-of-tree/build.gradle
@@ -208,6 +208,7 @@
     docs(project(":room:room-guava"))
     docs(project(":room:room-ktx"))
     docs(project(":room:room-migration"))
+    docs(project(":room:room-paging"))
     docs(project(":room:room-runtime"))
     docs(project(":room:room-rxjava2"))
     docs(project(":room:room-rxjava3"))
diff --git a/navigation/integration-tests/testapp/src/main/java/androidx/navigation/testapp/HelpActivity.kt b/navigation/integration-tests/testapp/src/main/java/androidx/navigation/testapp/HelpActivity.kt
index 55f03b2..5eb47d1 100644
--- a/navigation/integration-tests/testapp/src/main/java/androidx/navigation/testapp/HelpActivity.kt
+++ b/navigation/integration-tests/testapp/src/main/java/androidx/navigation/testapp/HelpActivity.kt
@@ -78,6 +78,7 @@
 }
 
 class BottomSheetNavigationView : BottomSheetDialogFragment() {
+    @Suppress("DEPRECATION")
     override fun onCreateView(
         inflater: LayoutInflater,
         container: ViewGroup?,
diff --git a/navigation/navigation-common/api/current.txt b/navigation/navigation-common/api/current.txt
index dda39ab..a889a60 100644
--- a/navigation/navigation-common/api/current.txt
+++ b/navigation/navigation-common/api/current.txt
@@ -226,7 +226,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
-    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
+    ctor @Deprecated public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
     ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, String? route);
     method public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
     method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
@@ -281,7 +281,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
-    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
+    ctor @Deprecated public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
     ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, String? route);
     method public final void addDestination(androidx.navigation.NavDestination destination);
     method public androidx.navigation.NavGraph build();
@@ -292,9 +292,9 @@
   }
 
   public final class NavGraphBuilderKt {
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
diff --git a/navigation/navigation-common/api/public_plus_experimental_current.txt b/navigation/navigation-common/api/public_plus_experimental_current.txt
index bd49a55..3dc13449 100644
--- a/navigation/navigation-common/api/public_plus_experimental_current.txt
+++ b/navigation/navigation-common/api/public_plus_experimental_current.txt
@@ -263,7 +263,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
-    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
+    ctor @Deprecated public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
     ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, String? route);
     method public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
     method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
@@ -322,7 +322,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
-    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
+    ctor @Deprecated public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
     ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, String? route);
     method public final void addDestination(androidx.navigation.NavDestination destination);
     method public androidx.navigation.NavGraph build();
@@ -333,9 +333,9 @@
   }
 
   public final class NavGraphBuilderKt {
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
diff --git a/navigation/navigation-common/api/restricted_current.txt b/navigation/navigation-common/api/restricted_current.txt
index dda39ab..a889a60 100644
--- a/navigation/navigation-common/api/restricted_current.txt
+++ b/navigation/navigation-common/api/restricted_current.txt
@@ -226,7 +226,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
-    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
+    ctor @Deprecated public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
     ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, String? route);
     method public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
     method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
@@ -281,7 +281,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
-    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
+    ctor @Deprecated public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
     ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, String? route);
     method public final void addDestination(androidx.navigation.NavDestination destination);
     method public androidx.navigation.NavGraph build();
@@ -292,9 +292,9 @@
   }
 
   public final class NavGraphBuilderKt {
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDestinationBuilderTest.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDestinationBuilderTest.kt
index 68fa76a..6572323 100644
--- a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDestinationBuilderTest.kt
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDestinationBuilderTest.kt
@@ -124,6 +124,7 @@
  * a NavDestination directly to allow for testing NavDestinationBuilder in
  * isolation.
  */
+@Suppress("DEPRECATION")
 fun NavigatorProvider.navDestination(
     @IdRes id: Int,
     builder: NavDestinationBuilder<NavDestination>.() -> Unit
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavGraphBuilderTest.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavGraphBuilderTest.kt
index cb75a08..69d1eda 100644
--- a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavGraphBuilderTest.kt
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavGraphBuilderTest.kt
@@ -32,6 +32,7 @@
         addNavigator(NoOpNavigator())
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun navigation() {
         val graph = provider.navigation(startDestination = DESTINATION_ID) {
@@ -54,6 +55,7 @@
             .isTrue()
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun navigationUnaryPlus() {
         val graph = provider.navigation(startDestination = DESTINATION_ID) {
@@ -80,6 +82,7 @@
             .isTrue()
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun navigationAddDestination() {
         val graph = provider.navigation(startDestination = DESTINATION_ID) {
@@ -108,6 +111,7 @@
             .isTrue()
     }
 
+    @Suppress("DEPRECATION")
     @Test(expected = IllegalStateException::class)
     fun navigationMissingStartDestination() {
         provider.navigation(startDestination = 0) {
@@ -124,6 +128,7 @@
         fail("NavGraph should throw IllegalStateException if no startDestinationRoute is set")
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun navigationNested() {
         val graph = provider.navigation(startDestination = DESTINATION_ID) {
@@ -158,6 +163,7 @@
  * Create a base NavDestination. Generally, only subtypes of NavDestination should be
  * added to a NavGraph (hence why this is not in the common-ktx library)
  */
+@Suppress("DEPRECATION")
 fun NavGraphBuilder.navDestination(
     @IdRes id: Int,
     builder: NavDestinationBuilder<NavDestination>.() -> Unit
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/NavDestinationBuilder.kt b/navigation/navigation-common/src/main/java/androidx/navigation/NavDestinationBuilder.kt
index f5453fd..22c9fa3 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/NavDestinationBuilder.kt
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/NavDestinationBuilder.kt
@@ -51,6 +51,10 @@
      *
      * @return the newly constructed [NavDestination]
      */
+    @Deprecated(
+        "Use routes to build your NavDestination instead",
+        ReplaceWith("NavDestinationBuilder(navigator, route = id.toString())")
+    )
     public constructor(navigator: Navigator<out D>, @IdRes id: Int) :
         this(navigator, id, null)
 
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/NavGraphBuilder.kt b/navigation/navigation-common/src/main/java/androidx/navigation/NavGraphBuilder.kt
index 28a4c0a..d69f5d2 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/NavGraphBuilder.kt
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/NavGraphBuilder.kt
@@ -27,6 +27,14 @@
  *
  * @return the newly constructed NavGraph
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to build your NavGraph instead",
+    ReplaceWith(
+        "navigation(startDestination = startDestination.toString(), route = id.toString()) " +
+            "{ builder.invoke() }"
+    )
+)
 public inline fun NavigatorProvider.navigation(
     @IdRes id: Int = 0,
     @IdRes startDestination: Int,
@@ -58,6 +66,14 @@
  *
  * @return the newly constructed nested NavGraph
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to build your nested NavGraph instead",
+    ReplaceWith(
+        "navigation(startDestination = startDestination.toString(), route = id.toString()) " +
+            "{ builder.invoke() }"
+    )
+)
 public inline fun NavGraphBuilder.navigation(
     @IdRes id: Int,
     @IdRes startDestination: Int,
@@ -100,6 +116,14 @@
      *
      * @return the newly created NavGraph
      */
+    @Suppress("Deprecation")
+    @Deprecated(
+        "Use routes to build your NavGraph instead",
+        ReplaceWith(
+            "NavGraphBuilder(provider, startDestination = startDestination.toString(), " +
+                "route = id.toString())"
+        )
+    )
     public constructor(
         provider: NavigatorProvider,
         @IdRes id: Int,
diff --git a/navigation/navigation-dynamic-features-fragment/api/current.txt b/navigation/navigation-dynamic-features-fragment/api/current.txt
index e6dd027..d42b4d5 100644
--- a/navigation/navigation-dynamic-features-fragment/api/current.txt
+++ b/navigation/navigation-dynamic-features-fragment/api/current.txt
@@ -15,7 +15,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class DynamicFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
-    ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, @IdRes int id, String fragmentClassName);
+    ctor @Deprecated public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, @IdRes int id, String fragmentClassName);
     ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, String route, String fragmentClassName);
     method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination build();
     method public String? getModuleName();
@@ -24,7 +24,7 @@
   }
 
   public final class DynamicFragmentNavigatorDestinationBuilderKt {
-    method public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
diff --git a/navigation/navigation-dynamic-features-fragment/api/public_plus_experimental_current.txt b/navigation/navigation-dynamic-features-fragment/api/public_plus_experimental_current.txt
index e6dd027..d42b4d5 100644
--- a/navigation/navigation-dynamic-features-fragment/api/public_plus_experimental_current.txt
+++ b/navigation/navigation-dynamic-features-fragment/api/public_plus_experimental_current.txt
@@ -15,7 +15,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class DynamicFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
-    ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, @IdRes int id, String fragmentClassName);
+    ctor @Deprecated public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, @IdRes int id, String fragmentClassName);
     ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, String route, String fragmentClassName);
     method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination build();
     method public String? getModuleName();
@@ -24,7 +24,7 @@
   }
 
   public final class DynamicFragmentNavigatorDestinationBuilderKt {
-    method public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
diff --git a/navigation/navigation-dynamic-features-fragment/api/restricted_current.txt b/navigation/navigation-dynamic-features-fragment/api/restricted_current.txt
index e6dd027..d42b4d5 100644
--- a/navigation/navigation-dynamic-features-fragment/api/restricted_current.txt
+++ b/navigation/navigation-dynamic-features-fragment/api/restricted_current.txt
@@ -15,7 +15,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class DynamicFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
-    ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, @IdRes int id, String fragmentClassName);
+    ctor @Deprecated public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, @IdRes int id, String fragmentClassName);
     ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, String route, String fragmentClassName);
     method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination build();
     method public String? getModuleName();
@@ -24,7 +24,7 @@
   }
 
   public final class DynamicFragmentNavigatorDestinationBuilderKt {
-    method public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id);
     method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
diff --git a/navigation/navigation-dynamic-features-fragment/src/androidTest/java/androidx/navigation/dynamicfeatures/fragment/DynamicFragmentNavigatorDestinationBuilderTest.kt b/navigation/navigation-dynamic-features-fragment/src/androidTest/java/androidx/navigation/dynamicfeatures/fragment/DynamicFragmentNavigatorDestinationBuilderTest.kt
index 30da2f9..9a18178 100644
--- a/navigation/navigation-dynamic-features-fragment/src/androidTest/java/androidx/navigation/dynamicfeatures/fragment/DynamicFragmentNavigatorDestinationBuilderTest.kt
+++ b/navigation/navigation-dynamic-features-fragment/src/androidTest/java/androidx/navigation/dynamicfeatures/fragment/DynamicFragmentNavigatorDestinationBuilderTest.kt
@@ -40,6 +40,7 @@
     )
     private val fragmentManager get() = rule.withActivity { supportFragmentManager }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     public fun reified() {
@@ -56,6 +57,7 @@
             .isEqualTo(TestFragment::class.java.name)
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     public fun moduleName() {
@@ -77,6 +79,7 @@
             .isEqualTo(MODULE_NAME)
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     public fun no_moduleName() {
diff --git a/navigation/navigation-dynamic-features-fragment/src/main/java/androidx/navigation/dynamicfeatures/fragment/DynamicFragmentNavigatorDestinationBuilder.kt b/navigation/navigation-dynamic-features-fragment/src/main/java/androidx/navigation/dynamicfeatures/fragment/DynamicFragmentNavigatorDestinationBuilder.kt
index dd0b7f2..d337aa2 100644
--- a/navigation/navigation-dynamic-features-fragment/src/main/java/androidx/navigation/dynamicfeatures/fragment/DynamicFragmentNavigatorDestinationBuilder.kt
+++ b/navigation/navigation-dynamic-features-fragment/src/main/java/androidx/navigation/dynamicfeatures/fragment/DynamicFragmentNavigatorDestinationBuilder.kt
@@ -29,6 +29,11 @@
  * Construct a new [DynamicFragmentNavigator.Destination]
  * @param id Destination id.
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to create your DynamicFragmentDestination instead",
+    ReplaceWith("fragment(route = id.toString())")
+)
 public inline fun <reified F : Fragment> DynamicNavGraphBuilder.fragment(
     @IdRes id: Int
 ): Unit = fragment<F>(id) {}
@@ -37,6 +42,11 @@
  * Construct a new [DynamicFragmentNavigator.Destination]
  * @param id Destination id.
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to create your DynamicFragmentDestination instead",
+    ReplaceWith("fragment(route = id.toString()) { builder.invoke() }")
+)
 public inline fun <reified F : Fragment> DynamicNavGraphBuilder.fragment(
     @IdRes id: Int,
     builder: DynamicFragmentNavigatorDestinationBuilder.() -> Unit
@@ -47,6 +57,11 @@
  * @param id Destination id.
  * @param fragmentClassName Fully qualified class name of destination Fragment.
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to create your DynamicFragmentDestination instead",
+    ReplaceWith("fragment(route = id.toString(), fragmentClassName) { builder.invoke() }")
+)
 public inline fun DynamicNavGraphBuilder.fragment(
     @IdRes id: Int,
     fragmentClassName: String,
@@ -102,6 +117,14 @@
 
     private var fragmentClassName: String
 
+    @Suppress("Deprecation")
+    @Deprecated(
+        "Use routes to create your DynamicFragmentDestinationBuilder instead",
+        ReplaceWith(
+            "DynamicFragmentNavigatorDestinationBuilder(navigator, route = id.toString(), " +
+                "fragmentClassName)"
+        )
+    )
     public constructor(
         navigator: DynamicFragmentNavigator,
         @IdRes id: Int,
diff --git a/navigation/navigation-dynamic-features-runtime/api/current.txt b/navigation/navigation-dynamic-features-runtime/api/current.txt
index 9807b58..ea49279 100644
--- a/navigation/navigation-dynamic-features-runtime/api/current.txt
+++ b/navigation/navigation-dynamic-features-runtime/api/current.txt
@@ -15,7 +15,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class DynamicActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
-    ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, @IdRes int id);
+    ctor @Deprecated public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, @IdRes int id);
     ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, String route);
     method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination build();
     method public String? getAction();
@@ -39,7 +39,7 @@
   }
 
   public final class DynamicActivityNavigatorDestinationBuilderKt {
-    method public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
@@ -87,7 +87,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class DynamicIncludeNavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
-    ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, @IdRes int id, String moduleName, String graphResourceName);
+    ctor @Deprecated public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, @IdRes int id, String moduleName, String graphResourceName);
     ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, String route, String moduleName, String graphResourceName);
     method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph build();
     method public String? getGraphPackage();
@@ -96,8 +96,8 @@
   }
 
   public final class DynamicIncludeNavGraphBuilderKt {
-    method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName);
-    method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName);
+    method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
     method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName);
     method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
   }
@@ -120,7 +120,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class DynamicNavGraphBuilder extends androidx.navigation.NavGraphBuilder {
-    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
+    ctor @Deprecated public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
     ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, optional String? route);
     method public String? getModuleName();
     method public int getProgressDestination();
@@ -134,19 +134,20 @@
   }
 
   public final class DynamicNavGraphBuilderKt {
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavControllerKt {
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavHostKt {
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
 }
diff --git a/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_current.txt b/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_current.txt
index 9807b58..ea49279 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
@@ -15,7 +15,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class DynamicActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
-    ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, @IdRes int id);
+    ctor @Deprecated public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, @IdRes int id);
     ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, String route);
     method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination build();
     method public String? getAction();
@@ -39,7 +39,7 @@
   }
 
   public final class DynamicActivityNavigatorDestinationBuilderKt {
-    method public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
@@ -87,7 +87,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class DynamicIncludeNavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
-    ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, @IdRes int id, String moduleName, String graphResourceName);
+    ctor @Deprecated public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, @IdRes int id, String moduleName, String graphResourceName);
     ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, String route, String moduleName, String graphResourceName);
     method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph build();
     method public String? getGraphPackage();
@@ -96,8 +96,8 @@
   }
 
   public final class DynamicIncludeNavGraphBuilderKt {
-    method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName);
-    method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName);
+    method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
     method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName);
     method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
   }
@@ -120,7 +120,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class DynamicNavGraphBuilder extends androidx.navigation.NavGraphBuilder {
-    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
+    ctor @Deprecated public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
     ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, optional String? route);
     method public String? getModuleName();
     method public int getProgressDestination();
@@ -134,19 +134,20 @@
   }
 
   public final class DynamicNavGraphBuilderKt {
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavControllerKt {
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavHostKt {
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
 }
diff --git a/navigation/navigation-dynamic-features-runtime/api/restricted_current.txt b/navigation/navigation-dynamic-features-runtime/api/restricted_current.txt
index 9807b58..ea49279 100644
--- a/navigation/navigation-dynamic-features-runtime/api/restricted_current.txt
+++ b/navigation/navigation-dynamic-features-runtime/api/restricted_current.txt
@@ -15,7 +15,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class DynamicActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
-    ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, @IdRes int id);
+    ctor @Deprecated public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, @IdRes int id);
     ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, String route);
     method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination build();
     method public String? getAction();
@@ -39,7 +39,7 @@
   }
 
   public final class DynamicActivityNavigatorDestinationBuilderKt {
-    method public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
@@ -87,7 +87,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class DynamicIncludeNavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
-    ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, @IdRes int id, String moduleName, String graphResourceName);
+    ctor @Deprecated public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, @IdRes int id, String moduleName, String graphResourceName);
     ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, String route, String moduleName, String graphResourceName);
     method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph build();
     method public String? getGraphPackage();
@@ -96,8 +96,8 @@
   }
 
   public final class DynamicIncludeNavGraphBuilderKt {
-    method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName);
-    method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName);
+    method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
     method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName);
     method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
   }
@@ -120,7 +120,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class DynamicNavGraphBuilder extends androidx.navigation.NavGraphBuilder {
-    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
+    ctor @Deprecated public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
     ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, optional String? route);
     method public String? getModuleName();
     method public int getProgressDestination();
@@ -134,19 +134,20 @@
   }
 
   public final class DynamicNavGraphBuilderKt {
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavControllerKt {
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
   public final class NavHostKt {
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
   }
 
 }
diff --git a/navigation/navigation-dynamic-features-runtime/src/androidTest/java/androidx/navigation/dynamicfeatures/DynamicActivityNavigatorDestinationBuilderTest.kt b/navigation/navigation-dynamic-features-runtime/src/androidTest/java/androidx/navigation/dynamicfeatures/DynamicActivityNavigatorDestinationBuilderTest.kt
index 5fd5b65..613d5b3 100644
--- a/navigation/navigation-dynamic-features-runtime/src/androidTest/java/androidx/navigation/dynamicfeatures/DynamicActivityNavigatorDestinationBuilderTest.kt
+++ b/navigation/navigation-dynamic-features-runtime/src/androidTest/java/androidx/navigation/dynamicfeatures/DynamicActivityNavigatorDestinationBuilderTest.kt
@@ -46,6 +46,7 @@
             )
         }
 
+    @Suppress("DEPRECATION")
     @Test
     fun module() {
         val graph = navController.createGraph(startDestination = DESTINATION_ID) {
@@ -60,6 +61,7 @@
             .isEqualTo(MODULE_NAME)
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun noModule() {
         val graph = navController.createGraph(startDestination = DESTINATION_ID) {
@@ -71,6 +73,7 @@
         ).isNull()
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun activity() {
         val graph = navController.createGraph(startDestination = DESTINATION_ID) {
@@ -90,6 +93,7 @@
         )
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun noActivity() {
         val graph = navController.createGraph(startDestination = DESTINATION_ID) {
@@ -102,6 +106,7 @@
         ).isNull()
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun modulePackage() {
         val graph = navController.createGraph(startDestination = DESTINATION_ID) {
diff --git a/navigation/navigation-dynamic-features-runtime/src/androidTest/java/androidx/navigation/dynamicfeatures/DynamicIncludeNavGraphBuilderTest.kt b/navigation/navigation-dynamic-features-runtime/src/androidTest/java/androidx/navigation/dynamicfeatures/DynamicIncludeNavGraphBuilderTest.kt
index aa3b07d..fe10518 100644
--- a/navigation/navigation-dynamic-features-runtime/src/androidTest/java/androidx/navigation/dynamicfeatures/DynamicIncludeNavGraphBuilderTest.kt
+++ b/navigation/navigation-dynamic-features-runtime/src/androidTest/java/androidx/navigation/dynamicfeatures/DynamicIncludeNavGraphBuilderTest.kt
@@ -44,6 +44,7 @@
         navigatorProvider += NoOpNavigator()
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun includeDynamic() {
         val graph = navController.navigatorProvider.navigation(startDestination = GRAPH_ID) {
@@ -65,6 +66,7 @@
             .isEqualTo(GRAPH_RESOURCE_NAME)
     }
 
+    @Suppress("DEPRECATION")
     fun includeDynamic_emptyModuleName() {
         navController.navigatorProvider.navigation(startDestination = GRAPH_ID) {
             try {
@@ -76,6 +78,7 @@
         }
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun includeDynamic_graphPackage_null() {
         val graph = navController.navigatorProvider.navigation(startDestination = GRAPH_ID) {
@@ -87,6 +90,7 @@
             .that(includeDynamic.graphPackage).isEqualTo("${context.packageName}.$MODULE_NAME")
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun includeDynamic_graphPackage_empty() {
         navController.navigatorProvider.navigation(startDestination = GRAPH_ID) {
@@ -101,6 +105,7 @@
         }
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun includeDynamic_graphResourceName_empty() {
         navController.navigatorProvider.navigation(startDestination = GRAPH_ID) {
diff --git a/navigation/navigation-dynamic-features-runtime/src/androidTest/java/androidx/navigation/dynamicfeatures/DynamicNavGraphBuilderTest.kt b/navigation/navigation-dynamic-features-runtime/src/androidTest/java/androidx/navigation/dynamicfeatures/DynamicNavGraphBuilderTest.kt
index de954ca..b190825 100644
--- a/navigation/navigation-dynamic-features-runtime/src/androidTest/java/androidx/navigation/dynamicfeatures/DynamicNavGraphBuilderTest.kt
+++ b/navigation/navigation-dynamic-features-runtime/src/androidTest/java/androidx/navigation/dynamicfeatures/DynamicNavGraphBuilderTest.kt
@@ -44,6 +44,7 @@
         addNavigator(NoOpNavigator())
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun navigation() {
         val graph = provider.navigation(startDestination = DESTINATION_ID) {
@@ -59,6 +60,7 @@
             .isEqualTo(MODULE_NAME)
     }
 
+    @Suppress("DEPRECATION")
     fun navigation_emptyModuleName() {
         val graph = provider.navigation(startDestination = DESTINATION_ID) {
         }
@@ -66,6 +68,7 @@
             .that(graph !is DynamicGraphNavigator.DynamicNavGraph)
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun progressDestination() {
         val graph = provider.navigation(startDestination = DESTINATION_ID) {
@@ -83,6 +86,7 @@
             .isTrue()
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun progressDestination_notSet() {
         val graph = provider.navigation(startDestination = DESTINATION_ID) {
@@ -155,6 +159,7 @@
  * Create a base NavDestination. Generally, only subtypes of NavDestination should be
  * added to a NavGraph (hence why this is not in the common-ktx library)
  */
+@Suppress("DEPRECATION")
 fun DynamicNavGraphBuilder.navDestination(
     @IdRes id: Int,
     builder: NavDestinationBuilder<NavDestination>.() -> Unit
diff --git a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicActivityNavigatorDestinationBuilder.kt b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicActivityNavigatorDestinationBuilder.kt
index 67dde4b..7fefcef 100644
--- a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicActivityNavigatorDestinationBuilder.kt
+++ b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicActivityNavigatorDestinationBuilder.kt
@@ -30,6 +30,11 @@
  * Construct a new [DynamicActivityNavigator.Destination]
  * @param id Destination id.
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to build your DynamicActivityDestination instead",
+    ReplaceWith("activity(route = id.toString()) { builder.invoke() }")
+)
 public inline fun DynamicNavGraphBuilder.activity(
     @IdRes id: Int,
     builder: DynamicActivityNavigatorDestinationBuilder.() -> Unit
@@ -62,6 +67,13 @@
     NavDestinationBuilder<ActivityNavigator.Destination> {
     private var activityNavigator: DynamicActivityNavigator
 
+    @Suppress("Deprecation")
+    @Deprecated(
+        "Use routes to build your DynamicActivityDestination instead",
+        ReplaceWith(
+            "DynamicActivityNavigatorDestinationBuilder(activityNavigator, route = id.toString())"
+        )
+    )
     public constructor(
         activityNavigator: DynamicActivityNavigator,
         @IdRes id: Int
diff --git a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicIncludeNavGraphBuilder.kt b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicIncludeNavGraphBuilder.kt
index 4b8cc85..a59d702 100644
--- a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicIncludeNavGraphBuilder.kt
+++ b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicIncludeNavGraphBuilder.kt
@@ -33,6 +33,11 @@
  * @param graphResourceName Graph's resource name without the `navigation` qualifier. This
  * must not be an empty string.
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to include your DynamicNavGraph instead",
+    ReplaceWith("includeDynamic(route = id.toString(), moduleName, graphResourceName)")
+)
 public inline fun DynamicNavGraphBuilder.includeDynamic(
     @IdRes id: Int,
     moduleName: String,
@@ -49,6 +54,13 @@
  * must not be an empty string.
  * @param builder Another builder for chaining.
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to include your DynamicNavGraph instead",
+    ReplaceWith(
+        "includeDynamic(route = id.toString(), moduleName, graphResourceName) { builder.invoke() }"
+    )
+)
 public inline fun DynamicNavGraphBuilder.includeDynamic(
     @IdRes id: Int,
     moduleName: String,
@@ -112,6 +124,14 @@
     private var moduleName: String
     private var graphResourceName: String
 
+    @Suppress("Deprecation")
+    @Deprecated(
+        "Use routes to create your DynamicIncludeNavGraphBuilder instead",
+        ReplaceWith(
+            "DynamicIncludeNavGraphBuilder(dynamicIncludeGraphNavigator, route = id.toString(), " +
+                "moduleName, graphResourceName)"
+        )
+    )
     public constructor(
         dynamicIncludeGraphNavigator: DynamicIncludeGraphNavigator,
         @IdRes id: Int,
diff --git a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicNavGraphBuilder.kt b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicNavGraphBuilder.kt
index 1919a1f..367d36f 100644
--- a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicNavGraphBuilder.kt
+++ b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicNavGraphBuilder.kt
@@ -32,6 +32,14 @@
  * @param startDestination Id start destination in the graph
  * @param builder Another builder for chaining.
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to create your DynamicNavGraph instead",
+    ReplaceWith(
+        "navigation(startDestination = startDestination.toString(), route = id.toString()) " +
+            "{ builder.invoke() }"
+    )
+)
 public inline fun NavigatorProvider.navigation(
     @IdRes id: Int = 0,
     @IdRes startDestination: Int,
@@ -49,6 +57,14 @@
  * @param startDestination Id start destination in the graph
  * @param builder Another builder for chaining.
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to create your DynamicNavGraph instead",
+    ReplaceWith(
+        "navigation(startDestination = startDestination.toString(), route = id.toString()) " +
+            "{ builder.invoke() }"
+    )
+)
 public inline fun DynamicNavGraphBuilder.navigation(
     @IdRes id: Int,
     @IdRes startDestination: Int,
@@ -105,6 +121,14 @@
     @IdRes private var startDestinationId: Int = 0
     private var startDestinationRoute: String? = null
 
+    @Suppress("Deprecation")
+    @Deprecated(
+        "Use routes to create your DynamicNavGraphBuilder instead",
+        ReplaceWith(
+            "DynamicNavGraphBuilder(provider, startDestination = startDestination.toString(), " +
+                "route = id.toString())"
+        )
+    )
     public constructor(
         provider: NavigatorProvider,
         @IdRes id: Int,
diff --git a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/NavController.kt b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/NavController.kt
index f9e3d8f..f35e4e4 100644
--- a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/NavController.kt
+++ b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/NavController.kt
@@ -23,6 +23,14 @@
 /**
  * Construct a new [androidx.navigation.NavGraph] that supports dynamic navigation destinations
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to create your dynamic NavGraph instead",
+    ReplaceWith(
+        "createGraph(startDestination = startDestination.toString(), route = id.toString()) " +
+            "{ builder.invoke() }"
+    )
+)
 public inline fun NavController.createGraph(
     @IdRes id: Int = 0,
     @IdRes startDestination: Int,
diff --git a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/NavHost.kt b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/NavHost.kt
index 800645a..9bd3e8ee 100644
--- a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/NavHost.kt
+++ b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/NavHost.kt
@@ -23,8 +23,25 @@
 /**
  * Construct a new [androidx.navigation.NavGraph] that supports dynamic navigation destinations
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to create your dynamic NavGraph instead",
+    ReplaceWith(
+        "createGraph(startDestination = startDestination.toString(), route = id.toString()) " +
+            "{ builder.invoke() }"
+    )
+)
 public inline fun NavHost.createGraph(
     @IdRes id: Int = 0,
     @IdRes startDestination: Int,
     builder: DynamicNavGraphBuilder.() -> Unit
 ): NavGraph = navController.createGraph(id, startDestination, builder)
+
+/**
+ * Construct a new [androidx.navigation.NavGraph] that supports dynamic navigation destinations
+ */
+public inline fun NavHost.createGraph(
+    startDestination: String,
+    route: String? = null,
+    builder: DynamicNavGraphBuilder.() -> Unit
+): NavGraph = navController.createGraph(startDestination, route, builder)
diff --git a/navigation/navigation-fragment/api/current.txt b/navigation/navigation-fragment/api/current.txt
index ce7ec82..dd116f0 100644
--- a/navigation/navigation-fragment/api/current.txt
+++ b/navigation/navigation-fragment/api/current.txt
@@ -23,13 +23,16 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
-    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+    ctor @Deprecated public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
     method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
   }
 
   public final class DialogFragmentNavigatorDestinationBuilderKt {
     method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id);
     method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
   }
 
   public final class FragmentKt {
@@ -67,7 +70,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
-    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
+    ctor @Deprecated public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
     ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
     method public androidx.navigation.fragment.FragmentNavigator.Destination build();
   }
diff --git a/navigation/navigation-fragment/api/public_plus_experimental_current.txt b/navigation/navigation-fragment/api/public_plus_experimental_current.txt
index ce7ec82..dd116f0 100644
--- a/navigation/navigation-fragment/api/public_plus_experimental_current.txt
+++ b/navigation/navigation-fragment/api/public_plus_experimental_current.txt
@@ -23,13 +23,16 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
-    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+    ctor @Deprecated public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
     method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
   }
 
   public final class DialogFragmentNavigatorDestinationBuilderKt {
     method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id);
     method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
   }
 
   public final class FragmentKt {
@@ -67,7 +70,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
-    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
+    ctor @Deprecated public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
     ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
     method public androidx.navigation.fragment.FragmentNavigator.Destination build();
   }
diff --git a/navigation/navigation-fragment/api/restricted_current.txt b/navigation/navigation-fragment/api/restricted_current.txt
index ce7ec82..dd116f0 100644
--- a/navigation/navigation-fragment/api/restricted_current.txt
+++ b/navigation/navigation-fragment/api/restricted_current.txt
@@ -23,13 +23,16 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
-    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+    ctor @Deprecated public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
     method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
   }
 
   public final class DialogFragmentNavigatorDestinationBuilderKt {
     method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id);
     method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
   }
 
   public final class FragmentKt {
@@ -67,7 +70,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
-    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
+    ctor @Deprecated public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
     ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
     method public androidx.navigation.fragment.FragmentNavigator.Destination build();
   }
diff --git a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/DialogFragmentNavigatorDestinationBuilderTest.kt b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/DialogFragmentNavigatorDestinationBuilderTest.kt
index fed4875..7532fdb 100644
--- a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/DialogFragmentNavigatorDestinationBuilderTest.kt
+++ b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/DialogFragmentNavigatorDestinationBuilderTest.kt
@@ -36,6 +36,7 @@
     val activityRule = androidx.test.rule.ActivityTestRule<TestActivity>(TestActivity::class.java)
     private val fragmentManager get() = activityRule.activity.supportFragmentManager
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test fun fragment() {
         val navHostFragment = NavHostFragment()
@@ -53,6 +54,7 @@
             .isEqualTo(BuilderTestDialogFragment::class.java.name)
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test fun fragmentWithBody() {
         val navHostFragment = NavHostFragment()
@@ -74,8 +76,48 @@
             .that(graph[DESTINATION_ID].label)
             .isEqualTo(LABEL)
     }
+
+    @UiThreadTest
+    @Test fun fragmentRoute() {
+        val navHostFragment = NavHostFragment()
+        fragmentManager.beginTransaction()
+            .add(android.R.id.content, navHostFragment)
+            .commitNow()
+        val graph = navHostFragment.createGraph(startDestination = DESTINATION_ROUTE) {
+            dialog<BuilderTestDialogFragment>(DESTINATION_ROUTE)
+        }
+        assertWithMessage("Destination should be added to the graph")
+            .that(DESTINATION_ROUTE in graph)
+            .isTrue()
+        assertWithMessage("DialogFragment class should be set to BuilderTestDialogFragment")
+            .that((graph[DESTINATION_ROUTE] as DialogFragmentNavigator.Destination).className)
+            .isEqualTo(BuilderTestDialogFragment::class.java.name)
+    }
+
+    @UiThreadTest
+    @Test fun fragmentWithBodyRoute() {
+        val navHostFragment = NavHostFragment()
+        fragmentManager.beginTransaction()
+            .add(android.R.id.content, navHostFragment)
+            .commitNow()
+        val graph = navHostFragment.createGraph(startDestination = DESTINATION_ROUTE) {
+            dialog<BuilderTestDialogFragment>(DESTINATION_ROUTE) {
+                label = LABEL
+            }
+        }
+        assertWithMessage("Destination should be added to the graph")
+            .that(DESTINATION_ROUTE in graph)
+            .isTrue()
+        assertWithMessage("DialogFragment class should be set to BuilderTestDialogFragment")
+            .that((graph[DESTINATION_ROUTE] as DialogFragmentNavigator.Destination).className)
+            .isEqualTo(BuilderTestDialogFragment::class.java.name)
+        assertWithMessage("DialogFragment should have label set")
+            .that(graph[DESTINATION_ROUTE].label)
+            .isEqualTo(LABEL)
+    }
 }
 
 private const val DESTINATION_ID = 1
+private const val DESTINATION_ROUTE = "destination"
 private const val LABEL = "Test"
 class BuilderTestDialogFragment : DialogFragment()
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 6e28a13..616174b 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
@@ -37,6 +37,7 @@
     val activityRule = androidx.test.rule.ActivityTestRule<TestActivity>(TestActivity::class.java)
     private val fragmentManager get() = activityRule.activity.supportFragmentManager
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test fun fragment() {
         val navHostFragment = NavHostFragment()
@@ -57,6 +58,7 @@
         )
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test fun fragmentWithBody() {
         val navHostFragment = NavHostFragment()
diff --git a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/NavGraphViewModelLazyTest.kt b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/NavGraphViewModelLazyTest.kt
index f3c50e7..73b3b9bf 100644
--- a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/NavGraphViewModelLazyTest.kt
+++ b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/NavGraphViewModelLazyTest.kt
@@ -56,6 +56,7 @@
             navigatorProvider += TestNavigator()
         }
 
+    @Suppress("DEPRECATION")
     @Test
     fun vmInitialization() {
         val scenario = launchFragmentInContainer<TestVMFragment>()
diff --git a/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/DialogFragmentNavigatorDestinationBuilder.kt b/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/DialogFragmentNavigatorDestinationBuilder.kt
index 465cf75..cf58061 100644
--- a/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/DialogFragmentNavigatorDestinationBuilder.kt
+++ b/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/DialogFragmentNavigatorDestinationBuilder.kt
@@ -27,6 +27,11 @@
 /**
  * Construct a new [DialogFragmentNavigator.Destination]
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to create your DialogFragmentDestination instead",
+    ReplaceWith("dialog<F>(route = id.toString())")
+)
 public inline fun <reified F : DialogFragment> NavGraphBuilder.dialog(
     @IdRes id: Int
 ): Unit = dialog<F>(id) {}
@@ -34,6 +39,11 @@
 /**
  * Construct a new [DialogFragmentNavigator.Destination]
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to create your DialogFragmentDestination instead",
+    ReplaceWith("dialog<F>(route = id.toString()) { builder.invoke() }")
+)
 public inline fun <reified F : DialogFragment> NavGraphBuilder.dialog(
     @IdRes id: Int,
     builder: DialogFragmentNavigatorDestinationBuilder.() -> Unit
@@ -44,16 +54,59 @@
         F::class
     ).apply(builder)
 )
+/**
+ * Construct a new [DialogFragmentNavigator.Destination]
+ */
+public inline fun <reified F : DialogFragment> NavGraphBuilder.dialog(
+    route: String
+): Unit = dialog<F>(route) {}
+
+/**
+ * Construct a new [DialogFragmentNavigator.Destination]
+ */
+public inline fun <reified F : DialogFragment> NavGraphBuilder.dialog(
+    route: String,
+    builder: DialogFragmentNavigatorDestinationBuilder.() -> Unit
+): Unit = destination(
+    DialogFragmentNavigatorDestinationBuilder(
+        provider[DialogFragmentNavigator::class],
+        route,
+        F::class
+    ).apply(builder)
+)
 
 /**
  * DSL for constructing a new [DialogFragmentNavigator.Destination]
  */
 @NavDestinationDsl
-public class DialogFragmentNavigatorDestinationBuilder(
-    navigator: DialogFragmentNavigator,
-    @IdRes id: Int,
-    private val fragmentClass: KClass<out DialogFragment>
-) : NavDestinationBuilder<DialogFragmentNavigator.Destination>(navigator, id) {
+public class DialogFragmentNavigatorDestinationBuilder :
+    NavDestinationBuilder<DialogFragmentNavigator.Destination> {
+
+    private var fragmentClass: KClass<out DialogFragment>
+
+    @Suppress("Deprecation")
+    @Deprecated(
+        "Use routes to build your DialogFragmentNavigatorDestination instead",
+        ReplaceWith(
+            "DialogFragmentNavigatorDestinationBuilder(navigator, route = id.toString(), " +
+                "fragmentClass) "
+        )
+    )
+    public constructor(
+        navigator: DialogFragmentNavigator,
+        @IdRes id: Int,
+        fragmentClass: KClass<out DialogFragment>
+    ) : super(navigator, id) {
+        this.fragmentClass = fragmentClass
+    }
+
+    public constructor(
+        navigator: DialogFragmentNavigator,
+        route: String,
+        fragmentClass: KClass<out DialogFragment>
+    ) : super(navigator, route) {
+        this.fragmentClass = fragmentClass
+    }
 
     override fun build(): DialogFragmentNavigator.Destination =
         super.build().also { destination ->
diff --git a/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/FragmentNavigatorDestinationBuilder.kt b/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/FragmentNavigatorDestinationBuilder.kt
index 60eda99..e0060d9 100644
--- a/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/FragmentNavigatorDestinationBuilder.kt
+++ b/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/FragmentNavigatorDestinationBuilder.kt
@@ -27,6 +27,11 @@
 /**
  * Construct a new [FragmentNavigator.Destination]
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to create your FragmentDestination instead",
+    ReplaceWith("fragment<F>(route = id.toString())")
+)
 public inline fun <reified F : Fragment> NavGraphBuilder.fragment(
     @IdRes id: Int
 ): Unit = fragment<F>(id) {}
@@ -34,6 +39,11 @@
 /**
  * Construct a new [FragmentNavigator.Destination]
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to create your FragmentDestination instead",
+    ReplaceWith("fragment<F>(route = id.toString()) { builder.invoke() }")
+)
 public inline fun <reified F : Fragment> NavGraphBuilder.fragment(
     @IdRes id: Int,
     builder: FragmentNavigatorDestinationBuilder.() -> Unit
@@ -75,6 +85,13 @@
 
     private var fragmentClass: KClass<out Fragment>
 
+    @Suppress("Deprecation")
+    @Deprecated(
+        "Use routes to build your FragmentNavigatorDestination instead",
+        ReplaceWith(
+            "FragmentNavigatorDestinationBuilder(navigator, route = id.toString(), fragmentClass) "
+        )
+    )
     public constructor(
         navigator: FragmentNavigator,
         @IdRes id: Int,
diff --git a/navigation/navigation-runtime/api/current.txt b/navigation/navigation-runtime/api/current.txt
index 03eef05..33808c0 100644
--- a/navigation/navigation-runtime/api/current.txt
+++ b/navigation/navigation-runtime/api/current.txt
@@ -59,7 +59,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
-    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
+    ctor @Deprecated public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
     ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, String route);
     method public androidx.navigation.ActivityNavigator.Destination build();
     method public String? getAction();
@@ -80,7 +80,7 @@
   }
 
   public final class ActivityNavigatorDestinationBuilderKt {
-    method public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void activity(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
@@ -152,7 +152,7 @@
   }
 
   public final class NavControllerKt {
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
@@ -189,7 +189,7 @@
   }
 
   public final class NavHostKt {
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
diff --git a/navigation/navigation-runtime/api/public_plus_experimental_current.txt b/navigation/navigation-runtime/api/public_plus_experimental_current.txt
index f98c73a..1a5eb2b 100644
--- a/navigation/navigation-runtime/api/public_plus_experimental_current.txt
+++ b/navigation/navigation-runtime/api/public_plus_experimental_current.txt
@@ -61,7 +61,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
-    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
+    ctor @Deprecated public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
     ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, String route);
     method public androidx.navigation.ActivityNavigator.Destination build();
     method public String? getAction();
@@ -82,7 +82,7 @@
   }
 
   public final class ActivityNavigatorDestinationBuilderKt {
-    method public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void activity(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
@@ -166,7 +166,7 @@
   }
 
   public final class NavControllerKt {
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
@@ -203,7 +203,7 @@
   }
 
   public final class NavHostKt {
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
diff --git a/navigation/navigation-runtime/api/restricted_current.txt b/navigation/navigation-runtime/api/restricted_current.txt
index 03eef05..33808c0 100644
--- a/navigation/navigation-runtime/api/restricted_current.txt
+++ b/navigation/navigation-runtime/api/restricted_current.txt
@@ -59,7 +59,7 @@
   }
 
   @androidx.navigation.NavDestinationDsl public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
-    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
+    ctor @Deprecated public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
     ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, String route);
     method public androidx.navigation.ActivityNavigator.Destination build();
     method public String? getAction();
@@ -80,7 +80,7 @@
   }
 
   public final class ActivityNavigatorDestinationBuilderKt {
-    method public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
     method public static inline void activity(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
   }
 
@@ -152,7 +152,7 @@
   }
 
   public final class NavControllerKt {
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
@@ -189,7 +189,7 @@
   }
 
   public final class NavHostKt {
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
     method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
   }
 
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 53c3aea..6e1ae7a 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/ActivityNavigatorDestinationBuilderTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/ActivityNavigatorDestinationBuilderTest.kt
@@ -32,6 +32,7 @@
     private val navController =
         NavController(ApplicationProvider.getApplicationContext() as android.content.Context)
 
+    @Suppress("DEPRECATION")
     @Test
     fun activity() {
         val graph = navController.createGraph(startDestination = DESTINATION_ID) {
@@ -50,6 +51,7 @@
         )
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun activityPackage() {
         val graph = navController.createGraph(startDestination = DESTINATION_ID) {
@@ -65,6 +67,7 @@
             .isEqualTo(PACKAGE_NAME)
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun activityClass() {
         val graph = navController.createGraph(startDestination = DESTINATION_ID) {
@@ -83,6 +86,7 @@
         )
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun action() {
         val graph = navController.createGraph(startDestination = DESTINATION_ID) {
@@ -101,6 +105,7 @@
         )
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun data() {
         val graph = navController.createGraph(startDestination = DESTINATION_ID) {
@@ -119,6 +124,7 @@
         )
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun dataPattern() {
         val graph = navController.createGraph(startDestination = DESTINATION_ID) {
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryLifecycleTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryLifecycleTest.kt
index 1c9b115..f276f45 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryLifecycleTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryLifecycleTest.kt
@@ -43,6 +43,7 @@
     /**
      * Test that navigating between siblings correctly stops the previous sibling.
      */
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testLifecycle() {
@@ -105,6 +106,7 @@
      * Test that navigating from a sibling to a FloatingWindow sibling leaves the previous
      * destination started.
      */
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testLifecycleWithDialog() {
@@ -167,6 +169,7 @@
      * Test that navigating from within a nested navigation graph to one of the graph's
      * siblings correctly stops both the previous destination and its graph.
      */
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testLifecycleNested() {
@@ -232,6 +235,7 @@
      * FloatingWindow siblings correctly moves both the previous destination and its graph to
      * started.
      */
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testLifecycleNestedWithDialog() {
@@ -299,6 +303,7 @@
      * Test that navigating from within a nested navigation graph to one of the graph's
      * siblings correctly stops both the previous destination and its graph.
      */
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testLifecycleNestedOrdering() {
@@ -394,6 +399,7 @@
      * FloatingWindow siblings correctly moves both the previous destination and its graph to
      * started.
      */
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testLifecycleNestedOrderingWithDialog() {
@@ -476,6 +482,7 @@
      * Test that popping the last destination in a graph while navigating to a new
      * destination in that graph keeps the graph around
      */
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testLifecycleReplaceLastDestination() {
@@ -533,6 +540,7 @@
      * Test that popping the last destination in a graph while navigating correctly
      * cleans up the previous navigation graph
      */
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testLifecycleOrphanedGraph() {
@@ -590,6 +598,7 @@
      * Test that navigating to a new instance of a graph leaves the previous instance in its
      * current state.
      */
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testLifecycleNestedRepeated() {
@@ -663,6 +672,7 @@
      * Test that navigating to a new instance of a graph back to back with its previous
      * instance creates a brand new graph instance
      */
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testLifecycleNestedRepeatedBackToBack() {
@@ -722,6 +732,7 @@
      * last destination from the previous instance of the graph correctly cleans up
      * the orphaned graph and creates a new graph instance.
      */
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testLifecycleNestedRepeatedBackToBackWithOrphanedGraph() {
@@ -789,6 +800,7 @@
      * Test that navigating to a new instance of a graph via a deep link to a FloatingWindow
      * destination leaves the previous instance in its current state.
      */
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testLifecycleNestedRepeatedWithDialog() {
@@ -861,6 +873,7 @@
             .isEqualTo(Lifecycle.State.RESUMED)
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testLifecycleToDestroyedWhenInitialized() {
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryTest.kt
index bcd0b19..b061ee6 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryTest.kt
@@ -42,6 +42,7 @@
 @RunWith(AndroidJUnit4::class)
 class NavBackStackEntryTest {
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testGetViewModelStoreOwner() {
@@ -61,6 +62,7 @@
         assertThat(store).isNotNull()
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testGetViewModelStoreOwnerAndroidViewModel() {
@@ -81,6 +83,7 @@
         assertThat(viewModel).isNotNull()
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testGetViewModelStoreOwnerSavedStateViewModel() {
@@ -116,6 +119,7 @@
         assertThat(restoredState).isEqualTo("test")
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testSaveRestoreGetViewModelStoreOwner() {
@@ -165,6 +169,7 @@
         }
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testGetViewModelStoreOwnerSameGraph() {
@@ -188,6 +193,7 @@
         assertThat(sameGraphOwner.viewModelStore).isSameInstanceAs(viewStore)
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testGetSavedStateHandleRestored() {
@@ -278,6 +284,7 @@
         }
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testOnClearedWhenHostCleared() {
@@ -304,6 +311,7 @@
             .isTrue()
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testOnClearedWhenPopped() {
@@ -338,6 +346,7 @@
             .isTrue()
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testOnClearedWhenHostClearedAfterSaveState() {
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
index d3f9e3a..c2e4857 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
@@ -173,6 +173,7 @@
         navController.setGraph(R.navigation.nav_start_destination, args)
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testStartDestinationWithArgsProgrammatic() {
@@ -238,6 +239,7 @@
         }
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testSetViewModelStoreOwnerAfterGraphSet() {
@@ -260,6 +262,7 @@
         }
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testSetSameViewModelStoreOwnerAfterGraphSet() {
@@ -1977,6 +1980,7 @@
         navController.navigate(R.id.second_test)
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun createGraph() {
         val graph = navController.createGraph(startDestination = DESTINATION_ID) {
@@ -1988,7 +1992,7 @@
 
     @UiThreadTest
     @Test
-    @Suppress("EXPERIMENTAL_API_USAGE")
+    @Suppress("DEPRECATION", "EXPERIMENTAL_API_USAGE")
     fun currentBackStackEntryFlow() = runBlocking {
         navController.graph = navController.createGraph(startDestination = 1) {
             test(1)
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 951a236..0b21a08 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavDeepLinkBuilderTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavDeepLinkBuilderTest.kt
@@ -105,6 +105,7 @@
         assertEquals("Expected one Intent", 1, taskStackBuilder.intentCount)
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun fromContextSetGraphProgrammatic() {
         val deepLinkBuilder = NavDeepLinkBuilder(targetContext)
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavHostTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavHostTest.kt
index 37ecb1e..5ef8394 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavHostTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavHostTest.kt
@@ -35,6 +35,7 @@
             get() = [email protected]
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun createGraph() {
         val graph = navHost.createGraph(startDestination = DESTINATION_ID) {
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/test/FloatingTestNavigator.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/test/FloatingTestNavigator.kt
index 689f7c6..94ea1b6 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/test/FloatingTestNavigator.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/test/FloatingTestNavigator.kt
@@ -59,6 +59,7 @@
 /**
  * DSL for constructing a new [TestNavigator.Destination] from a [FloatingTestNavigator].
  */
+@Suppress("DEPRECATION")
 @NavDestinationDsl
 class FloatingTestNavigatorDestinationBuilder(
     navigator: FloatingTestNavigator,
diff --git a/navigation/navigation-runtime/src/main/java/androidx/navigation/ActivityNavigatorDestinationBuilder.kt b/navigation/navigation-runtime/src/main/java/androidx/navigation/ActivityNavigatorDestinationBuilder.kt
index 1089b72..c0cc861 100644
--- a/navigation/navigation-runtime/src/main/java/androidx/navigation/ActivityNavigatorDestinationBuilder.kt
+++ b/navigation/navigation-runtime/src/main/java/androidx/navigation/ActivityNavigatorDestinationBuilder.kt
@@ -28,6 +28,11 @@
 /**
  * Construct a new [ActivityNavigator.Destination]
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to build your ActivityDestination instead",
+    ReplaceWith("activity(route = id.toString()) { builder.invoke() }")
+)
 public inline fun NavGraphBuilder.activity(
     @IdRes id: Int,
     builder: ActivityNavigatorDestinationBuilder.() -> Unit
@@ -59,6 +64,11 @@
     NavDestinationBuilder<ActivityNavigator.Destination> {
     private var context: Context
 
+    @Suppress("Deprecation")
+    @Deprecated(
+        "Use routes to create your ActivityNavigatorDestinationBuilder instead",
+        ReplaceWith("ActivityNavigatorDestinationBuilder(navigator, route = id.toString())")
+    )
     public constructor(navigator: ActivityNavigator, @IdRes id: Int) : super(navigator, id) {
         context = navigator.context
     }
diff --git a/navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.kt b/navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.kt
index 24b4764..fc4bde0 100644
--- a/navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.kt
+++ b/navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.kt
@@ -1949,6 +1949,14 @@
  * @param startDestination the route for the start destination
  * @param builder the builder used to construct the graph
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to create your NavGraph instead",
+    ReplaceWith(
+        "createGraph(startDestination = startDestination.toString(), route = id.toString()) " +
+            "{ builder.invoke() }"
+    )
+)
 public inline fun NavController.createGraph(
     @IdRes id: Int = 0,
     @IdRes startDestination: Int,
diff --git a/navigation/navigation-runtime/src/main/java/androidx/navigation/NavHost.kt b/navigation/navigation-runtime/src/main/java/androidx/navigation/NavHost.kt
index bb6b996..f3e159b 100644
--- a/navigation/navigation-runtime/src/main/java/androidx/navigation/NavHost.kt
+++ b/navigation/navigation-runtime/src/main/java/androidx/navigation/NavHost.kt
@@ -53,6 +53,14 @@
 /**
  * Construct a new [NavGraph]
  */
+@Suppress("Deprecation")
+@Deprecated(
+    "Use routes to create your NavGraph instead",
+    ReplaceWith(
+        "createGraph(startDestination = startDestination.toString(), route = id.toString()) " +
+            "{ builder.invoke() }"
+    )
+)
 public inline fun NavHost.createGraph(
     @IdRes id: Int = 0,
     @IdRes startDestination: Int,
diff --git a/navigation/navigation-testing/src/androidTest/java/androidx/navigation/testing/TestNavHostControllerTest.kt b/navigation/navigation-testing/src/androidTest/java/androidx/navigation/testing/TestNavHostControllerTest.kt
index 2612a35..76aa369 100644
--- a/navigation/navigation-testing/src/androidTest/java/androidx/navigation/testing/TestNavHostControllerTest.kt
+++ b/navigation/navigation-testing/src/androidTest/java/androidx/navigation/testing/TestNavHostControllerTest.kt
@@ -76,6 +76,7 @@
         assertThat(backStack[1].destination).isInstanceOf(TestNavigator.Destination::class.java)
     }
 
+    @Suppress("DEPRECATION")
     @UiThreadTest
     @Test
     fun testDsl() {
diff --git a/navigation/navigation-ui/src/androidTest/java/androidx/navigation/ui/AppBarConfigurationTest.kt b/navigation/navigation-ui/src/androidTest/java/androidx/navigation/ui/AppBarConfigurationTest.kt
index 1f393b1..c2576ae 100644
--- a/navigation/navigation-ui/src/androidTest/java/androidx/navigation/ui/AppBarConfigurationTest.kt
+++ b/navigation/navigation-ui/src/androidTest/java/androidx/navigation/ui/AppBarConfigurationTest.kt
@@ -42,6 +42,7 @@
         context = InstrumentationRegistry.getInstrumentation().targetContext
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun testTopLevelFromGraph() {
         val navGraph = NavController(context).apply {
diff --git a/playground-common/playground.properties b/playground-common/playground.properties
index 3e7dfa5..945474e 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=7378367
+androidx.playground.snapshotBuildId=7396899
 androidx.playground.metalavaBuildId=7255182
 androidx.playground.dokkaBuildId=7299536
 androidx.studio.type=playground
diff --git a/profileinstaller/integration-tests/init-macrobenchmark-target/README.md b/profileinstaller/integration-tests/init-macrobenchmark-target/README.md
new file mode 100644
index 0000000..1bed279
--- /dev/null
+++ b/profileinstaller/integration-tests/init-macrobenchmark-target/README.md
@@ -0,0 +1 @@
+Benchmark startup overhead introduced by profileinstaller's use of startup library
\ No newline at end of file
diff --git a/profileinstaller/integration-tests/init-macrobenchmark-target/build.gradle b/profileinstaller/integration-tests/init-macrobenchmark-target/build.gradle
new file mode 100644
index 0000000..411e5df
--- /dev/null
+++ b/profileinstaller/integration-tests/init-macrobenchmark-target/build.gradle
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+import static androidx.build.dependencies.DependenciesKt.*
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.application")
+    id("kotlin-android")
+}
+
+android {
+    buildTypes {
+        release {
+            minifyEnabled true
+            shrinkResources true
+            proguardFiles getDefaultProguardFile("proguard-android-optimize.txt")
+        }
+    }
+}
+
+dependencies {
+    implementation(KOTLIN_STDLIB)
+    implementation(project(":profileinstaller:profileinstaller"))
+}
diff --git a/profileinstaller/integration-tests/init-macrobenchmark-target/src/main/AndroidManifest.xml b/profileinstaller/integration-tests/init-macrobenchmark-target/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..f2fbc15
--- /dev/null
+++ b/profileinstaller/integration-tests/init-macrobenchmark-target/src/main/AndroidManifest.xml
@@ -0,0 +1,48 @@
+<!--
+  ~ 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.
+  -->
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    package="androidx.profileinstaller.integration.macrobenchmark.target">
+
+    <application
+        android:label="Profileinstaller Macrobenchmark Target"
+        android:allowBackup="false"
+        android:supportsRtl="true"
+        tools:ignore="MissingApplicationIcon">
+
+        <!-- Profileable to enable macrobenchmark profiling -->
+        <!--suppress AndroidElementNotAllowed -->
+        <profileable android:shell="true"/>
+
+        <!--
+        Activities need to be exported so the macrobenchmark can discover them
+        under the new package visibility changes for Android 11.
+         -->
+        <activity
+            android:name=".SimpleTextActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="profileinstaller.init.macrobenchmark.TARGET" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/profileinstaller/integration-tests/init-macrobenchmark-target/src/main/java/androidx/profileinstaller/integration/macrobenchmark/target/SimpleTextActivity.kt b/profileinstaller/integration-tests/init-macrobenchmark-target/src/main/java/androidx/profileinstaller/integration/macrobenchmark/target/SimpleTextActivity.kt
new file mode 100644
index 0000000..c19d537
--- /dev/null
+++ b/profileinstaller/integration-tests/init-macrobenchmark-target/src/main/java/androidx/profileinstaller/integration/macrobenchmark/target/SimpleTextActivity.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.profileinstaller.integration.macrobenchmark.target
+
+import android.app.Activity
+import android.os.Bundle
+import android.widget.TextView
+
+class SimpleTextActivity : Activity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_main)
+
+        val notice = findViewById<TextView>(R.id.txtNotice)
+        notice.setText(R.string.app_notice)
+    }
+}
diff --git a/profileinstaller/integration-tests/init-macrobenchmark-target/src/main/res/layout/activity_main.xml b/profileinstaller/integration-tests/init-macrobenchmark-target/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..42146bc
--- /dev/null
+++ b/profileinstaller/integration-tests/init-macrobenchmark-target/src/main/res/layout/activity_main.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  Copyright 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/txtNotice"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="50sp"
+        tools:text="profileinstaller benchmark️" />
+
+</FrameLayout>
diff --git a/profileinstaller/integration-tests/init-macrobenchmark-target/src/main/res/values/donottranslate-strings.xml b/profileinstaller/integration-tests/init-macrobenchmark-target/src/main/res/values/donottranslate-strings.xml
new file mode 100644
index 0000000..c2c1ed3
--- /dev/null
+++ b/profileinstaller/integration-tests/init-macrobenchmark-target/src/main/res/values/donottranslate-strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <string name="app_notice">profileinstaller macrobenchmark app.</string>
+</resources>
diff --git a/profileinstaller/integration-tests/init-macrobenchmark/build.gradle b/profileinstaller/integration-tests/init-macrobenchmark/build.gradle
new file mode 100644
index 0000000..33e00c2
--- /dev/null
+++ b/profileinstaller/integration-tests/init-macrobenchmark/build.gradle
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 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.
+ */
+
+
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
+import static androidx.build.dependencies.DependenciesKt.*
+import androidx.build.LibraryGroups
+import androidx.build.Publish
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+    id("kotlin-android")
+}
+
+android {
+    defaultConfig {
+        minSdkVersion 28
+    }
+}
+
+dependencies {
+    androidTestImplementation(project(":profileinstaller:profileinstaller"))
+    androidTestImplementation(project(":benchmark:benchmark-macro-junit4"))
+    androidTestImplementation(project(":internal-testutils-macrobenchmark"))
+    androidTestImplementation(ANDROIDX_TEST_RULES)
+    androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
+    androidTestImplementation(ANDROIDX_TEST_CORE)
+    androidTestImplementation(ANDROIDX_TEST_RUNNER)
+}
+
+def installReleaseTarget = tasks.getByPath(
+        ":profileinstaller:integration-tests:init-macrobenchmark-target:installRelease"
+)
+
+// Define a task dependency so the app is installed before we run macro benchmarks.
+tasks.getByPath(":profileinstaller:integration-tests:init-macrobenchmark:connectedCheck")
+    .dependsOn(installReleaseTarget)
diff --git a/profileinstaller/integration-tests/init-macrobenchmark/src/androidTest/AndroidManifest.xml b/profileinstaller/integration-tests/init-macrobenchmark/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..c1bd315
--- /dev/null
+++ b/profileinstaller/integration-tests/init-macrobenchmark/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 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.
+  -->
+<manifest package="androidx.profileinstaller.integration.macrobenchmark.test"/>
diff --git a/profileinstaller/integration-tests/init-macrobenchmark/src/androidTest/java/androidx/profileinstaller/integration/macrobenchmark/ProfileinstallerStartupBenchmark.kt b/profileinstaller/integration-tests/init-macrobenchmark/src/androidTest/java/androidx/profileinstaller/integration/macrobenchmark/ProfileinstallerStartupBenchmark.kt
new file mode 100644
index 0000000..83d0a926
--- /dev/null
+++ b/profileinstaller/integration-tests/init-macrobenchmark/src/androidTest/java/androidx/profileinstaller/integration/macrobenchmark/ProfileinstallerStartupBenchmark.kt
@@ -0,0 +1,53 @@
+/*
+ * 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.profileinstaller.integration.macrobenchmark
+
+import androidx.benchmark.macro.CompilationMode
+import androidx.benchmark.macro.StartupMode
+import androidx.benchmark.macro.junit4.MacrobenchmarkRule
+import androidx.test.filters.LargeTest
+import androidx.testutils.createStartupCompilationParams
+import androidx.testutils.measureStartup
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+@LargeTest
+@RunWith(Parameterized::class)
+class ProfileinstallerStartupBenchmark(
+    private val startupMode: StartupMode,
+    private val compilationMode: CompilationMode
+) {
+    @get:Rule
+    val benchmarkRule = MacrobenchmarkRule()
+
+    @Test
+    fun startup() = benchmarkRule.measureStartup(
+        compilationMode = compilationMode,
+        startupMode = startupMode,
+        packageName = "androidx.profileinstaller.integration.macrobenchmark.target"
+    ) {
+        action = "profileinstaller.init.macrobenchmark.TARGET"
+    }
+
+    companion object {
+        @Parameterized.Parameters(name = "startup={0},compilation={1}")
+        @JvmStatic
+        fun parameters() = createStartupCompilationParams()
+    }
+}
\ No newline at end of file
diff --git a/profileinstaller/integration-tests/init-macrobenchmark/src/main/AndroidManifest.xml b/profileinstaller/integration-tests/init-macrobenchmark/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..ccd5d59
--- /dev/null
+++ b/profileinstaller/integration-tests/init-macrobenchmark/src/main/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 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.
+  -->
+<manifest package="androidx.profileinstaller.integration.macrobenchmark" />
diff --git a/profileinstaller/profileinstaller/integration-tests/testapp/build.gradle b/profileinstaller/integration-tests/testapp/build.gradle
similarity index 100%
rename from profileinstaller/profileinstaller/integration-tests/testapp/build.gradle
rename to profileinstaller/integration-tests/testapp/build.gradle
diff --git a/profileinstaller/profileinstaller/integration-tests/testapp/cli/all_compose_profile.txt b/profileinstaller/integration-tests/testapp/cli/all_compose_profile.txt
similarity index 100%
rename from profileinstaller/profileinstaller/integration-tests/testapp/cli/all_compose_profile.txt
rename to profileinstaller/integration-tests/testapp/cli/all_compose_profile.txt
diff --git a/profileinstaller/profileinstaller/integration-tests/testapp/cli/build_bundle_launch.sh b/profileinstaller/integration-tests/testapp/cli/build_bundle_launch.sh
similarity index 91%
rename from profileinstaller/profileinstaller/integration-tests/testapp/cli/build_bundle_launch.sh
rename to profileinstaller/integration-tests/testapp/cli/build_bundle_launch.sh
index cfcb5dc..ad3ab2b 100755
--- a/profileinstaller/profileinstaller/integration-tests/testapp/cli/build_bundle_launch.sh
+++ b/profileinstaller/integration-tests/testapp/cli/build_bundle_launch.sh
@@ -19,20 +19,20 @@
 
 SCRIPT=`realpath $0`
 SCRIPT_DIR=`dirname $SCRIPT`
-SUPPORT_DIR=$SCRIPT_DIR/../../../../../
+SUPPORT_DIR=$SCRIPT_DIR/../../../../
 TMP_DIR=`mktemp -d`
 
 pushd $SUPPORT_DIR
 
 echo "===START=== Rebuilding apk..."
 ANDROIDX_PROJECTS=COMPOSE ./gradlew \
-  :profileinstaller:profileinstaller:integration-tests:testapp:clean
+  :profileinstaller:integration-tests:testapp:clean
 if [ $DEBUG = true ]; then
   ANDROIDX_PROJECTS=COMPOSE ./gradlew \
-    :profileinstaller:profileinstaller:integration-tests:testapp:assembleDebug
+    :profileinstaller:integration-tests:testapp:assembleDebug
 else
   ANDROIDX_PROJECTS=COMPOSE ./gradlew \
-    :profileinstaller:profileinstaller:integration-tests:testapp:assembleRelease
+    :profileinstaller:integration-tests:testapp:assembleRelease
 fi
 echo "===/DONE=== Rebuilding apk..."
 
diff --git a/profileinstaller/profileinstaller/integration-tests/testapp/cli/instructions.md b/profileinstaller/integration-tests/testapp/cli/instructions.md
similarity index 100%
rename from profileinstaller/profileinstaller/integration-tests/testapp/cli/instructions.md
rename to profileinstaller/integration-tests/testapp/cli/instructions.md
diff --git a/profileinstaller/profileinstaller/integration-tests/testapp/cli/profgen-cli.jar b/profileinstaller/integration-tests/testapp/cli/profgen-cli.jar
similarity index 100%
rename from profileinstaller/profileinstaller/integration-tests/testapp/cli/profgen-cli.jar
rename to profileinstaller/integration-tests/testapp/cli/profgen-cli.jar
Binary files differ
diff --git a/profileinstaller/profileinstaller/integration-tests/testapp/cli/repackage.py b/profileinstaller/integration-tests/testapp/cli/repackage.py
similarity index 94%
rename from profileinstaller/profileinstaller/integration-tests/testapp/cli/repackage.py
rename to profileinstaller/integration-tests/testapp/cli/repackage.py
index 9a5db31..3b30a3f 100755
--- a/profileinstaller/profileinstaller/integration-tests/testapp/cli/repackage.py
+++ b/profileinstaller/integration-tests/testapp/cli/repackage.py
@@ -14,13 +14,13 @@
 PATH_TO_APKSIGNER = 'apksigner'
 
 SCRIPT_PATH = Path(__file__).parent.absolute()
-SUPPORT_PATH = (SCRIPT_PATH / Path("../../../../..")).resolve()
+SUPPORT_PATH = (SCRIPT_PATH / Path("../../../..")).resolve()
 ROOT_DIR = (SUPPORT_PATH / Path("../..")).resolve()
 BUILD_OUT_DIR = (Path(SUPPORT_PATH) / Path(
-    "../../out/androidx/profileinstaller/profileinstaller/integration-tests/"
+    "../../out/androidx/profileinstaller/integration-tests/"
     "testapp/build/outputs/apk/")).resolve()
 MAPPING_OUT_PATH = (Path(SUPPORT_PATH) / Path(
-    "../../out/androidx/profileinstaller/profileinstaller/integration-tests/"
+    "../../out/androidx/profileinstaller/integration-tests/"
     "testapp/build/outputs/mapping/release/mapping.txt")).resolve()
 
 APK_PREFIX = "testapp"
@@ -119,6 +119,8 @@
     working_dir.mkdir()
     working_apk = working_dir / Path("working.apk")
     shutil.copyfile(apk_src, working_apk)
+    print(f"copying to {SUPPORT_PATH / Path('baseline.prof')}")
+    shutil.copyfile(profile, SUPPORT_PATH / Path("baseline.prof"))
     with ZipFile(working_apk, 'a') as zip:
         profile_destination = Path('assets/dexopt/') / Path(APK_PROFILE_FILE)
         if str(profile_destination) in [it.filename for it in zip.infolist()]:
@@ -155,4 +157,4 @@
     profile = profile_from(args.profile)
     jar = jar_from(args.jar)
     output_apk = output_apk_from(args.output)
-    generate_apk(apk_src, profile, jar, output_apk, args.debug, args.apk_signer)
\ No newline at end of file
+    generate_apk(apk_src, profile, jar, output_apk, args.debug, args.apk_signer)
diff --git a/profileinstaller/profileinstaller/integration-tests/testapp/src/main/AndroidManifest.xml b/profileinstaller/integration-tests/testapp/src/main/AndroidManifest.xml
similarity index 100%
rename from profileinstaller/profileinstaller/integration-tests/testapp/src/main/AndroidManifest.xml
rename to profileinstaller/integration-tests/testapp/src/main/AndroidManifest.xml
diff --git a/profileinstaller/profileinstaller/integration-tests/testapp/src/main/java/androidx/profileinstaller/integration/testapp/MainActivity.kt b/profileinstaller/integration-tests/testapp/src/main/java/androidx/profileinstaller/integration/testapp/MainActivity.kt
similarity index 100%
rename from profileinstaller/profileinstaller/integration-tests/testapp/src/main/java/androidx/profileinstaller/integration/testapp/MainActivity.kt
rename to profileinstaller/integration-tests/testapp/src/main/java/androidx/profileinstaller/integration/testapp/MainActivity.kt
diff --git a/profileinstaller/profileinstaller/integration-tests/testapp/OWNERS b/profileinstaller/profileinstaller/integration-tests/testapp/OWNERS
deleted file mode 100644
index 42abc4e..0000000
--- a/profileinstaller/profileinstaller/integration-tests/testapp/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
[email protected]
[email protected]
diff --git a/room/OWNERS b/room/OWNERS
index 3ea2934..6d57c2e 100644
--- a/room/OWNERS
+++ b/room/OWNERS
@@ -1,5 +1,6 @@
 [email protected]
 [email protected]
 [email protected]
[email protected]
 
-per-file settings.gradle = [email protected], [email protected]
+per-file settings.gradle = [email protected]
diff --git a/room/room-paging/api/current.txt b/room/room-paging/api/current.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/room/room-paging/api/current.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/room/room-paging/api/public_plus_experimental_current.txt b/room/room-paging/api/public_plus_experimental_current.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/room/room-paging/api/public_plus_experimental_current.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/room/room-paging/api/res-current.txt b/room/room-paging/api/res-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/room/room-paging/api/res-current.txt
diff --git a/room/room-paging/api/restricted_current.txt b/room/room-paging/api/restricted_current.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/room/room-paging/api/restricted_current.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/room/room-paging/build.gradle b/room/room-paging/build.gradle
new file mode 100644
index 0000000..e9645b8
--- /dev/null
+++ b/room/room-paging/build.gradle
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import static androidx.build.dependencies.DependenciesKt.*
+import androidx.build.LibraryGroups
+import androidx.build.LibraryType
+import androidx.build.LibraryVersions
+import androidx.build.Publish
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+    id("org.jetbrains.kotlin.android")
+}
+
+dependencies {
+    api(KOTLIN_STDLIB)
+    // Add dependencies here
+}
+
+androidx {
+    name = "Room Paging"
+    type = LibraryType.PUBLISHED_LIBRARY
+    mavenGroup = LibraryGroups.ROOM
+    inceptionYear = "2021"
+    description = "Room Paging integration"
+    publish = Publish.NONE
+}
diff --git a/room/room-paging/src/androidTest/AndroidManifest.xml b/room/room-paging/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..50ba2eb
--- /dev/null
+++ b/room/room-paging/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="androidx.room.paging.test">
+
+</manifest>
diff --git a/room/room-paging/src/main/AndroidManifest.xml b/room/room-paging/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..fa18cd8
--- /dev/null
+++ b/room/room-paging/src/main/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="androidx.room.paging">
+
+</manifest>
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 935a639..ba10801 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -504,7 +504,9 @@
 includeProject(":preference:preference-ktx", "preference/preference-ktx", [BuildType.MAIN])
 includeProject(":print:print", "print/print", [BuildType.MAIN])
 includeProject(":profileinstaller:profileinstaller", "profileinstaller/profileinstaller", [BuildType.MAIN, BuildType.COMPOSE])
-includeProject(":profileinstaller:profileinstaller:integration-tests:testapp", "profileinstaller/profileinstaller/integration-tests/testapp", [BuildType.COMPOSE])
+includeProject(":profileinstaller:integration-tests:init-macrobenchmark", "profileinstaller/integration-tests/init-macrobenchmark", [BuildType.MAIN])
+includeProject(":profileinstaller:integration-tests:init-macrobenchmark-target", "profileinstaller/integration-tests/init-macrobenchmark-target", [BuildType.MAIN])
+includeProject(":profileinstaller:integration-tests:testapp", "profileinstaller/integration-tests/testapp", [BuildType.COMPOSE])
 includeProject(":recommendation:recommendation", "recommendation/recommendation", [BuildType.MAIN])
 includeProject(":recyclerview:recyclerview", "recyclerview/recyclerview", [BuildType.MAIN])
 includeProject(":recyclerview:recyclerview-benchmark", "recyclerview/recyclerview-benchmark", [BuildType.MAIN])
@@ -527,6 +529,7 @@
 includeProject(":room:room-guava", "room/guava", [BuildType.MAIN])
 includeProject(":room:room-ktx", "room/ktx", [BuildType.MAIN])
 includeProject(":room:room-migration", "room/migration", [BuildType.MAIN])
+includeProject(":room:room-paging", "room/room-paging", [BuildType.MAIN])
 includeProject(":room:room-runtime", "room/runtime", [BuildType.MAIN])
 includeProject(":room:room-rxjava2", "room/rxjava2", [BuildType.MAIN])
 includeProject(":room:room-rxjava3", "room/rxjava3", [BuildType.MAIN])
diff --git a/testutils/testutils-navigation/src/androidTest/java/androidx/testutils/TestNavigatorDestinationBuilderTest.kt b/testutils/testutils-navigation/src/androidTest/java/androidx/testutils/TestNavigatorDestinationBuilderTest.kt
index fb2d187..20383a3 100644
--- a/testutils/testutils-navigation/src/androidTest/java/androidx/testutils/TestNavigatorDestinationBuilderTest.kt
+++ b/testutils/testutils-navigation/src/androidTest/java/androidx/testutils/TestNavigatorDestinationBuilderTest.kt
@@ -31,6 +31,7 @@
 class TestNavigatorDestinationBuilderTest {
     private val provider = TestNavigatorProvider()
 
+    @Suppress("DEPRECATION")
     @Test
     fun test() {
         val graph = provider.navigation(startDestination = DESTINATION_ID) {
@@ -53,6 +54,7 @@
         )
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun testWithBody() {
         val graph = provider.navigation(startDestination = DESTINATION_ID) {
diff --git a/testutils/testutils-navigation/src/main/java/androidx/testutils/TestNavigatorDestinationBuilder.kt b/testutils/testutils-navigation/src/main/java/androidx/testutils/TestNavigatorDestinationBuilder.kt
index f8b90e7..a9bcbad 100644
--- a/testutils/testutils-navigation/src/main/java/androidx/testutils/TestNavigatorDestinationBuilder.kt
+++ b/testutils/testutils-navigation/src/main/java/androidx/testutils/TestNavigatorDestinationBuilder.kt
@@ -37,6 +37,7 @@
 /**
  * Construct a new [TestNavigator.Destination]
  */
+@Suppress("DEPRECATION")
 inline fun NavGraphBuilder.test(
     @IdRes id: Int,
     builder: TestNavigatorDestinationBuilder.() -> Unit
@@ -62,6 +63,7 @@
  */
 @NavDestinationDsl
 class TestNavigatorDestinationBuilder : NavDestinationBuilder<TestNavigator.Destination> {
+    @Suppress("DEPRECATION")
     constructor(navigator: TestNavigator, @IdRes id: Int = 0) : super(navigator, id)
     constructor(navigator: TestNavigator, route: String) : super(navigator, route)
 }
diff --git a/versionedparcelable/versionedparcelable-compiler/build.gradle b/versionedparcelable/versionedparcelable-compiler/build.gradle
index 72cbdae..83f50b6 100644
--- a/versionedparcelable/versionedparcelable-compiler/build.gradle
+++ b/versionedparcelable/versionedparcelable-compiler/build.gradle
@@ -18,15 +18,13 @@
 import androidx.build.LibraryType
 import androidx.build.LibraryVersions
 
-import static androidx.build.dependencies.DependenciesKt.*
-
 plugins {
     id("AndroidXPlugin")
     id("java-library")
 }
 
 dependencies {
-    implementation(JAVAPOET)
+    implementation(libs.javapoet)
 }
 
 androidx {
diff --git a/versionedparcelable/versionedparcelable/build.gradle b/versionedparcelable/versionedparcelable/build.gradle
index 5ffba1b..b093782 100644
--- a/versionedparcelable/versionedparcelable/build.gradle
+++ b/versionedparcelable/versionedparcelable/build.gradle
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-import static androidx.build.dependencies.DependenciesKt.*
-
 import androidx.build.LibraryGroups
 import androidx.build.LibraryVersions
 import androidx.build.Publish
@@ -29,12 +27,12 @@
     api("androidx.annotation:annotation:1.2.0")
     implementation("androidx.collection:collection:1.0.0")
 
-    androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
-    androidTestImplementation(ANDROIDX_TEST_CORE)
-    androidTestImplementation(ANDROIDX_TEST_RUNNER)
-    androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
-    androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
-    androidTestImplementation(TRUTH)
+    androidTestImplementation(libs.testExtJunit)
+    androidTestImplementation(libs.testCore)
+    androidTestImplementation(libs.testRunner)
+    androidTestImplementation(libs.mockitoCore, excludes.bytebuddy)
+    androidTestImplementation(libs.dexmakerMockito, excludes.bytebuddy)
+    androidTestImplementation(libs.truth)
     androidTestAnnotationProcessor project(":versionedparcelable:versionedparcelable-compiler")
 }
 
diff --git a/wear/compose/material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ChipTest.kt b/wear/compose/material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ChipTest.kt
index addff08..48a160f 100644
--- a/wear/compose/material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ChipTest.kt
+++ b/wear/compose/material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ChipTest.kt
@@ -19,6 +19,7 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.shape.CornerSize
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.runtime.Composable
@@ -37,6 +38,7 @@
 import androidx.compose.ui.test.assertIsEnabled
 import androidx.compose.ui.test.assertIsNotEnabled
 import androidx.compose.ui.test.assertTopPositionInRootIsEqualTo
+import androidx.compose.ui.test.assertWidthIsEqualTo
 import androidx.compose.ui.test.captureToImage
 import androidx.compose.ui.test.getUnclippedBoundsInRoot
 import androidx.compose.ui.test.junit4.ComposeContentTestRule
@@ -45,6 +47,7 @@
 import androidx.compose.ui.test.onChildAt
 import androidx.compose.ui.test.onNodeWithContentDescription
 import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.onRoot
 import androidx.compose.ui.test.performClick
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.unit.Dp
@@ -254,6 +257,108 @@
             .assertTopPositionInRootIsEqualTo((itemBounds.height - iconBounds.height) / 2)
     }
 
+    @Test
+    fun icon_only_compact_chip_has_correct_default_width_and_height() {
+        val iconTag = "TestIcon"
+        val chipTag = "chip"
+        rule
+            .setContentWithThemeForSizeAssertions(useUnmergedTree = true) {
+                CompactChip(
+                    onClick = {},
+                    modifier = Modifier.testTag(chipTag),
+                    icon = { CreateImage(iconTag) }
+                )
+            }
+
+        rule.onRoot().assertWidthIsEqualTo(52.dp).assertHeightIsEqualTo(32.dp)
+    }
+
+    @Test
+    fun label_only_compact_chip_has_correct_default_height() {
+        val chipTag = "chip"
+        rule
+            .setContentWithThemeForSizeAssertions(useUnmergedTree = true) {
+                CompactChip(
+                    onClick = {},
+                    modifier = Modifier.testTag(chipTag),
+                    label = { Text("Test") }
+                )
+            }
+
+        rule.onRoot().assertHeightIsEqualTo(32.dp)
+    }
+
+    @Test
+    fun no_content_compact_chip_has_correct_default_width_and_height() {
+        val chipTag = "chip"
+        rule
+            .setContentWithThemeForSizeAssertions(useUnmergedTree = true) {
+                CompactChip(
+                    onClick = {},
+                    modifier = Modifier.testTag(chipTag),
+                )
+            }
+
+        rule.onRoot().assertWidthIsEqualTo(52.dp).assertHeightIsEqualTo(32.dp)
+    }
+
+    @Test
+    fun icon_only_compact_chip_can_have_width_overridden() {
+        val iconTag = "TestIcon"
+        val chipTag = "chip"
+        rule
+            .setContentWithThemeForSizeAssertions(useUnmergedTree = true) {
+                CompactChip(
+                    onClick = {},
+                    modifier = Modifier.testTag(chipTag).width(100.dp),
+                    icon = { CreateImage(iconTag) }
+                )
+            }
+
+        rule.onRoot().assertWidthIsEqualTo(100.dp)
+    }
+
+    @Test
+    fun has_icon_in_correct_location_when_compact_chip() {
+        val iconTag = "TestIcon"
+        val chipTag = "chip"
+        rule
+            .setContentWithThemeForSizeAssertions(useUnmergedTree = true) {
+                CompactChip(
+                    onClick = {},
+                    label = { Text("Blue green orange") },
+                    icon = { CreateImage(iconTag) },
+                    modifier = Modifier.testTag(chipTag)
+                )
+            }
+        val itemBounds = rule.onNodeWithTag(chipTag).getUnclippedBoundsInRoot()
+        val iconBounds = rule.onNodeWithTag(iconTag, useUnmergedTree = true)
+            .getUnclippedBoundsInRoot()
+
+        rule.onNodeWithContentDescription(iconTag, useUnmergedTree = true)
+            .assertTopPositionInRootIsEqualTo((itemBounds.height - iconBounds.height) / 2)
+    }
+
+    @Test
+    fun has_icon_in_correct_location_when_icon_only_chip() {
+        val iconTag = "TestIcon"
+        val chipTag = "chip"
+        rule
+            .setContentWithThemeForSizeAssertions(useUnmergedTree = true) {
+                CompactChip(
+                    onClick = {},
+                    modifier = Modifier.testTag(chipTag),
+                    icon = { CreateImage(iconTag) }
+                )
+            }
+        val itemBounds = rule.onNodeWithTag(chipTag).getUnclippedBoundsInRoot()
+        val iconBounds = rule.onNodeWithTag(iconTag, useUnmergedTree = true)
+            .getUnclippedBoundsInRoot()
+
+        rule.onNodeWithContentDescription(iconTag, useUnmergedTree = true)
+            .assertTopPositionInRootIsEqualTo((itemBounds.height - iconBounds.height) / 2)
+    }
+
     private fun verifyHeight(expectedHeight: Dp) {
         rule.verifyHeight(expectedHeight) {
             Chip(
@@ -281,7 +386,7 @@
 
     @Test
     fun three_slot_layout_gives_primary_enabled_colors() =
-        verifyThreeSlotColors(
+        verifySlotColors(
             TestChipColors.Primary,
             ChipStatus.Enabled,
             { MaterialTheme.colors.primary },
@@ -291,6 +396,18 @@
         )
 
     @Test
+    fun compact_chip_gives_primary_enabled_colors() =
+        verifySlotColors(
+            TestChipColors.Primary,
+            ChipStatus.Enabled,
+            { MaterialTheme.colors.primary },
+            { MaterialTheme.colors.onPrimary },
+            { MaterialTheme.colors.onPrimary },
+            { MaterialTheme.colors.onPrimary },
+            compactChip = true
+        )
+
+    @Test
     fun gives_primary_disabled_colors() =
         verifyColors(
             TestChipColors.Primary,
@@ -301,7 +418,7 @@
 
     @Test
     fun three_slot_layout_gives_primary_disabled_colors() =
-        verifyThreeSlotColors(
+        verifySlotColors(
             TestChipColors.Primary,
             ChipStatus.Disabled,
             { MaterialTheme.colors.primary },
@@ -321,7 +438,7 @@
 
     @Test
     fun three_slot_layout_gives_secondary_enabled_colors() =
-        verifyThreeSlotColors(
+        verifySlotColors(
             TestChipColors.Secondary,
             ChipStatus.Enabled,
             { MaterialTheme.colors.surface },
@@ -341,7 +458,7 @@
 
     @Test
     fun three_slot_layout_gives_secondary_disabled_colors() =
-        verifyThreeSlotColors(
+        verifySlotColors(
             TestChipColors.Secondary,
             ChipStatus.Enabled,
             { MaterialTheme.colors.surface },
@@ -351,6 +468,18 @@
         )
 
     @Test
+    fun compact_chip_gives_secondary_disabled_colors() =
+        verifySlotColors(
+            TestChipColors.Secondary,
+            ChipStatus.Enabled,
+            { MaterialTheme.colors.surface },
+            { MaterialTheme.colors.onSurface },
+            { MaterialTheme.colors.onSurface },
+            { MaterialTheme.colors.onSurface },
+            compactChip = true
+        )
+
+    @Test
     fun allows_custom_enabled_background_color_override() {
         val overrideColor = Color.Yellow
         rule.setContentWithTheme {
@@ -531,13 +660,14 @@
         }
     }
 
-    private fun verifyThreeSlotColors(
+    private fun verifySlotColors(
         testChipColors: TestChipColors,
         status: ChipStatus,
         backgroundColor: @Composable () -> Color,
         contentColor: @Composable () -> Color,
         secondaryContentColor: @Composable () -> Color,
-        iconColor: @Composable () -> Color
+        iconColor: @Composable () -> Color,
+        compactChip: Boolean = false
     ) {
         var expectedBackground = Color.Transparent
         var expectedContent = Color.Transparent
@@ -559,28 +689,43 @@
                     .fillMaxSize()
                     .background(expectedBackground)
             ) {
-                Chip(
-                    onClick = {},
-                    colors = testChipColors.chipColors(),
-                    label = { actualContent = LocalContentColor.current },
-                    secondaryLabel = { actualSecondaryContent = LocalContentColor.current },
-                    icon = { actualIcon = LocalContentColor.current },
-                    enabled = status.enabled(),
-                    modifier = Modifier.testTag("test-item")
-                )
+                if (compactChip) {
+                    CompactChip(
+                        onClick = {},
+                        colors = testChipColors.chipColors(),
+                        label = { actualContent = LocalContentColor.current },
+                        icon = { actualIcon = LocalContentColor.current },
+                        enabled = status.enabled(),
+                        modifier = Modifier.testTag("test-item")
+                    )
+                } else {
+                    Chip(
+                        onClick = {},
+                        colors = testChipColors.chipColors(),
+                        label = { actualContent = LocalContentColor.current },
+                        secondaryLabel = { actualSecondaryContent = LocalContentColor.current },
+                        icon = { actualIcon = LocalContentColor.current },
+                        enabled = status.enabled(),
+                        modifier = Modifier.testTag("test-item")
+                    )
+                }
             }
         }
 
         if (status.enabled()) {
             assertEquals(expectedContent, actualContent)
-            assertEquals(expectedSecondaryContent, actualSecondaryContent)
+            if (! compactChip) {
+                assertEquals(expectedSecondaryContent, actualSecondaryContent)
+            }
             assertEquals(expectedIcon, actualIcon)
         } else {
             assertEquals(expectedContent.copy(alpha = expectedAlpha), actualContent)
-            assertEquals(
-                expectedSecondaryContent.copy(alpha = expectedAlpha),
-                actualSecondaryContent
-            )
+            if (! compactChip) {
+                assertEquals(
+                    expectedSecondaryContent.copy(alpha = expectedAlpha),
+                    actualSecondaryContent
+                )
+            }
             assertEquals(expectedIcon.copy(alpha = expectedAlpha), actualIcon)
         }
 
diff --git a/wear/compose/material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/MaterialThemeTest.kt b/wear/compose/material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/MaterialThemeTest.kt
new file mode 100644
index 0000000..32c54d7
--- /dev/null
+++ b/wear/compose/material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/MaterialThemeTest.kt
@@ -0,0 +1,456 @@
+/*
+ * 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.material
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.captureToImage
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.test.performClick
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.sp
+import org.junit.Assert.assertEquals
+import org.junit.Rule
+import org.junit.Test
+
+class MaterialThemeTest {
+    @get:Rule
+    val rule = createComposeRule()
+
+    @Test
+    fun sets_default_color() {
+        var expectedBackground = Color.Transparent
+        rule.setContentWithTheme {
+            expectedBackground = MaterialTheme.colors.primary
+            Chip(
+                onClick = {},
+                colors = ChipDefaults.primaryChipColors(), // make sure using the primary color
+                label = { Text("Test") },
+            )
+        }
+
+        rule.onNodeWithText("Test")
+            .captureToImage()
+            .assertContainsColor(expectedBackground, 50.0f)
+    }
+
+    @Test
+    fun overrides_color_when_nested() {
+        // MaterialTheme in 'setWearContent' sets the primary background
+        // to cornflower blue. The nested theme should override that for primary.
+        rule.setContentWithTheme {
+            MaterialTheme(colors = MaterialTheme.colors.copy(primary = Color.Cyan)) {
+                Chip(
+                    onClick = {},
+                    colors = ChipDefaults.primaryChipColors(), // make sure using the primary color
+                    label = { Text("Test") },
+                )
+            }
+        }
+
+        rule.onNodeWithText("Test")
+            .captureToImage()
+            .assertContainsColor(Color.Cyan, 50.0f)
+    }
+
+    @Test
+    fun can_be_overridden_by_component_color_explicitly() {
+        rule.setContentWithTheme {
+            Chip(
+                onClick = {},
+                colors = ChipDefaults.primaryChipColors(backgroundColor = Color.Yellow),
+                label = { Text("Test") },
+            )
+        }
+
+        rule.onNodeWithText("Test")
+            .captureToImage()
+            .assertContainsColor(Color.Yellow, 50.0f)
+    }
+
+    @Test
+    fun sets_default_textstyle() {
+        var expectedStyle: TextStyle? = null
+
+        rule.setContentWithTheme {
+            expectedStyle = MaterialTheme.typography.button
+            Chip(
+                onClick = {},
+                label = { Text("Test") },
+            )
+        }
+
+        assertTextStyleEquals(expectedStyle!!, rule.textStyleOf("Test"))
+    }
+
+    @Test
+    fun overrides_textstyle_when_nested() {
+        val override = TextStyle(
+            fontFamily = FontFamily.Default,
+            fontWeight = FontWeight.Normal,
+            fontSize = 16.sp,
+            letterSpacing = 0.sp
+        )
+        rule.setContentWithTheme {
+            MaterialTheme(
+                typography = MaterialTheme.typography
+                    .copy(button = override)
+            ) {
+                Chip(
+                    onClick = {},
+                    label = { Text("Test") },
+                )
+            }
+        }
+
+        assertTextStyleEquals(override, rule.textStyleOf("Test"))
+    }
+
+    @Test
+    fun sets_primary_color_dynamically() =
+        verifyBackgroundColorIsDynamic(
+            initial = { MaterialTheme.colors.primary },
+            selectChipColors = { ChipDefaults.primaryChipColors() },
+            updateThemeColors = { colors, primary -> colors.copy(primary = primary) }
+        )
+
+    @Test
+    fun sets_primaryvariant_color_dynamically() =
+        verifyBackgroundColorIsDynamic(
+            initial = { MaterialTheme.colors.primaryVariant },
+            selectChipColors = {
+                ChipDefaults
+                    .primaryChipColors(backgroundColor = MaterialTheme.colors.primaryVariant)
+            },
+            updateThemeColors =
+                { colors, primaryVariant -> colors.copy(primaryVariant = primaryVariant) }
+        )
+
+    @Test
+    fun sets_secondary_color_dynamically() =
+        verifyBackgroundColorIsDynamic(
+            initial = { MaterialTheme.colors.secondary },
+            selectChipColors = {
+                ChipDefaults
+                    .secondaryChipColors(backgroundColor = MaterialTheme.colors.secondary)
+            },
+            updateThemeColors = { colors, secondary -> colors.copy(secondary = secondary) }
+        )
+
+    @Test
+    fun sets_secondaryvariant_color_dynamically() =
+        verifyBackgroundColorIsDynamic(
+            initial = { MaterialTheme.colors.secondaryVariant },
+            selectChipColors = {
+                ChipDefaults
+                    .secondaryChipColors(backgroundColor = MaterialTheme.colors.secondaryVariant)
+            },
+            updateThemeColors =
+                { colors, secondaryVariant -> colors.copy(secondaryVariant = secondaryVariant) }
+        )
+
+    @Test
+    fun sets_error_color_dynamically() =
+        verifyBackgroundColorIsDynamic(
+            initial = { MaterialTheme.colors.error },
+            selectChipColors = {
+                ChipDefaults
+                    .secondaryChipColors(backgroundColor = MaterialTheme.colors.error)
+            },
+            updateThemeColors = { colors, error -> colors.copy(error = error) }
+        )
+
+    @Test
+    fun sets_colors_dynamically() {
+        var initialBackground = Color.Transparent
+        val overrideBackground = Color.Cyan
+
+        rule.setContentWithTheme {
+            initialBackground = MaterialTheme.colors.primary
+            val colors = Colors()
+            val rememberedColors = remember { mutableStateOf(colors) }
+            MaterialTheme(colors = rememberedColors.value) {
+                Column {
+                    Chip(
+                        onClick = {},
+                        colors = ChipDefaults.primaryChipColors(),
+                        label = { Text("Test") },
+                    )
+                    Chip(
+                        onClick = {
+                            rememberedColors.value = colors.copy(primary = overrideBackground)
+                        },
+                        label = { },
+                        modifier = Modifier.testTag("button")
+                    )
+                }
+            }
+        }
+
+        rule.onNodeWithText("Test")
+            .captureToImage()
+            .assertContainsColor(initialBackground, 60.0f)
+        rule.onNodeWithTag("button")
+            .performClick()
+        rule.onNodeWithText("Test")
+            .captureToImage()
+            .assertContainsColor(overrideBackground, 60.0f)
+    }
+
+    @Test
+    fun sets_button_textstyle_dynamically() =
+        verifyTextStyleIsDynamic(
+            selectStyle = { it.button },
+            updateTextStyle = { typography, button -> typography.copy(button = button) }
+        )
+
+    @Test
+    fun sets_display1_textstyle_dynamically() =
+        verifyTextStyleIsDynamic(
+            selectStyle = { it.display1 },
+            updateTextStyle = { typography, display1 -> typography.copy(display1 = display1) }
+        )
+
+    @Test
+    fun sets_display2_textstyle_dynamically() =
+        verifyTextStyleIsDynamic(
+            selectStyle = { it.display2 },
+            updateTextStyle = { typography, display2 -> typography.copy(display2 = display2) }
+        )
+
+    @Test
+    fun sets_display3_textstyle_dynamically() =
+        verifyTextStyleIsDynamic(
+            selectStyle = { it.display3 },
+            updateTextStyle = { typography, display3 -> typography.copy(display3 = display3) }
+        )
+
+    @Test
+    fun sets_title1_textstyle_dynamically() =
+        verifyTextStyleIsDynamic(
+            selectStyle = { it.title1 },
+            updateTextStyle = { typography, title1 -> typography.copy(title1 = title1) }
+        )
+
+    @Test
+    fun sets_title2_textstyle_dynamically() =
+        verifyTextStyleIsDynamic(
+            selectStyle = { it.title2 },
+            updateTextStyle = { typography, title2 -> typography.copy(title2 = title2) }
+        )
+
+    @Test
+    fun sets_title3_textstyle_dynamically() =
+        verifyTextStyleIsDynamic(
+            selectStyle = { it.title3 },
+            updateTextStyle = { typography, title3 -> typography.copy(title3 = title3) }
+        )
+
+    @Test
+    fun sets_body1_textstyle_dynamically() =
+        verifyTextStyleIsDynamic(
+            selectStyle = { it.body1 },
+            updateTextStyle = { typography, body1 -> typography.copy(body1 = body1) }
+        )
+
+    @Test
+    fun sets_body2_textstyle_dynamically() =
+        verifyTextStyleIsDynamic(
+            selectStyle = { it.body2 },
+            updateTextStyle = { typography, body2 -> typography.copy(body2 = body2) }
+        )
+
+    @Test
+    fun sets_caption1_textstyle_dynamically() =
+        verifyTextStyleIsDynamic(
+            selectStyle = { it.caption1 },
+            updateTextStyle = { typography, caption1 -> typography.copy(caption1 = caption1) }
+        )
+
+    @Test
+    fun sets_caption2_textstyle_dynamically() =
+        verifyTextStyleIsDynamic(
+            selectStyle = { it.caption2 },
+            updateTextStyle = { typography, caption2 -> typography.copy(caption2 = caption2) }
+        )
+
+    @Test
+    fun sets_typography_dynamically() {
+        val initialStyle = TextStyle(
+            fontFamily = FontFamily.Default,
+            fontWeight = FontWeight.Bold,
+            fontSize = 14.sp,
+            letterSpacing = 0.sp
+        )
+        val overrideTextStyle = TextStyle(
+            fontFamily = FontFamily.Default,
+            fontWeight = FontWeight.Normal,
+            fontSize = 8.sp,
+            letterSpacing = 0.sp
+        )
+
+        rule.setContentWithTheme {
+            val typography = Typography()
+            val rememberedTypography = remember { mutableStateOf(typography) }
+            MaterialTheme(typography = rememberedTypography.value) {
+                Column {
+                    Chip(
+                        onClick = {},
+                        colors = ChipDefaults.primaryChipColors(),
+                        label = { Text("Test") },
+                    )
+                    Chip(
+                        onClick = {
+                            rememberedTypography.value =
+                                typography.copy(button = overrideTextStyle)
+                        },
+                        label = { },
+                        modifier = Modifier.testTag("button")
+                    )
+                }
+            }
+        }
+
+        assertTextStyleEquals(initialStyle, rule.textStyleOf("Test"))
+        rule.onNodeWithTag("button").performClick()
+        assertTextStyleEquals(overrideTextStyle, rule.textStyleOf("Test"))
+    }
+
+    private fun verifyBackgroundColorIsDynamic(
+        initial: @Composable () -> Color,
+        selectChipColors: @Composable () -> ChipColors,
+        updateThemeColors: (Colors, Color) -> Colors
+    ) {
+        var initialColor = Color.Transparent
+        val overrideColor = Color.Cyan
+        val colors = Colors()
+
+        rule.setContentWithTheme {
+            initialColor = initial()
+            val dynamicColor = remember { mutableStateOf(initialColor) }
+            val themeColors = updateThemeColors(colors, dynamicColor.value)
+            MaterialTheme(colors = themeColors) {
+                Column {
+                    Chip(
+                        onClick = {},
+                        colors = selectChipColors(),
+                        label = { Text("Test") },
+                    )
+                    Chip(
+                        onClick = { dynamicColor.value = overrideColor },
+                        label = { },
+                        modifier = Modifier.testTag("button")
+                    )
+                }
+            }
+        }
+
+        rule.onNodeWithText("Test")
+            .captureToImage()
+            .assertContainsColor(initialColor, 60.0f)
+        rule.onNodeWithTag("button")
+            .performClick()
+        rule.onNodeWithText("Test")
+            .captureToImage()
+            .assertContainsColor(overrideColor, 60.0f)
+    }
+
+    private fun verifyContentColorIsDynamic(
+        initial: @Composable () -> Color,
+        selectChipColors: @Composable () -> ChipColors,
+        updateThemeColors: (Colors, Color) -> Colors
+    ) {
+        var initialColor = Color.White
+        val overrideColor = Color.Cyan
+        val colors = Colors()
+
+        rule.setContentWithTheme {
+            initialColor = initial()
+            val dynamicColor = remember { mutableStateOf(initialColor) }
+            val themeColors = updateThemeColors(colors, dynamicColor.value)
+            MaterialTheme(colors = themeColors) {
+                Column {
+                    Chip(
+                        onClick = {},
+                        colors = selectChipColors(),
+                        label = { Text("Test") },
+                    )
+                    Chip(
+                        onClick = { dynamicColor.value = overrideColor },
+                        label = { Text("Test") },
+                        modifier = Modifier.testTag("button")
+                    )
+                }
+            }
+        }
+
+        assertEquals(initialColor, rule.textStyleOf("Test").color)
+        rule.onNodeWithTag("button")
+            .performClick()
+        assertEquals(overrideColor, rule.textStyleOf("Test").color)
+    }
+
+    private fun verifyTextStyleIsDynamic(
+        selectStyle: (Typography) -> TextStyle,
+        updateTextStyle: (Typography, TextStyle) -> Typography
+    ) {
+        var initialStyle = TextStyle()
+        val overrideTextStyle = TextStyle(
+            fontFamily = FontFamily.Default,
+            fontWeight = FontWeight.Normal,
+            fontSize = 8.sp,
+            letterSpacing = 0.sp
+        )
+        val typography = Typography()
+
+        rule.setContentWithTheme {
+            initialStyle = selectStyle(typography)
+            val dynamicStyle = remember { mutableStateOf(initialStyle) }
+            val rememberedTypography =
+                updateTextStyle(typography, dynamicStyle.value)
+            MaterialTheme(
+                // WearChip always uses 'button' style for text, so assign the style under test to button.
+                typography = rememberedTypography.copy(button = selectStyle(rememberedTypography))
+            ) {
+                Column {
+                    Chip(
+                        onClick = {},
+                        label = { Text("Test") },
+                    )
+                    Chip(
+                        onClick = { dynamicStyle.value = overrideTextStyle },
+                        label = { },
+                        modifier = Modifier.testTag("button")
+                    )
+                }
+            }
+        }
+
+        assertTextStyleEquals(initialStyle, rule.textStyleOf("Test"))
+        rule.onNodeWithTag("button").performClick()
+        assertTextStyleEquals(overrideTextStyle, rule.textStyleOf("Test"))
+    }
+}
\ No newline at end of file
diff --git a/wear/compose/material/src/commonMain/kotlin/androidx/wear/compose/material/Chip.kt b/wear/compose/material/src/commonMain/kotlin/androidx/wear/compose/material/Chip.kt
index 35e949e..fce5d9c 100644
--- a/wear/compose/material/src/commonMain/kotlin/androidx/wear/compose/material/Chip.kt
+++ b/wear/compose/material/src/commonMain/kotlin/androidx/wear/compose/material/Chip.kt
@@ -15,8 +15,6 @@
  */
 package androidx.wear.compose.material
 
-import androidx.compose.foundation.Indication
-import androidx.compose.foundation.LocalIndication
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.interaction.Interaction
 import androidx.compose.foundation.interaction.MutableInteractionSource
@@ -29,9 +27,11 @@
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.material.ContentAlpha
 import androidx.compose.material.Surface
+import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.Immutable
@@ -75,7 +75,6 @@
  * @param modifier Modifier to be applied to the chip
  * @param enabled Controls the enabled state of the chip. When `false`, this chip will not
  * be clickable
- * @param onClickLabel Semantic / accessibility label for the [onClick] action
  * @param contentPadding The spacing values to apply internally between the container and the
  * content
  * @param shape Defines the chip's shape. It is strongly recommended to use the default as this
@@ -84,9 +83,6 @@
  * [Interaction]s for this Chip. You can create and pass in your own remembered
  * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
  * appearance / behavior of this Chip in different [Interaction]s.
- * @param indication Indication to be shown when surface is pressed. By default, indication from
- * [LocalIndication] will be used. Pass `null` to show no indication, or current value from
- * [LocalIndication] to show theme default
  * @param role The type of user interface element. Accessibility services might use this
  * to describe the element or do customizations
  */
@@ -96,11 +92,9 @@
     colors: ChipColors,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
-    onClickLabel: String? = null,
     contentPadding: PaddingValues = ChipDefaults.ContentPadding,
     shape: Shape = MaterialTheme.shapes.small,
     interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
-    indication: Indication? = LocalIndication.current,
     role: Role? = Role.Button,
     content: @Composable () -> Unit,
 ) {
@@ -122,10 +116,9 @@
         val contentBoxModifier = Modifier
             .clickable(
                 enabled = enabled,
-                onClickLabel = onClickLabel,
                 onClick = onClick,
                 role = role,
-                indication = indication,
+                indication = rememberRipple(),
                 interactionSource = interactionSource,
             )
             .padding(contentPadding)
@@ -148,7 +141,7 @@
 /**
  * Wear Material [Chip] that offers three slots and a specific layout for an icon, label and
  * secondaryLabel. The icon and secondaryLabel are optional. The items are laid out with the icon,
- * if provided, a the start of a row, with a column next containing the two label slots.
+ * if provided, at the start of a row, with a column next containing the two label slots.
  *
  * The [Chip] is Stadium shaped and has a max height designed to take no more than two lines of text
  * of [Typography.button] style. If no secondary label is provided then the label
@@ -167,26 +160,25 @@
  *
  * Chips can be enabled or disabled. A disabled chip will not respond to click events.
  *
- * @param label A slot for providing the chips main label. The contents are expected to be text
+ * @param label A slot for providing the chip's main label. The contents are expected to be text
  * which is "start" aligned if there is an icon preset and "start" or "center" aligned if not.
  * @param onClick Will be called when the user clicks the chip
  * @param modifier Modifier to be applied to the chip
- * @param secondaryLabel A slot for providing the chips secondary label. The contents are expected
+ * @param secondaryLabel A slot for providing the chip's secondary label. The contents are expected
  * to be text which is "start" aligned if there is an icon preset and "start" or "center" aligned if
  * not. label and secondaryLabel contents should be consistently aligned.
+ * @param icon A slot for providing the chip's icon. The contents are expected to be a horizontally
+ * and vertically aligned icon of size [ChipDefaults.IconSize] or [ChipDefaults.LargeIconSize].
  * @param colors [ChipColors] that will be used to resolve the background and content color for
  * this chip in different states. See [ChipDefaults.chipColors]. Defaults to
  * [ChipDefaults.primaryChipColors]
  * @param enabled Controls the enabled state of the chip. When `false`, this chip will not
  * be clickable
- * @param onClickLabel Semantic / accessibility label for the [onClick] action
  * @param interactionSource The [MutableInteractionSource] representing the stream of
  * [Interaction]s for this Chip. You can create and pass in your own remembered
  * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
  * appearance / behavior of this Chip in different [Interaction]s.
- * @param indication Indication to be shown when surface is pressed. By default, indication from
- * [LocalIndication] will be used. Pass `null` to show no indication, or current value from
- * [LocalIndication] to show theme default
+
  * @param contentPadding The spacing values to apply internally between the container and the
  * content
  */
@@ -199,9 +191,7 @@
     icon: (@Composable () -> Unit)? = null,
     colors: ChipColors = ChipDefaults.primaryChipColors(),
     enabled: Boolean = true,
-    onClickLabel: String? = null,
     interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
-    indication: Indication? = LocalIndication.current,
     contentPadding: PaddingValues = ChipDefaults.contentPadding(icon != null),
 ) {
     Chip(
@@ -209,9 +199,7 @@
         colors = colors,
         modifier = modifier,
         enabled = enabled,
-        onClickLabel = onClickLabel,
         interactionSource = interactionSource,
-        indication = indication,
         contentPadding = contentPadding
     ) {
         Row(
@@ -248,6 +236,94 @@
 }
 
 /**
+ * A compact Wear Material Chip that offers two slots and a specific layout for an icon and label.
+ * Both the icon and label are optional however it is expected that at least one will be provided.
+ *
+ * The [CompactChip] is Stadium shaped and has a max height designed to take no more than one line
+ * of text of [Typography.button] style and/or one 24x24 icon. The default max height is
+ * [ChipDefaults.CompactChipHeight].
+ *
+ * If a icon is provided then the labels should be "start" aligned, e.g. left aligned in ltr so that
+ * the text starts next to the icon.
+ *
+ * The items are laid out as follows.
+ *
+ * 1. If a label is provided then the chip will be laid out with the optional icon at the start of a
+ * row followed by the label with a default max height of [ChipDefaults.CompactChipHeight].
+ *
+ * 2. If only an icon is provided it will be laid out vertically and horizontally centered with a
+ * default height of [ChipDefaults.CompactChipHeight] and the default width of
+ * [ChipDefaults.IconOnlyCompactChipWidth]
+ *
+ * The [CompactChip] can have different styles with configurable content colors, background colors
+ * including gradients, these are provided by [ChipColors] implementations.
+ *
+ * The recommended set of [ChipColors] styles can be obtained from [ChipDefaults], e.g.
+ * [ChipDefaults.primaryChipColors] to get a color scheme for a primary [Chip] which by default
+ * will have a solid background of [Colors.primary] and content color of
+ * [Colors.onPrimary].
+ *
+ * Chips can be enabled or disabled. A disabled chip will not respond to click events.
+ *
+ * @param onClick Will be called when the user clicks the chip
+ * @param modifier Modifier to be applied to the chip
+ * @param label A slot for providing the chip's main label. The contents are expected to be text
+ * which is "start" aligned if there is an icon preset and "start" or "center" aligned if not.
+ * @param icon A slot for providing the chip's icon. The contents are expected to be a horizontally
+ * and vertically aligned icon of size [ChipDefaults.IconSize] or [ChipDefaults.LargeIconSize].
+ * @param colors [ChipColors] that will be used to resolve the background and content color for
+ * this chip in different states. See [ChipDefaults.chipColors]. Defaults to
+ * [ChipDefaults.primaryChipColors]
+ * @param enabled Controls the enabled state of the chip. When `false`, this chip will not
+ * be clickable
+ * @param interactionSource The [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this Chip. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this Chip in different [Interaction]s.
+ * @param contentPadding The spacing values to apply internally between the container and the
+ * content
+ */
+@Composable
+fun CompactChip(
+    onClick: () -> Unit,
+    modifier: Modifier = Modifier,
+    label: (@Composable () -> Unit)? = null,
+    icon: (@Composable () -> Unit)? = null,
+    colors: ChipColors = ChipDefaults.primaryChipColors(),
+    enabled: Boolean = true,
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    contentPadding: PaddingValues = ChipDefaults.contentPadding(icon != null),
+) {
+    if (label != null) {
+        Chip(
+            label = label,
+            onClick = onClick,
+            modifier = modifier.height(ChipDefaults.CompactChipHeight),
+            icon = icon,
+            colors = colors,
+            enabled = enabled,
+            interactionSource = interactionSource,
+            contentPadding = contentPadding
+        )
+    } else {
+        Chip(
+            onClick = onClick,
+            modifier = modifier
+                .height(ChipDefaults.CompactChipHeight)
+                .width(ChipDefaults.IconOnlyCompactChipWidth),
+            colors = colors,
+            enabled = enabled,
+            interactionSource = interactionSource,
+            contentPadding = contentPadding
+        ) {
+            if (icon != null) {
+                icon()
+            }
+        }
+    }
+}
+
+/**
  * Represents the background and content colors used in a chip in different states.
  *
  * See [ChipDefaults.primaryChipColors] for the default colors used in a primary styled [Chip].
@@ -377,6 +453,18 @@
     internal val Height = 52.dp
 
     /**
+     * The height applied for the [CompactChip].
+     * Note that you can override it by applying Modifier.height directly on [CompactChip].
+     */
+    internal val CompactChipHeight = 32.dp
+
+    /**
+     * The default width applied for the [CompactChip] when it has no label provided.
+     * Note that you can override it by applying Modifier.width directly on [CompactChip].
+     */
+    internal val IconOnlyCompactChipWidth = 52.dp
+
+    /**
      * The default size of the icon when used inside a [Chip].
      */
     public val IconSize = 24.dp
diff --git a/wear/wear-complications-data/api/restricted_current.txt b/wear/wear-complications-data/api/restricted_current.txt
index 4b1188f..77a59ce 100644
--- a/wear/wear-complications-data/api/restricted_current.txt
+++ b/wear/wear-complications-data/api/restricted_current.txt
@@ -1,5 +1,5 @@
 // Signature format: 4.0
-package android.support.wearable.complications {
+package @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) android.support.wearable.complications {
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final class ComplicationData implements android.os.Parcelable {
     method public int describeContents();
diff --git a/wear/wear-complications-data/src/main/java/android/support/wearable/complications/package-info.java b/wear/wear-complications-data/src/main/java/android/support/wearable/complications/package-info.java
new file mode 100644
index 0000000..7aa7905
--- /dev/null
+++ b/wear/wear-complications-data/src/main/java/android/support/wearable/complications/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+/**
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+package android.support.wearable.complications;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import androidx.annotation.RestrictTo;
diff --git a/wear/wear-ongoing/api/current.txt b/wear/wear-ongoing/api/current.txt
index edd5ae4..9eb1123 100644
--- a/wear/wear-ongoing/api/current.txt
+++ b/wear/wear-ongoing/api/current.txt
@@ -12,6 +12,7 @@
     method public androidx.wear.ongoing.Status? getStatus();
     method public String? getTag();
     method public long getTimestamp();
+    method public String? getTitle();
     method public android.app.PendingIntent getTouchIntent();
     method public static androidx.wear.ongoing.OngoingActivity? recoverOngoingActivity(android.content.Context, java.util.function.Predicate<androidx.wear.ongoing.OngoingActivity!>);
     method public static androidx.wear.ongoing.OngoingActivity? recoverOngoingActivity(android.content.Context);
@@ -31,6 +32,7 @@
     method public androidx.wear.ongoing.OngoingActivity.Builder setStaticIcon(android.graphics.drawable.Icon);
     method public androidx.wear.ongoing.OngoingActivity.Builder setStaticIcon(@DrawableRes int);
     method public androidx.wear.ongoing.OngoingActivity.Builder setStatus(androidx.wear.ongoing.Status);
+    method public androidx.wear.ongoing.OngoingActivity.Builder setTitle(String);
     method public androidx.wear.ongoing.OngoingActivity.Builder setTouchIntent(android.app.PendingIntent);
   }
 
diff --git a/wear/wear-ongoing/api/public_plus_experimental_current.txt b/wear/wear-ongoing/api/public_plus_experimental_current.txt
index edd5ae4..9eb1123 100644
--- a/wear/wear-ongoing/api/public_plus_experimental_current.txt
+++ b/wear/wear-ongoing/api/public_plus_experimental_current.txt
@@ -12,6 +12,7 @@
     method public androidx.wear.ongoing.Status? getStatus();
     method public String? getTag();
     method public long getTimestamp();
+    method public String? getTitle();
     method public android.app.PendingIntent getTouchIntent();
     method public static androidx.wear.ongoing.OngoingActivity? recoverOngoingActivity(android.content.Context, java.util.function.Predicate<androidx.wear.ongoing.OngoingActivity!>);
     method public static androidx.wear.ongoing.OngoingActivity? recoverOngoingActivity(android.content.Context);
@@ -31,6 +32,7 @@
     method public androidx.wear.ongoing.OngoingActivity.Builder setStaticIcon(android.graphics.drawable.Icon);
     method public androidx.wear.ongoing.OngoingActivity.Builder setStaticIcon(@DrawableRes int);
     method public androidx.wear.ongoing.OngoingActivity.Builder setStatus(androidx.wear.ongoing.Status);
+    method public androidx.wear.ongoing.OngoingActivity.Builder setTitle(String);
     method public androidx.wear.ongoing.OngoingActivity.Builder setTouchIntent(android.app.PendingIntent);
   }
 
diff --git a/wear/wear-ongoing/api/restricted_current.txt b/wear/wear-ongoing/api/restricted_current.txt
index edd5ae4..9eb1123 100644
--- a/wear/wear-ongoing/api/restricted_current.txt
+++ b/wear/wear-ongoing/api/restricted_current.txt
@@ -12,6 +12,7 @@
     method public androidx.wear.ongoing.Status? getStatus();
     method public String? getTag();
     method public long getTimestamp();
+    method public String? getTitle();
     method public android.app.PendingIntent getTouchIntent();
     method public static androidx.wear.ongoing.OngoingActivity? recoverOngoingActivity(android.content.Context, java.util.function.Predicate<androidx.wear.ongoing.OngoingActivity!>);
     method public static androidx.wear.ongoing.OngoingActivity? recoverOngoingActivity(android.content.Context);
@@ -31,6 +32,7 @@
     method public androidx.wear.ongoing.OngoingActivity.Builder setStaticIcon(android.graphics.drawable.Icon);
     method public androidx.wear.ongoing.OngoingActivity.Builder setStaticIcon(@DrawableRes int);
     method public androidx.wear.ongoing.OngoingActivity.Builder setStatus(androidx.wear.ongoing.Status);
+    method public androidx.wear.ongoing.OngoingActivity.Builder setTitle(String);
     method public androidx.wear.ongoing.OngoingActivity.Builder setTouchIntent(android.app.PendingIntent);
   }
 
diff --git a/wear/wear-ongoing/src/main/java/androidx/wear/ongoing/OngoingActivity.java b/wear/wear-ongoing/src/main/java/androidx/wear/ongoing/OngoingActivity.java
index c51d447..dd65d05 100644
--- a/wear/wear-ongoing/src/main/java/androidx/wear/ongoing/OngoingActivity.java
+++ b/wear/wear-ongoing/src/main/java/androidx/wear/ongoing/OngoingActivity.java
@@ -106,6 +106,7 @@
         private LocusIdCompat mLocusId;
         private int mOngoingActivityId = DEFAULT_ID;
         private String mCategory;
+        private String mTitle;
 
         static final int DEFAULT_ID = -1;
 
@@ -242,6 +243,16 @@
         }
 
         /**
+         * Sets the Title of this {@link OngoingActivity}, this could be used by the launcher to
+         * override the app's title.
+         */
+        @NonNull
+        public Builder setTitle(@NonNull String title) {
+            mTitle = title;
+            return this;
+        }
+
+        /**
          * Combine all options provided and the information in the notification if needed,
          * return a new {@link OngoingActivity} object.
          *
@@ -288,7 +299,8 @@
                         locusId == null ? null : locusId.getId(),
                         mOngoingActivityId,
                         category,
-                        SystemClock.elapsedRealtime()
+                        SystemClock.elapsedRealtime(),
+                        mTitle
                     ));
         }
     }
@@ -384,6 +396,14 @@
     }
 
     /**
+     * Get the title of this {@link OngoingActivity} if set.
+     */
+    @Nullable
+    public String getTitle() {
+        return mData.getTitle();
+    }
+
+    /**
      * Notify the system that this activity should be shown as an Ongoing Activity.
      *
      * This will modify the notification builder associated with this Ongoing Activity, so needs
diff --git a/wear/wear-ongoing/src/main/java/androidx/wear/ongoing/OngoingActivityData.java b/wear/wear-ongoing/src/main/java/androidx/wear/ongoing/OngoingActivityData.java
index 9e06859..75bc162 100644
--- a/wear/wear-ongoing/src/main/java/androidx/wear/ongoing/OngoingActivityData.java
+++ b/wear/wear-ongoing/src/main/java/androidx/wear/ongoing/OngoingActivityData.java
@@ -17,7 +17,6 @@
 
 import android.app.PendingIntent;
 import android.graphics.drawable.Icon;
-import android.os.SystemClock;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -65,6 +64,10 @@
     @ParcelField(value = 8)
     long mTimestamp;
 
+    @Nullable
+    @ParcelField(value = 9, defaultValue = "null")
+    String mTitle;
+
     // Required by VersionedParcelable
     OngoingActivityData() {
     }
@@ -77,7 +80,8 @@
             @Nullable String locusId,
             int ongoingActivityId,
             @Nullable String category,
-            long timestamp
+            long timestamp,
+            @Nullable String title
     ) {
         mAnimatedIcon = animatedIcon;
         mStaticIcon = staticIcon;
@@ -87,81 +91,52 @@
         mOngoingActivityId = ongoingActivityId;
         mCategory = category;
         mTimestamp = timestamp;
+        mTitle = title;
     }
 
-    /**
-     * Get the animated icon that can be used on some surfaces to represent this
-     * {@link OngoingActivity}. For example, in the WatchFace.
-     */
     @Nullable
-    public Icon getAnimatedIcon() {
+    Icon getAnimatedIcon() {
         return mAnimatedIcon;
     }
 
-    /**
-     * Get the static icon that can be used on some surfaces to represent this
-     * {@link OngoingActivity}. For example in the WatchFace in ambient mode. If not set, returns
-     *  the small icon of the corresponding Notification.
-     */
     @NonNull
-    public Icon getStaticIcon() {
+    Icon getStaticIcon() {
         return mStaticIcon;
     }
 
-    /**
-     * Get the status of this ongoing activity, the status may be displayed on the UI to
-     * show progress of the Ongoing Activity. If not set, returns the content text of the
-     * corresponding Notification.
-     */
     @Nullable
-    public OngoingActivityStatus getStatus() {
+    OngoingActivityStatus getStatus() {
         return mStatus;
     }
 
-    /**
-     * Get the intent to be used to go back to the activity when the user interacts with the
-     * Ongoing Activity in other surfaces (for example, taps the Icon on the WatchFace). If not
-     * set, returns the touch intent of the corresponding Notification.
-     */
     @NonNull
-    public PendingIntent getTouchIntent() {
+    PendingIntent getTouchIntent() {
         return mTouchIntent;
     }
 
-    /**
-     * Get the LocusId of this {@link OngoingActivity}, this can be used by the launcher to
-     * identify the corresponding launcher item and display it accordingly. If not set, returns
-     * the one in the corresponding Notification.
-     */
     @Nullable
-    public LocusIdCompat getLocusId() {
+    LocusIdCompat getLocusId() {
         return mLocusId == null ? null : new LocusIdCompat(mLocusId);
     }
 
-    /**
-     * Give the id to this {@link OngoingActivity}, as a way to reference it in
-     * [fromExistingOngoingActivity]
-     */
-    public int getOngoingActivityId() {
+    int getOngoingActivityId() {
         return mOngoingActivityId;
     }
 
-    /**
-     * Get the Category of this {@link OngoingActivity} if set, otherwise the category of the
-     * corresponding notification.
-     */
     @Nullable
-    public String getCategory() {
+    String getCategory() {
         return mCategory;
     }
 
-    /**
-     * Get the time (in {@link SystemClock#elapsedRealtime()} time) the OngoingActivity was built.
-     */
-    public long getTimestamp() {
+    long getTimestamp() {
         return mTimestamp;
     }
 
+    @Nullable
+    String getTitle() {
+        return mTitle;
+    }
+
     // Status is mutable, by the library.
     void setStatus(@NonNull OngoingActivityStatus status) {
         mStatus = status;
diff --git a/wear/wear-ongoing/src/test/java/androidx/wear/ongoing/OngoingActivityTest.kt b/wear/wear-ongoing/src/test/java/androidx/wear/ongoing/OngoingActivityTest.kt
index 1519bf6..93290b7 100644
--- a/wear/wear-ongoing/src/test/java/androidx/wear/ongoing/OngoingActivityTest.kt
+++ b/wear/wear-ongoing/src/test/java/androidx/wear/ongoing/OngoingActivityTest.kt
@@ -34,6 +34,7 @@
     )
     private val NotificationId = 4321
     private val ChannelId = "ChannelId"
+    private val Title = "AppTitle"
 
     private lateinit var context: Context
     private lateinit var notificationManager: NotificationManager
@@ -78,6 +79,7 @@
             .setOngoingActivityId(OaId)
             .setStatus(BasicStatus)
             .setTouchIntent(PendingIntentValue)
+            .setTitle(Title)
             .build()
         oa.apply(context)
 
@@ -91,6 +93,7 @@
         assertEquals(OaId, received.ongoingActivityId)
         // TODO(ssancho): check status
         assertEquals(PendingIntentValue, received.touchIntent)
+        assertEquals(Title, received.title)
     }
 
     @Test
@@ -103,6 +106,7 @@
             .setOngoingActivityId(OaId)
             .setStatus(BasicStatus)
             .setTouchIntent(PendingIntentValue)
+            .setTitle(Title)
             .build()
         oa.apply(context)
         notificationManager.notify(NotificationId, builder.build())
@@ -126,6 +130,7 @@
         assertEquals(OaId, received.ongoingActivityId)
         // TODO(ssancho): check status
         assertEquals(PendingIntentValue, received.touchIntent)
+        assertEquals(Title, received.title)
 
         notificationManager.cancel(NotificationId)
     }
@@ -193,6 +198,7 @@
             .setOngoingActivityId(OaId)
             .setStatus(BasicStatus)
             .setTouchIntent(PendingIntentValue)
+            .setTitle(Title)
             .build()
         oa.apply(context)
         val notification = builder.build()
@@ -209,6 +215,7 @@
         assertEquals(OaId, received.ongoingActivityId)
         // TODO(ssancho): check status
         assertEquals(PendingIntentValue, received.touchIntent)
+        assertEquals(Title, received.title)
     }
 
     @Test
diff --git a/wear/wear-watchface-data/api/restricted_current.txt b/wear/wear-watchface-data/api/restricted_current.txt
index 58265360..12e7670 100644
--- a/wear/wear-watchface-data/api/restricted_current.txt
+++ b/wear/wear-watchface-data/api/restricted_current.txt
@@ -1,5 +1,5 @@
 // Signature format: 4.0
-package android.support.wearable.watchface {
+package @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) android.support.wearable.watchface {
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final class Constants {
     field public static final String ACTION_REQUEST_STATE = "com.google.android.wearable.watchfaces.action.REQUEST_STATE";
@@ -93,7 +93,7 @@
 
 }
 
-package android.support.wearable.watchface.accessibility {
+package @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) android.support.wearable.watchface.accessibility {
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public class AccessibilityUtils {
     method public static android.support.wearable.complications.TimeDependentText generateContentDescription(android.content.Context, android.support.wearable.complications.ComplicationData);
diff --git a/wear/wear-watchface-data/src/main/java/android/support/wearable/watchface/accessibility/package-info.java b/wear/wear-watchface-data/src/main/java/android/support/wearable/watchface/accessibility/package-info.java
new file mode 100644
index 0000000..45c6efc
--- /dev/null
+++ b/wear/wear-watchface-data/src/main/java/android/support/wearable/watchface/accessibility/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+/**
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+package android.support.wearable.watchface.accessibility;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import androidx.annotation.RestrictTo;
diff --git a/wear/wear-watchface-data/src/main/java/android/support/wearable/watchface/package-info.java b/wear/wear-watchface-data/src/main/java/android/support/wearable/watchface/package-info.java
new file mode 100644
index 0000000..4b57c76
--- /dev/null
+++ b/wear/wear-watchface-data/src/main/java/android/support/wearable/watchface/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+/**
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+package android.support.wearable.watchface;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import androidx.annotation.RestrictTo;
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 ef2ef3f..fe73ba9 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
@@ -1110,6 +1110,9 @@
         val editorObserver = TestEditorObserver()
         val observerId = EditorService.globalEditorService.registerObserver(editorObserver)
 
+        val oldWFColorStyleSetting = editorDelegate.userStyle[colorStyleSetting]!!.id.value
+        val oldWFWatchHandStyleSetting = editorDelegate.userStyle[watchHandStyleSetting]!!.id.value
+
         scenario.onActivity { activity ->
             runBlocking {
                 // Select [blueStyleOption] and [gothicStyleOption].
@@ -1135,11 +1138,12 @@
         assertThat(result.watchFaceId.id).isEqualTo(testInstanceId.id)
         assertTrue(result.shouldCommitChanges)
 
-        // The style change should also have been applied to the watchface
+        // The style change shouldn't be applied to the watchface as it gets reverted to the old
+        // one when editor closes.
         assertThat(editorDelegate.userStyle[colorStyleSetting]!!.id.value)
-            .isEqualTo(blueStyleOption.id.value)
+            .isEqualTo(oldWFColorStyleSetting)
         assertThat(editorDelegate.userStyle[watchHandStyleSetting]!!.id.value)
-            .isEqualTo(gothicStyleOption.id.value)
+            .isEqualTo(oldWFWatchHandStyleSetting)
 
         assertThat(result.previewComplicationsData.size).isEqualTo(2)
         val leftComplicationData = result.previewComplicationsData[LEFT_COMPLICATION_ID] as
@@ -1514,7 +1518,8 @@
                 mockWatchFaceHostApi,
                 watchState,
                 currentUserStyleRepository,
-                ComplicationsManager(emptyList(), currentUserStyleRepository)
+                ComplicationsManager(emptyList(), currentUserStyleRepository),
+                Calendar.getInstance()
             )
 
             assertThat(activity.onCreateException).isInstanceOf(IllegalStateException::class.java)
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 c974e38..eef4f27 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
@@ -77,7 +77,10 @@
  * Interface for manipulating watch face state during an editing session for a watch face editing
  * session. The editor should adjust [userStyle] and call [openComplicationProviderChooser] to
  * configure the watch face and call [close] when done. This reports the updated [EditorState] to
- * the [EditorListener]s registered via [EditorServiceClient.addListener].
+ * the [EditorListener]s registered via [EditorServiceClient.addListener]. Style changes applied
+ * during the editor session are temporary and will be reverted when the editor session completes.
+ * In the event that the editor sessions results in a new watch face configuration that will be
+ * subsequently reapplied when the new configuration is provided by the system.
  */
 public abstract class EditorSession : AutoCloseable {
     /** The [ComponentName] of the watch face being edited. */
@@ -91,7 +94,8 @@
     @get:RequiresApi(Build.VERSION_CODES.R)
     public abstract val watchFaceId: WatchFaceId
 
-    /** The current [UserStyle]. Assigning to this will cause the style to update. */
+    /** The current [UserStyle]. Assigning to this will cause the style to update. However, styling
+     * changes to the watch face will be reverted upon exit. */
     public abstract var userStyle: UserStyle
 
     /** The UTC reference preview time for this watch face in milliseconds since the epoch. */
@@ -113,10 +117,10 @@
      * because there are circumstances where [ComponentActivity.onStop] doesn't get called but the
      * UX requires us to commit changes.
      *
-     * If false upon exit for an on watch face editor, the original UserStyle is restored. Note we
-     * need SysUI's help to revert any complication provider changes. Caveat some providers have
-     * their own config (e.g. the world clock has a timezone setting) and that config currently
-     * can't be reverted.
+     * Regardless of the value, on completion of the editor session, the original UserStyle is
+     * restored. Note we need SysUI's help to revert any complication provider changes. Caveat
+     * some providers have their own config (e.g. the world clock has a timezone setting) and
+     * that config currently can't be reverted.
      */
     @get:UiThread
     @get:JvmName("isCommitChangesOnClose")
@@ -665,8 +669,11 @@
         if (this::editorDelegate.isInitialized) {
             editorDelegate.onDestroy()
         }
-        // Revert any changes to the UserStyle if needed.
-        if (!commitChangesOnClose && this::previousWatchFaceUserStyle.isInitialized) {
+        // Revert any changes to the user style that was set during the editing session. The
+        // system will update the user style and communicate it to the active watch face if
+        // needed. This guarantees that the system is always the source of truth for the current
+        // style.
+        if (this::previousWatchFaceUserStyle.isInitialized) {
             userStyle = previousWatchFaceUserStyle
         }
     }
diff --git a/wear/wear-watchface/api/current.txt b/wear/wear-watchface/api/current.txt
index 53b8d81..3e4c282 100644
--- a/wear/wear-watchface/api/current.txt
+++ b/wear/wear-watchface/api/current.txt
@@ -21,7 +21,7 @@
   }
 
   public interface CanvasComplicationFactory {
-    method @UiThread public androidx.wear.watchface.CanvasComplication create(androidx.wear.watchface.WatchState, androidx.wear.watchface.CanvasComplication.InvalidateCallback);
+    method @WorkerThread public androidx.wear.watchface.CanvasComplication create(androidx.wear.watchface.WatchState, androidx.wear.watchface.CanvasComplication.InvalidateCallback);
   }
 
   public final class Complication {
@@ -121,14 +121,7 @@
     enum_constant public static final androidx.wear.watchface.DrawMode MUTE;
   }
 
-  public final class MutableObservableWatchData<T> extends androidx.wear.watchface.ObservableWatchData<T> {
-    ctor public MutableObservableWatchData(T? initialValue);
-    ctor public MutableObservableWatchData();
-    method @UiThread public void setValue(T v);
-    property @UiThread public T value;
-  }
-
-  public class ObservableWatchData<T> {
+  public abstract sealed class ObservableWatchData<T> {
     method @UiThread public final void addObserver(androidx.wear.watchface.Observer<T> observer);
     method @UiThread public T getValue();
     method @UiThread public final T getValueOr(T p);
@@ -138,6 +131,13 @@
     property @UiThread public T value;
   }
 
+  public static final class ObservableWatchData.MutableObservableWatchData<T> extends androidx.wear.watchface.ObservableWatchData<T> {
+    ctor public ObservableWatchData.MutableObservableWatchData(T? initialValue);
+    ctor public ObservableWatchData.MutableObservableWatchData();
+    method @UiThread public void setValue(T v);
+    property @UiThread public T value;
+  }
+
   public interface Observer<T> {
     method public void onChanged(T);
   }
diff --git a/wear/wear-watchface/api/public_plus_experimental_current.txt b/wear/wear-watchface/api/public_plus_experimental_current.txt
index 0049d9a..b12e928 100644
--- a/wear/wear-watchface/api/public_plus_experimental_current.txt
+++ b/wear/wear-watchface/api/public_plus_experimental_current.txt
@@ -21,7 +21,7 @@
   }
 
   public interface CanvasComplicationFactory {
-    method @UiThread public androidx.wear.watchface.CanvasComplication create(androidx.wear.watchface.WatchState, androidx.wear.watchface.CanvasComplication.InvalidateCallback);
+    method @WorkerThread public androidx.wear.watchface.CanvasComplication create(androidx.wear.watchface.WatchState, androidx.wear.watchface.CanvasComplication.InvalidateCallback);
   }
 
   public final class Complication {
@@ -121,14 +121,7 @@
     enum_constant public static final androidx.wear.watchface.DrawMode MUTE;
   }
 
-  public final class MutableObservableWatchData<T> extends androidx.wear.watchface.ObservableWatchData<T> {
-    ctor public MutableObservableWatchData(T? initialValue);
-    ctor public MutableObservableWatchData();
-    method @UiThread public void setValue(T v);
-    property @UiThread public T value;
-  }
-
-  public class ObservableWatchData<T> {
+  public abstract sealed class ObservableWatchData<T> {
     method @UiThread public final void addObserver(androidx.wear.watchface.Observer<T> observer);
     method @UiThread public T getValue();
     method @UiThread public final T getValueOr(T p);
@@ -138,6 +131,13 @@
     property @UiThread public T value;
   }
 
+  public static final class ObservableWatchData.MutableObservableWatchData<T> extends androidx.wear.watchface.ObservableWatchData<T> {
+    ctor public ObservableWatchData.MutableObservableWatchData(T? initialValue);
+    ctor public ObservableWatchData.MutableObservableWatchData();
+    method @UiThread public void setValue(T v);
+    property @UiThread public T value;
+  }
+
   public interface Observer<T> {
     method public void onChanged(T);
   }
diff --git a/wear/wear-watchface/api/restricted_current.txt b/wear/wear-watchface/api/restricted_current.txt
index 95a9235..23a2893 100644
--- a/wear/wear-watchface/api/restricted_current.txt
+++ b/wear/wear-watchface/api/restricted_current.txt
@@ -21,7 +21,7 @@
   }
 
   public interface CanvasComplicationFactory {
-    method @UiThread public androidx.wear.watchface.CanvasComplication create(androidx.wear.watchface.WatchState, androidx.wear.watchface.CanvasComplication.InvalidateCallback);
+    method @WorkerThread public androidx.wear.watchface.CanvasComplication create(androidx.wear.watchface.WatchState, androidx.wear.watchface.CanvasComplication.InvalidateCallback);
   }
 
   public final class Complication {
@@ -122,13 +122,6 @@
     enum_constant public static final androidx.wear.watchface.DrawMode MUTE;
   }
 
-  public final class MutableObservableWatchData<T> extends androidx.wear.watchface.ObservableWatchData<T> {
-    ctor public MutableObservableWatchData(T? initialValue);
-    ctor public MutableObservableWatchData();
-    method @UiThread public void setValue(T v);
-    property @UiThread public T value;
-  }
-
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final class MutableWatchState {
     method public androidx.wear.watchface.WatchState asWatchState();
     method public long getAnalogPreviewReferenceTimeMillis();
@@ -136,31 +129,31 @@
     method public long getDigitalPreviewReferenceTimeMillis();
     method public boolean getHasBurnInProtection();
     method public boolean getHasLowBitAmbient();
-    method public androidx.wear.watchface.MutableObservableWatchData<java.lang.Integer> getInterruptionFilter();
-    method public androidx.wear.watchface.MutableObservableWatchData<java.lang.Boolean> isAmbient();
-    method public androidx.wear.watchface.MutableObservableWatchData<java.lang.Boolean> isBatteryLowAndNotCharging();
+    method public androidx.wear.watchface.ObservableWatchData.MutableObservableWatchData<java.lang.Integer> getInterruptionFilter();
+    method public androidx.wear.watchface.ObservableWatchData.MutableObservableWatchData<java.lang.Boolean> isAmbient();
+    method public androidx.wear.watchface.ObservableWatchData.MutableObservableWatchData<java.lang.Boolean> isBatteryLowAndNotCharging();
     method public boolean isHeadless();
-    method public androidx.wear.watchface.MutableObservableWatchData<java.lang.Boolean> isVisible();
+    method public androidx.wear.watchface.ObservableWatchData.MutableObservableWatchData<java.lang.Boolean> isVisible();
     method public void setAnalogPreviewReferenceTimeMillis(long p);
     method public void setChinHeight(@Px int value);
     method public void setDigitalPreviewReferenceTimeMillis(long p);
     method public void setHasBurnInProtection(boolean p);
     method public void setHasLowBitAmbient(boolean p);
     method public void setHeadless(boolean p);
-    method public void setInterruptionFilter(androidx.wear.watchface.MutableObservableWatchData<java.lang.Integer> p);
+    method public void setInterruptionFilter(androidx.wear.watchface.ObservableWatchData.MutableObservableWatchData<java.lang.Integer> p);
     property public final long analogPreviewReferenceTimeMillis;
     property @Px public final int chinHeight;
     property public final long digitalPreviewReferenceTimeMillis;
     property public final boolean hasBurnInProtection;
     property public final boolean hasLowBitAmbient;
-    property public final androidx.wear.watchface.MutableObservableWatchData<java.lang.Integer> interruptionFilter;
-    property public final androidx.wear.watchface.MutableObservableWatchData<java.lang.Boolean> isAmbient;
-    property public final androidx.wear.watchface.MutableObservableWatchData<java.lang.Boolean> isBatteryLowAndNotCharging;
+    property public final androidx.wear.watchface.ObservableWatchData.MutableObservableWatchData<java.lang.Integer> interruptionFilter;
+    property public final androidx.wear.watchface.ObservableWatchData.MutableObservableWatchData<java.lang.Boolean> isAmbient;
+    property public final androidx.wear.watchface.ObservableWatchData.MutableObservableWatchData<java.lang.Boolean> isBatteryLowAndNotCharging;
     property public final boolean isHeadless;
-    property public final androidx.wear.watchface.MutableObservableWatchData<java.lang.Boolean> isVisible;
+    property public final androidx.wear.watchface.ObservableWatchData.MutableObservableWatchData<java.lang.Boolean> isVisible;
   }
 
-  public class ObservableWatchData<T> {
+  public abstract sealed class ObservableWatchData<T> {
     method @UiThread public final void addObserver(androidx.wear.watchface.Observer<T> observer);
     method @UiThread public T getValue();
     method @UiThread public final T getValueOr(T p);
@@ -170,6 +163,13 @@
     property @UiThread public T value;
   }
 
+  public static final class ObservableWatchData.MutableObservableWatchData<T> extends androidx.wear.watchface.ObservableWatchData<T> {
+    ctor public ObservableWatchData.MutableObservableWatchData(T? initialValue);
+    ctor public ObservableWatchData.MutableObservableWatchData();
+    method @UiThread public void setValue(T v);
+    property @UiThread public T value;
+  }
+
   public interface Observer<T> {
     method public void onChanged(T);
   }
@@ -368,7 +368,7 @@
   }
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final class WatchFaceImpl {
-    ctor @UiThread public WatchFaceImpl(androidx.wear.watchface.WatchFace watchface, androidx.wear.watchface.WatchFaceHostApi watchFaceHostApi, androidx.wear.watchface.WatchState watchState, androidx.wear.watchface.style.CurrentUserStyleRepository currentUserStyleRepository, androidx.wear.watchface.ComplicationsManager complicationsManager);
+    ctor @UiThread public WatchFaceImpl(androidx.wear.watchface.WatchFace watchface, androidx.wear.watchface.WatchFaceHostApi watchFaceHostApi, androidx.wear.watchface.WatchState watchState, androidx.wear.watchface.style.CurrentUserStyleRepository currentUserStyleRepository, androidx.wear.watchface.ComplicationsManager complicationsManager, android.icu.util.Calendar calendar);
     method public long getPreviewReferenceTimeMillis();
     property public final long previewReferenceTimeMillis;
   }
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/CanvasComplicationFactory.java b/wear/wear-watchface/src/main/java/androidx/wear/watchface/CanvasComplicationFactory.java
index 133b6d0..6d46712 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/CanvasComplicationFactory.java
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/CanvasComplicationFactory.java
@@ -17,7 +17,7 @@
 package androidx.wear.watchface;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.UiThread;
+import androidx.annotation.WorkerThread;
 
 /**
  * Factory for creating a CanvasComplication. This decouples construction of Complications and
@@ -26,7 +26,9 @@
 // TODO(b/188035300): Put links into the comments.
 public interface CanvasComplicationFactory {
     /**
-     * Creates a CanvasComplication.
+     * Creates a CanvasComplication. This will be called on a background thread, however all
+     * CanvasComplication rendering will be done on the UI thread and there's a memory barrier
+     * between construction and usage so no special threading primitives are required.
      *
      * @param watchState The current WatchState
      * @param invalidateCallback The CanvasComplication.InvalidateCallback the constructed
@@ -36,7 +38,7 @@
      * @return The constructed CanvasComplication.
      */
     @NonNull
-    @UiThread
+    @WorkerThread
     @SuppressWarnings("ExecutorRegistration") // This is UI thread only.
     CanvasComplication create(
             @NonNull WatchState watchState,
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/Complication.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/Complication.kt
index 017b5675..062cdca 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/Complication.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/Complication.kt
@@ -29,6 +29,7 @@
 import androidx.wear.complications.DefaultComplicationProviderPolicy
 import androidx.wear.complications.data.ComplicationData
 import androidx.wear.complications.data.ComplicationType
+import androidx.wear.watchface.ObservableWatchData.MutableObservableWatchData
 import androidx.wear.watchface.data.ComplicationBoundsType
 import androidx.wear.watchface.style.UserStyleSetting
 import androidx.wear.watchface.style.UserStyleSetting.ComplicationsUserStyleSetting
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/ComplicationsManager.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/ComplicationsManager.kt
index 5a13a2d..a89c976 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/ComplicationsManager.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/ComplicationsManager.kt
@@ -33,6 +33,7 @@
 import androidx.wear.complications.data.ComplicationType
 import androidx.wear.complications.data.EmptyComplicationData
 import androidx.wear.utility.TraceEvent
+import androidx.wear.watchface.ObservableWatchData.MutableObservableWatchData
 import androidx.wear.watchface.control.data.IdTypeAndDefaultProviderPolicyWireFormat
 import androidx.wear.watchface.data.ComplicationBoundsType
 import androidx.wear.watchface.style.CurrentUserStyleRepository
@@ -152,6 +153,7 @@
     }
 
     /** Finish initialization. */
+    @WorkerThread
     internal fun init(
         watchFaceHostApi: WatchFaceHostApi,
         calendar: Calendar,
@@ -164,6 +166,9 @@
 
         for ((_, complication) in complications) {
             complication.init(complicationInvalidateListener)
+
+            // Force lazy construction of renderers.
+            complication.renderer
         }
 
         // Activate complications.
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/ObservableWatchData.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/ObservableWatchData.kt
index ba4ac3f..12b1443 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/ObservableWatchData.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/ObservableWatchData.kt
@@ -24,7 +24,7 @@
  * @param T The type of data held by this instance.
  * @param _value The initial value or `null` if there isn't an initial value.
  */
-public open class ObservableWatchData<T : Any> internal constructor(internal var _value: T?) {
+public sealed class ObservableWatchData<T : Any> constructor(internal var _value: T?) {
 
     private var iterating = false
     private val observers = ArrayList<Observer<T>>()
@@ -104,26 +104,26 @@
             "<unset>"
         }
     }
-}
-
-/**
- * [ObservableWatchData] which publicly exposes [setValue(T)] method.
- *
- * @param T The type of data held by this instance
- */
-public class MutableObservableWatchData<T : Any>(initialValue: T?) :
-    ObservableWatchData<T>(initialValue) {
-    public constructor() : this(null)
 
     /**
-     * Mutable observable value. Assigning a different value will trigger [Observer.onChanged]
-     * callbacks.
+     * [ObservableWatchData] which publicly exposes [setValue(T)] method.
+     *
+     * @param T The type of data held by this instance
      */
-    override var value: T
-        @UiThread
-        get() = _value!!
-        @UiThread
-        public set(v) {
-            super.value = v
-        }
+    public class MutableObservableWatchData<T : Any>(initialValue: T?) :
+        ObservableWatchData<T>(initialValue) {
+        public constructor() : this(null)
+
+        /**
+         * Mutable observable value. Assigning a different value will trigger [Observer.onChanged]
+         * callbacks.
+         */
+        override var value: T
+            @UiThread
+            get() = _value!!
+            @UiThread
+            public set(v) {
+                super.value = v
+            }
+    }
 }
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/Renderer.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/Renderer.kt
index ff7ebb2..6dfc3f8 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/Renderer.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/Renderer.kt
@@ -102,7 +102,8 @@
 
 /**
  * The base class for [CanvasRenderer] and [GlesRenderer]. Renderers are constructed on a background
- * thread but all rendering is done on the UiThread.
+ * thread but all rendering is done on the UiThread. There is a memory barrier between construction
+ * and rendering so no special threading primitives are required.
  *
  * @param surfaceHolder The [SurfaceHolder] that [renderInternal] will draw into.
  * @param currentUserStyleRepository The associated [CurrentUserStyleRepository].
@@ -306,7 +307,9 @@
      *
      * A CanvasRenderer is expected to be constructed on the background thread associated with
      * [WatchFaceService.getBackgroundThreadHandler] inside a call to
-     * [WatchFaceService.createWatchFace]. All rendering is be done on the UiThread.
+     * [WatchFaceService.createWatchFace]. All rendering is be done on the UiThread. There is a
+     * memory barrier between construction and rendering so no special threading primitives are
+     * required.
      *
      * @param surfaceHolder The [SurfaceHolder] from which a [Canvas] to will be obtained and passed
      * into [render].
@@ -463,7 +466,9 @@
      *
      * A GlesRenderer is expected to be constructed on the background thread associated with
      * [WatchFaceService.getBackgroundThreadHandler] inside a call to
-     * [WatchFaceService.createWatchFace]. All rendering is be done on the UiThread.
+     * [WatchFaceService.createWatchFace]. All rendering is be done on the UiThread. There is a
+     * memory barrier between construction and rendering so no special threading primitives are
+     * required.
      *
      * Two linked [EGLContext]s are created [eglBackgroundThreadContext] and [eglUiThreadContext]
      * which are associated with background and UiThread respectively. OpenGL objects created on
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFace.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFace.kt
index 3865712..ff3c3a2 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFace.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFace.kt
@@ -19,7 +19,6 @@
 import android.annotation.SuppressLint
 import android.app.NotificationManager
 import android.content.ComponentName
-import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
 import android.graphics.Bitmap
@@ -32,7 +31,6 @@
 import android.os.Bundle
 import android.support.wearable.watchface.SharedMemoryImage
 import android.support.wearable.watchface.WatchFaceStyle
-import android.util.Base64
 import android.view.Gravity
 import android.view.Surface.FRAME_RATE_COMPATIBILITY_DEFAULT
 import androidx.annotation.ColorInt
@@ -41,7 +39,6 @@
 import androidx.annotation.Px
 import androidx.annotation.RequiresApi
 import androidx.annotation.RestrictTo
-import androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP
 import androidx.annotation.UiThread
 import androidx.annotation.VisibleForTesting
 import androidx.wear.complications.SystemProviders
@@ -49,6 +46,7 @@
 import androidx.wear.complications.data.ComplicationType
 import androidx.wear.complications.data.toApiComplicationData
 import androidx.wear.utility.TraceEvent
+import androidx.wear.watchface.ObservableWatchData.MutableObservableWatchData
 import androidx.wear.watchface.control.data.ComplicationRenderParams
 import androidx.wear.watchface.control.data.WatchFaceRenderParams
 import androidx.wear.watchface.data.ComplicationStateWireFormat
@@ -58,10 +56,7 @@
 import androidx.wear.watchface.style.UserStyleData
 import androidx.wear.watchface.style.UserStyleSchema
 import androidx.wear.watchface.style.WatchFaceLayer
-import androidx.wear.watchface.style.data.UserStyleWireFormat
 import kotlinx.coroutines.CompletableDeferred
-import java.io.FileNotFoundException
-import java.io.InputStreamReader
 import java.security.InvalidParameterException
 import kotlin.math.max
 
@@ -94,35 +89,6 @@
     }
 }
 
-private fun readPrefs(context: Context, fileName: String): UserStyleWireFormat {
-    val hashMap = HashMap<String, ByteArray>()
-    try {
-        val reader = InputStreamReader(context.openFileInput(fileName)).buffered()
-        reader.use {
-            while (true) {
-                val key = reader.readLine() ?: break
-                val value = reader.readLine() ?: break
-                hashMap[key] = Base64.decode(value, Base64.NO_WRAP)
-            }
-        }
-    } catch (e: FileNotFoundException) {
-        // We don't need to do anything special here.
-    }
-    return UserStyleWireFormat(hashMap)
-}
-
-private fun writePrefs(context: Context, fileName: String, style: UserStyle) {
-    val writer = context.openFileOutput(fileName, Context.MODE_PRIVATE).bufferedWriter()
-    writer.use {
-        for ((key, value) in style.selectedOptions) {
-            writer.write(key.id.value)
-            writer.newLine()
-            writer.write(Base64.encodeToString(value.id.value, Base64.NO_WRAP))
-            writer.newLine()
-        }
-    }
-}
-
 /**
  * The return value of [WatchFaceService.createWatchFace] which brings together rendering, styling,
  * complications and state observers.
@@ -241,7 +207,7 @@
      * Interface for getting the current system time.
      * @hide
      */
-    @RestrictTo(LIBRARY_GROUP)
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     public interface SystemTimeProvider {
         /** Returns the current system time in milliseconds. */
         public fun getSystemTimeMillis(): Long
@@ -370,7 +336,7 @@
     }
 
     /** @hide */
-    @RestrictTo(LIBRARY_GROUP)
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     public fun setSystemTimeProvider(systemTimeProvider: SystemTimeProvider): WatchFace = apply {
         this.systemTimeProvider = systemTimeProvider
     }
@@ -384,7 +350,12 @@
     private val watchFaceHostApi: WatchFaceHostApi,
     private val watchState: WatchState,
     internal val currentUserStyleRepository: CurrentUserStyleRepository,
-    internal var complicationsManager: ComplicationsManager
+    internal var complicationsManager: ComplicationsManager,
+
+    /** @hide */
+    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    @get:VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    public val calendar: Calendar
 ) {
     internal companion object {
         internal const val NO_DEFAULT_PROVIDER = SystemProviders.NO_PROVIDER
@@ -459,11 +430,6 @@
     private var muteMode = false
     private var nextDrawTimeMillis: Long = 0
 
-    /** @hide */
-    @RestrictTo(LIBRARY_GROUP)
-    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
-    public val calendar: Calendar = Calendar.getInstance()
-
     private val pendingUpdateTime: CancellableUniqueTask =
         CancellableUniqueTask(watchFaceHostApi.getUiThreadHandler())
 
@@ -602,35 +568,6 @@
     }
 
     init {
-        // If the system has a stored user style then Home/SysUI is in charge of style
-        // persistence, otherwise we need to do our own.
-        val storedUserStyle = watchFaceHostApi.getInitialUserStyle()
-        if (storedUserStyle != null) {
-            TraceEvent("WatchFaceImpl.init apply userStyle").use {
-                currentUserStyleRepository.userStyle =
-                    UserStyle(UserStyleData(storedUserStyle), currentUserStyleRepository.schema)
-            }
-        } else {
-            TraceEvent("WatchFaceImpl.init apply userStyle from prefs").use {
-                // The system doesn't support preference persistence we need to do it ourselves.
-                val preferencesFile =
-                    "watchface_prefs_${watchFaceHostApi.getContext().javaClass.name}.txt"
-
-                currentUserStyleRepository.userStyle = UserStyle(
-                    UserStyleData(readPrefs(watchFaceHostApi.getContext(), preferencesFile)),
-                    currentUserStyleRepository.schema
-                )
-
-                currentUserStyleRepository.addUserStyleChangeListener(
-                    object : CurrentUserStyleRepository.UserStyleChangeListener {
-                        @SuppressLint("SyntheticAccessor")
-                        override fun onUserStyleChanged(userStyle: UserStyle) {
-                            writePrefs(watchFaceHostApi.getContext(), preferencesFile, userStyle)
-                        }
-                    })
-            }
-        }
-
         renderer.watchFaceHostApi = watchFaceHostApi
         renderer.uiThreadInit()
 
@@ -640,34 +577,6 @@
             }
         )
 
-        // We need to inhibit an immediate callback during initialization because members are not
-        // fully constructed and it will fail. It's also superfluous because we're going to render
-        // anyway.
-        var initFinished = false
-        complicationsManager.init(
-            watchFaceHostApi, calendar, renderer,
-            object : Complication.InvalidateListener {
-                @SuppressWarnings("SyntheticAccessor")
-                override fun onInvalidate() {
-                    // This could be called on any thread.
-                    watchFaceHostApi.getUiThreadHandler().runOnHandlerWithTracing("onInvalidate") {
-                        // Ensure we render a frame if the Complication needs rendering, e.g.
-                        // because it loaded an image. However if we're animating there's no need
-                        // to trigger an extra invalidation.
-                        if (initFinished && (
-                            !renderer.shouldAnimate() || computeDelayTillNextFrame(
-                                    nextDrawTimeMillis,
-                                    systemTimeProvider.getSystemTimeMillis()
-                                ) > MIN_PERCEPTABLE_DELAY_MILLIS
-                            )
-                        ) {
-                            watchFaceHostApi.invalidate()
-                        }
-                    }
-                }
-            }
-        )
-
         if (!watchState.isHeadless) {
             WatchFace.registerEditorDelegate(componentName, WFEditorDelegate())
         }
@@ -678,8 +587,19 @@
         }
         watchState.interruptionFilter.addObserver(interruptionFilterObserver)
         watchState.isVisible.addObserver(visibilityObserver)
+    }
 
-        initFinished = true
+    internal fun invalidateIfNotAnimating() {
+        // Ensure we render a frame if the Complication needs rendering, e.g.
+        // because it loaded an image. However if we're animating there's no need
+        // to trigger an extra invalidation.
+        if (!renderer.shouldAnimate() || computeDelayTillNextFrame(
+                nextDrawTimeMillis,
+                systemTimeProvider.getSystemTimeMillis()
+            ) > MIN_PERCEPTABLE_DELAY_MILLIS
+        ) {
+            watchFaceHostApi.invalidate()
+        }
     }
 
     internal fun createWFEditorDelegate() = WFEditorDelegate() as WatchFace.EditorDelegate
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 5b988bc..567c93a 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
@@ -22,6 +22,7 @@
 import android.content.Intent
 import android.graphics.Canvas
 import android.graphics.Rect
+import android.icu.util.Calendar
 import android.os.Build
 import android.os.Bundle
 import android.os.Handler
@@ -35,6 +36,7 @@
 import android.support.wearable.watchface.IWatchFaceService
 import android.support.wearable.watchface.accessibility.AccessibilityUtils
 import android.support.wearable.watchface.accessibility.ContentDescriptionLabel
+import android.util.Base64
 import android.util.Log
 import android.view.Choreographer
 import android.view.Surface
@@ -79,8 +81,9 @@
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.withContext
 import java.io.FileDescriptor
+import java.io.FileNotFoundException
+import java.io.InputStreamReader
 import java.io.PrintWriter
 import java.util.concurrent.CountDownLatch
 
@@ -155,7 +158,8 @@
  * [UserStyleSetting]. To enable support for styling override [createUserStyleSchema].
  *
  * WatchFaces are initially constructed on a background thread before being used exclusively on
- * the ui thread afterwards.
+ * the ui thread afterwards. There is a memory barrier between construction and rendering so no
+ * special threading primitives are required.
  *
  * To aid debugging watch face animations, WatchFaceService allows you to speed up or slow down
  * time, and to loop between two instants.  This is controlled by MOCK_TIME_INTENT intents
@@ -281,7 +285,8 @@
      * library on the UiThread. If possible any expensive initialization should be done on a
      * background thread to avoid blocking the UiThread. This will be called from a background
      * thread but the [WatchFace] and its [Renderer] should be accessed exclusively from the
-     * UiThread afterwards.
+     * UiThread afterwards. There is a memory barrier between construction and rendering so no
+     * special threading primitives are required.
      *
      * Warning watch face initialization will fail if createWatchFace takes longer than
      * [MAX_CREATE_WATCHFACE_TIME_MILLIS] milliseconds.
@@ -316,8 +321,6 @@
     /** This is open for testing. */
     internal open fun getUiThreadHandlerImpl(): Handler = Handler(Looper.getMainLooper())
 
-    internal var backgroundThread: HandlerThread? = null
-
     /**
      * Returns the lazily constructed background thread [Handler]. During initialization
      * [createUserStyleSchema], [createComplicationsManager] and [createWatchFace] are posted on
@@ -325,16 +328,15 @@
      */
     public fun getBackgroundThreadHandler(): Handler = getBackgroundThreadHandlerImpl()
 
-    /** This is open for testing. */
-    internal open fun getBackgroundThreadHandlerImpl(): Handler {
-        if (backgroundThread == null) {
-            backgroundThread = HandlerThread("WatchFaceBackground").apply {
-                start()
-            }
-        }
-        return Handler(backgroundThread!!.looper)
+    internal val backgroundThread = lazy {
+        HandlerThread("WatchFaceBackground").apply { start() }
     }
 
+    private val _backgroundThreadHandler by lazy { Handler(backgroundThread.value.looper) }
+
+    /** This is open for testing. */
+    internal open fun getBackgroundThreadHandlerImpl() = _backgroundThreadHandler
+
     /** This is open to allow mocking. */
     internal open fun getMutableWatchState() = MutableWatchState()
 
@@ -358,6 +360,10 @@
         attachBaseContext(context)
     }
 
+    /**
+     * Reads WallpaperInteractiveWatchFaceInstanceParams from a file. This is only used in the
+     * android R flow.
+     */
     internal open fun readDirectBootPrefs(
         context: Context,
         fileName: String
@@ -375,6 +381,10 @@
         }
     }
 
+    /**
+     * Writes WallpaperInteractiveWatchFaceInstanceParams to a file. This is only used in the
+     * android R flow.
+     */
     internal open fun writeDirectBootPrefs(
         context: Context,
         fileName: String,
@@ -387,6 +397,37 @@
         }
     }
 
+    /** Reads user style from a file. This is only used in the pre-android R flow. */
+    internal fun readPrefs(context: Context, fileName: String): UserStyleWireFormat {
+        val hashMap = HashMap<String, ByteArray>()
+        try {
+            val reader = InputStreamReader(context.openFileInput(fileName)).buffered()
+            reader.use {
+                while (true) {
+                    val key = reader.readLine() ?: break
+                    val value = reader.readLine() ?: break
+                    hashMap[key] = Base64.decode(value, Base64.NO_WRAP)
+                }
+            }
+        } catch (e: FileNotFoundException) {
+            // We don't need to do anything special here.
+        }
+        return UserStyleWireFormat(hashMap)
+    }
+
+    /** Reads the user style to a file. This is only used in the pre-android R flow. */
+    internal fun writePrefs(context: Context, fileName: String, style: UserStyle) {
+        val writer = context.openFileOutput(fileName, Context.MODE_PRIVATE).bufferedWriter()
+        writer.use {
+            for ((key, value) in style.selectedOptions) {
+                writer.write(key.id.value)
+                writer.newLine()
+                writer.write(Base64.encodeToString(value.id.value, Base64.NO_WRAP))
+                writer.newLine()
+            }
+        }
+    }
+
     /** This is the old pre Android R flow that's needed for backwards compatibility. */
     internal class WslFlow(private val engineWrapper: EngineWrapper) {
         class PendingComplicationData(val complicationId: Int, val data: ComplicationData)
@@ -1032,7 +1073,9 @@
         }
 
         internal fun quitBackgroundThreadIfCreated() {
-            backgroundThread?.quitSafely()
+            if (backgroundThread.isInitialized()) {
+                backgroundThread.value.quitSafely()
+            }
         }
 
         @UiThread
@@ -1293,9 +1336,12 @@
                             "milliseconds."
                     }
 
+                    val calendar = Calendar.getInstance()
+                    val initStyleAndComplicationsDone = CompletableDeferred<Unit>()
+
                     // WatchFaceImpl (which registers broadcast observers) needs to be constructed
                     // on the UIThread.
-                    withContext(uiThreadCoroutineScope.coroutineContext) {
+                    uiThreadCoroutineScope.launch {
                         pendingInitialComplications?.let {
                             for (idAndData in it) {
                                 complicationsManager.onComplicationDataUpdate(
@@ -1305,20 +1351,35 @@
                             }
                         }
 
-                        require(getUiThreadHandler().looper.isCurrentThread)
                         TraceEvent("WatchFaceImpl.init").use {
-                            deferredWatchFaceImpl.complete(
-                                WatchFaceImpl(
-                                    watchFace,
-                                    this@EngineWrapper,
-                                    watchState,
-                                    currentUserStyleRepository,
-                                    complicationsManager
-                                )
+                            val watchFaceImpl = WatchFaceImpl(
+                                watchFace,
+                                this@EngineWrapper,
+                                watchState,
+                                currentUserStyleRepository,
+                                complicationsManager,
+                                calendar
                             )
+
+                            // Make sure no UI thread rendering (a consequence of completing
+                            // deferredWatchFaceImpl) occurs before initStyleAndComplications has
+                            // executed. NB usually we won't have to wait at all.
+                            initStyleAndComplicationsDone.await()
+                            deferredWatchFaceImpl.complete(watchFaceImpl)
                             asyncWatchFaceConstructionPending = false
                         }
                     }
+
+                    // Perform more initialization on the background thread.
+                    initStyleAndComplications(
+                        complicationsManager,
+                        currentUserStyleRepository,
+                        watchFace.renderer,
+                        calendar
+                    )
+
+                    // Now init has completed, it's OK to complete deferredWatchFaceImpl.
+                    initStyleAndComplicationsDone.complete(Unit)
                 } catch (e: Exception) {
                     Log.e(TAG, "WatchFace crashed during init", e)
                     deferredWatchFaceImpl.completeExceptionally(e)
@@ -1326,6 +1387,68 @@
             }
         }
 
+        /**
+         * It is OK to call this from a worker thread because we carefully ensure there's no
+         * concurrent writes to the ComplicationsManager. No UI thread rendering can be done until
+         * after this has completed.
+         */
+        @WorkerThread
+        internal fun initStyleAndComplications(
+            complicationsManager: ComplicationsManager,
+            currentUserStyleRepository: CurrentUserStyleRepository,
+            renderer: Renderer,
+            calendar: Calendar
+        ) = TraceEvent("initStyleAndComplications").use {
+            // If the system has a stored user style then Home/SysUI is in charge of style
+            // persistence, otherwise we need to do our own.
+            val storedUserStyle = getInitialUserStyle()
+            if (storedUserStyle != null) {
+                TraceEvent("WatchFaceImpl.init apply userStyle").use {
+                    currentUserStyleRepository.userStyle =
+                        UserStyle(UserStyleData(storedUserStyle), currentUserStyleRepository.schema)
+                }
+            } else {
+                TraceEvent("WatchFaceImpl.init apply userStyle from prefs").use {
+                    // The system doesn't support preference persistence we need to do it ourselves.
+                    val preferencesFile = "watchface_prefs_${_context.javaClass.name}.txt"
+
+                    currentUserStyleRepository.userStyle = UserStyle(
+                        UserStyleData(readPrefs(_context, preferencesFile)),
+                        currentUserStyleRepository.schema
+                    )
+
+                    currentUserStyleRepository.addUserStyleChangeListener(
+                        object : CurrentUserStyleRepository.UserStyleChangeListener {
+                            @SuppressLint("SyntheticAccessor")
+                            override fun onUserStyleChanged(userStyle: UserStyle) {
+                                writePrefs(_context, preferencesFile, userStyle)
+                            }
+                        }
+                    )
+                }
+            }
+
+            // We need to inhibit an immediate callback during initialization because members are
+            // not fully constructed and it will fail. It's also superfluous because we're going
+            // to render soon anyway.
+            var initFinished = false
+            complicationsManager.init(
+                this, calendar, renderer,
+                object : Complication.InvalidateListener {
+                    @SuppressWarnings("SyntheticAccessor")
+                    override fun onInvalidate() {
+                        // This could be called on any thread.
+                        uiThreadHandler.runOnHandlerWithTracing("onInvalidate") {
+                            if (initFinished) {
+                                getWatchFaceImplOrNull()?.invalidateIfNotAnimating()
+                            }
+                        }
+                    }
+                }
+            )
+            initFinished = true
+        }
+
         override fun onVisibilityChanged(visible: Boolean): Unit = TraceEvent(
             "onVisibilityChanged"
         ).use {
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchState.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchState.kt
index a32f6ce..d67a288 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchState.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchState.kt
@@ -20,6 +20,7 @@
 import androidx.annotation.Px
 import androidx.annotation.RestrictTo
 import androidx.annotation.UiThread
+import androidx.wear.watchface.ObservableWatchData.MutableObservableWatchData
 
 /**
  * Describes the current state of the wearable including some hardware details such as whether or
diff --git a/wear/wear-watchface/src/test/java/androidx/wear/watchface/ObservableWatchDataTest.kt b/wear/wear-watchface/src/test/java/androidx/wear/watchface/ObservableWatchDataTest.kt
index b29815d..8f796dd 100644
--- a/wear/wear-watchface/src/test/java/androidx/wear/watchface/ObservableWatchDataTest.kt
+++ b/wear/wear-watchface/src/test/java/androidx/wear/watchface/ObservableWatchDataTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.wear.watchface
 
+import androidx.wear.watchface.ObservableWatchData.MutableObservableWatchData
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
@@ -30,7 +31,7 @@
 
 @Config(manifest = Config.NONE)
 @RunWith(WatchFaceTestRunner::class)
-class ObservableWatchDataTest {
+public class ObservableWatchDataTest {
     @Mock
     private lateinit var observer: Observer<Int>
 
@@ -41,39 +42,39 @@
     private lateinit var observer3: Observer<Int>
 
     @Before
-    fun setUp() {
+    public fun setUp() {
         MockitoAnnotations.initMocks(this)
     }
 
     @Test
-    fun initialValue() {
+    public fun initialValue() {
         val data = MutableObservableWatchData(10)
         assertThat(data.value).isEqualTo(10)
     }
 
     @Test
-    fun mutatedValue() {
+    public fun mutatedValue() {
         val data = MutableObservableWatchData(10)
         data.value = 20
         assertThat(data.value).isEqualTo(20)
     }
 
     @Test
-    fun addObserverNoData() {
+    public fun addObserverNoData() {
         val data = MutableObservableWatchData<Int>()
         data.addObserver(observer)
         verify(observer, never()).onChanged(any())
     }
 
     @Test
-    fun addObserver() {
+    public fun addObserver() {
         val data = MutableObservableWatchData(10)
         data.addObserver(observer)
         verify(observer).onChanged(10)
     }
 
     @Test
-    fun addObserverAndAssign() {
+    public fun addObserverAndAssign() {
         val data = MutableObservableWatchData(10)
         data.addObserver(observer)
         verify(observer).onChanged(10)
@@ -83,7 +84,7 @@
     }
 
     @Test
-    fun addObserverNoDataThenAssign() {
+    public fun addObserverNoDataThenAssign() {
         val data = MutableObservableWatchData<Int>()
         data.addObserver(observer)
 
@@ -92,7 +93,7 @@
     }
 
     @Test
-    fun addAndRemoveObserver() {
+    public fun addAndRemoveObserver() {
         val data = MutableObservableWatchData(10)
         data.addObserver(observer)
         data.removeObserver(observer)
@@ -103,7 +104,7 @@
     }
 
     @Test
-    fun removeObserverDuringCallback() {
+    public fun removeObserverDuringCallback() {
         val data = MutableObservableWatchData(10)
         data.addObserver(observer)
         data.addObserver(observer2)
@@ -124,7 +125,7 @@
     }
 
     @Test
-    fun addObserverInObserver() {
+    public fun addObserverInObserver() {
         val data = MutableObservableWatchData(10)
         var observersAdded = 0
         var addedObserverObservations = 0