[go: nahoru, domu]

Merge "Set tileResources to default instance if none provided." into androidx-main
diff --git a/benchmark/benchmark-macro-junit4/src/main/java/androidx/benchmark/macro/junit4/BaselineProfileRule.kt b/benchmark/benchmark-macro-junit4/src/main/java/androidx/benchmark/macro/junit4/BaselineProfileRule.kt
new file mode 100644
index 0000000..912c9e8
--- /dev/null
+++ b/benchmark/benchmark-macro-junit4/src/main/java/androidx/benchmark/macro/junit4/BaselineProfileRule.kt
@@ -0,0 +1,68 @@
+/*
+ * 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.benchmark.macro.junit4
+
+import android.Manifest
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.benchmark.macro.MacrobenchmarkScope
+import androidx.benchmark.macro.collectBaselineProfile
+import androidx.test.rule.GrantPermissionRule
+import org.junit.rules.RuleChain
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+
+/**
+ * A [TestRule] that helps collect baseline profiles.
+ *
+ * @suppress
+ */
+@RequiresApi(28)
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class BaselineProfileRule : TestRule {
+    private lateinit var currentDescription: Description
+
+    override fun apply(base: Statement, description: Description): Statement {
+        return RuleChain
+            .outerRule(GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE))
+            .around(::applyInternal)
+            .apply(base, description)
+    }
+
+    private fun applyInternal(base: Statement, description: Description) = object : Statement() {
+        override fun evaluate() {
+            currentDescription = description
+            base.evaluate()
+        }
+    }
+
+    public fun collectBaselineProfile(
+        packageName: String,
+        setupBlock: MacrobenchmarkScope.() -> Unit = {},
+        profileBlock: MacrobenchmarkScope.() -> Unit
+    ) {
+        collectBaselineProfile(
+            currentDescription.toUniqueName(),
+            packageName = packageName,
+            setupBlock = setupBlock,
+            profileBlock = profileBlock
+        )
+    }
+
+    private fun Description.toUniqueName() = testClass.simpleName + "_" + methodName
+}
diff --git a/benchmark/benchmark-macro/api/current.txt b/benchmark/benchmark-macro/api/current.txt
index 3b186e6..8ebc594 100644
--- a/benchmark/benchmark-macro/api/current.txt
+++ b/benchmark/benchmark-macro/api/current.txt
@@ -4,6 +4,9 @@
   @RequiresApi(29) public final class Api29Kt {
   }
 
+  public final class BaselineProfilesKt {
+  }
+
   public abstract sealed class CompilationMode {
   }
 
diff --git a/benchmark/benchmark-macro/api/public_plus_experimental_current.txt b/benchmark/benchmark-macro/api/public_plus_experimental_current.txt
index 3b186e6..8ebc594 100644
--- a/benchmark/benchmark-macro/api/public_plus_experimental_current.txt
+++ b/benchmark/benchmark-macro/api/public_plus_experimental_current.txt
@@ -4,6 +4,9 @@
   @RequiresApi(29) public final class Api29Kt {
   }
 
+  public final class BaselineProfilesKt {
+  }
+
   public abstract sealed class CompilationMode {
   }
 
diff --git a/benchmark/benchmark-macro/api/restricted_current.txt b/benchmark/benchmark-macro/api/restricted_current.txt
index 6ae5bc9..2f039ee 100644
--- a/benchmark/benchmark-macro/api/restricted_current.txt
+++ b/benchmark/benchmark-macro/api/restricted_current.txt
@@ -4,6 +4,9 @@
   @RequiresApi(29) public final class Api29Kt {
   }
 
+  public final class BaselineProfilesKt {
+  }
+
   public abstract sealed class CompilationMode {
   }
 
diff --git a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/BaselineProfiles.kt b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/BaselineProfiles.kt
new file mode 100644
index 0000000..e4f60641
--- /dev/null
+++ b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/BaselineProfiles.kt
@@ -0,0 +1,117 @@
+/*
+ * 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.benchmark.macro
+
+import android.os.Build
+import android.util.Log
+import androidx.annotation.RestrictTo
+import androidx.benchmark.ConfigurationError
+import androidx.benchmark.DeviceInfo
+import androidx.benchmark.InstrumentationResults
+import androidx.benchmark.Outputs
+import androidx.benchmark.Shell
+import androidx.benchmark.checkAndGetSuppressionState
+import androidx.benchmark.conditionalError
+import androidx.benchmark.userspaceTrace
+
+/**
+ * A list of configuration errors applicable for baseline profile collection.
+ */
+private val errors: List<ConfigurationError> = listOfNotNull(
+    conditionalError(
+        hasError = !DeviceInfo.isRooted,
+        id = "NEEDS-ROOT",
+        summary = "Run on a rooted device",
+        message = "Baseline Profile Collection needs to run on a rooted device."
+    )
+)
+
+/**
+ * Collects baseline profiles using a given [profileBlock].
+ *
+ * @suppress
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+fun collectBaselineProfile(
+    uniqueName: String,
+    packageName: String,
+    setupBlock: MacrobenchmarkScope.() -> Unit,
+    profileBlock: MacrobenchmarkScope.() -> Unit
+) {
+    require(Build.VERSION.SDK_INT >= 28) {
+        "Baseline Profile Collection requires API 28 or higher."
+    }
+
+    errors.checkAndGetSuppressionState(emptySet())
+
+    val startTime = System.nanoTime()
+    val scope = MacrobenchmarkScope(packageName, /* launchWithClearTask */ true)
+    val speedProfile = CompilationMode.SpeedProfile(warmupIterations = 3)
+
+    // always kill the process at beginning of a collection.
+    scope.killProcess()
+    try {
+        userspaceTrace("compile $packageName") {
+            speedProfile.compile(packageName) {
+                setupBlock(scope)
+                profileBlock(scope)
+            }
+        }
+        // The path of the reference profile
+        val referenceProfile = "/data/misc/profiles/ref/$packageName/primary.prof"
+        Log.d(TAG, "Reference profile location: $referenceProfile")
+        val pathResult = Shell.executeScript("pm path $packageName")
+        // The result looks like: `package: <result>`
+        val apkPath = pathResult.substringAfter("package:").trim()
+        Log.d(TAG, "APK Path: $apkPath")
+        // Convert to HRF
+        Log.d(TAG, "Converting to human readable profile format")
+        val profile = Shell.executeScript(
+            "profman --dump-classes-and-methods --profile-file=$referenceProfile --apk=$apkPath"
+        )
+        require(profile.isNotBlank()) {
+            """
+                The profile is empty. This usually happens when you forget to `adb root` before
+                "running the test."
+            """.trimIndent()
+        }
+        InstrumentationResults.instrumentationReport {
+            val fileName = "$uniqueName-baseline-prof.txt"
+            val absolutePath = Outputs.writeFile(fileName, "baseline-profile") {
+                it.writeText(profile)
+            }
+            val totalRunTime = System.nanoTime() - startTime
+            val summary = summaryRecord(totalRunTime, absolutePath)
+            ideSummaryRecord(summaryV1 = summary, summaryV2 = summary)
+            Log.d(TAG, "Total Run Time Ns: $totalRunTime")
+        }
+    } finally {
+        scope.killProcess()
+    }
+}
+
+private fun summaryRecord(totalRunTime: Long, absolutePath: String): String {
+    val relativePath = Outputs.relativePathFor(absolutePath)
+        .replace("(", "\\(")
+        .replace(")", "\\)")
+
+    return """
+        Total run time Ns: $totalRunTime.
+
+        Baseline profile [results](file://$relativePath)
+    """.trimIndent()
+}
diff --git a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt
index 471d8ea..7a639fc 100644
--- a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt
+++ b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt
@@ -17,7 +17,10 @@
 package androidx.benchmark.macro
 
 import android.content.Intent
+import android.os.Build
 import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.benchmark.DeviceInfo
 import androidx.benchmark.Shell
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
@@ -126,18 +129,56 @@
     }
 
     /**
+     * Drop caches via setprop added in API 31
+     *
+     * Feature for dropping caches without root added in 31: https://r.android.com/1584525
+     * Passing 3 will cause caches to be dropped, and prop will go back to 0 when it's done
+     */
+    @RequiresApi(31)
+    private fun dropKernelPageCacheSetProp() {
+        val result = Shell.executeScriptWithStderr("setprop perf.drop_caches 3")
+        check(result.stdout.isEmpty() && result.stderr.isEmpty()) {
+            "Failed to trigger drop cache via setprop: $result"
+        }
+        // Polling duration is very conservative, on Pixel 4L finishes in ~150ms
+        repeat(50) {
+            Thread.sleep(50)
+            when (val getPropResult = Shell.executeCommand("getprop perf.drop_caches").trim()) {
+                "0" -> return // completed!
+                "3" -> {} // not completed, continue
+                else -> throw IllegalStateException(
+                    "Unable to drop caches: Failed to read drop cache via getprop: $getPropResult"
+                )
+            }
+        }
+        throw IllegalStateException(
+            "Unable to drop caches: Did not observe perf.drop_caches reset automatically"
+        )
+    }
+
+    /**
      * Drop Kernel's in-memory cache of disk pages.
      *
      * Enables measuring disk-based startup cost, without simply accessing cache of disk data
      * held in memory, such as during [cold startup](androidx.benchmark.macro.StartupMode.COLD).
+     *
+     * @Throws IllegalStateException if dropping the cache fails on a API 31+ or rooted device,
+     * where it is expecte to work.
      */
     public fun dropKernelPageCache() {
-        val result = Shell.executeScript(
-            "echo 3 > /proc/sys/vm/drop_caches && echo Success || echo Failure"
-        ).trim()
-        // User builds don't allow drop caches yet.
-        if (result != "Success") {
-            Log.w(TAG, "Failed to drop kernel page cache, result: '$result'")
+        if (Build.VERSION.SDK_INT >= 31) {
+            dropKernelPageCacheSetProp()
+        } else {
+            val result = Shell.executeScript(
+                "echo 3 > /proc/sys/vm/drop_caches && echo Success || echo Failure"
+            ).trim()
+            // Older user builds don't allow drop caches, should investigate workaround
+            if (result != "Success") {
+                if (DeviceInfo.isRooted && !Shell.isSessionRooted()) {
+                    throw IllegalStateException("Failed to drop caches - run `adb root`")
+                }
+                Log.w(TAG, "Failed to drop kernel page cache, result: '$result'")
+            }
         }
     }
 }
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialListScrollBaselineProfile.kt b/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialListScrollBaselineProfile.kt
new file mode 100644
index 0000000..3fb560a
--- /dev/null
+++ b/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialListScrollBaselineProfile.kt
@@ -0,0 +1,78 @@
+/*
+ * 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.benchmark.integration.macrobenchmark
+
+import android.content.Intent
+import android.graphics.Point
+import androidx.benchmark.macro.junit4.BaselineProfileRule
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.UiDevice
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+@LargeTest
+@SdkSuppress(minSdkVersion = 29)
+class TrivialListScrollBaselineProfile {
+    @get:Rule
+    val baselineRule = BaselineProfileRule()
+
+    private lateinit var device: UiDevice
+
+    @Before
+    fun setUp() {
+        val instrumentation = InstrumentationRegistry.getInstrumentation()
+        device = UiDevice.getInstance(instrumentation)
+    }
+
+    @Test
+    fun baselineProfiles() {
+        baselineRule.collectBaselineProfile(
+            packageName = "androidx.benchmark.integration.macrobenchmark.target",
+            setupBlock = {
+                val intent = Intent()
+                intent.action = ACTION
+                startActivityAndWait(intent)
+            },
+            profileBlock = {
+                val recycler = device.findObject(
+                    By.res(
+                        PACKAGE_NAME,
+                        RESOURCE_ID
+                    )
+                )
+                // Setting a gesture margin is important otherwise gesture nav is triggered.
+                recycler.setGestureMargin(device.displayWidth / 5)
+                repeat(10) {
+                    // From center we scroll 2/3 of it which is 1/3 of the screen.
+                    recycler.drag(Point(0, recycler.visibleCenter.y / 3))
+                    device.waitForIdle()
+                }
+            }
+        )
+    }
+
+    companion object {
+        private const val PACKAGE_NAME = "androidx.benchmark.integration.macrobenchmark.target"
+        private const val ACTION =
+            "androidx.benchmark.integration.macrobenchmark.target.RECYCLER_VIEW"
+        private const val RESOURCE_ID = "recycler"
+    }
+}
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/docs/AndroidXDocsImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/docs/AndroidXDocsImplPlugin.kt
index a63eac1..e8b7c8b 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/docs/AndroidXDocsImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/docs/AndroidXDocsImplPlugin.kt
@@ -622,7 +622,7 @@
     }
 }
 
-private const val DACKKA_DEPENDENCY = "com.google.devsite:dackka:0.0.9"
+private const val DACKKA_DEPENDENCY = "com.google.devsite:dackka:0.0.11"
 private const val DOCLAVA_DEPENDENCY = "com.android:doclava:1.0.6"
 
 // List of packages to exclude from both Java and Kotlin refdoc generation
diff --git a/buildSrc/public/src/main/kotlin/androidx/build/LibraryVersions.kt b/buildSrc/public/src/main/kotlin/androidx/build/LibraryVersions.kt
index 3c92e54..486ca38 100644
--- a/buildSrc/public/src/main/kotlin/androidx/build/LibraryVersions.kt
+++ b/buildSrc/public/src/main/kotlin/androidx/build/LibraryVersions.kt
@@ -20,7 +20,7 @@
  * The list of versions codes of all the libraries in this project.
  */
 object LibraryVersions {
-    val ACTIVITY = Version("1.4.0-beta02")
+    val ACTIVITY = Version("1.4.0-rc01")
     val ADS_IDENTIFIER = Version("1.0.0-alpha05")
     val ANNOTATION = Version("1.3.0-beta02")
     val ANNOTATION_EXPERIMENTAL = Version("1.2.0-alpha01")
@@ -103,7 +103,7 @@
     val RECYCLERVIEW_SELECTION = Version("1.2.0-alpha02")
     val REMOTECALLBACK = Version("1.0.0-alpha02")
     val RESOURCEINSPECTION = Version("1.0.0-beta02")
-    val ROOM = Version("2.4.0-alpha06")
+    val ROOM = Version("2.4.0-beta01")
     val SAVEDSTATE = Version("1.2.0-alpha01")
     val SECURITY = Version("1.1.0-alpha04")
     val SECURITY_APP_AUTHENTICATOR = Version("1.0.0-alpha03")
@@ -117,7 +117,7 @@
     val SLICE_REMOTECALLBACK = Version("1.0.0-alpha01")
     val SLIDINGPANELAYOUT = Version("1.2.0-beta02")
     val STARTUP = Version("1.2.0-alpha01")
-    val SQLITE = Version("2.2.0-alpha04")
+    val SQLITE = Version("2.2.0-beta01")
     val SQLITE_INSPECTOR = Version("2.1.0-alpha01")
     val SWIPEREFRESHLAYOUT = Version("1.2.0-alpha01")
     val TESTSCREENSHOT = Version("1.0.0-alpha01")
@@ -139,7 +139,7 @@
     val WEAR_ONGOING = Version("1.1.0-alpha01")
     val WEAR_PHONE_INTERACTIONS = Version("1.1.0-alpha02")
     val WEAR_REMOTE_INTERACTIONS = Version("1.1.0-alpha01")
-    val WEAR_TILES = Version("1.0.0-alpha13")
+    val WEAR_TILES = Version("1.0.0-beta01")
     val WEAR_WATCHFACE = Version("1.0.0-alpha24")
     val WEBKIT = Version("1.5.0-alpha01")
     val WINDOW = Version("1.0.0-beta03")
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsInfo.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsInfo.java
index 0cddd0d..71948b2 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsInfo.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsInfo.java
@@ -249,6 +249,11 @@
     private static VendorExtender getVendorExtender(int mode) {
         boolean isAdvancedExtenderSupported = isAdvancedExtenderSupported();
 
+        // Disable Advanced Extender until it is well tested.
+        if (isAdvancedExtenderSupported) {
+            return new DisabledVendorExtender();
+        }
+
         // Force disable extension for some devices by quirk.
         if (sExtensionDisabledValidator.shouldDisableExtension(isAdvancedExtenderSupported)) {
             return new DisabledVendorExtender();
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/PendingRecording.java b/camera/camera-video/src/main/java/androidx/camera/video/PendingRecording.java
index 5ef67b5..f2f95ff 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/PendingRecording.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/PendingRecording.java
@@ -67,6 +67,15 @@
         mOutputOptions = options;
     }
 
+    /**
+     * Returns an application context which was retrieved from the {@link Context} used to
+     * create this object.
+     */
+    @NonNull
+    Context getApplicationContext() {
+        return mContext;
+    }
+
     @NonNull
     Recorder getRecorder() {
         return mRecorder;
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/Recorder.java b/camera/camera-video/src/main/java/androidx/camera/video/Recorder.java
index fe90ac9..bbc4191 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/Recorder.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/Recorder.java
@@ -36,6 +36,7 @@
 import android.content.Context;
 import android.media.MediaCodecInfo;
 import android.media.MediaMuxer;
+import android.media.MediaScannerConnection;
 import android.net.Uri;
 import android.os.Build;
 import android.os.ParcelFileDescriptor;
@@ -95,6 +96,7 @@
 import java.util.concurrent.Executor;
 import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * An implementation of {@link VideoOutput} for starting video recordings that are saved
@@ -1820,10 +1822,7 @@
         OutputOptions outputOptions = mInProgressRecording.getOutputOptions();
         RecordingStats stats = getInProgressRecordingStats();
 
-        if (outputOptions instanceof MediaStoreOutputOptions) {
-            // Toggle off pending status for the video file.
-            finalizeMediaStoreFile((MediaStoreOutputOptions) outputOptions);
-        }
+        mInProgressRecording.finalizeOutputFile(mOutputUri);
 
         OutputResults outputResults = OutputResults.of(mOutputUri);
         mInProgressRecording.updateVideoRecordEvent(errorToSend == ERROR_NONE
@@ -2060,20 +2059,6 @@
         }
     }
 
-    @ExecutedBy("mSequentialExecutor")
-    private void finalizeMediaStoreFile(@NonNull MediaStoreOutputOptions mediaStoreOutputOptions) {
-        if (mOutputUri.equals(Uri.EMPTY)) {
-            return;
-        }
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
-            ContentValues contentValues = new ContentValues();
-            contentValues.put(MediaStore.Video.Media.IS_PENDING, NOT_PENDING);
-            mediaStoreOutputOptions.getContentResolver().update(mOutputUri, contentValues, null,
-                    null);
-        }
-        // TODO (b/198551531): Trigger MediaScannerConnection.scanFile to rescan.
-    }
-
     @SuppressWarnings("WeakerAccess") /* synthetic accessor */
     @ExecutedBy("mSequentialExecutor")
     @NonNull
@@ -2186,14 +2171,73 @@
     @AutoValue
     abstract static class RecordingRecord {
 
+        private final AtomicReference<Consumer<Uri>> mOutputFileFinalizer =
+                new AtomicReference<>(ignored -> {
+                    /* no-op by default */
+                });
+
         static RecordingRecord from(@NonNull PendingRecording pendingRecording, long recordingId) {
-            return new AutoValue_Recorder_RecordingRecord(
-                    pendingRecording.getOutputOptions(),
+            OutputOptions outputOptions = pendingRecording.getOutputOptions();
+            RecordingRecord recordingRecord = new AutoValue_Recorder_RecordingRecord(
+                    outputOptions,
                     pendingRecording.getCallbackExecutor(),
                     pendingRecording.getEventListener(),
                     pendingRecording.isAudioEnabled(),
                     recordingId
             );
+
+            if (outputOptions instanceof MediaStoreOutputOptions) {
+                MediaStoreOutputOptions mediaStoreOutputOptions =
+                        (MediaStoreOutputOptions) outputOptions;
+                // TODO(b/201946954): Investigate whether we should add a setting to disable
+                //  scan/update to allow users to perform it themselves.
+                Consumer<Uri> outputFileFinalizer;
+                if (Build.VERSION.SDK_INT >= 29) {
+                    outputFileFinalizer = outputUri -> {
+                        if (outputUri.equals(Uri.EMPTY)) {
+                            return;
+                        }
+                        ContentValues contentValues = new ContentValues();
+                        contentValues.put(MediaStore.Video.Media.IS_PENDING, NOT_PENDING);
+                        mediaStoreOutputOptions.getContentResolver().update(outputUri,
+                                contentValues, null, null);
+                    };
+                } else {
+                    // Context will only be held in local scope of the consumer so it will not be
+                    // retained after finalizeOutputFile() is called.
+                    Context finalContext = pendingRecording.getApplicationContext();
+                    outputFileFinalizer = outputUri -> {
+                        if (outputUri.equals(Uri.EMPTY)) {
+                            return;
+                        }
+                        String filePath = OutputUtil.getAbsolutePathFromUri(
+                                mediaStoreOutputOptions.getContentResolver(), outputUri,
+                                MEDIA_COLUMN);
+                        if (filePath != null) {
+                            // Use null mime type list to have MediaScanner derive mime type from
+                            // extension
+                            MediaScannerConnection.scanFile(finalContext,
+                                    new String[]{filePath}, /*mimeTypes=*/null, (path, uri) -> {
+                                        if (uri == null) {
+                                            Logger.e(TAG, String.format("File scanning operation "
+                                                    + "failed [path: %s]", path));
+                                        } else {
+                                            Logger.d(TAG, String.format("File scan completed "
+                                                    + "successfully [path: %s, URI: %s]", path,
+                                                    uri));
+                                        }
+                                    });
+                        } else {
+                            Logger.d(TAG,
+                                    "Skipping media scanner scan. Unable to retrieve file path "
+                                            + "from URI: " + outputUri);
+                        }
+                    };
+                }
+                recordingRecord.mOutputFileFinalizer.set(outputFileFinalizer);
+            }
+
+            return recordingRecord;
         }
 
         @NonNull
@@ -2225,6 +2269,24 @@
                 }
             }
         }
+
+        /**
+         * Performs final operations required to prepare completed output file.
+         *
+         * <p>Output file finalization can only occur once. Any subsequent calls to this method
+         * will throw an {@link AssertionError}.
+         *
+         * @param uri The uri of the output file.
+         */
+        void finalizeOutputFile(@NonNull Uri uri) {
+            Consumer<Uri> outputFileFinalizer = mOutputFileFinalizer.getAndSet(null);
+            if (outputFileFinalizer == null) {
+                throw new AssertionError(
+                        "Output file has already been finalized for recording " + this);
+            }
+
+            outputFileFinalizer.accept(uri);
+        }
     }
 
     /**
diff --git a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
index c29d31d..146cfdc 100644
--- a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
+++ b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
@@ -37,9 +37,7 @@
 import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.hardware.display.DisplayManager;
-import android.media.MediaScannerConnection;
 import android.net.Uri;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
@@ -57,7 +55,6 @@
 import android.view.ScaleGestureDetector;
 import android.view.View;
 import android.view.ViewStub;
-import android.webkit.MimeTypeMap;
 import android.widget.Button;
 import android.widget.CompoundButton;
 import android.widget.ImageButton;
@@ -96,10 +93,8 @@
 import androidx.camera.core.impl.utils.executor.CameraXExecutors;
 import androidx.camera.lifecycle.ProcessCameraProvider;
 import androidx.camera.video.ActiveRecording;
-import androidx.camera.video.FileOutputOptions;
 import androidx.camera.video.MediaStoreOutputOptions;
 import androidx.camera.video.OutputOptions;
-import androidx.camera.video.PendingRecording;
 import androidx.camera.video.QualitySelector;
 import androidx.camera.video.Recorder;
 import androidx.camera.video.RecordingStats;
@@ -378,20 +373,10 @@
             switch (state) {
                 case IDLE:
                     createDefaultVideoFolderIfNotExist();
-                    PendingRecording pendingRecording = null;
-                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
-                        // For Android 10 or versions above, use MediaStoreOutputOptions for public
-                        // share media storage.
-                        pendingRecording = getVideoCapture().getOutput()
-                                .prepareRecording(this, getNewVideoOutputMediaStoreOptions());
-                    } else {
-                        // For Android 9 or versions below, use FileOutputOptions. Can still use
-                        // MediaStoreOutputOptions, but there are some known issues, b/197476455 or
-                        // b/198543058.
-                        pendingRecording = getVideoCapture().getOutput()
-                                .prepareRecording(this, getNewVideoOutputFileOptions());
-                    }
-                    mActiveRecording = pendingRecording.withAudioEnabled()
+                    // Use MediaStoreOutputOptions for public share media storage.
+                    mActiveRecording = getVideoCapture().getOutput()
+                            .prepareRecording(this, getNewVideoOutputMediaStoreOptions())
+                            .withAudioEnabled()
                             .withEventListener(ContextCompat.getMainExecutor(CameraXActivity.this),
                                     mVideoRecordEventListener)
                             .start();
@@ -495,16 +480,6 @@
                                 getApplicationContext().getContentResolver(),
                                 uri
                         );
-                        // For OutputOptionsType is OutputOptions.OPTIONS_TYPE_MEDIA_STORE,
-                        // the Photo/Gallery apps on devices (API Level < Q) sometimes will
-                        // not show the video files saved in MediaStore, suggest to call
-                        // scanFile still to force scan the media file.
-                        // scanVideoOutputFile(new File(videoFilePath));
-                    } else if (outputOptions instanceof FileOutputOptions) {
-                        videoFilePath = ((FileOutputOptions) outputOptions)
-                                .getFile().getAbsolutePath();
-                        msg = "Saved video file: " + videoFilePath;
-                        scanVideoOutputFile(new File(videoFilePath));
                     } else {
                         throw new AssertionError("Unknown or unsupported OutputOptions type: "
                                 + outputOptions.getClass().getSimpleName());
@@ -543,34 +518,6 @@
                 .build();
     }
 
-    @NonNull
-    private FileOutputOptions getNewVideoOutputFileOptions() {
-        String videoFileName = "video_" + System.currentTimeMillis();
-        File videoFile = new File(
-                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES),
-                videoFileName + ".mp4");
-        Log.d(TAG, "VideoOutputFileOptions file: " + videoFile.getAbsolutePath());
-        return new FileOutputOptions.Builder(videoFile).build();
-    }
-
-    @NonNull
-    private void scanVideoOutputFile(@NonNull File videoFile) {
-        String extension = MimeTypeMap.getFileExtensionFromUrl(videoFile.getName());
-        String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
-        MediaScannerConnection.scanFile(this,
-                new String[] {videoFile.getAbsolutePath()},
-                new String[] {mimeType},
-                new MediaScannerConnection.OnScanCompletedListener() {
-                    @Override
-                    public void onScanCompleted(final String path, final Uri uri) {
-                        Log.d(TAG, "Video scanned into media store: " + path
-                                + ", Uri: " + uri
-                                + ", mimetype: " + mimeType
-                                + ".");
-                    }
-                });
-    }
-
     private void updateRecordingStats(@NonNull RecordingStats stats) {
         double durationSec = TimeUnit.NANOSECONDS.toMillis(stats.getRecordedDurationNanos())
                 / 1000d;
diff --git a/collection2/collection2/src/jvmMain/java/androidx/collection/ArrayMap.java b/collection2/collection2/src/jvmMain/java/androidx/collection/ArrayMap.java
index 86d45c9..473b371 100644
--- a/collection2/collection2/src/jvmMain/java/androidx/collection/ArrayMap.java
+++ b/collection2/collection2/src/jvmMain/java/androidx/collection/ArrayMap.java
@@ -26,6 +26,12 @@
 /**
  * Memory-efficient map of keys to values with list-style random-access semantics.
  *
+ * <p><b>Note:</b></p> This is the only class in this package that is implemented in Java. It is
+ * difficult to implement this class in Kotlin without breaking runtime or compile-time
+ * compatibility due to the many implicit bridges between Kotlin's and Java's collection classes
+ * and methods. See https://youtrack.jetbrains.com/issue/KT-43543 and
+ * https://youtrack.jetbrains.com/issue/KT-43542 for why we have arrived at this decision.
+ *
  * @param <K> the type of keys maintained by this map
  * @param <V> the type of mapped values
  */
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/decoys/CreateDecoysTransformer.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/decoys/CreateDecoysTransformer.kt
index 8038409..b6b129c 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/decoys/CreateDecoysTransformer.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/decoys/CreateDecoysTransformer.kt
@@ -43,6 +43,10 @@
 import org.jetbrains.kotlin.ir.declarations.IrFunction
 import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
 import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
+import org.jetbrains.kotlin.ir.declarations.IrValueParameter
+import org.jetbrains.kotlin.ir.expressions.IrExpression
+import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
+import org.jetbrains.kotlin.ir.expressions.IrGetValue
 import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
 import org.jetbrains.kotlin.ir.types.IrSimpleType
 import org.jetbrains.kotlin.ir.types.IrType
@@ -53,6 +57,8 @@
 import org.jetbrains.kotlin.ir.util.hasDefaultValue
 import org.jetbrains.kotlin.ir.util.isLocal
 import org.jetbrains.kotlin.ir.util.patchDeclarationParents
+import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
+import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
 import org.jetbrains.kotlin.name.Name
 import org.jetbrains.kotlin.resolve.BindingTrace
 
@@ -218,9 +224,43 @@
 
         newFunction.addDecoyImplementationAnnotation(newName.asString(), original.getSignatureId())
 
+        newFunction.valueParameters.forEach {
+            it.defaultValue?.transformDefaultValue(
+                originalFunction = original,
+                newFunction = newFunction
+            )
+        }
+
         return newFunction
     }
 
+    /**
+     *  Expressions for default values can use other parameters.
+     *  In such cases we need to ensure that default values expressions use parameters of the new
+     *  function (new/copied value parameters).
+     *
+     *  Example:
+     *  fun Foo(a: String, b: String = a) {...}
+     */
+    private fun IrExpressionBody.transformDefaultValue(
+        originalFunction: IrFunction,
+        newFunction: IrFunction
+    ) {
+        transformChildrenVoid(object : IrElementTransformerVoid() {
+            override fun visitGetValue(expression: IrGetValue): IrExpression {
+                val original = super.visitGetValue(expression)
+                val valueParameter =
+                    (expression.symbol.owner as? IrValueParameter) ?: return original
+
+                val parameterIndex = valueParameter.index
+                if (parameterIndex < 0 || valueParameter.parent != originalFunction) {
+                    return super.visitGetValue(expression)
+                }
+                return irGet(newFunction.valueParameters[parameterIndex])
+            }
+        })
+    }
+
     private fun IrFunction.stubBody() {
         body = DeclarationIrBuilder(context, symbol).irBlockBody {
             + irReturn(
diff --git a/compose/material3/material3/api/current.txt b/compose/material3/material3/api/current.txt
index 20e1c56..bf88dc9 100644
--- a/compose/material3/material3/api/current.txt
+++ b/compose/material3/material3/api/current.txt
@@ -2,17 +2,15 @@
 package androidx.compose.material3 {
 
   @androidx.compose.runtime.Stable public final class ColorScheme {
-    ctor public ColorScheme(long primary, long onPrimary, long primaryContainer, long onPrimaryContainer, long inversePrimary, long secondary, long onSecondary, long secondaryContainer, long onSecondaryContainer, long tertiary, long onTertiary, long tertiaryContainer, long onTertiaryContainer, long background, long onBackground, long surface, long onSurface, long surfaceVariant, long onSurfaceVariant, long inverseSurface, long inverseOnSurface, long disabled, long onDisabled, long error, long onError, long errorContainer, long onErrorContainer, long outline);
-    method public androidx.compose.material3.ColorScheme copy(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long disabled, optional long onDisabled, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
+    ctor public ColorScheme(long primary, long onPrimary, long primaryContainer, long onPrimaryContainer, long inversePrimary, long secondary, long onSecondary, long secondaryContainer, long onSecondaryContainer, long tertiary, long onTertiary, long tertiaryContainer, long onTertiaryContainer, long background, long onBackground, long surface, long onSurface, long surfaceVariant, long onSurfaceVariant, long inverseSurface, long inverseOnSurface, long error, long onError, long errorContainer, long onErrorContainer, long outline);
+    method public androidx.compose.material3.ColorScheme copy(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
     method public long getBackground();
-    method public long getDisabled();
     method public long getError();
     method public long getErrorContainer();
     method public long getInverseOnSurface();
     method public long getInversePrimary();
     method public long getInverseSurface();
     method public long getOnBackground();
-    method public long getOnDisabled();
     method public long getOnError();
     method public long getOnErrorContainer();
     method public long getOnPrimary();
@@ -33,14 +31,12 @@
     method public long getTertiary();
     method public long getTertiaryContainer();
     property public final long background;
-    property public final long disabled;
     property public final long error;
     property public final long errorContainer;
     property public final long inverseOnSurface;
     property public final long inversePrimary;
     property public final long inverseSurface;
     property public final long onBackground;
-    property public final long onDisabled;
     property public final long onError;
     property public final long onErrorContainer;
     property public final long onPrimary;
@@ -65,8 +61,8 @@
   public final class ColorSchemeKt {
     method public static long contentColorFor(androidx.compose.material3.ColorScheme, long backgroundColor);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static long contentColorFor(long backgroundColor);
-    method public static androidx.compose.material3.ColorScheme darkColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long disabled, optional long onDisabled, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
-    method public static androidx.compose.material3.ColorScheme lightColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long disabled, optional long onDisabled, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
+    method public static androidx.compose.material3.ColorScheme darkColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
+    method public static androidx.compose.material3.ColorScheme lightColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
   }
 
   public final class ContentColorKt {
@@ -74,6 +70,8 @@
   }
 
   public final class DynamicTonalPaletteKt {
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public static androidx.compose.material3.ColorScheme dynamicDarkColorScheme(android.content.Context context);
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public static androidx.compose.material3.ColorScheme dynamicLightColorScheme(android.content.Context context);
   }
 
   public final class IconButtonKt {
@@ -89,35 +87,19 @@
 
   public final class MaterialTheme {
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.ColorScheme getColorScheme();
-    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.Shapes getShapes();
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.Typography getTypography();
     property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.ColorScheme colorScheme;
-    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.Shapes shapes;
     property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.Typography typography;
     field public static final androidx.compose.material3.MaterialTheme INSTANCE;
   }
 
   public final class MaterialThemeKt {
-    method @androidx.compose.runtime.Composable public static void MaterialTheme(optional androidx.compose.material3.ColorScheme colorScheme, optional androidx.compose.material3.Typography typography, optional androidx.compose.material3.Shapes shapes, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void MaterialTheme(optional androidx.compose.material3.ColorScheme colorScheme, optional androidx.compose.material3.Typography typography, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   public final class ScaffoldKt {
   }
 
-  @androidx.compose.runtime.Immutable public final class Shapes {
-    ctor public Shapes(optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large);
-    method public androidx.compose.material3.Shapes copy(optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large);
-    method public androidx.compose.foundation.shape.CornerBasedShape getLarge();
-    method public androidx.compose.foundation.shape.CornerBasedShape getMedium();
-    method public androidx.compose.foundation.shape.CornerBasedShape getSmall();
-    property public final androidx.compose.foundation.shape.CornerBasedShape large;
-    property public final androidx.compose.foundation.shape.CornerBasedShape medium;
-    property public final androidx.compose.foundation.shape.CornerBasedShape small;
-  }
-
-  public final class ShapesKt {
-  }
-
   public final class SurfaceKt {
     method @androidx.compose.runtime.Composable public static void Surface(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> content);
diff --git a/compose/material3/material3/api/public_plus_experimental_current.txt b/compose/material3/material3/api/public_plus_experimental_current.txt
index 6a56f61..40e7c6e 100644
--- a/compose/material3/material3/api/public_plus_experimental_current.txt
+++ b/compose/material3/material3/api/public_plus_experimental_current.txt
@@ -2,17 +2,15 @@
 package androidx.compose.material3 {
 
   @androidx.compose.runtime.Stable public final class ColorScheme {
-    ctor public ColorScheme(long primary, long onPrimary, long primaryContainer, long onPrimaryContainer, long inversePrimary, long secondary, long onSecondary, long secondaryContainer, long onSecondaryContainer, long tertiary, long onTertiary, long tertiaryContainer, long onTertiaryContainer, long background, long onBackground, long surface, long onSurface, long surfaceVariant, long onSurfaceVariant, long inverseSurface, long inverseOnSurface, long disabled, long onDisabled, long error, long onError, long errorContainer, long onErrorContainer, long outline);
-    method public androidx.compose.material3.ColorScheme copy(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long disabled, optional long onDisabled, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
+    ctor public ColorScheme(long primary, long onPrimary, long primaryContainer, long onPrimaryContainer, long inversePrimary, long secondary, long onSecondary, long secondaryContainer, long onSecondaryContainer, long tertiary, long onTertiary, long tertiaryContainer, long onTertiaryContainer, long background, long onBackground, long surface, long onSurface, long surfaceVariant, long onSurfaceVariant, long inverseSurface, long inverseOnSurface, long error, long onError, long errorContainer, long onErrorContainer, long outline);
+    method public androidx.compose.material3.ColorScheme copy(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
     method public long getBackground();
-    method public long getDisabled();
     method public long getError();
     method public long getErrorContainer();
     method public long getInverseOnSurface();
     method public long getInversePrimary();
     method public long getInverseSurface();
     method public long getOnBackground();
-    method public long getOnDisabled();
     method public long getOnError();
     method public long getOnErrorContainer();
     method public long getOnPrimary();
@@ -33,14 +31,12 @@
     method public long getTertiary();
     method public long getTertiaryContainer();
     property public final long background;
-    property public final long disabled;
     property public final long error;
     property public final long errorContainer;
     property public final long inverseOnSurface;
     property public final long inversePrimary;
     property public final long inverseSurface;
     property public final long onBackground;
-    property public final long onDisabled;
     property public final long onError;
     property public final long onErrorContainer;
     property public final long onPrimary;
@@ -65,8 +61,8 @@
   public final class ColorSchemeKt {
     method public static long contentColorFor(androidx.compose.material3.ColorScheme, long backgroundColor);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static long contentColorFor(long backgroundColor);
-    method public static androidx.compose.material3.ColorScheme darkColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long disabled, optional long onDisabled, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
-    method public static androidx.compose.material3.ColorScheme lightColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long disabled, optional long onDisabled, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
+    method public static androidx.compose.material3.ColorScheme darkColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
+    method public static androidx.compose.material3.ColorScheme lightColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
   }
 
   public final class ContentColorKt {
@@ -74,6 +70,8 @@
   }
 
   public final class DynamicTonalPaletteKt {
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public static androidx.compose.material3.ColorScheme dynamicDarkColorScheme(android.content.Context context);
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public static androidx.compose.material3.ColorScheme dynamicLightColorScheme(android.content.Context context);
   }
 
   @kotlin.RequiresOptIn(message="This material API is experimental and is likely to change or to be removed in" + " the future.") public @interface ExperimentalMaterial3Api {
@@ -103,36 +101,20 @@
 
   public final class MaterialTheme {
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.ColorScheme getColorScheme();
-    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.Shapes getShapes();
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.Typography getTypography();
     property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.ColorScheme colorScheme;
-    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.Shapes shapes;
     property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.Typography typography;
     field public static final androidx.compose.material3.MaterialTheme INSTANCE;
   }
 
   public final class MaterialThemeKt {
-    method @androidx.compose.runtime.Composable public static void MaterialTheme(optional androidx.compose.material3.ColorScheme colorScheme, optional androidx.compose.material3.Typography typography, optional androidx.compose.material3.Shapes shapes, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void MaterialTheme(optional androidx.compose.material3.ColorScheme colorScheme, optional androidx.compose.material3.Typography typography, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   public final class ScaffoldKt {
     method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Scaffold(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional int floatingActionButtonPosition, optional long containerColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
   }
 
-  @androidx.compose.runtime.Immutable public final class Shapes {
-    ctor public Shapes(optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large);
-    method public androidx.compose.material3.Shapes copy(optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large);
-    method public androidx.compose.foundation.shape.CornerBasedShape getLarge();
-    method public androidx.compose.foundation.shape.CornerBasedShape getMedium();
-    method public androidx.compose.foundation.shape.CornerBasedShape getSmall();
-    property public final androidx.compose.foundation.shape.CornerBasedShape large;
-    property public final androidx.compose.foundation.shape.CornerBasedShape medium;
-    property public final androidx.compose.foundation.shape.CornerBasedShape small;
-  }
-
-  public final class ShapesKt {
-  }
-
   public final class SurfaceKt {
     method @androidx.compose.runtime.Composable public static void Surface(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> content);
diff --git a/compose/material3/material3/api/restricted_current.txt b/compose/material3/material3/api/restricted_current.txt
index 20e1c56..bf88dc9 100644
--- a/compose/material3/material3/api/restricted_current.txt
+++ b/compose/material3/material3/api/restricted_current.txt
@@ -2,17 +2,15 @@
 package androidx.compose.material3 {
 
   @androidx.compose.runtime.Stable public final class ColorScheme {
-    ctor public ColorScheme(long primary, long onPrimary, long primaryContainer, long onPrimaryContainer, long inversePrimary, long secondary, long onSecondary, long secondaryContainer, long onSecondaryContainer, long tertiary, long onTertiary, long tertiaryContainer, long onTertiaryContainer, long background, long onBackground, long surface, long onSurface, long surfaceVariant, long onSurfaceVariant, long inverseSurface, long inverseOnSurface, long disabled, long onDisabled, long error, long onError, long errorContainer, long onErrorContainer, long outline);
-    method public androidx.compose.material3.ColorScheme copy(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long disabled, optional long onDisabled, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
+    ctor public ColorScheme(long primary, long onPrimary, long primaryContainer, long onPrimaryContainer, long inversePrimary, long secondary, long onSecondary, long secondaryContainer, long onSecondaryContainer, long tertiary, long onTertiary, long tertiaryContainer, long onTertiaryContainer, long background, long onBackground, long surface, long onSurface, long surfaceVariant, long onSurfaceVariant, long inverseSurface, long inverseOnSurface, long error, long onError, long errorContainer, long onErrorContainer, long outline);
+    method public androidx.compose.material3.ColorScheme copy(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
     method public long getBackground();
-    method public long getDisabled();
     method public long getError();
     method public long getErrorContainer();
     method public long getInverseOnSurface();
     method public long getInversePrimary();
     method public long getInverseSurface();
     method public long getOnBackground();
-    method public long getOnDisabled();
     method public long getOnError();
     method public long getOnErrorContainer();
     method public long getOnPrimary();
@@ -33,14 +31,12 @@
     method public long getTertiary();
     method public long getTertiaryContainer();
     property public final long background;
-    property public final long disabled;
     property public final long error;
     property public final long errorContainer;
     property public final long inverseOnSurface;
     property public final long inversePrimary;
     property public final long inverseSurface;
     property public final long onBackground;
-    property public final long onDisabled;
     property public final long onError;
     property public final long onErrorContainer;
     property public final long onPrimary;
@@ -65,8 +61,8 @@
   public final class ColorSchemeKt {
     method public static long contentColorFor(androidx.compose.material3.ColorScheme, long backgroundColor);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static long contentColorFor(long backgroundColor);
-    method public static androidx.compose.material3.ColorScheme darkColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long disabled, optional long onDisabled, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
-    method public static androidx.compose.material3.ColorScheme lightColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long disabled, optional long onDisabled, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
+    method public static androidx.compose.material3.ColorScheme darkColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
+    method public static androidx.compose.material3.ColorScheme lightColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline);
   }
 
   public final class ContentColorKt {
@@ -74,6 +70,8 @@
   }
 
   public final class DynamicTonalPaletteKt {
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public static androidx.compose.material3.ColorScheme dynamicDarkColorScheme(android.content.Context context);
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public static androidx.compose.material3.ColorScheme dynamicLightColorScheme(android.content.Context context);
   }
 
   public final class IconButtonKt {
@@ -89,35 +87,19 @@
 
   public final class MaterialTheme {
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.ColorScheme getColorScheme();
-    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.Shapes getShapes();
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.Typography getTypography();
     property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.ColorScheme colorScheme;
-    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.Shapes shapes;
     property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.Typography typography;
     field public static final androidx.compose.material3.MaterialTheme INSTANCE;
   }
 
   public final class MaterialThemeKt {
-    method @androidx.compose.runtime.Composable public static void MaterialTheme(optional androidx.compose.material3.ColorScheme colorScheme, optional androidx.compose.material3.Typography typography, optional androidx.compose.material3.Shapes shapes, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void MaterialTheme(optional androidx.compose.material3.ColorScheme colorScheme, optional androidx.compose.material3.Typography typography, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   public final class ScaffoldKt {
   }
 
-  @androidx.compose.runtime.Immutable public final class Shapes {
-    ctor public Shapes(optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large);
-    method public androidx.compose.material3.Shapes copy(optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large);
-    method public androidx.compose.foundation.shape.CornerBasedShape getLarge();
-    method public androidx.compose.foundation.shape.CornerBasedShape getMedium();
-    method public androidx.compose.foundation.shape.CornerBasedShape getSmall();
-    property public final androidx.compose.foundation.shape.CornerBasedShape large;
-    property public final androidx.compose.foundation.shape.CornerBasedShape medium;
-    property public final androidx.compose.foundation.shape.CornerBasedShape small;
-  }
-
-  public final class ShapesKt {
-  }
-
   public final class SurfaceKt {
     method @androidx.compose.runtime.Composable public static void Surface(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> content);
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ColorSchemeTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ColorSchemeTest.kt
index af82a05..b372bc0 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ColorSchemeTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ColorSchemeTest.kt
@@ -114,8 +114,6 @@
     if (onSurfaceVariant != other.onSurfaceVariant) return false
     if (inverseSurface != other.inverseSurface) return false
     if (inverseOnSurface != other.inverseOnSurface) return false
-    if (disabled != other.disabled) return false
-    if (onDisabled != other.onDisabled) return false
     if (error != other.error) return false
     if (onError != other.onError) return false
     if (errorContainer != other.errorContainer) return false
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/DynamicTonalPalette.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/DynamicTonalPalette.kt
index 67de4b4..55cc1905 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/DynamicTonalPalette.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/DynamicTonalPalette.kt
@@ -25,112 +25,155 @@
 
 /** Dynamic colors in Material. */
 @RequiresApi(Build.VERSION_CODES.S)
-internal fun dynamicTonalPalette(context: Context): TonalPalette =
-    TonalPalette(
-        // The neutral tonal range from the generated dynamic color palette.
-        neutral100 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_0),
-        neutral99 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_10),
-        neutral95 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_50),
-        neutral90 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_100),
-        neutral80 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_200),
-        neutral70 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_300),
-        neutral60 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_400),
-        neutral50 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_500),
-        neutral40 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_600),
-        neutral30 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_700),
-        neutral20 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_800),
-        neutral10 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_900),
-        neutral0 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_1000),
+internal fun dynamicTonalPalette(context: Context): TonalPalette = TonalPalette(
+    // The neutral tonal range from the generated dynamic color palette.
+    neutral100 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_0),
+    neutral99 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_10),
+    neutral95 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_50),
+    neutral90 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_100),
+    neutral80 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_200),
+    neutral70 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_300),
+    neutral60 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_400),
+    neutral50 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_500),
+    neutral40 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_600),
+    neutral30 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_700),
+    neutral20 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_800),
+    neutral10 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_900),
+    neutral0 = ColorResourceHelper.getColor(context, android.R.color.system_neutral1_1000),
 
-        // The neutral variant tonal range, sometimes called "neutral 2",  from the
-        // generated dynamic color palette.
-        neutralVariant100 = ColorResourceHelper.getColor(
-            context,
-            android.R.color.system_neutral2_0
-        ),
-        neutralVariant99 = ColorResourceHelper.getColor(
-            context,
-            android.R.color.system_neutral2_10
-        ),
-        neutralVariant95 = ColorResourceHelper.getColor(
-            context, android.R.color.system_neutral2_50
-        ),
-        neutralVariant90 = ColorResourceHelper.getColor(
-            context, android.R.color.system_neutral2_100
-        ),
-        neutralVariant80 = ColorResourceHelper.getColor(
-            context, android.R.color.system_neutral2_200
-        ),
-        neutralVariant70 = ColorResourceHelper.getColor(
-            context, android.R.color.system_neutral2_300
-        ),
-        neutralVariant60 = ColorResourceHelper.getColor(
-            context, android.R.color.system_neutral2_400
-        ),
-        neutralVariant50 = ColorResourceHelper.getColor(
-            context, android.R.color.system_neutral2_500
-        ),
-        neutralVariant40 = ColorResourceHelper.getColor(
-            context, android.R.color.system_neutral2_600
-        ),
-        neutralVariant30 = ColorResourceHelper.getColor(
-            context, android.R.color.system_neutral2_700
-        ),
-        neutralVariant20 = ColorResourceHelper.getColor(
-            context, android.R.color.system_neutral2_800
-        ),
-        neutralVariant10 = ColorResourceHelper.getColor(
-            context, android.R.color.system_neutral2_900
-        ),
-        neutralVariant0 = ColorResourceHelper.getColor(
-            context, android.R.color.system_neutral2_1000
-        ),
+    // The neutral variant tonal range, sometimes called "neutral 2",  from the
+    // generated dynamic color palette.
+    neutralVariant100 = ColorResourceHelper.getColor(context, android.R.color.system_neutral2_0),
+    neutralVariant99 = ColorResourceHelper.getColor(context, android.R.color.system_neutral2_10),
+    neutralVariant95 = ColorResourceHelper.getColor(context, android.R.color.system_neutral2_50),
+    neutralVariant90 = ColorResourceHelper.getColor(context, android.R.color.system_neutral2_100),
+    neutralVariant80 = ColorResourceHelper.getColor(context, android.R.color.system_neutral2_200),
+    neutralVariant70 = ColorResourceHelper.getColor(context, android.R.color.system_neutral2_300),
+    neutralVariant60 = ColorResourceHelper.getColor(context, android.R.color.system_neutral2_400),
+    neutralVariant50 = ColorResourceHelper.getColor(context, android.R.color.system_neutral2_500),
+    neutralVariant40 = ColorResourceHelper.getColor(context, android.R.color.system_neutral2_600),
+    neutralVariant30 = ColorResourceHelper.getColor(context, android.R.color.system_neutral2_700),
+    neutralVariant20 = ColorResourceHelper.getColor(context, android.R.color.system_neutral2_800),
+    neutralVariant10 = ColorResourceHelper.getColor(context, android.R.color.system_neutral2_900),
+    neutralVariant0 = ColorResourceHelper.getColor(context, android.R.color.system_neutral2_1000),
 
-        // The primary tonal range from the generated dynamic color palette.
-        primary100 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_0),
-        primary99 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_10),
-        primary95 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_50),
-        primary90 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_100),
-        primary80 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_200),
-        primary70 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_300),
-        primary60 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_400),
-        primary50 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_500),
-        primary40 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_600),
-        primary30 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_700),
-        primary20 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_800),
-        primary10 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_900),
-        primary0 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_1000),
+    // The primary tonal range from the generated dynamic color palette.
+    primary100 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_0),
+    primary99 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_10),
+    primary95 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_50),
+    primary90 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_100),
+    primary80 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_200),
+    primary70 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_300),
+    primary60 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_400),
+    primary50 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_500),
+    primary40 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_600),
+    primary30 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_700),
+    primary20 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_800),
+    primary10 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_900),
+    primary0 = ColorResourceHelper.getColor(context, android.R.color.system_accent1_1000),
 
-        // The secondary tonal range from the generated dynamic color palette.
-        secondary100 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_0),
-        secondary99 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_10),
-        secondary95 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_50),
-        secondary90 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_100),
-        secondary80 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_200),
-        secondary70 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_300),
-        secondary60 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_400),
-        secondary50 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_500),
-        secondary40 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_600),
-        secondary30 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_700),
-        secondary20 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_800),
-        secondary10 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_900),
-        secondary0 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_1000),
+    // The secondary tonal range from the generated dynamic color palette.
+    secondary100 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_0),
+    secondary99 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_10),
+    secondary95 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_50),
+    secondary90 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_100),
+    secondary80 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_200),
+    secondary70 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_300),
+    secondary60 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_400),
+    secondary50 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_500),
+    secondary40 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_600),
+    secondary30 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_700),
+    secondary20 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_800),
+    secondary10 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_900),
+    secondary0 = ColorResourceHelper.getColor(context, android.R.color.system_accent2_1000),
 
-        // The tertiary tonal range from the generated dynamic color palette.
-        tertiary100 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_0),
-        tertiary99 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_10),
-        tertiary95 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_50),
-        tertiary90 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_100),
-        tertiary80 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_200),
-        tertiary70 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_300),
-        tertiary60 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_400),
-        tertiary50 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_500),
-        tertiary40 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_600),
-        tertiary30 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_700),
-        tertiary20 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_800),
-        tertiary10 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_900),
-        tertiary0 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_1000),
+    // The tertiary tonal range from the generated dynamic color palette.
+    tertiary100 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_0),
+    tertiary99 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_10),
+    tertiary95 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_50),
+    tertiary90 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_100),
+    tertiary80 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_200),
+    tertiary70 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_300),
+    tertiary60 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_400),
+    tertiary50 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_500),
+    tertiary40 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_600),
+    tertiary30 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_700),
+    tertiary20 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_800),
+    tertiary10 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_900),
+    tertiary0 = ColorResourceHelper.getColor(context, android.R.color.system_accent3_1000),
+)
+
+/**
+ * Creates a light dynamic color scheme.
+ *
+ * Use this function to create a color scheme based off the system wallpaper. If the developer
+ * changes the wallpaper this color scheme will change accordingly. This dynamic scheme is a
+ * light theme variant.
+ *
+ * @param context The context required to get system resource data.
+ */
+@RequiresApi(Build.VERSION_CODES.S)
+fun dynamicLightColorScheme(context: Context): ColorScheme {
+    val tonalPalette = dynamicTonalPalette(context)
+    return lightColorScheme(
+        primary = tonalPalette.primary40,
+        >
+        primaryContainer = tonalPalette.primary90,
+        >
+        inversePrimary = tonalPalette.primary80,
+        secondary = tonalPalette.secondary40,
+        >
+        secondaryContainer = tonalPalette.secondary90,
+        >
+        tertiaryContainer = tonalPalette.tertiary90,
+        >
+        background = tonalPalette.neutral99,
+        >
+        surface = tonalPalette.neutral99,
+        >
+        surfaceVariant = tonalPalette.neutralVariant90,
+        >
+        inverseSurface = tonalPalette.neutral20,
+        inverseOnSurface = tonalPalette.neutral95,
+        outline = tonalPalette.neutralVariant50,
     )
+}
+
+/**
+ * Creates a dark dynamic color scheme.
+ *
+ * Use this function to create a color scheme based off the system wallpaper. If the developer
+ * changes the wallpaper this color scheme will change accordingly. This dynamic scheme is a dark
+ * theme variant.
+ *
+ * @param context The context required to get system resource data.
+ */
+@RequiresApi(Build.VERSION_CODES.S)
+fun dynamicDarkColorScheme(context: Context): ColorScheme {
+    val tonalPalette = dynamicTonalPalette(context)
+    return darkColorScheme(
+        primary = tonalPalette.primary80,
+        >
+        primaryContainer = tonalPalette.primary30,
+        >
+        inversePrimary = tonalPalette.primary40,
+        secondary = tonalPalette.secondary80,
+        >
+        secondaryContainer = tonalPalette.secondary30,
+        >
+        tertiaryContainer = tonalPalette.tertiary30,
+        >
+        background = tonalPalette.neutral10,
+        >
+        surface = tonalPalette.neutral10,
+        >
+        surfaceVariant = tonalPalette.neutralVariant30,
+        >
+        inverseSurface = tonalPalette.neutral90,
+        inverseOnSurface = tonalPalette.neutral20,
+        outline = tonalPalette.neutralVariant60,
+    )
+}
 
 @RequiresApi(23)
 private object ColorResourceHelper {
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ColorScheme.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ColorScheme.kt
index d2b588f..1299783 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ColorScheme.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ColorScheme.kt
@@ -77,8 +77,6 @@
  * sit on top of other surfaces with [surface] color.
  * @property inverseOnSurface A color that contrasts well with [inverseSurface]. Useful for content
  * that sits on top of containers that are [inverseSurface].
- * @property disabled A disabled color.
- * @property onDisabled Color used for text and icons displayed on top of the disabled color.
  * @property error The error color is used to indicate errors in components, such as invalid text in
  * a text field.
  * @property onError Color used for text and icons displayed on top of the error color.
@@ -111,8 +109,6 @@
     onSurfaceVariant: Color,
     inverseSurface: Color,
     inverseOnSurface: Color,
-    disabled: Color,
-    onDisabled: Color,
     error: Color,
     onError: Color,
     errorContainer: Color,
@@ -161,10 +157,6 @@
         internal set
     var inverseOnSurface by mutableStateOf(inverseOnSurface, structuralEqualityPolicy())
         internal set
-    var disabled by mutableStateOf(disabled, structuralEqualityPolicy())
-        internal set
-    var onDisabled by mutableStateOf(onDisabled, structuralEqualityPolicy())
-        internal set
     var error by mutableStateOf(error, structuralEqualityPolicy())
         internal set
     var onError by mutableStateOf(onError, structuralEqualityPolicy())
@@ -199,8 +191,6 @@
         onSurfaceVariant: Color = this.onSurfaceVariant,
         inverseSurface: Color = this.inverseSurface,
         inverseOnSurface: Color = this.inverseOnSurface,
-        disabled: Color = this.disabled,
-        onDisabled: Color = this.onDisabled,
         error: Color = this.error,
         onError: Color = this.onError,
         errorContainer: Color = this.errorContainer,
@@ -229,8 +219,6 @@
             >
             inverseSurface = inverseSurface,
             inverseOnSurface = inverseOnSurface,
-            disabled = disabled,
-            >
             error = error,
             >
             errorContainer = errorContainer,
@@ -261,8 +249,6 @@
             " +
             "inverseSurface=$inverseSurface" +
             "inverseOnSurface=$inverseOnSurface" +
-            "disabled=$disabled" +
-            " +
             "error=$error" +
             " +
             "errorContainer=$errorContainer" +
@@ -297,8 +283,6 @@
     onSurfaceVariant: Color = ColorLight.OnSurfaceVariant,
     inverseSurface: Color = ColorLight.InverseSurface,
     inverseOnSurface: Color = ColorLight.InverseOnSurface,
-    disabled: Color = ColorLight.Disabled,
-    onDisabled: Color = ColorLight.OnDisabled,
     error: Color = ColorLight.Error,
     onError: Color = ColorLight.OnError,
     errorContainer: Color = ColorLight.ErrorContainer,
@@ -327,8 +311,6 @@
         >
         inverseSurface = inverseSurface,
         inverseOnSurface = inverseOnSurface,
-        disabled = disabled,
-        >
         error = error,
         >
         errorContainer = errorContainer,
@@ -361,8 +343,6 @@
     onSurfaceVariant: Color = ColorDark.OnSurfaceVariant,
     inverseSurface: Color = ColorDark.InverseSurface,
     inverseOnSurface: Color = ColorDark.InverseOnSurface,
-    disabled: Color = ColorDark.Disabled,
-    onDisabled: Color = ColorDark.OnDisabled,
     error: Color = ColorDark.Error,
     onError: Color = ColorDark.OnError,
     errorContainer: Color = ColorDark.ErrorContainer,
@@ -391,8 +371,6 @@
         >
         inverseSurface = inverseSurface,
         inverseOnSurface = inverseOnSurface,
-        disabled = disabled,
-        >
         error = error,
         >
         errorContainer = errorContainer,
@@ -523,8 +501,6 @@
     >
     inverseSurface = other.inverseSurface
     inverseOnSurface = other.inverseOnSurface
-    disabled = other.disabled
-    >
     error = other.error
     >
     errorContainer = other.errorContainer
@@ -540,14 +516,12 @@
 internal fun ColorScheme.fromToken(value: ColorSchemeKey): Color {
     return when (value) {
         ColorSchemeKey.Background -> background
-        ColorSchemeKey.Disabled -> disabled
         ColorSchemeKey.Error -> error
         ColorSchemeKey.ErrorContainer -> errorContainer
         ColorSchemeKey.InverseOnSurface -> inverseOnSurface
         ColorSchemeKey.InversePrimary -> inversePrimary
         ColorSchemeKey.InverseSurface -> inverseSurface
         ColorSchemeKey.OnBackground -> onBackground
-        ColorSchemeKey.OnDisabled -> onDisabled
         ColorSchemeKey.OnError -> onError
         ColorSchemeKey.OnErrorContainer -> onErrorContainer
         ColorSchemeKey.OnPrimary -> onPrimary
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MaterialTheme.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MaterialTheme.kt
index 46117af..9db274c 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MaterialTheme.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MaterialTheme.kt
@@ -38,7 +38,7 @@
  * default values.
  *
  * All values may be set by providing this component with the [colorScheme][ColorScheme],
- * [typography][Typography], and [shapes][Shapes] attributes. Use this to configure the overall
+ * [typography][Typography] attributes. Use this to configure the overall
  * theme of elements within this MaterialTheme.
  *
  * Any values that are not set will inherit the current value from the theme, falling back to the
@@ -48,13 +48,12 @@
  *
  * @param colorScheme A complete definition of the Material Color theme for this hierarchy
  * @param typography A set of text styles to be used as this hierarchy's typography system
- * @param shapes A set of shapes to be used by the components in this hierarchy
  */
+
 @Composable
 fun MaterialTheme(
     colorScheme: ColorScheme = MaterialTheme.colorScheme,
     typography: Typography = MaterialTheme.typography,
-    shapes: Shapes = MaterialTheme.shapes,
     content: @Composable () -> Unit
 ) {
     val rememberedColorScheme = remember {
@@ -68,7 +67,6 @@
         LocalColorScheme provides rememberedColorScheme,
         LocalTypography provides typography,
         LocalRippleTheme provides MaterialRippleTheme,
-        LocalShapes provides shapes,
     ) {
         ProvideTextStyle(value = typography.bodyLarge, content = content)
     }
@@ -94,14 +92,6 @@
         @Composable
         @ReadOnlyComposable
         get() = LocalTypography.current
-
-    /**
-     * Retrieves the current [Shapes] at the call site's position in the hierarchy.
-     */
-    val shapes: Shapes
-        @Composable
-        @ReadOnlyComposable
-        get() = LocalShapes.current
 }
 
 @Immutable
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Shapes.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Shapes.kt
deleted file mode 100644
index dcf0421..0000000
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Shapes.kt
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.material3
-
-import androidx.compose.foundation.shape.CornerBasedShape
-import androidx.compose.material3.tokens.Shape
-import androidx.compose.runtime.Immutable
-import androidx.compose.runtime.staticCompositionLocalOf
-
-/**
- * Material surfaces can be displayed in different shapes. Shapes direct attention, identify
- * components, communicate state, and express brand.
- *
- * Components are grouped into shape categories based on their size. These categories provide a
- * way to change multiple component values at once, by changing the category’s values.
- * Shape categories include:
- * - Small components
- * - Medium components
- * - Large components
- *
- * See [Material shape specification](https://material.io/design/shape/applying-shape-to-ui.html)
- */
-@Immutable
-class Shapes(
-    // TODO(connieshi): add examples.
-    /**
-     * Shape used by small components.
-     */
-    val small: CornerBasedShape = Shape.Small,
-    // TODO(connieshi): add examples.
-    /**
-     * Shape used by medium components.
-     */
-    val medium: CornerBasedShape = Shape.Medium,
-    // TODO(connieshi): add examples.
-    /**
-     * Shape used by large components.
-     */
-    val large: CornerBasedShape = Shape.Large
-) {
-
-    /**
-     * Returns a copy of this Shapes, optionally overriding some of the values.
-     */
-    fun copy(
-        small: CornerBasedShape = this.small,
-        medium: CornerBasedShape = this.medium,
-        large: CornerBasedShape = this.large
-    ): Shapes = Shapes(
-        small = small,
-        medium = medium,
-        large = large
-    )
-
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (other !is Shapes) return false
-
-        if (small != other.small) return false
-        if (medium != other.medium) return false
-        if (large != other.large) return false
-
-        return true
-    }
-
-    override fun hashCode(): Int {
-        var result = small.hashCode()
-        result = 31 * result + medium.hashCode()
-        result = 31 * result + large.hashCode()
-        return result
-    }
-
-    override fun toString(): String {
-        return "Shapes(small=$small, medium=$medium, large=$large)"
-    }
-}
-
-/**
- * CompositionLocal used to specify the default shapes for the surfaces.
- */
-internal val LocalShapes = staticCompositionLocalOf { Shapes() }
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/ColorDark.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/ColorDark.kt
index 650c19f..3ebe5e6 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/ColorDark.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/ColorDark.kt
@@ -19,14 +19,12 @@
 
 internal object ColorDark {
     val Background = Palette.Neutral10
-    val Disabled = Palette.Neutral20
     val Error = Palette.Error80
     val ErrorContainer = Palette.Error30
     val InverseOnSurface = Palette.Neutral20
     val InversePrimary = Palette.Primary40
     val InverseSurface = Palette.Neutral90
     val >
-    val >
     val >
     val >
     val >
@@ -42,7 +40,6 @@
     val PrimaryContainer = Palette.Primary30
     val Secondary = Palette.Secondary80
     val SecondaryContainer = Palette.Secondary30
-    val Shadow = Palette.Neutral0
     val Surface = Palette.Neutral10
     val SurfaceVariant = Palette.NeutralVariant30
     val Tertiary = Palette.Tertiary80
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/ColorLight.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/ColorLight.kt
index 4072df1..fdaa91e 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/ColorLight.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/ColorLight.kt
@@ -19,14 +19,12 @@
 
 internal object ColorLight {
     val Background = Palette.Neutral99
-    val Disabled = Palette.Neutral95
     val Error = Palette.Error40
     val ErrorContainer = Palette.Error90
     val InverseOnSurface = Palette.Neutral95
     val InversePrimary = Palette.Primary80
     val InverseSurface = Palette.Neutral20
     val >
-    val >
     val >
     val >
     val >
@@ -42,7 +40,6 @@
     val PrimaryContainer = Palette.Primary90
     val Secondary = Palette.Secondary40
     val SecondaryContainer = Palette.Secondary90
-    val Shadow = Palette.Neutral0
     val Surface = Palette.Neutral99
     val SurfaceVariant = Palette.NeutralVariant90
     val Tertiary = Palette.Tertiary40
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/ColorSchemeKey.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/ColorSchemeKey.kt
index e9af878..ad6e665 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/ColorSchemeKey.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/ColorSchemeKey.kt
@@ -19,14 +19,12 @@
 
 internal enum class ColorSchemeKey {
     Background,
-    Disabled,
     Error,
     ErrorContainer,
     InverseOnSurface,
     InversePrimary,
     InverseSurface,
     OnBackground,
-    OnDisabled,
     OnError,
     OnErrorContainer,
     OnPrimary,
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 ed21806..7aeaea8 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
@@ -2571,7 +2571,7 @@
             isComposing = true
             try {
                 startRoot()
-                // Ignore reads of derivedStatOf recalculations
+                // Ignore reads of derivedStateOf recalculations
                 observeDerivedStateRecalculations(
                     start = {
                         childrenComposing++
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
index 871a8dc..a2a09dc 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
@@ -817,13 +817,17 @@
     }
 
     private fun applyAndCheck(snapshot: MutableSnapshot) {
-        val applyResult = snapshot.apply()
-        if (applyResult is SnapshotApplyResult.Failure) {
-            error(
-                "Unsupported concurrent change during composition. A state object was " +
-                    "modified by composition as well as being modified outside composition."
-            )
-            // TODO(chuckj): Consider lifting this restriction by forcing a recompose
+        try {
+            val applyResult = snapshot.apply()
+            if (applyResult is SnapshotApplyResult.Failure) {
+                error(
+                    "Unsupported concurrent change during composition. A state object was " +
+                        "modified by composition as well as being modified outside composition."
+                )
+                // TODO(chuckj): Consider lifting this restriction by forcing a recompose
+            }
+        } finally {
+            snapshot.dispose()
         }
     }
 
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotState.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotState.kt
index ffa0316..884040e 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotState.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotState.kt
@@ -15,6 +15,7 @@
  */
 
 @file:OptIn(ExperimentalTypeInference::class)
+
 package androidx.compose.runtime
 
 import androidx.compose.runtime.external.kotlinx.collections.immutable.PersistentList
@@ -204,9 +205,11 @@
      * The componentN() operators allow state objects to be used with the property destructuring
      * syntax
      *
+     * ```
      * var (foo, setFoo) = remember { mutableStateOf(0) }
      * setFoo(123) // set
      * foo == 123 // get
+     * ```
      */
     override operator fun component1(): T = value
 
@@ -330,12 +333,13 @@
     SnapshotStateList<T>().also { it.addAll(elements.toList()) }
 
 /**
- * Create an instance of MutableList<T> from a collection that is observable and can be snapshot.
+ * Create an instance of [MutableList]<T> from a collection that is observable and can be
+ * snapshot.
  */
 fun <T> Collection<T>.toMutableStateList() = SnapshotStateList<T>().also { it.addAll(this) }
 
 /**
- * Create a instance of MutableMap<K, V> that is observable and can be snapshot.
+ * Create a instance of [MutableMap]<K, V> that is observable and can be snapshot.
  *
  * @sample androidx.compose.runtime.samples.stateMapSample
  *
@@ -347,7 +351,7 @@
 fun <K, V> mutableStateMapOf() = SnapshotStateMap<K, V>()
 
 /**
- * Create a instance of MutableMap<K, V> that is observable and can be snapshot.
+ * Create a instance of [MutableMap]<K, V> that is observable and can be snapshot.
  *
  * @see mutableStateOf
  * @see mutableMapOf
@@ -358,7 +362,7 @@
     SnapshotStateMap<K, V>().apply { putAll(pairs.toMap()) }
 
 /**
- * Create an instance of MutableMap<K, V> from a collection of pairs that is observable and can be
+ * Create an instance of [MutableMap]<K, V> from a collection of pairs that is observable and can be
  * snapshot.
  */
 @Suppress("unused")
@@ -386,11 +390,14 @@
 }
 
 private typealias DerivedStateObservers = Pair<(DerivedState<*>) -> Unit, (DerivedState<*>) -> Unit>
+
 private val derivedStateObservers = SnapshotThreadLocal<PersistentList<DerivedStateObservers>>()
+
 private class DerivedSnapshotState<T>(
     private val calculation: () -> T
 ) : StateObject, DerivedState<T> {
     private var first: ResultRecord<T> = ResultRecord()
+
     private class ResultRecord<T> : StateRecord() {
         var dependencies: HashSet<StateObject>? = null
         var result: T? = null
@@ -467,15 +474,16 @@
         first = value as ResultRecord<T>
     }
 
-    override val value: T get() {
-        // Unlike most state objects, the record list of a derived state can change during a read
-        // because reading updates the cache. To account for this, instead of calling readable,
-        // which sends the read notification, the read observer is notified directly and current
-        // value is used instead which doesn't notify. This allow the read observer to read the
-        // value and only update the cache once.
-        Snapshot.current.readObserver?.invoke(this)
-        return currentValue
-    }
+    override val value: T
+        get() {
+            // Unlike most state objects, the record list of a derived state can change during a read
+            // because reading updates the cache. To account for this, instead of calling readable,
+            // which sends the read notification, the read observer is notified directly and current
+            // value is used instead which doesn't notify. This allow the read observer to read the
+            // value and only update the cache once.
+            Snapshot.current.readObserver?.invoke(this)
+            return currentValue
+        }
 
     override val currentValue: T
         get() = first.withCurrent {
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt
index b2dcb4e..fe17ea1 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt
@@ -338,9 +338,8 @@
         ): R = takeMutableSnapshot().run {
             try {
                 enter(block).also { apply().check() }
-            } catch (t: Throwable) {
+            } finally {
                 dispose()
-                throw t
             }
         }
 
@@ -536,11 +535,11 @@
             sync {
                 val newId = nextSnapshotId++
                 openSnapshots = openSnapshots.set(newId)
-                val invalid = invalid
-                this.invalid = invalid.set(newId)
+                val currentInvalid = invalid
+                this.invalid = currentInvalid.set(newId)
                 NestedMutableSnapshot(
                     newId,
-                    invalid,
+                    currentInvalid.addRange(id + 1, newId),
                     mergedReadObserver(readObserver, this.readObserver),
                     mergedWriteObserver(writeObserver, this.writeObserver),
                     this
@@ -652,13 +651,9 @@
             sync {
                 val readonlyId = nextSnapshotId++
                 openSnapshots = openSnapshots.set(readonlyId)
-                var currentInvalid = invalid
-                for (invalidId in previousId + 1 until readonlyId) {
-                    currentInvalid = currentInvalid.set(invalidId)
-                }
                 NestedReadonlySnapshot(
                     readonlyId,
-                    currentInvalid,
+                    invalid.addRange(previousId + 1, readonlyId),
                     readObserver,
                     this
                 )
@@ -818,11 +813,7 @@
                 id = nextSnapshotId++
                 openSnapshots = openSnapshots.set(id)
             }
-            var currentInvalid = invalid
-            for (invalidId in previousId + 1 until id) {
-                currentInvalid = currentInvalid.set(invalidId)
-            }
-            invalid = currentInvalid
+            invalid = invalid.addRange(previousId + 1, id)
         }
     }
 
@@ -1191,6 +1182,7 @@
     writeObserver: ((Any) -> Unit)?,
     val parent: MutableSnapshot
 ) : MutableSnapshot(id, invalid, readObserver, writeObserver) {
+    private var deactivated = false
 
     init { parent.nestedActivated(this) }
 
@@ -1199,7 +1191,7 @@
     override fun dispose() {
         if (!disposed) {
             super.dispose()
-            parent.nestedDeactivated(this)
+            deactivate()
         }
     }
 
@@ -1248,8 +1240,16 @@
         }
 
         applied = true
+        deactivate()
         return SnapshotApplyResult.Success
     }
+
+    private fun deactivate() {
+        if (!deactivated) {
+            deactivated = true
+            parent.nestedDeactivated(this)
+        }
+    }
 }
 
 /**
@@ -1317,7 +1317,7 @@
 
     override fun notifyObjectsInitialized() = currentSnapshot.notifyObjectsInitialized()
 
-    // The following should never be called.
+    /** Should never be called. */
     override fun nestedActivated(snapshot: Snapshot) = unsupported()
 
     override fun nestedDeactivated(snapshot: Snapshot) = unsupported()
@@ -1362,8 +1362,10 @@
  */
 private val threadSnapshot = SnapshotThreadLocal<Snapshot>()
 
-// A global synchronization object. This synchronization object should be taken before modifying any
-// of the fields below.
+/**
+ * A global synchronization object. This synchronization object should be taken before modifying any
+ * of the fields below.
+ */
 @PublishedApi
 internal val lock = Any()
 
@@ -1372,16 +1374,18 @@
 
 // The following variables should only be written when sync is taken
 
-// A set of snapshots that are currently open and should be considered invalid for new snapshots.
+/**
+ * A set of snapshots that are currently open and should be considered invalid for new snapshots.
+ */
 private var openSnapshots = SnapshotIdSet.EMPTY
 
-// The first snapshot created must be at least on more than the INVALID_SNAPSHOT
+/** The first snapshot created must be at least on more than the INVALID_SNAPSHOT */
 private var nextSnapshotId = INVALID_SNAPSHOT + 1
 
-// A list of apply observers
+/** A list of apply observers */
 private val applyObservers = mutableListOf<(Set<Any>, Snapshot) -> Unit>()
 
-// A list of observers of writes to the global state.
+/** A list of observers of writes to the global state. */
 private val globalWriteObservers = mutableListOf<((Any) -> Unit)>()
 
 private val currentGlobalSnapshot = AtomicReference(
@@ -1393,12 +1397,14 @@
     }
 )
 
-// A value to use to initialize the snapshot local variable of writable below. The value of this
-// doesn't matter as it is just used to initialize the local that is immediately overwritten by
-// Snapshot.current. This is done to avoid a compiler error complaining that the var has not been
-// initialized. This can be removed once contracts are out of experimental; then we can mark sync
-// with the correct contracts so the compiler would be able to figure out that the variable is
-// initialized.
+/**
+ * A value to use to initialize the snapshot local variable of writable below. The value of this
+ * doesn't matter as it is just used to initialize the local that is immediately overwritten by
+ * Snapshot.current. This is done to avoid a compiler error complaining that the var has not been
+ * initialized. This can be removed once contracts are out of experimental; then we can mark sync
+ * with the correct contracts so the compiler would be able to figure out that the variable is
+ * initialized.
+ */
 @PublishedApi
 internal val snapshotInitializer: Snapshot = currentGlobalSnapshot.get()
 
@@ -1459,17 +1465,19 @@
     if (!openSnapshots.get(snapshot.id)) error("Snapshot is not open")
 }
 
+/**
+ * A candidate snapshot is valid if the it is less than or equal to the current snapshot
+ * and it wasn't specifically marked as invalid when the snapshot started.
+ *
+ * All snapshot active at when the snapshot was taken considered invalid for the snapshot
+ * (they have not been applied and therefore are considered invalid).
+ *
+ * All snapshots taken after the current snapshot are considered invalid since they where taken
+ * after the current snapshot was taken.
+ *
+ * INVALID_SNAPSHOT is reserved as an invalid snapshot id.
+ */
 private fun valid(currentSnapshot: Int, candidateSnapshot: Int, invalid: SnapshotIdSet): Boolean {
-    // A candidate snapshot is valid if the it is less than or equal to the current snapshot
-    // and it wasn't specifically marked as invalid when the snapshot started.
-    //
-    // All snapshot active at when the snapshot was taken considered invalid for the snapshot
-    // (they have not been applied and therefore are considered invalid).
-    //
-    // All snapshots taken after the current snapshot are considered invalid since they where taken
-    // after the current snapshot was taken.
-    //
-    // INVALID_SNAPSHOT is reserved as an invalid snapshot id.
     return candidateSnapshot != INVALID_SNAPSHOT && candidateSnapshot <= currentSnapshot &&
         !invalid.get(candidateSnapshot)
 }
@@ -1768,3 +1776,13 @@
  */
 inline fun <T : StateRecord, R> T.withCurrent(block: (r: T) -> R): R =
     block(current(this, Snapshot.current))
+
+/**
+ * Helper routine to add a range of values ot a snapshot set
+ */
+internal fun SnapshotIdSet.addRange(from: Int, until: Int): SnapshotIdSet {
+    var result = this
+    for (invalidId in from until until)
+        result = result.set(invalidId)
+    return result
+}
diff --git a/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/snapshots/SnapshotTests.kt b/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/snapshots/SnapshotTests.kt
index 14bf4b8..f01ebb3 100644
--- a/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/snapshots/SnapshotTests.kt
+++ b/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/snapshots/SnapshotTests.kt
@@ -747,6 +747,57 @@
         }
     }
 
+    @Test // Regression test for b/200575924
+    // Test copied from b/200575924 bu chrnie@foxmail.com
+    fun nestedMutableSnapshotCanNotSeeOtherSnapshotChange() {
+        var state by mutableStateOf(0)
+
+        val snapshot1 = Snapshot.takeMutableSnapshot()
+        val snapshot2 = Snapshot.takeMutableSnapshot()
+        try {
+            snapshot2.enter {
+                state = 1
+            }
+
+            snapshot1.enter {
+                Snapshot.withMutableSnapshot {
+                    assertEquals(0, state)
+                }
+            }
+        } finally {
+            snapshot1.dispose()
+            snapshot2.dispose()
+        }
+    }
+
+    @Test // Regression test for b/200575924
+    // Test copied from b/200575924 by chrnie@foxmail.com
+    fun nestedSnapshotCanNotSeeOtherSnapshotChange() {
+        var state by mutableStateOf(0)
+
+        val snapshot1 = Snapshot.takeMutableSnapshot()
+        val snapshot2 = Snapshot.takeMutableSnapshot()
+        try {
+            snapshot2.enter {
+                state = 1
+            }
+
+            snapshot1.enter {
+                val nestedSnapshot = Snapshot.takeSnapshot()
+                try {
+                    nestedSnapshot.enter {
+                        assertEquals(0, state)
+                    }
+                } finally {
+                    nestedSnapshot.dispose()
+                }
+            }
+        } finally {
+            snapshot1.dispose()
+            snapshot2.dispose()
+        }
+    }
+
     private var count = 0
 
     @BeforeTest
diff --git a/compose/ui/ui-tooling/build.gradle b/compose/ui/ui-tooling/build.gradle
index 754f00d..80b5066 100644
--- a/compose/ui/ui-tooling/build.gradle
+++ b/compose/ui/ui-tooling/build.gradle
@@ -57,6 +57,8 @@
         androidTestImplementation(libs.truth)
         androidTestImplementation(libs.kotlinReflect)
         androidTestImplementation(project(":compose:animation:animation-tooling-internal"))
+        androidTestImplementation(project(":lifecycle:lifecycle-viewmodel-compose"))
+        androidTestImplementation(project(":compose:runtime:runtime-livedata"))
     }
 }
 
@@ -110,6 +112,8 @@
                 implementation(libs.truth)
                 implementation(libs.kotlinReflect)
                 implementation(project(":compose:animation:animation-tooling-internal"))
+                implementation(project(":lifecycle:lifecycle-viewmodel-compose"))
+                implementation(project(":compose:runtime:runtime-livedata"))
             }
         }
     }
diff --git a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ComposeViewAdapterTest.kt b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ComposeViewAdapterTest.kt
index f84a9f7..f52e504 100644
--- a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ComposeViewAdapterTest.kt
+++ b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ComposeViewAdapterTest.kt
@@ -312,6 +312,14 @@
         )
     }
 
+    @Test
+    fun viewModelPreviewRendersCorrectly() {
+        assertRendersCorrectly(
+            "androidx.compose.ui.tooling.SimpleComposablePreviewKt",
+            "ViewModelPreview"
+        )
+    }
+
     /**
      * Check that no re-composition happens without forcing it.
      */
diff --git a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/SimpleComposablePreview.kt b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/SimpleComposablePreview.kt
index c4098c8..52dd52c 100644
--- a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/SimpleComposablePreview.kt
+++ b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/SimpleComposablePreview.kt
@@ -18,14 +18,19 @@
 
 import androidx.activity.compose.LocalActivityResultRegistryOwner
 import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
+import androidx.compose.foundation.layout.Column
+import androidx.compose.material.Button
 import androidx.compose.material.Surface
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.livedata.observeAsState
 import androidx.compose.runtime.saveable.LocalSaveableStateRegistry
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.platform.LocalLifecycleOwner
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.viewmodel.compose.viewModel
 
 @Preview
 @Composable
@@ -106,6 +111,19 @@
     Text("ActivityResultRegistry preview")
 }
 
+@Preview
+@Composable
+fun ViewModelPreview(model: TestViewModel = viewModel()) {
+    val count by model.counterLiveData.observeAsState(0)
+    Column {
+        Button(
+             model.increaseCounter() },
+        ) {
+            Text("Clicks: $count")
+        }
+    }
+}
+
 class TestGroup {
     @Preview
     @Composable
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/Shape.kt b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/TestViewModel.kt
similarity index 60%
rename from compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/Shape.kt
rename to compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/TestViewModel.kt
index 7d09b6d..fa3f31c 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/Shape.kt
+++ b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/TestViewModel.kt
@@ -13,15 +13,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// GENERATED CODE - DO NOT MODIFY BY HAND
 
-package androidx.compose.material3.tokens
+package androidx.compose.ui.tooling
 
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.ui.unit.dp
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
 
-internal object Shape {
-    val Large = RoundedCornerShape(8.0.dp)
-    val Medium = RoundedCornerShape(8.0.dp)
-    val Small = RoundedCornerShape(4.0.dp)
-}
+class TestViewModel : ViewModel() {
+
+    val counterLiveData: LiveData<Int>
+        get() = counter
+
+    private val counter = MutableLiveData<Int>()
+    private var count = 0
+
+    fun increaseCounter() {
+        counter.value = ++count
+    }
+}
\ No newline at end of file
diff --git a/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/ComposeViewAdapter.kt b/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/ComposeViewAdapter.kt
index 78304d5..9e42082 100644
--- a/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/ComposeViewAdapter.kt
+++ b/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/ComposeViewAdapter.kt
@@ -59,6 +59,7 @@
 import androidx.core.app.ActivityOptionsCompat
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleRegistry
+import androidx.lifecycle.ViewModelStore
 import androidx.lifecycle.ViewModelStoreOwner
 import androidx.lifecycle.ViewTreeLifecycleOwner
 import androidx.lifecycle.ViewTreeViewModelStoreOwner
@@ -628,6 +629,7 @@
         if (::clock.isInitialized) {
             clock.dispose()
         }
+        FakeViewModelStoreOwner.viewModelStore.clear()
     }
 
     /**
@@ -713,8 +715,10 @@
         override fun getLifecycle(): Lifecycle = lifecycle
     }
 
-    private val FakeViewModelStoreOwner = ViewModelStoreOwner {
-        throw IllegalStateException("ViewModels creation is not supported in Preview")
+    private val FakeViewModelStoreOwner = object : ViewModelStoreOwner {
+        private val viewModelStore = ViewModelStore()
+
+        override fun getViewModelStore() = viewModelStore
     }
 
     private val FakeOnBackPressedDispatcherOwner = object : OnBackPressedDispatcherOwner {
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt
index 6846fec..edcf54b 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt
@@ -28,6 +28,7 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.runtime.snapshots.Snapshot
 import androidx.compose.runtime.structuralEqualityPolicy
+import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.graphics.toAndroidRect
 import androidx.compose.ui.node.InnerPlaceable
@@ -54,13 +55,13 @@
 import androidx.compose.ui.semantics.cutText
 import androidx.compose.ui.semantics.disabled
 import androidx.compose.ui.semantics.dismiss
+import androidx.compose.ui.semantics.error
 import androidx.compose.ui.semantics.expand
 import androidx.compose.ui.semantics.focused
 import androidx.compose.ui.semantics.getTextLayoutResult
 import androidx.compose.ui.semantics.heading
 import androidx.compose.ui.semantics.horizontalScrollAxisRange
 import androidx.compose.ui.semantics.liveRegion
-import androidx.compose.ui.semantics.error
 import androidx.compose.ui.semantics.onClick
 import androidx.compose.ui.semantics.onLongClick
 import androidx.compose.ui.semantics.pasteText
@@ -922,6 +923,323 @@
         accessibilityDelegate.sendSemanticsPropertyChangeEvents(newNodes)
     }
 
+    @Test
+    fun canScroll_returnsFalse_whenPositionInvalid() {
+        val semanticsNode = createSemanticsNodeWithAdjustedBoundsWithProperties(
+            id = 1,
+            mergeDescendants = true
+        ) {
+            horizontalScrollAxisRange = ScrollAxisRange(
+                value = { 0f },
+                maxValue = { 1f },
+                reverseScrolling = false
+            )
+        }.apply {
+            adjustedBounds.set(0, 0, 100, 100)
+        }
+
+        assertFalse(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = false,
+                direction = 1,
+                position = Offset.Unspecified
+            )
+        )
+        assertFalse(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = false,
+                direction = -1,
+                position = Offset.Unspecified
+            )
+        )
+        assertFalse(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = false,
+                direction = 0,
+                position = Offset.Unspecified
+            )
+        )
+    }
+
+    @Test
+    fun canScroll_returnsTrue_whenHorizontalScrollableNotAtLimit() {
+        val semanticsNode = createSemanticsNodeWithAdjustedBoundsWithProperties(
+            id = 1,
+            mergeDescendants = true
+        ) {
+            horizontalScrollAxisRange = ScrollAxisRange(
+                value = { 0.5f },
+                maxValue = { 1f },
+                reverseScrolling = false
+            )
+        }.apply {
+            adjustedBounds.set(0, 0, 100, 100)
+        }
+
+        // Should be scrollable in both directions.
+        assertTrue(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = false,
+                direction = 1,
+                position = Offset(50f, 50f)
+            )
+        )
+        assertTrue(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = false,
+                direction = 0,
+                position = Offset(50f, 50f)
+            )
+        )
+        assertTrue(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = false,
+                direction = -1,
+                position = Offset(50f, 50f)
+            )
+        )
+    }
+
+    @Test
+    fun canScroll_returnsTrue_whenVerticalScrollableNotAtLimit() {
+        val semanticsNode = createSemanticsNodeWithAdjustedBoundsWithProperties(
+            id = 1,
+            mergeDescendants = true
+        ) {
+            verticalScrollAxisRange = ScrollAxisRange(
+                value = { 0.5f },
+                maxValue = { 1f },
+                reverseScrolling = false
+            )
+        }.apply {
+            adjustedBounds.set(0, 0, 100, 100)
+        }
+
+        // Should be scrollable in both directions.
+        assertTrue(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = true,
+                direction = -1,
+                position = Offset(50f, 50f)
+            )
+        )
+        assertTrue(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = true,
+                direction = 0,
+                position = Offset(50f, 50f)
+            )
+        )
+        assertTrue(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = true,
+                direction = 1,
+                position = Offset(50f, 50f)
+            )
+        )
+    }
+
+    @Test
+    fun canScroll_returnsFalse_whenHorizontalScrollable_whenScrolledRightAndAtLimit() {
+        val semanticsNode = createSemanticsNodeWithAdjustedBoundsWithProperties(
+            id = 1,
+            mergeDescendants = true
+        ) {
+            horizontalScrollAxisRange = ScrollAxisRange(
+                value = { 1f },
+                maxValue = { 1f },
+                reverseScrolling = false
+            )
+        }.apply {
+            adjustedBounds.set(0, 0, 100, 100)
+        }
+
+        assertFalse(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = false,
+                direction = 1,
+                position = Offset(50f, 50f)
+            )
+        )
+        assertFalse(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = false,
+                direction = 0,
+                position = Offset(50f, 50f)
+            )
+        )
+    }
+
+    @Test
+    fun canScroll_returnsFalse_whenHorizontalScrollable_whenScrolledLeftAndAtLimit() {
+        val semanticsNode = createSemanticsNodeWithAdjustedBoundsWithProperties(
+            id = 1,
+            mergeDescendants = true
+        ) {
+            horizontalScrollAxisRange = ScrollAxisRange(
+                value = { 0f },
+                maxValue = { 1f },
+                reverseScrolling = false
+            )
+        }.apply {
+            adjustedBounds.set(0, 0, 100, 100)
+        }
+
+        assertFalse(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = false,
+                direction = -1,
+                position = Offset(50f, 50f)
+            )
+        )
+    }
+
+    @Test
+    fun canScroll_returnsFalse_whenVerticalScrollable_whenScrolledDownAndAtLimit() {
+        val semanticsNode = createSemanticsNodeWithAdjustedBoundsWithProperties(
+            id = 1,
+            mergeDescendants = true
+        ) {
+            verticalScrollAxisRange = ScrollAxisRange(
+                value = { 1f },
+                maxValue = { 1f },
+                reverseScrolling = false
+            )
+        }.apply {
+            adjustedBounds.set(0, 0, 100, 100)
+        }
+
+        assertFalse(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = true,
+                direction = 1,
+                position = Offset(50f, 50f)
+            )
+        )
+        assertFalse(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = true,
+                direction = 0,
+                position = Offset(50f, 50f)
+            )
+        )
+    }
+
+    @Test
+    fun canScroll_returnsFalse_whenVerticalScrollable_whenScrolledUpAndAtLimit() {
+        val semanticsNode = createSemanticsNodeWithAdjustedBoundsWithProperties(
+            id = 1,
+            mergeDescendants = true
+        ) {
+            verticalScrollAxisRange = ScrollAxisRange(
+                value = { 0f },
+                maxValue = { 1f },
+                reverseScrolling = false
+            )
+        }.apply {
+            adjustedBounds.set(0, 0, 100, 100)
+        }
+
+        assertFalse(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = true,
+                direction = -1,
+                position = Offset(50f, 50f)
+            )
+        )
+    }
+
+    @Test
+    fun canScroll_respectsReverseDirection() {
+        val semanticsNode = createSemanticsNodeWithAdjustedBoundsWithProperties(
+            id = 1,
+            mergeDescendants = true
+        ) {
+            horizontalScrollAxisRange = ScrollAxisRange(
+                value = { 0f },
+                maxValue = { 1f },
+                reverseScrolling = true
+            )
+        }.apply {
+            adjustedBounds.set(0, 0, 100, 100)
+        }
+
+        assertTrue(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = false,
+                // Scroll left, even though value is 0.
+                direction = -1,
+                position = Offset(50f, 50f)
+            )
+        )
+    }
+
+    @Test
+    fun canScroll_returnsFalse_forVertical_whenScrollableIsHorizontal() {
+        val semanticsNode = createSemanticsNodeWithAdjustedBoundsWithProperties(
+            id = 1,
+            mergeDescendants = true
+        ) {
+            horizontalScrollAxisRange = ScrollAxisRange(
+                value = { 0.5f },
+                maxValue = { 1f },
+                reverseScrolling = true
+            )
+        }.apply {
+            adjustedBounds.set(0, 0, 100, 100)
+        }
+
+        assertFalse(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = true,
+                direction = 1,
+                position = Offset(50f, 50f)
+            )
+        )
+    }
+
+    @Test
+    fun canScroll_returnsFalse_whenTouchIsOutsideBounds() {
+        val semanticsNode = createSemanticsNodeWithAdjustedBoundsWithProperties(
+            id = 1,
+            mergeDescendants = true
+        ) {
+            horizontalScrollAxisRange = ScrollAxisRange(
+                value = { 0.5f },
+                maxValue = { 1f },
+                reverseScrolling = true
+            )
+        }.apply {
+            adjustedBounds.set(0, 0, 50, 50)
+        }
+
+        assertFalse(
+            accessibilityDelegate.canScroll(
+                currentSemanticsNodes = listOf(semanticsNode),
+                vertical = false,
+                direction = 1,
+                position = Offset(100f, 100f)
+            )
+        )
+    }
+
     private fun createSemanticsNodeWithProperties(
         id: Int,
         mergeDescendants: Boolean,
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/viewinterop/ComposeViewTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/viewinterop/ComposeViewTest.kt
index 27a978e..e797fca 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/viewinterop/ComposeViewTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/viewinterop/ComposeViewTest.kt
@@ -22,10 +22,20 @@
 import android.view.View
 import android.view.ViewGroup
 import android.view.ViewTreeObserver
+import android.widget.FrameLayout
 import androidx.activity.ComponentActivity
+import androidx.compose.foundation.horizontalScroll
 import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxHeight
 import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.requiredSize
+import androidx.compose.foundation.rememberScrollState
 import androidx.compose.foundation.text.BasicText
+import androidx.compose.foundation.verticalScroll
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Rect
@@ -33,13 +43,20 @@
 import androidx.compose.ui.layout.onGloballyPositioned
 import androidx.compose.ui.platform.AbstractComposeView
 import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.LocalView
 import androidx.compose.ui.platform.ViewCompositionStrategy
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.R
 import androidx.compose.ui.test.assertTextEquals
 import androidx.compose.ui.test.junit4.createAndroidComposeRule
 import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.performScrollTo
+import androidx.compose.ui.test.performTouchInput
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.dp
+import androidx.core.view.setPadding
 import androidx.lifecycle.Lifecycle
 import androidx.test.espresso.Espresso
 import androidx.test.espresso.assertion.ViewAssertions.matches
@@ -335,6 +352,245 @@
         }
         assertNotNull("test did not run", result?.getOrThrow())
     }
+
+    @Test
+    fun canScrollVerticallyDown_returnsTrue_onlyAfterDownEventInScrollable() {
+        lateinit var composeView: View
+        rule.setContent {
+            composeView = LocalView.current
+            ScrollableAndNonScrollable(vertical = true)
+        }
+
+        rule.onNodeWithTag(SCROLLABLE_FIRST_TAG)
+            .performScrollTo()
+
+        // No down event yet, should not be scrollable in any direction
+        rule.runOnIdle {
+            composeView.assertCanScroll()
+        }
+
+        // Send a down event.
+        rule.onNodeWithTag(SCROLLABLE_TAG)
+            .performTouchInput { down(center) }
+
+        rule.runOnIdle {
+            composeView.assertCanScroll(down = true)
+        }
+    }
+
+    @Test
+    fun canScrollVerticallyUp_returnsTrue_onlyAfterDownEventInScrollable() {
+        lateinit var composeView: View
+        rule.setContent {
+            composeView = LocalView.current
+            ScrollableAndNonScrollable(vertical = true)
+        }
+
+        rule.onNodeWithTag(SCROLLABLE_LAST_TAG)
+            .performScrollTo()
+
+        // No down event yet, should not be scrollable in any direction
+        rule.runOnIdle {
+            composeView.assertCanScroll()
+        }
+
+        // Send a down event.
+        rule.onNodeWithTag(SCROLLABLE_TAG)
+            .performTouchInput {
+                down(center)
+            }
+
+        rule.runOnIdle {
+            composeView.assertCanScroll(up = true)
+        }
+    }
+
+    @Test
+    fun canScrollVertically_returnsFalse_afterDownEventOutsideScrollable() {
+        lateinit var composeView: View
+        rule.setContent {
+            composeView = LocalView.current
+            ScrollableAndNonScrollable(vertical = true)
+        }
+
+        // No down event yet, should not be scrollable in any direction
+        rule.runOnIdle {
+            composeView.assertCanScroll()
+        }
+
+        // Send a down event.
+        rule.onNodeWithTag(NON_SCROLLABLE_TAG)
+            .performTouchInput { down(center) }
+
+        // No down event yet, should not be scrollable in any direction
+        rule.runOnIdle {
+            composeView.assertCanScroll()
+        }
+    }
+
+    @Test
+    fun canScrollHorizontallyRight_returnsTrue_onlyAfterDownEventInScrollable() {
+        lateinit var composeView: View
+        rule.setContent {
+            composeView = LocalView.current
+            ScrollableAndNonScrollable(vertical = false)
+        }
+
+        rule.onNodeWithTag(SCROLLABLE_FIRST_TAG)
+            .performScrollTo()
+
+        // No down event yet, should not be scrollable in any direction
+        rule.runOnIdle {
+            composeView.assertCanScroll()
+        }
+
+        // Send a down event.
+        rule.onNodeWithTag(SCROLLABLE_TAG)
+            .performTouchInput { down(center) }
+
+        rule.runOnIdle {
+            composeView.assertCanScroll(right = true)
+        }
+    }
+
+    @Test
+    fun canScrollHorizontallyLeft_returnsTrue_onlyAfterDownEventInScrollable() {
+        lateinit var composeView: View
+        rule.setContent {
+            composeView = LocalView.current
+            ScrollableAndNonScrollable(vertical = false)
+        }
+
+        rule.onNodeWithTag(SCROLLABLE_LAST_TAG)
+            .performScrollTo()
+
+        // No down event yet, should not be scrollable in any direction
+        rule.runOnIdle {
+            composeView.assertCanScroll()
+        }
+
+        // Send a down event.
+        rule.onNodeWithTag(SCROLLABLE_TAG)
+            .performTouchInput { down(center) }
+
+        rule.runOnIdle {
+            composeView.assertCanScroll(left = true)
+        }
+    }
+
+    @Test
+    fun canScrollHorizontally_returnsFalse_afterDownEventOutsideScrollable() {
+        lateinit var composeView: View
+        rule.setContent {
+            composeView = LocalView.current
+            ScrollableAndNonScrollable(vertical = false)
+        }
+
+        // No down event yet, should not be scrollable in any direction
+        rule.runOnIdle {
+            composeView.assertCanScroll()
+        }
+
+        // Send a down event.
+        rule.onNodeWithTag(NON_SCROLLABLE_TAG)
+            .performTouchInput { down(center) }
+
+        // No down event yet, should not be scrollable in any direction
+        rule.runOnIdle {
+            composeView.assertCanScroll()
+        }
+    }
+
+    /**
+     * Puts a scrollable area of size 1 px square inside a series of nested paddings, both compose-
+     * and view-based, to ensure that the pointer calculations account for all the offsets those
+     * paddings introduce.
+     *
+     * ```
+     *  ┌───────────────61────────────────┐
+     *  │AndroidComposeView (root)        │
+     *  │                                 │
+     *  │  ┌─────────────41─────────────┐ │
+     *  │  │AndroidView/FrameLayout     │ │
+     *  │  │                            │ │
+     *  │  │  ┌──────────21───────────┐ │ │
+     *  6  │  │ComposeView            │ │ │
+     *  1  4  │                       │ │ │
+     *  │  1  2  ┌─────────1────────┐ │ │ │
+     *  │  │  1  │Box (scrollable)  │ │ │ │
+     *  │  │  │  1                  │ │ │ │
+     *  │  │  │  └──────────────────┘ │ │ │
+     *  │  │  └───────────────────────┘ │ │
+     *  │  └────────────────────────────┘ │
+     *  └─────────────────────────────────┘
+     * ```
+     */
+    @Test
+    fun canScroll_accountsForViewAndNodeOffsets() {
+        lateinit var composeView: View
+        rule.setContent {
+            with(LocalDensity.current) {
+                AndroidView(
+                    modifier = Modifier
+                        .requiredSize(61.toDp())
+                        .padding(10.toDp()),
+                    factory = { context ->
+                        FrameLayout(context).apply {
+                            setPadding(10)
+                            addView(ComposeView(context).apply {
+                                setContent {
+                                    // Query the inner android view, not the outer one.
+                                    composeView = LocalView.current
+                                    Box(
+                                        Modifier
+                                            .padding(10.toDp())
+                                            .testTag(SCROLLABLE_TAG)
+                                            .horizontalScroll(rememberScrollState())
+                                            // Give it something to scroll.
+                                            .requiredSize(100.dp)
+                                    )
+                                }
+                            })
+                        }
+                    }
+                )
+            }
+        }
+
+        val scrollable = rule.onNodeWithTag(SCROLLABLE_TAG)
+            .fetchSemanticsNode()
+        assertEquals(IntSize(1, 1), scrollable.size)
+
+        rule.runOnIdle {
+            composeView.assertCanScroll()
+        }
+
+        rule.onNodeWithTag(SCROLLABLE_TAG)
+            .performTouchInput {
+                down(center)
+            }
+
+        rule.runOnIdle {
+            composeView.assertCanScroll(right = true)
+        }
+    }
+}
+
+private const val SCROLLABLE_TAG = "scrollable"
+private const val NON_SCROLLABLE_TAG = "non-scrollable"
+private const val SCROLLABLE_FIRST_TAG = "first-scrollable-child"
+private const val SCROLLABLE_LAST_TAG = "last-scrollable-child"
+
+private fun View.assertCanScroll(
+    left: Boolean = false,
+    up: Boolean = false,
+    right: Boolean = false,
+    down: Boolean = false
+) {
+    assertEquals(left, canScrollHorizontally(-1))
+    assertEquals(right, canScrollHorizontally(1))
+    assertEquals(up, canScrollVertically(-1))
+    assertEquals(down, canScrollVertically(1))
 }
 
 private inline fun ViewGroup.assertUnsupported(
@@ -353,6 +609,45 @@
     )
 }
 
+@Composable
+private fun ScrollableAndNonScrollable(vertical: Boolean) {
+    @Composable
+    fun layout(size: Dp, content: @Composable (Modifier) -> Unit) {
+        if (vertical) {
+            Column(Modifier.requiredSize(size)) {
+                content(Modifier.weight(1f).fillMaxWidth())
+            }
+        } else {
+            Row(Modifier.requiredSize(100.dp)) {
+                content(Modifier.weight(1f).fillMaxHeight())
+            }
+        }
+    }
+
+    val scrollState = rememberScrollState(0)
+    val scrollModifier = if (vertical) {
+        Modifier.verticalScroll(scrollState)
+    } else {
+        Modifier.horizontalScroll(scrollState)
+    }
+
+    layout(100.dp) { modifier ->
+        Box(
+            modifier
+                .testTag(SCROLLABLE_TAG)
+                .then(scrollModifier)
+        ) {
+            layout(10000.dp) {
+                Box(Modifier.testTag(SCROLLABLE_FIRST_TAG))
+                // Give the scrollable some content that actually requires scrolling.
+                Box(it)
+                Box(Modifier.testTag(SCROLLABLE_LAST_TAG))
+            }
+        }
+        Box(modifier.testTag(NON_SCROLLABLE_TAG))
+    }
+}
+
 private class TestComposeView(
     context: Context
 ) : AbstractComposeView(context) {
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 df59efd..5fce5d4 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
@@ -52,7 +52,6 @@
 import androidx.compose.ui.autofill.AutofillTree
 import androidx.compose.ui.autofill.performAutofill
 import androidx.compose.ui.autofill.populateViewStructure
-import androidx.compose.ui.focus.FocusTag
 import androidx.compose.ui.focus.FocusDirection
 import androidx.compose.ui.focus.FocusDirection.Companion.Down
 import androidx.compose.ui.focus.FocusDirection.Companion.In
@@ -64,6 +63,7 @@
 import androidx.compose.ui.focus.FocusDirection.Companion.Up
 import androidx.compose.ui.focus.FocusManager
 import androidx.compose.ui.focus.FocusManagerImpl
+import androidx.compose.ui.focus.FocusTag
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Canvas
 import androidx.compose.ui.graphics.CanvasHolder
@@ -138,6 +138,13 @@
     ViewGroup(context), Owner, ViewRootForTest, PositionCalculator, DefaultLifecycleObserver {
 
     /**
+     * Remembers the position of the last pointer input event that was down. This position will be
+     * used to calculate whether this view is considered scrollable via [canScrollHorizontally]/
+     * [canScrollVertically].
+     */
+    private var lastDownPointerPosition: Offset = Offset.Unspecified
+
+    /**
      * Signal that AndroidComposeView's superclass constructors have finished running.
      * If this is false, it's because the runtime's default uninitialized value is currently
      * visible and AndroidComposeView's constructor hasn't started running yet. In this state
@@ -915,6 +922,15 @@
                 val pointerInputEvent =
                     motionEventAdapter.convertToPointerInputEvent(motionEvent, this)
                 if (pointerInputEvent != null) {
+                    // Cache the last position of the last pointer to go down so we can check if
+                    // it's in a scrollable region in canScroll{Vertically|Horizontally}. Those
+                    // methods use semantics data, and because semantics coordinates are local to
+                    // this view, the pointer _position_, not _positionOnScreen_, is the offset that
+                    // needs to be cached.
+                    pointerInputEvent.pointers.lastOrNull { it.down }?.position?.let {
+                        lastDownPointerPosition = it
+                    }
+
                     pointerInputEventProcessor.process(
                         pointerInputEvent,
                         this,
@@ -935,6 +951,22 @@
         }
     }
 
+    /**
+     * This method is required to correctly support swipe-to-dismiss layouts on WearOS, which search
+     * their children for scrollable views to determine whether or not to intercept touch events –
+     * a sort of simplified nested scrolling mechanism.
+     *
+     * Because a composition may contain many scrollable and non-scrollable areas, and this method
+     * doesn't know which part of the view the caller cares about, it uses the
+     * [lastDownPointerPosition] as the location to check.
+     */
+    override fun canScrollHorizontally(direction: Int): Boolean =
+        accessibilityDelegate.canScroll(vertical = false, direction, lastDownPointerPosition)
+
+    /** See [canScrollHorizontally]. */
+    override fun canScrollVertically(direction: Int): Boolean =
+        accessibilityDelegate.canScroll(vertical = true, direction, lastDownPointerPosition)
+
     private fun isInBounds(motionEvent: MotionEvent): Boolean {
         val x = motionEvent.x
         val y = motionEvent.y
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
index 7c83066..5c06c55 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
@@ -38,6 +38,7 @@
 import androidx.annotation.IntRange
 import androidx.annotation.RequiresApi
 import androidx.annotation.VisibleForTesting
+import androidx.annotation.VisibleForTesting.PRIVATE
 import androidx.collection.ArraySet
 import androidx.collection.SparseArrayCompat
 import androidx.compose.ui.ExperimentalComposeUiApi
@@ -47,6 +48,7 @@
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.graphics.toAndroidRect
+import androidx.compose.ui.graphics.toComposeRect
 import androidx.compose.ui.layout.boundsInParent
 import androidx.compose.ui.layout.positionInRoot
 import androidx.compose.ui.node.HitTestResult
@@ -209,11 +211,14 @@
         val toIndex: Int,
         val traverseTime: Long
     )
+
     private var pendingTextTraversedEvent: PendingTextTraversedEvent? = null
 
-    // Up to date semantics nodes in pruned semantics tree. It always reflects the current
-    // semantics tree. They key is the virtual view id(the root node has a key of
-    // AccessibilityNodeProviderCompat.HOST_VIEW_ID and other node has a key of its id).
+    /**
+     * Up to date semantics nodes in pruned semantics tree. It always reflects the current
+     * semantics tree. They key is the virtual view id(the root node has a key of
+     * AccessibilityNodeProviderCompat.HOST_VIEW_ID and other node has a key of its id).
+     */
     private var currentSemanticsNodes: Map<Int, SemanticsNodeWithAdjustedBounds> = mapOf()
         get() {
             if (currentSemanticsNodesInvalidated) {
@@ -267,6 +272,63 @@
         })
     }
 
+    /**
+     * Returns true if there is any semantics node in the tree that can scroll in the given
+     * [orientation][vertical] and [direction] at the given [position] in the view associated with
+     * this delegate.
+     *
+     * @param direction The direction to check for scrolling: <0 means scrolling left or up, >0
+     * means scrolling right or down.
+     * @param position The position in the view to check in view-local coordinates.
+     */
+    internal fun canScroll(
+        vertical: Boolean,
+        direction: Int,
+        position: Offset
+    ): Boolean = canScroll(currentSemanticsNodes.values, vertical, direction, position)
+
+    @VisibleForTesting(otherwise = PRIVATE)
+    internal fun canScroll(
+        currentSemanticsNodes: Collection<SemanticsNodeWithAdjustedBounds>,
+        vertical: Boolean,
+        direction: Int,
+        position: Offset
+    ): Boolean {
+        // No down event has occurred yet which gives us a location to hit test.
+        if (position == Offset.Unspecified || !position.isValid()) return false
+
+        val scrollRangeProperty = when (vertical) {
+            true -> SemanticsProperties.VerticalScrollAxisRange
+            false -> SemanticsProperties.HorizontalScrollAxisRange
+        }
+
+        return currentSemanticsNodes.any { node ->
+            // Only consider nodes that are under the touch event. Checks the adjusted bounds to
+            // avoid overlapping siblings. Because position is a float (touch event can happen in-
+            // between pixels), convert the int-based Android Rect to a float-based Compose Rect
+            // before doing the comparison.
+            if (!node.adjustedBounds.toComposeRect().contains(position)) {
+                return@any false
+            }
+
+            val scrollRange = node.semanticsNode.config.getOrNull(scrollRangeProperty)
+                ?: return@any false
+
+            // A node simply having scrollable semantics doesn't mean it's necessarily scrollable
+            // in the given direction – it must also not be scrolled to its limit in that direction.
+            var actualDirection = if (scrollRange.reverseScrolling) -direction else direction
+            if (direction == 0 && scrollRange.reverseScrolling) {
+                // The View implementation of canScroll* treat zero as a positive direction, so
+                // this code should do the same. That means if scrolling is reversed, zero should be
+                // a negative direction. The actual number doesn't matter, just its sign.
+                actualDirection = -1
+            }
+
+            if (actualDirection < 0) scrollRange.value() > 0
+            else scrollRange.value() < scrollRange.maxValue()
+        }
+    }
+
     private fun createNodeInfo(virtualViewId: Int): AccessibilityNodeInfo? {
         val info: AccessibilityNodeInfoCompat = AccessibilityNodeInfoCompat.obtain()
         val semanticsNodeWithAdjustedBounds = currentSemanticsNodes[virtualViewId]
@@ -2499,9 +2561,11 @@
     }
 }
 
-// These objects are used as snapshot observation scopes for the purpose of sending accessibility
-// scroll events whenever the scroll offset changes.  There is one per scroller and their lifecycle
-// is the same as the scroller's lifecycle in the semantics tree.
+/**
+ * These objects are used as snapshot observation scopes for the purpose of sending accessibility
+ * scroll events whenever the scroll offset changes.  There is one per scroller and their lifecycle
+ * is the same as the scroller's lifecycle in the semantics tree.
+ */
 internal class ScrollObservationScope(
     val semanticsNodeId: Int,
     val allScopes: List<ScrollObservationScope>,
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/InternalPointerInput.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/InternalPointerInput.kt
index 783debd8..b5ba973 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/InternalPointerInput.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/InternalPointerInput.kt
@@ -35,7 +35,8 @@
 /**
  * Data that describes a particular pointer
  *
- * [positionOnScreen] is relative to the device screen. [position] is relative to the owner.
+ * @param positionOnScreen The position of the event relative to the device screen.
+ * @param position The position of the event relative to the owner.
  */
 @OptIn(ExperimentalComposeUiApi::class)
 internal data class PointerInputEventData(
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt
index d24f050..23c5517 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt
@@ -530,7 +530,11 @@
     val value: () -> Float,
     val maxValue: () -> Float,
     val reverseScrolling: Boolean = false
-)
+) {
+    override fun toString(): String =
+        "ScrollAxisRange(value=${value()}, maxValue=${maxValue()}, " +
+            "reverseScrolling=$reverseScrolling)"
+}
 
 /**
  * The type of user interface element. Accessibility services might use this to describe the
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentTransitionTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentTransitionTest.kt
index 9a12236..4c241d2 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentTransitionTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentTransitionTest.kt
@@ -15,6 +15,7 @@
  */
 package androidx.fragment.app
 
+import android.os.Build
 import android.os.Bundle
 import android.transition.Transition
 import android.transition.TransitionSet
@@ -51,7 +52,7 @@
 
 @MediumTest
 @RunWith(Parameterized::class)
-@SdkSuppress(minSdkVersion = 31)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
 class FragmentTransitionTest(
     private val reorderingAllowed: ReorderingAllowed
 ) {
diff --git a/glance/glance-appwidget/api/current.txt b/glance/glance-appwidget/api/current.txt
index d20e647..f0d3b30 100644
--- a/glance/glance-appwidget/api/current.txt
+++ b/glance/glance-appwidget/api/current.txt
@@ -103,6 +103,10 @@
   @kotlin.DslMarker public @interface LazyScopeMarker {
   }
 
+  public final class SwitchKt {
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, optional androidx.glance.Modifier modifier, optional String text, optional androidx.glance.text.TextStyle? textStyle);
+  }
+
 }
 
 package androidx.glance.appwidget.translators {
@@ -110,6 +114,9 @@
   public final class CheckBoxTranslatorKt {
   }
 
+  public final class SwitchTranslatorKt {
+  }
+
   public final class TextTranslatorKt {
   }
 
diff --git a/glance/glance-appwidget/api/public_plus_experimental_current.txt b/glance/glance-appwidget/api/public_plus_experimental_current.txt
index d20e647..f0d3b30 100644
--- a/glance/glance-appwidget/api/public_plus_experimental_current.txt
+++ b/glance/glance-appwidget/api/public_plus_experimental_current.txt
@@ -103,6 +103,10 @@
   @kotlin.DslMarker public @interface LazyScopeMarker {
   }
 
+  public final class SwitchKt {
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, optional androidx.glance.Modifier modifier, optional String text, optional androidx.glance.text.TextStyle? textStyle);
+  }
+
 }
 
 package androidx.glance.appwidget.translators {
@@ -110,6 +114,9 @@
   public final class CheckBoxTranslatorKt {
   }
 
+  public final class SwitchTranslatorKt {
+  }
+
   public final class TextTranslatorKt {
   }
 
diff --git a/glance/glance-appwidget/api/restricted_current.txt b/glance/glance-appwidget/api/restricted_current.txt
index d20e647..f0d3b30 100644
--- a/glance/glance-appwidget/api/restricted_current.txt
+++ b/glance/glance-appwidget/api/restricted_current.txt
@@ -103,6 +103,10 @@
   @kotlin.DslMarker public @interface LazyScopeMarker {
   }
 
+  public final class SwitchKt {
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, optional androidx.glance.Modifier modifier, optional String text, optional androidx.glance.text.TextStyle? textStyle);
+  }
+
 }
 
 package androidx.glance.appwidget.translators {
@@ -110,6 +114,9 @@
   public final class CheckBoxTranslatorKt {
   }
 
+  public final class SwitchTranslatorKt {
+  }
+
   public final class TextTranslatorKt {
   }
 
diff --git a/glance/glance-appwidget/build.gradle b/glance/glance-appwidget/build.gradle
index e8d6185..189616b 100644
--- a/glance/glance-appwidget/build.gradle
+++ b/glance/glance-appwidget/build.gradle
@@ -39,6 +39,7 @@
 
     implementation project(path: ':annotation:annotation')
     implementation project(path: ':core:core-remoteviews')
+    implementation project(path: ':core:core-ktx')
     implementation(libs.kotlinStdlib)
 
     testImplementation(project(":core:core-ktx"))
diff --git a/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/LayoutGenerator.kt b/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/LayoutGenerator.kt
index b79fc53..3751bf8 100644
--- a/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/LayoutGenerator.kt
+++ b/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/LayoutGenerator.kt
@@ -128,6 +128,7 @@
                 setNamedItemNS(generated.androidWeight("1"))
             }
             setNamedItemNS(generated.androidLayoutDirection("locale"))
+            setNamedItemNS(generated.androidClipToOutline(true))
         }
         return generated
     }
@@ -227,6 +228,7 @@
                 setNamedItemNS(generated.androidAttr("layout_alignBottom", "@id/sizeView"))
             }
             setNamedItemNS(generated.androidLayoutDirection("locale"))
+            setNamedItemNS(generated.androidClipToOutline(true))
         }
         return generated
     }
@@ -269,6 +271,9 @@
 internal fun Document.androidLayoutDirection(value: String) =
     androidAttr("layoutDirection", value)
 
+internal fun Document.androidClipToOutline(value: Boolean) =
+    androidAttr("clipToOutline", value.toString())
+
 internal val Document.androidNamespace
     get() = createAttribute("xmlns:android").apply {
         textContent = AndroidNS
diff --git a/glance/glance-appwidget/integration-tests/demos/src/main/AndroidManifest.xml b/glance/glance-appwidget/integration-tests/demos/src/main/AndroidManifest.xml
index 57f8c28..c8b9405 100644
--- a/glance/glance-appwidget/integration-tests/demos/src/main/AndroidManifest.xml
+++ b/glance/glance-appwidget/integration-tests/demos/src/main/AndroidManifest.xml
@@ -59,5 +59,17 @@
                 android:name="android.appwidget.provider"
                 android:resource="@xml/check_box_app_widget_info" />
         </receiver>
+
+        <receiver
+            android:name="androidx.glance.appwidget.demos.SwitchAppWidgetReceiver"
+            android:label="@string/switch_widget_name"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+            </intent-filter>
+            <meta-data
+                android:name="android.appwidget.provider"
+                android:resource="@xml/check_box_app_widget_info" />
+        </receiver>
     </application>
 </manifest>
diff --git a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ResponsiveAppWidget.kt b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ResponsiveAppWidget.kt
index 1a9764f..0b1e4fa 100644
--- a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ResponsiveAppWidget.kt
+++ b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ResponsiveAppWidget.kt
@@ -16,12 +16,15 @@
 
 package androidx.glance.appwidget.demos
 
+import android.app.Activity
 import androidx.compose.runtime.Composable
 import androidx.glance.LocalSize
 import androidx.glance.Modifier
+import androidx.glance.action.launchActivityAction
 import androidx.glance.appwidget.GlanceAppWidget
 import androidx.glance.appwidget.GlanceAppWidgetReceiver
 import androidx.glance.appwidget.SizeMode
+import androidx.glance.layout.Button
 import androidx.glance.layout.Column
 import androidx.glance.layout.Row
 import androidx.glance.layout.Text
@@ -69,6 +72,7 @@
                 }
             }
             Text(content)
+            Button("Button", >
         }
     }
 }
diff --git a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/SwitchAppWidget.kt b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/SwitchAppWidget.kt
new file mode 100644
index 0000000..84efdb8
--- /dev/null
+++ b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/SwitchAppWidget.kt
@@ -0,0 +1,61 @@
+/*
+ * 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.glance.appwidget.demos
+
+import androidx.compose.runtime.Composable
+import androidx.glance.LocalSize
+import androidx.glance.appwidget.GlanceAppWidget
+import androidx.glance.appwidget.GlanceAppWidgetReceiver
+import androidx.glance.appwidget.SizeMode
+import androidx.glance.appwidget.layout.LazyColumn
+import androidx.glance.appwidget.layout.Switch
+import androidx.glance.text.FontStyle
+import androidx.glance.text.FontWeight
+import androidx.glance.text.TextStyle
+import androidx.glance.unit.dp
+import androidx.glance.unit.sp
+
+class SwitchAppWidget : GlanceAppWidget() {
+
+    override val sizeMode: SizeMode = SizeMode.Exact
+
+    @Composable
+    override fun Content() {
+        val size = LocalSize.current
+        LazyColumn {
+            item {
+                Switch(checked = size.width >= 100.dp, text = "Switch 1")
+            }
+
+            item {
+                Switch(
+                    checked = size.width < 100.dp,
+                    text = "Switch 2",
+                    textStyle = TextStyle(
+                        fontSize = 16.sp,
+                        fontWeight = FontWeight.Bold,
+                        fontStyle = FontStyle.Italic
+                    )
+                )
+            }
+        }
+    }
+}
+
+class SwitchAppWidgetReceiver : GlanceAppWidgetReceiver() {
+    override val glanceAppWidget = SwitchAppWidget()
+}
\ No newline at end of file
diff --git a/glance/glance-appwidget/integration-tests/demos/src/main/res/values/strings.xml b/glance/glance-appwidget/integration-tests/demos/src/main/res/values/strings.xml
index ea405f9..7d7fd91 100644
--- a/glance/glance-appwidget/integration-tests/demos/src/main/res/values/strings.xml
+++ b/glance/glance-appwidget/integration-tests/demos/src/main/res/values/strings.xml
@@ -21,4 +21,5 @@
     <string name="responsive_widget_title"><u>Responsive</u></string>
     <string name="resizing_widget_name">Resizing Widget</string>
     <string name="check_box_widget_name">CheckBox Widget</string>
+    <string name="switch_widget_name">Switch Widget</string>
 </resources>
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiverTest.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiverTest.kt
similarity index 79%
rename from glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiverTest.kt
rename to glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiverTest.kt
index ab73e01..5dd11fc 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiverTest.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiverTest.kt
@@ -20,25 +20,21 @@
 import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
-import android.os.Looper.getMainLooper
-import android.util.Log
 import androidx.test.core.app.ApplicationProvider
-import androidx.test.filters.FlakyTest
 import androidx.test.filters.MediumTest
+import androidx.test.platform.app.InstrumentationRegistry
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
 import kotlinx.coroutines.CancellationException
 import kotlinx.coroutines.awaitCancellation
 import kotlinx.coroutines.launch
 import org.junit.Test
-import org.junit.runner.RunWith
-import org.robolectric.RobolectricTestRunner
-import org.robolectric.Shadows.shadowOf
+import java.io.FileInputStream
+import java.nio.charset.StandardCharsets
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.TimeUnit
 import java.util.concurrent.atomic.AtomicReference
 
-@RunWith(RobolectricTestRunner::class)
 class CoroutineBroadcastReceiverTest {
 
     private val context = ApplicationProvider.getApplicationContext<Context>()
@@ -55,12 +51,10 @@
                     try {
                         awaitCancellation()
                     } catch (ex: CancellationException) {
-                        Log.i("CoroutineBRTest", "Scope cancelled")
                         scopeCancelled.countDown()
                         throw ex
                     }
                 }
-                Log.i("CoroutineBRTest", "Broadcast executed")
                 broadcastExecuted.countDown()
             }
         }
@@ -68,7 +62,6 @@
 
     @MediumTest
     @Test
-    @FlakyTest
     fun onReceive() {
         val broadcastReceiver = TestBroadcast()
         context.registerReceiver(
@@ -77,8 +70,12 @@
         )
 
         val value = "value"
-        context.sendBroadcast(Intent(BROADCAST_ACTION).putExtra(EXTRA_STRING, value))
-        shadowOf(getMainLooper()).idle()
+        context.sendBroadcast(
+            Intent(BROADCAST_ACTION)
+                .putExtra(EXTRA_STRING, value)
+                .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
+        )
+        waitForBroadcastIdle()
 
         assertWithMessage("Broadcast receiver did not execute")
             .that(broadcastReceiver.broadcastExecuted.await(5, TimeUnit.SECONDS))
@@ -89,6 +86,15 @@
         assertThat(broadcastReceiver.extraValue.get()).isEqualTo(value)
     }
 
+    private fun waitForBroadcastIdle() {
+        val uiAutomation = InstrumentationRegistry.getInstrumentation().uiAutomation
+        val outputFd = uiAutomation.executeShellCommand("am wait-for-broadcast-idle")
+        val output = FileInputStream(outputFd.fileDescriptor).use { it.readBytes() }
+
+        assertThat(String(output, StandardCharsets.US_ASCII))
+            .contains("All broadcast queues are idle!")
+    }
+
     private companion object {
         const val BROADCAST_ACTION = "androidx.glance.appwidget.utils.TEST_ACTION"
         const val EXTRA_STRING = "extra_string"
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverScreenshotTest.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverScreenshotTest.kt
index 6a02d98..a4c138b 100644
--- a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverScreenshotTest.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverScreenshotTest.kt
@@ -18,16 +18,24 @@
 
 import androidx.compose.runtime.Composable
 import androidx.glance.Modifier
+import androidx.glance.background
 import androidx.glance.appwidget.layout.CheckBox
+import androidx.glance.appwidget.layout.Switch
+import androidx.glance.layout.Box
 import androidx.glance.layout.Column
 import androidx.glance.layout.Row
 import androidx.glance.layout.Text
 import androidx.glance.layout.fillMaxWidth
+import androidx.glance.layout.height
+import androidx.glance.layout.padding
+import androidx.glance.layout.width
 import androidx.glance.text.FontStyle
 import androidx.glance.text.FontWeight
 import androidx.glance.text.TextAlign
 import androidx.glance.text.TextDecoration
 import androidx.glance.text.TextStyle
+import androidx.glance.unit.Color
+import androidx.glance.unit.dp
 import androidx.test.filters.MediumTest
 import androidx.test.filters.SdkSuppress
 import org.junit.Rule
@@ -95,6 +103,36 @@
     }
 
     @Test
+    fun createCheckSwitchAppWidget() {
+        TestGlanceAppWidget.uiDefinition = {
+            Column {
+                Switch(
+                    checked = true,
+                    text = "Hello Checked Switch",
+                    textStyle = TextStyle(
+                        fontWeight = FontWeight.Bold,
+                        fontStyle = FontStyle.Normal,
+                    )
+                )
+
+                Switch(
+                    checked = false,
+                    text = "Hello Unchecked Switch",
+                    textStyle = TextStyle(
+                        textDecoration = TextDecoration.Underline,
+                        fontWeight = FontWeight.Medium,
+                        fontStyle = FontStyle.Italic,
+                    )
+                )
+            }
+        }
+
+        mHostRule.startHost()
+
+        mScreenshotRule.checkScreenshot(mHostRule.mHostView, "switchWidget")
+    }
+
+    @Test
     fun createRowWidget() {
         TestGlanceAppWidget.uiDefinition = { RowTest() }
 
@@ -131,6 +169,40 @@
 
         mScreenshotRule.checkScreenshot(mHostRule.mHostView, "textAlignment_rtl")
     }
+
+    @Test
+    fun checkBackgroundColor() {
+        TestGlanceAppWidget.uiDefinition = {
+            Column(modifier = Modifier.background(Color.White)) {
+                Text(
+                    "100x50 and cyan",
+                    modifier = Modifier.width(100.dp).height(50.dp).background(Color.Cyan)
+                )
+                Text(
+                    "Transparent background",
+                    modifier = Modifier.height(50.dp).background(Color.Transparent)
+                )
+                Text(
+                    "wrapx50 and red",
+                    modifier = Modifier.height(50.dp).background(Color.Red)
+                )
+                Text("Below this should be 4 color boxes")
+                Row(modifier = Modifier.padding(8.dp)) {
+                    val colors = listOf(Color.Black, Color.Red, Color.Green, Color.Blue)
+                    repeat(4) {
+                        Box(
+                            modifier = Modifier.width(32.dp).height(32.dp).background(colors[it])
+                        ) {}
+                        Box(modifier = Modifier.width(8.dp).height(1.dp)) {}
+                    }
+                }
+            }
+        }
+
+        mHostRule.startHost()
+
+        mScreenshotRule.checkScreenshot(mHostRule.mHostView, "backgroundColor")
+    }
 }
 
 @Composable
@@ -177,8 +249,10 @@
             style = TextStyle(textAlign = TextAlign.Center),
             modifier = Modifier.defaultWeight()
         )
-        Text("End",
+        Text(
+            "End",
             style = TextStyle(textAlign = TextAlign.End),
-            modifier = Modifier.defaultWeight())
+            modifier = Modifier.defaultWeight()
+        )
     }
 }
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt
index 9cadd02..883b4ebb 100644
--- a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.glance.appwidget
 
+import android.app.Activity
 import android.graphics.Typeface
 import android.os.Build
 import android.text.SpannedString
@@ -23,13 +24,16 @@
 import android.text.style.TextAppearanceSpan
 import android.text.style.UnderlineSpan
 import android.view.View
+import android.widget.Button
 import android.widget.LinearLayout
 import android.widget.RelativeLayout
 import android.widget.TextView
 import androidx.glance.LocalContext
 import androidx.glance.LocalSize
 import androidx.glance.Modifier
+import androidx.glance.action.launchActivityAction
 import androidx.glance.layout.Box
+import androidx.glance.layout.Button
 import androidx.glance.layout.Column
 import androidx.glance.layout.Row
 import androidx.glance.layout.Text
@@ -378,6 +382,23 @@
         }
     }
 
+    @Test
+    fun createButton() {
+        TestGlanceAppWidget.uiDefinition = {
+            Button("Button",  enabled = false)
+        }
+
+        mHostRule.startHost()
+
+        mHostRule.onHostView { hostView ->
+            assertThat(hostView.childCount).isEqualTo(1)
+            val button = assertIs<Button>(hostView.getChildAt(0))
+            assertThat(button.text).isEqualTo("Button")
+            assertThat(button.isEnabled).isFalse()
+            assertThat(button.hasOnClickListeners()).isFalse()
+        }
+    }
+
     // Check there is a single span of the given type and that it passes the [check].
     private inline fun <reified T> SpannedString.checkHasSingleTypedSpan(check: (T) -> Unit) {
         val spans = getSpans(0, length, T::class.java)
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/ResourceResolutionTest.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/ResourceResolutionTest.kt
new file mode 100644
index 0000000..bdb9f6a
--- /dev/null
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/ResourceResolutionTest.kt
@@ -0,0 +1,63 @@
+/*
+ * 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.glance.appwidget
+
+import android.widget.TextView
+import androidx.glance.Modifier
+import androidx.glance.appwidget.test.R
+import androidx.glance.layout.Column
+import androidx.glance.layout.Text
+import androidx.glance.layout.fillMaxSize
+import androidx.glance.layout.width
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import kotlin.test.assertNotNull
+
+@SdkSuppress(minSdkVersion = 29)
+@MediumTest
+class ResourceResolutionTest {
+
+    @get:Rule
+    val mHostRule = AppWidgetHostRule()
+
+    @Test
+    fun resolveFromResources() {
+        TestGlanceAppWidget.uiDefinition = {
+            Column(modifier = Modifier.fillMaxSize()) {
+                Text(
+                    "dimension",
+                    modifier = Modifier.width(R.dimen.testDimension)
+                )
+            }
+        }
+
+        mHostRule.startHost()
+
+        mHostRule.onHostView { hostView ->
+            val textView =
+                assertNotNull(hostView.findChild<TextView> { it.text.toString() == "dimension" })
+            assertThat(textView.measuredWidth).isEqualTo(
+                textView.context.resources.getDimensionPixelSize(
+                    R.dimen.testDimension
+                )
+            )
+        }
+    }
+}
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidAndroidTest/res/values/attrs.xml b/glance/glance-appwidget/src/androidAndroidTest/res/values/attrs.xml
new file mode 100644
index 0000000..f988b62
--- /dev/null
+++ b/glance/glance-appwidget/src/androidAndroidTest/res/values/attrs.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <attr name="dimensionAttr" type="dimension" />
+</resources>
diff --git a/glance/glance-appwidget/src/androidAndroidTest/res/values/dimens.xml b/glance/glance-appwidget/src/androidAndroidTest/res/values/dimens.xml
new file mode 100644
index 0000000..aa5017c
--- /dev/null
+++ b/glance/glance-appwidget/src/androidAndroidTest/res/values/dimens.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <dimen name="testDimension">40dp</dimen>
+</resources>
diff --git a/glance/glance-appwidget/src/androidAndroidTest/res/values/themes.xml b/glance/glance-appwidget/src/androidAndroidTest/res/values/themes.xml
new file mode 100644
index 0000000..efd9192
--- /dev/null
+++ b/glance/glance-appwidget/src/androidAndroidTest/res/values/themes.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <style name="Theme.TestDimensionAttr" parent="">
+        <item name="dimensionAttr">@dimen/testDimension</item>
+    </style>
+</resources>
diff --git a/glance/glance-appwidget/src/androidMain/AndroidManifest.xml b/glance/glance-appwidget/src/androidMain/AndroidManifest.xml
index d3cb1fc..63b320b 100644
--- a/glance/glance-appwidget/src/androidMain/AndroidManifest.xml
+++ b/glance/glance-appwidget/src/androidMain/AndroidManifest.xml
@@ -14,4 +14,16 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
-<manifest package="androidx.glance.appwidget" />
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="androidx.glance.appwidget" >
+    <application>
+        <receiver
+            android:name="androidx.glance.appwidget.ActionRunnableBroadcastReceiver"
+            android:exported="false"
+            android:enabled="true">
+            <intent-filter>
+                <data android:scheme="remoteAction" />
+            </intent-filter>
+        </receiver>
+    </application>
+</manifest>
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/ActionRunnableBroadcastReceiver.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/ActionRunnableBroadcastReceiver.kt
new file mode 100644
index 0000000..ce5df1a
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/ActionRunnableBroadcastReceiver.kt
@@ -0,0 +1,67 @@
+/*
+ * 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.glance.appwidget
+
+import android.app.PendingIntent
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import androidx.glance.action.ActionRunnable
+import androidx.glance.action.UpdateAction
+
+/**
+ * Responds to broadcasts from [UpdateAction] clicks by executing the associated action.
+ */
+internal class ActionRunnableBroadcastReceiver : BroadcastReceiver() {
+
+    override fun onReceive(context: Context?, intent: Intent?) {
+        if (intent == null || context == null) {
+            return
+        }
+
+        goAsync {
+            val className = requireNotNull(intent.getStringExtra(ExtraClassName)) {
+                "The custom work intent must contain a work class name string using extra: " +
+                    ExtraClassName
+            }
+            UpdateAction.run(context, className)
+        }
+    }
+
+    companion object {
+        private const val ExtraClassName = "CustomWorkBroadcastReceiver:className"
+
+        fun createPendingIntent(
+            context: Context,
+            runnableClass: Class<out ActionRunnable>
+        ): PendingIntent {
+            return PendingIntent.getBroadcast(
+                context,
+                0,
+                Intent(context, ActionRunnableBroadcastReceiver::class.java)
+                    .setPackage(context.packageName)
+                    .putExtra(ExtraClassName, runnableClass.canonicalName)
+                    .setData(Uri.Builder()
+                        .scheme("remoteAction")
+                        .appendQueryParameter("className", runnableClass.canonicalName)
+                        .build()),
+                PendingIntent.FLAG_MUTABLE
+            )
+        }
+    }
+}
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/ApplyModifiers.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/ApplyModifiers.kt
index f68a8a5..354f469 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/ApplyModifiers.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/ApplyModifiers.kt
@@ -19,25 +19,67 @@
 import android.app.PendingIntent
 import android.content.Context
 import android.content.Intent
-import android.content.res.Resources
 import android.os.Build
 import android.util.TypedValue
 import android.view.ViewGroup
 import android.widget.RemoteViews
+import androidx.annotation.ColorInt
 import androidx.annotation.DoNotInline
 import androidx.annotation.IdRes
 import androidx.annotation.RequiresApi
 import androidx.core.widget.setTextViewHeight
 import androidx.core.widget.setTextViewWidth
+import androidx.core.widget.setViewBackgroundColor
+import androidx.glance.BackgroundModifier
 import androidx.glance.Modifier
 import androidx.glance.action.Action
 import androidx.glance.action.ActionModifier
 import androidx.glance.action.LaunchActivityAction
+import androidx.glance.action.UpdateAction
 import androidx.glance.layout.Dimension
 import androidx.glance.layout.HeightModifier
 import androidx.glance.layout.PaddingModifier
 import androidx.glance.layout.WidthModifier
+import androidx.glance.unit.Color
 import androidx.glance.unit.dp
+import kotlin.math.roundToInt
+
+internal fun applyModifiers(
+    translationContext: TranslationContext,
+    rv: RemoteViews,
+    modifiers: Modifier,
+    layoutDef: LayoutIds
+) {
+    val context = translationContext.context
+    modifiers.foldOut(Unit) { modifier, _ ->
+        when (modifier) {
+            is ActionModifier -> applyAction(rv, modifier.action, context, layoutDef.mainViewId)
+            is PaddingModifier -> applyPadding(
+                rv,
+                modifier,
+                translationContext,
+                layoutDef.mainViewId
+            )
+            is WidthModifier -> applyWidthModifier(
+                rv,
+                modifier,
+                context,
+                layoutDef
+            )
+            is HeightModifier -> applyHeightModifier(
+                rv,
+                modifier,
+                context,
+                layoutDef
+            )
+            is BackgroundModifier -> applyBackgroundModifier(
+                rv,
+                modifier,
+                layoutDef
+            )
+        }
+    }
+}
 
 private fun applyAction(
     rv: RemoteViews,
@@ -57,6 +99,11 @@
                 )
             rv.setOnClickPendingIntent(viewId, pendingIntent)
         }
+        is UpdateAction -> {
+            val pendingIntent =
+                ActionRunnableBroadcastReceiver.createPendingIntent(context, action.runnableClass)
+            rv.setOnClickPendingIntent(viewId, pendingIntent)
+        }
         else -> throw IllegalArgumentException("Unrecognized action type.")
     }
 }
@@ -80,42 +127,10 @@
     )
 }
 
-internal fun applyModifiers(
-    translationContext: TranslationContext,
-    rv: RemoteViews,
-    modifiers: Modifier,
-    layoutDef: LayoutIds
-) {
-    val context = translationContext.context
-    modifiers.foldOut(Unit) { modifier, _ ->
-        when (modifier) {
-            is ActionModifier -> applyAction(rv, modifier.action, context, layoutDef.mainViewId)
-            is PaddingModifier -> applyPadding(
-                rv,
-                modifier,
-                translationContext,
-                layoutDef.mainViewId
-            )
-            is WidthModifier -> applyWidthModifier(
-                rv,
-                modifier,
-                context.resources,
-                layoutDef
-            )
-            is HeightModifier -> applyHeightModifier(
-                rv,
-                modifier,
-                context.resources,
-                layoutDef
-            )
-        }
-    }
-}
-
 private fun applyWidthModifier(
     rv: RemoteViews,
     modifier: WidthModifier,
-    resources: Resources,
+    context: Context,
     layoutDef: LayoutIds?,
 ) {
     checkNotNull(layoutDef) { "No layout spec, cannot change size" }
@@ -127,16 +142,33 @@
         }
         return
     }
-    val width = modifier.width
-    if (width !is Dimension.Dp) return
+    val widthPx = modifier.width.toPixels(context)
+    // Sizes in pixel must be >= 0 to be valid
+    if (widthPx < 0) return
     checkNotNull(layoutDef.sizeViewId) { "The layout specified does not allow specifying the size" }
-    rv.setTextViewWidth(layoutDef.sizeViewId, width.dp.toPixels(resources.displayMetrics))
+    rv.setTextViewWidth(layoutDef.sizeViewId, widthPx)
+}
+
+/**
+ * Returns the dimension, in pixels, from the given context or a negative value if the Dimension is
+ * not in Pixels (i.e. Wrap, Fill or Expand).
+ *
+ * @return the size in Pixel, or a negative number if the dimension cannot be computed (e.g.
+ * set by choosing the correct layout).
+ */
+private fun Dimension.toPixels(context: Context): Int {
+    val resources = context.resources
+    return when (this) {
+        is Dimension.Dp -> dp.toPixels(resources.displayMetrics)
+        is Dimension.Resource -> resources.getDimensionPixelSize(res)
+        else -> -1
+    }
 }
 
 private fun applyHeightModifier(
     rv: RemoteViews,
     modifier: HeightModifier,
-    resources: Resources,
+    context: Context,
     layoutDef: LayoutIds?,
 ) {
     checkNotNull(layoutDef) { "No layout spec, cannot change size" }
@@ -148,10 +180,31 @@
         }
         return
     }
-    val height = modifier.height
-    if (height !is Dimension.Dp) return
+    val heightPx = modifier.height.toPixels(context)
+    if (heightPx < 0) return
     checkNotNull(layoutDef.sizeViewId) { "The layout specified does not allow specifying the size" }
-    rv.setTextViewHeight(layoutDef.sizeViewId, height.dp.toPixels(resources.displayMetrics))
+    rv.setTextViewHeight(layoutDef.sizeViewId, heightPx)
+}
+
+private fun applyBackgroundModifier(
+    rv: RemoteViews,
+    modifier: BackgroundModifier,
+    layoutDef: LayoutIds
+) {
+    rv.setViewBackgroundColor(layoutDef.mainViewId, modifier.color.toArgb())
+}
+
+// TODO(b/202150620): Use the shared Compose utility when we use the same Color class.
+@ColorInt
+private fun Color.toArgb(): Int {
+    // Converts a value from a float in [0,1] to an int in [0x00,0xFF].
+    fun Float.toColorComponent() = (this * 0xFF).roundToInt()
+    return android.graphics.Color.argb(
+        /* alpha= */ alpha.toColorComponent(),
+        /* red= */ red.toColorComponent(),
+        /* green= */ green.toColorComponent(),
+        /* blue= */ blue.toColorComponent()
+    )
 }
 
 @RequiresApi(Build.VERSION_CODES.S)
@@ -176,6 +229,7 @@
             is Dimension.Dp -> {
                 rv.setViewLayoutWidth(viewId, width.dp.value, TypedValue.COMPLEX_UNIT_DIP)
             }
+            is Dimension.Resource -> rv.setViewLayoutWidthDimen(viewId, width.res)
         }
     }
 
@@ -199,6 +253,7 @@
             is Dimension.Dp -> {
                 rv.setViewLayoutHeight(viewId, height.dp.value, TypedValue.COMPLEX_UNIT_DIP)
             }
+            is Dimension.Resource -> rv.setViewLayoutHeightDimen(viewId, height.res)
         }
     }
 }
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiver.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiver.kt
index aa10381..627d532 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiver.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiver.kt
@@ -39,10 +39,16 @@
 
     coroutineScope.launch {
         try {
-            block()
+            try {
+                block()
+            } finally {
+                // Nothing can be in the `finally` block after this, as this throws a
+                // `CancellationException`
+                coroutineScope.cancel()
+            }
         } finally {
+            // This must be the last call, as the process may be killed after calling this.
             pendingResult.finish()
-            coroutineScope.cancel()
         }
     }
 }
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/LayoutIds.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/LayoutIds.kt
index fa6b5fd..d5e7dad 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/LayoutIds.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/LayoutIds.kt
@@ -16,12 +16,15 @@
 
 package androidx.glance.appwidget
 
+import android.content.Context
 import android.os.Build
+import android.view.ViewGroup
 import androidx.glance.Modifier
 import androidx.glance.findModifier
 import androidx.glance.layout.Dimension
 import androidx.glance.layout.HeightModifier
 import androidx.glance.layout.WidthModifier
+import androidx.glance.unit.dp
 
 /**
  * Set of ids defining a layout.
@@ -64,7 +67,11 @@
         List3,
         ListItem,
         CheckBox,
-        CheckBoxBackport
+        CheckBoxBackport,
+        Button,
+        // Note: Java keywords, such as 'switch', can't be used for layout ids.
+        Swtch,
+        SwtchBackport
     }
 }
 
@@ -76,17 +83,19 @@
  * the layout they can be applied on.
  */
 internal fun selectLayout(
+    translationContext: TranslationContext,
     type: LayoutSelector.Type,
     modifier: Modifier
 ): LayoutIds {
+    val context = translationContext.context
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
         return selectApi31Layout(type, modifier)
     }
     val widthMod = modifier.findModifier<WidthModifier>()?.width ?: Dimension.Wrap
     val heightMod = modifier.findModifier<HeightModifier>()?.height ?: Dimension.Wrap
-    val needResize = widthMod is Dimension.Dp || heightMod is Dimension.Dp
-    val width = widthMod.toSpecSize()
-    val height = heightMod.toSpecSize()
+    val width = widthMod.resolveDimension(context).toSpecSize()
+    val height = heightMod.resolveDimension(context).toSpecSize()
+    val needResize = width == LayoutSelector.Size.Fixed || height == LayoutSelector.Size.Fixed
     return generatedLayouts[LayoutSelector(type, width, height, needResize)]
         ?: (if (!needResize) generatedLayouts[LayoutSelector(type, width, height, true)] else null)
         ?: throw IllegalArgumentException(
@@ -100,8 +109,19 @@
         is Dimension.Wrap -> LayoutSelector.Size.Wrap
         is Dimension.Expand -> LayoutSelector.Size.Expand
         is Dimension.Fill -> LayoutSelector.Size.MatchParent
+        else -> LayoutSelector.Size.Fixed
     }
 
+private fun Dimension.resolveDimension(context: Context): Dimension {
+    if (this !is Dimension.Resource) return this
+    val sizePx = context.resources.getDimension(res)
+    return when (sizePx.toInt()) {
+        ViewGroup.LayoutParams.MATCH_PARENT -> Dimension.Fill
+        ViewGroup.LayoutParams.WRAP_CONTENT -> Dimension.Wrap
+        else -> Dimension.Dp((sizePx / context.resources.displayMetrics.density).dp)
+    }
+}
+
 /**
  * For API 31, we will always select layouts marked as non-resizable, as starting Android S, we
  * can always resize views and we want the simplest layout possible.
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RemoteLazyListViewsTranslator.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RemoteLazyListViewsTranslator.kt
index 1b138c3..5eccb97 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RemoteLazyListViewsTranslator.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RemoteLazyListViewsTranslator.kt
@@ -36,8 +36,7 @@
             lists provide a non-composable [RemoteViews].
             """.trimIndent()
         }
-    val listLayout =
-        selectLayout(listLayoutType, element.modifier)
+    val listLayout = selectLayout(translationContext, listLayoutType, element.modifier)
     return translateEmittableLazyList(
         translationContext,
         element,
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RemoteViewsTranslator.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RemoteViewsTranslator.kt
index a0a3605..f9525dd 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RemoteViewsTranslator.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RemoteViewsTranslator.kt
@@ -32,10 +32,14 @@
 import androidx.glance.appwidget.layout.EmittableCheckBox
 import androidx.glance.appwidget.layout.EmittableLazyColumn
 import androidx.glance.appwidget.layout.EmittableLazyListItem
+import androidx.glance.appwidget.layout.EmittableSwitch
 import androidx.glance.appwidget.translators.translateEmittableCheckBox
+import androidx.glance.appwidget.translators.translateEmittableSwitch
 import androidx.glance.appwidget.translators.translateEmittableText
+import androidx.glance.appwidget.translators.setText
 import androidx.glance.layout.Alignment
 import androidx.glance.layout.EmittableBox
+import androidx.glance.layout.EmittableButton
 import androidx.glance.layout.EmittableColumn
 import androidx.glance.layout.EmittableRow
 import androidx.glance.layout.EmittableText
@@ -81,6 +85,7 @@
 ): RemoteViews {
     return when (element) {
         is EmittableBox -> translateEmittableBox(translationContext, element)
+        is EmittableButton -> translateEmittableButton(translationContext, element)
         is EmittableRow -> translateEmittableRow(translationContext, element)
         is EmittableColumn -> translateEmittableColumn(translationContext, element)
         is EmittableText -> translateEmittableText(translationContext, element)
@@ -90,6 +95,7 @@
             translateEmittableAndroidRemoteViews(translationContext, element)
         }
         is EmittableCheckBox -> translateEmittableCheckBox(translationContext, element)
+        is EmittableSwitch -> translateEmittableSwitch(translationContext, element)
         else -> throw IllegalArgumentException("Unknown element type ${element::javaClass}")
     }
 }
@@ -119,8 +125,7 @@
     translationContext: TranslationContext,
     element: EmittableBox
 ): RemoteViews {
-    val layoutDef =
-        selectLayout(LayoutSelector.Type.Box, element.modifier)
+    val layoutDef = selectLayout(translationContext, LayoutSelector.Type.Box, element.modifier)
     return remoteViews(translationContext, layoutDef.layoutId)
         .also { rv ->
             rv.setRelativeLayoutGravity(layoutDef.mainViewId, element.contentAlignment.toGravity())
@@ -142,8 +147,7 @@
     translationContext: TranslationContext,
     element: EmittableRow
 ): RemoteViews {
-    val layoutDef =
-        selectLayout(LayoutSelector.Type.Row, element.modifier)
+    val layoutDef = selectLayout(translationContext, LayoutSelector.Type.Row, element.modifier)
     return remoteViews(translationContext, layoutDef.layoutId)
         .also { rv ->
             rv.setLinearLayoutGravity(
@@ -168,8 +172,7 @@
     translationContext: TranslationContext,
     element: EmittableColumn
 ): RemoteViews {
-    val layoutDef =
-        selectLayout(LayoutSelector.Type.Column, element.modifier)
+    val layoutDef = selectLayout(translationContext, LayoutSelector.Type.Column, element.modifier)
     return remoteViews(translationContext, layoutDef.layoutId)
         .also { rv ->
             rv.setLinearLayoutGravity(
@@ -209,6 +212,25 @@
     return element.remoteViews
 }
 
+private fun translateEmittableButton(
+    translationContext: TranslationContext,
+    element: EmittableButton
+): RemoteViews {
+    val layoutDef =
+        selectLayout(translationContext, LayoutSelector.Type.Button, element.modifier)
+    return remoteViews(translationContext, layoutDef.layoutId)
+        .also { rv ->
+            rv.setText(
+                translationContext,
+                layoutDef.mainViewId,
+                element.text,
+                element.style
+            )
+            rv.setBoolean(layoutDef.mainViewId, "setEnabled", element.enabled)
+            applyModifiers(translationContext, rv, element.modifier, layoutDef)
+        }
+}
+
 // Sets the emittables as children to the view. This first remove any previously added view, the
 // add a view per child, with a stable id if of Android S+. Currently the stable id is the index
 // of the child in the iterable.
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/Utils.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/Utils.kt
index 40f8c9d5..78334dd 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/Utils.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/Utils.kt
@@ -18,6 +18,7 @@
 
 import android.util.DisplayMetrics
 import android.util.TypedValue
+import android.widget.RemoteViews
 import androidx.glance.unit.Dp
 import androidx.glance.unit.dp
 
@@ -25,4 +26,12 @@
     TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, displayMetrics).toInt()
 
 internal fun Int.pixelsToDp(displayMetrics: DisplayMetrics) =
-    (this / displayMetrics.density).dp
\ No newline at end of file
+    (this / displayMetrics.density).dp
+
+/**
+ * KTX for calling `setEnabled` on a View. Note that this is **not safe on TextViews (and
+ * descendants) before API 24**, but it is safe for any other view type.
+ */
+internal fun RemoteViews.setViewEnabled(viewId: Int, enabled: Boolean) {
+    setBoolean(viewId, "setEnabled", enabled)
+}
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/layout/CheckBox.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/layout/CheckBox.kt
index 5a85930..f0c4d6a 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/layout/CheckBox.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/layout/CheckBox.kt
@@ -25,6 +25,11 @@
 
 /**
  * Adds a check box view to the glance view.
+ *
+ * @param checked whether the check box is checked.
+ * @param modifier the modifier to apply to the check box.
+ * @param text the text to display to the end of the check box.
+ * @param textStyle the style to apply to [text].
  */
 @Composable
 public fun CheckBox(
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/layout/Switch.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/layout/Switch.kt
new file mode 100644
index 0000000..8a7a493
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/layout/Switch.kt
@@ -0,0 +1,64 @@
+/*
+ * 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.glance.appwidget.layout
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.ComposeNode
+import androidx.glance.Applier
+import androidx.glance.Emittable
+import androidx.glance.Modifier
+import androidx.glance.text.TextStyle
+
+/**
+ * Adds a switch view to the glance view.
+ *
+ * @param checked whether the switch is checked.
+ * @param modifier the modifier to apply to the switch.
+ * @param text the text to display to the end of the switch.
+ * @param textStyle the style to apply to [text].
+ */
+@Composable
+fun Switch(
+    checked: Boolean,
+    modifier: Modifier = Modifier,
+    text: String = "",
+    textStyle: TextStyle? = null
+) {
+    ComposeNode<EmittableSwitch, Applier>(
+        factory = ::EmittableSwitch,
+        update = {
+            this.set(checked) { this.checked = it }
+            this.set(text) { this.text = it }
+            this.set(modifier) { this.modifier = it }
+            this.set(textStyle) { this.textStyle = it }
+        }
+    )
+}
+
+internal class EmittableSwitch : Emittable {
+    override var modifier: Modifier = Modifier
+    var checked: Boolean = false
+    var text: String = ""
+    var textStyle: TextStyle? = null
+
+    override fun toString(): String = "EmittableSwitch(" +
+        "$text, " +
+        "checked=$checked, " +
+        "textStyle=$textStyle, " +
+        "modifier=$modifier" +
+        ")"
+}
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/CheckBoxTranslator.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/CheckBoxTranslator.kt
index 46454cd..fe66d44 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/CheckBoxTranslator.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/CheckBoxTranslator.kt
@@ -18,8 +18,6 @@
 
 import android.os.Build
 import android.widget.RemoteViews
-import androidx.annotation.DoNotInline
-import androidx.annotation.RequiresApi
 import androidx.glance.appwidget.LayoutSelector
 import androidx.glance.appwidget.R
 import androidx.glance.appwidget.TranslationContext
@@ -27,6 +25,7 @@
 import androidx.glance.appwidget.layout.EmittableCheckBox
 import androidx.glance.appwidget.remoteViews
 import androidx.glance.appwidget.selectLayout
+import androidx.glance.appwidget.setViewEnabled
 
 internal fun translateEmittableCheckBox(
     translationContext: TranslationContext,
@@ -39,34 +38,23 @@
         LayoutSelector.Type.CheckBoxBackport
     }
 
-    val layoutDef = selectLayout(layoutType, element.modifier)
+    val layoutDef = selectLayout(translationContext, layoutType, element.modifier)
     val rv = remoteViews(translationContext, layoutDef.layoutId)
     val textViewId: Int
 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
         textViewId = layoutDef.mainViewId
-        CheckBoxTranslatorApi31Impl.setCompoundButtonChecked(
+        CompoundButtonApi31Impl.setCompoundButtonChecked(
             rv,
             layoutDef.mainViewId,
             element.checked
         )
     } else {
         textViewId = R.id.checkBoxText
-        // Special case for needing the reflection method. View.setEnabled is only safe on
-        // TextViews from API 24, but is safe for other views before that, which is why
-        // RemoteViews.kt sets required api 24 on setViewEnabled.
-        rv.setBoolean(R.id.checkBoxIcon, "setEnabled", element.checked)
+        rv.setViewEnabled(R.id.checkBoxIcon, element.checked)
     }
 
     rv.setText(translationContext, textViewId, element.text, element.textStyle)
     applyModifiers(translationContext, rv, element.modifier, layoutDef)
     return rv
 }
-
-@RequiresApi(Build.VERSION_CODES.S)
-private object CheckBoxTranslatorApi31Impl {
-    @DoNotInline
-    fun setCompoundButtonChecked(rv: RemoteViews, viewId: Int, checked: Boolean) {
-        rv.setCompoundButtonChecked(viewId, checked)
-    }
-}
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/CompoundButtonApi31Impl.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/CompoundButtonApi31Impl.kt
new file mode 100644
index 0000000..c4b04e0
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/CompoundButtonApi31Impl.kt
@@ -0,0 +1,30 @@
+/*
+ * 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.glance.appwidget.translators
+
+import android.os.Build
+import android.widget.RemoteViews
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.S)
+internal object CompoundButtonApi31Impl {
+    @DoNotInline
+    fun setCompoundButtonChecked(rv: RemoteViews, viewId: Int, checked: Boolean) {
+        rv.setCompoundButtonChecked(viewId, checked)
+    }
+}
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/SwitchTranslator.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/SwitchTranslator.kt
new file mode 100644
index 0000000..58b5c12
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/SwitchTranslator.kt
@@ -0,0 +1,61 @@
+/*
+ * 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.glance.appwidget.translators
+
+import android.os.Build
+import android.widget.RemoteViews
+import androidx.glance.appwidget.LayoutSelector
+import androidx.glance.appwidget.R
+import androidx.glance.appwidget.TranslationContext
+import androidx.glance.appwidget.applyModifiers
+import androidx.glance.appwidget.layout.EmittableSwitch
+import androidx.glance.appwidget.remoteViews
+import androidx.glance.appwidget.selectLayout
+import androidx.glance.appwidget.setViewEnabled
+
+internal fun translateEmittableSwitch(
+    translationContext: TranslationContext,
+    element: EmittableSwitch
+): RemoteViews {
+
+    val layoutType = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+        LayoutSelector.Type.Swtch
+    } else {
+        LayoutSelector.Type.SwtchBackport
+    }
+
+    val layoutDef = selectLayout(translationContext, layoutType, element.modifier)
+    val rv = remoteViews(translationContext, layoutDef.layoutId)
+    val textViewId: Int
+
+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+        textViewId = layoutDef.mainViewId
+        CompoundButtonApi31Impl.setCompoundButtonChecked(
+            rv,
+            layoutDef.mainViewId,
+            element.checked
+        )
+    } else {
+        textViewId = R.id.switchText
+        rv.setViewEnabled(R.id.switchThumb, element.checked)
+        rv.setViewEnabled(R.id.switchTrack, element.checked)
+    }
+
+    rv.setText(translationContext, textViewId, element.text, element.textStyle)
+    applyModifiers(translationContext, rv, element.modifier, layoutDef)
+    return rv
+}
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/TextTranslator.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/TextTranslator.kt
index 23d3f49..1b48778 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/TextTranslator.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/TextTranslator.kt
@@ -50,7 +50,7 @@
     translationContext: TranslationContext,
     element: EmittableText
 ): RemoteViews {
-    val layoutDef = selectLayout(LayoutSelector.Type.Text, element.modifier)
+    val layoutDef = selectLayout(translationContext, LayoutSelector.Type.Text, element.modifier)
     return remoteViews(translationContext, layoutDef.layoutId)
         .also { rv ->
             rv.setText(
diff --git a/glance/glance-appwidget/src/androidMain/layoutTemplates/button.xml b/glance/glance-appwidget/src/androidMain/layoutTemplates/button.xml
new file mode 100644
index 0000000..9801e42
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/layoutTemplates/button.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<Button />
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/layoutTemplates/swtch.xml b/glance/glance-appwidget/src/androidMain/layoutTemplates/swtch.xml
new file mode 100644
index 0000000..b4e199b
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/layoutTemplates/swtch.xml
@@ -0,0 +1,18 @@
+<?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.
+  -->
+
+<Switch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:textDirection="locale" />
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/layoutTemplates/swtch_backport.xml b/glance/glance-appwidget/src/androidMain/layoutTemplates/swtch_backport.xml
new file mode 100644
index 0000000..46d43e4
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/layoutTemplates/swtch_backport.xml
@@ -0,0 +1,43 @@
+<?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.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:gravity="center">
+    <TextView
+        android:id="@id/switchText"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:textDirection="locale"/>
+    <FrameLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+        <ImageView
+            android:id="@id/switchTrack"
+            android:layout_width="42dp"
+            android:layout_height="28dp"
+            android:src="@drawable/switch_track_material"/>
+
+        <ImageView
+            android:id="@id/switchThumb"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical|start"
+            android:src="@drawable/switch_thumb_material"
+            android:tint="@color/switch_thumb_material"/>
+    </FrameLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/res/color-night/switch_thumb_material.xml b/glance/glance-appwidget/src/androidMain/res/color-night/switch_thumb_material.xml
new file mode 100644
index 0000000..ec16d65
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/color-night/switch_thumb_material.xml
@@ -0,0 +1,22 @@
+<?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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="true"
+        android:color="?android:attr/colorControlActivated" />
+    <item android:color="@color/switch_thumb_normal_material_dark" />
+</selector>
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/res/color/switch_thumb_material.xml b/glance/glance-appwidget/src/androidMain/res/color/switch_thumb_material.xml
new file mode 100644
index 0000000..4b1ed0c
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/color/switch_thumb_material.xml
@@ -0,0 +1,22 @@
+<?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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="true"
+        android:color="?android:attr/colorControlActivated" />
+    <item android:color="@color/switch_thumb_normal_material_light" />
+</selector>
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/res/color/switch_track_material.xml b/glance/glance-appwidget/src/androidMain/res/color/switch_track_material.xml
new file mode 100644
index 0000000..3d088e3
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/color/switch_track_material.xml
@@ -0,0 +1,22 @@
+<?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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="true"
+        android:color="?android:attr/colorControlActivated" />
+    <item android:color="?android:attr/colorForeground" />
+</selector>
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/res/color/white_disabled_material_anim.xml b/glance/glance-appwidget/src/androidMain/res/color/white_disabled_material_anim.xml
new file mode 100644
index 0000000..a8de78e
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/color/white_disabled_material_anim.xml
@@ -0,0 +1,21 @@
+<?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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="@android:color/white"
+        android:alpha="?android:attr/disabledAlpha" />
+</selector>
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/res/drawable-hdpi/abc_btn_switch_to_on_mtrl_00001.9.png b/glance/glance-appwidget/src/androidMain/res/drawable-hdpi/abc_btn_switch_to_on_mtrl_00001.9.png
new file mode 100644
index 0000000..4657a25
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/drawable-hdpi/abc_btn_switch_to_on_mtrl_00001.9.png
Binary files differ
diff --git a/glance/glance-appwidget/src/androidMain/res/drawable-hdpi/abc_btn_switch_to_on_mtrl_00012.9.png b/glance/glance-appwidget/src/androidMain/res/drawable-hdpi/abc_btn_switch_to_on_mtrl_00012.9.png
new file mode 100644
index 0000000..8dc415b
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/drawable-hdpi/abc_btn_switch_to_on_mtrl_00012.9.png
Binary files differ
diff --git a/glance/glance-appwidget/src/androidMain/res/drawable-ldrtl/switch_thumb_material_checked.xml b/glance/glance-appwidget/src/androidMain/res/drawable-ldrtl/switch_thumb_material_checked.xml
new file mode 100644
index 0000000..987c157
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/drawable-ldrtl/switch_thumb_material_checked.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/abc_btn_switch_to_on_mtrl_00012"
+    android:insetRight="18dp"/>
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/res/drawable-ldrtl/switch_thumb_material_unchecked.xml b/glance/glance-appwidget/src/androidMain/res/drawable-ldrtl/switch_thumb_material_unchecked.xml
new file mode 100644
index 0000000..d2d35b7
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/drawable-ldrtl/switch_thumb_material_unchecked.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/abc_btn_switch_to_on_mtrl_00001"
+    android:insetLeft="18dp"/>
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/res/drawable-mdpi/abc_btn_switch_to_on_mtrl_00001.9.png b/glance/glance-appwidget/src/androidMain/res/drawable-mdpi/abc_btn_switch_to_on_mtrl_00001.9.png
new file mode 100644
index 0000000..d0a41a5
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/drawable-mdpi/abc_btn_switch_to_on_mtrl_00001.9.png
Binary files differ
diff --git a/glance/glance-appwidget/src/androidMain/res/drawable-mdpi/abc_btn_switch_to_on_mtrl_00012.9.png b/glance/glance-appwidget/src/androidMain/res/drawable-mdpi/abc_btn_switch_to_on_mtrl_00012.9.png
new file mode 100644
index 0000000..bebb1e2
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/drawable-mdpi/abc_btn_switch_to_on_mtrl_00012.9.png
Binary files differ
diff --git a/glance/glance-appwidget/src/androidMain/res/drawable-xhdpi/abc_btn_switch_to_on_mtrl_00001.9.png b/glance/glance-appwidget/src/androidMain/res/drawable-xhdpi/abc_btn_switch_to_on_mtrl_00001.9.png
new file mode 100644
index 0000000..1d29f9a
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/drawable-xhdpi/abc_btn_switch_to_on_mtrl_00001.9.png
Binary files differ
diff --git a/glance/glance-appwidget/src/androidMain/res/drawable-xhdpi/abc_btn_switch_to_on_mtrl_00012.9.png b/glance/glance-appwidget/src/androidMain/res/drawable-xhdpi/abc_btn_switch_to_on_mtrl_00012.9.png
new file mode 100644
index 0000000..92b43ba
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/drawable-xhdpi/abc_btn_switch_to_on_mtrl_00012.9.png
Binary files differ
diff --git a/glance/glance-appwidget/src/androidMain/res/drawable-xxhdpi/abc_btn_switch_to_on_mtrl_00001.9.png b/glance/glance-appwidget/src/androidMain/res/drawable-xxhdpi/abc_btn_switch_to_on_mtrl_00001.9.png
new file mode 100644
index 0000000..c079867
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/drawable-xxhdpi/abc_btn_switch_to_on_mtrl_00001.9.png
Binary files differ
diff --git a/glance/glance-appwidget/src/androidMain/res/drawable-xxhdpi/abc_btn_switch_to_on_mtrl_00012.9.png b/glance/glance-appwidget/src/androidMain/res/drawable-xxhdpi/abc_btn_switch_to_on_mtrl_00012.9.png
new file mode 100644
index 0000000..3b9dc7c
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/drawable-xxhdpi/abc_btn_switch_to_on_mtrl_00012.9.png
Binary files differ
diff --git a/glance/glance-appwidget/src/androidMain/res/drawable-xxxhdpi/abc_btn_switch_to_on_mtrl_00001.9.png b/glance/glance-appwidget/src/androidMain/res/drawable-xxxhdpi/abc_btn_switch_to_on_mtrl_00001.9.png
new file mode 100644
index 0000000..639e6cb
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/drawable-xxxhdpi/abc_btn_switch_to_on_mtrl_00001.9.png
Binary files differ
diff --git a/glance/glance-appwidget/src/androidMain/res/drawable-xxxhdpi/abc_btn_switch_to_on_mtrl_00012.9.png b/glance/glance-appwidget/src/androidMain/res/drawable-xxxhdpi/abc_btn_switch_to_on_mtrl_00012.9.png
new file mode 100644
index 0000000..355d5b7
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/drawable-xxxhdpi/abc_btn_switch_to_on_mtrl_00012.9.png
Binary files differ
diff --git a/glance/glance-appwidget/src/androidMain/res/drawable/switch_thumb_material.xml b/glance/glance-appwidget/src/androidMain/res/drawable/switch_thumb_material.xml
new file mode 100644
index 0000000..939b1c2
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/drawable/switch_thumb_material.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="true" android:drawable="@drawable/switch_thumb_material_checked" />
+    <item android:drawable="@drawable/switch_thumb_material_unchecked" />
+</selector>
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/res/drawable/switch_thumb_material_checked.xml b/glance/glance-appwidget/src/androidMain/res/drawable/switch_thumb_material_checked.xml
new file mode 100644
index 0000000..ece7ee7
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/drawable/switch_thumb_material_checked.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/abc_btn_switch_to_on_mtrl_00012"
+    android:insetLeft="18dp"/>
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/res/drawable/switch_thumb_material_unchecked.xml b/glance/glance-appwidget/src/androidMain/res/drawable/switch_thumb_material_unchecked.xml
new file mode 100644
index 0000000..a151ef9
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/drawable/switch_thumb_material_unchecked.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/abc_btn_switch_to_on_mtrl_00001"
+    android:insetRight="18dp"/>
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/res/drawable/switch_track_material.xml b/glance/glance-appwidget/src/androidMain/res/drawable/switch_track_material.xml
new file mode 100644
index 0000000..8dff91a
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/drawable/switch_track_material.xml
@@ -0,0 +1,28 @@
+<?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.
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:gravity="center_vertical|fill_horizontal"
+        android:start="4dp"
+        android:end="4dp">
+        <shape android:shape="rectangle"
+            android:tint="@color/switch_track_material">
+            <corners android:radius="7dp" />
+            <solid android:color="@color/white_disabled_material_anim" />
+            <size android:height="14dp" />
+        </shape>
+    </item>
+</layer-list>
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/res/values/colors.xml b/glance/glance-appwidget/src/androidMain/res/values/colors.xml
new file mode 100644
index 0000000..3556757
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/res/values/colors.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <color name="switch_thumb_normal_material_dark">#ffbdbdbd</color>
+    <color name="switch_thumb_normal_material_light">#fff1f1f1</color>
+    <color name="switch_thumb_disabled_material_dark">#ff616161</color>
+    <color name="switch_thumb_disabled_material_light">#ffbdbdbd</color>
+</resources>
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/res/values/ids.xml b/glance/glance-appwidget/src/androidMain/res/values/ids.xml
index 4989b42..f6750d1 100644
--- a/glance/glance-appwidget/src/androidMain/res/values/ids.xml
+++ b/glance/glance-appwidget/src/androidMain/res/values/ids.xml
@@ -23,4 +23,7 @@
     <id name="glanceListView3"/>
     <id name="relativeLayout"/>
     <id name="sizeView"/>
+    <id name="switchText"/>
+    <id name="switchTrack"/>
+    <id name="switchThumb"/>
 </resources>
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/ApplyDimensionModifierTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/ApplyDimensionModifierTest.kt
new file mode 100644
index 0000000..cfb3b36
--- /dev/null
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/ApplyDimensionModifierTest.kt
@@ -0,0 +1,214 @@
+/*
+ * 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.glance.appwidget
+
+import android.content.Context
+import android.os.Build
+import android.view.ViewGroup
+import android.widget.LinearLayout
+import android.widget.TextView
+import androidx.glance.Modifier
+import androidx.glance.appwidget.test.R
+import androidx.glance.layout.Column
+import androidx.glance.layout.Row
+import androidx.glance.layout.Text
+import androidx.glance.layout.fillMaxHeight
+import androidx.glance.layout.fillMaxWidth
+import androidx.glance.layout.height
+import androidx.glance.layout.width
+import androidx.glance.layout.wrapContentHeight
+import androidx.glance.layout.wrapContentWidth
+import androidx.test.core.app.ApplicationProvider
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestCoroutineScope
+import kotlinx.coroutines.test.runBlockingTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+import kotlin.test.assertIs
+import kotlin.test.assertNotNull
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(RobolectricTestRunner::class)
+class ApplyDimensionModifierTest {
+
+    private lateinit var fakeCoroutineScope: TestCoroutineScope
+    private val context = ApplicationProvider.getApplicationContext<Context>()
+
+    @Before
+    fun setUp() {
+        fakeCoroutineScope = TestCoroutineScope()
+    }
+
+    @Test
+    fun normalResourceWidth() = fakeCoroutineScope.runBlockingTest {
+        val rv = context.runAndTranslate {
+            Text(
+                "content",
+                modifier = Modifier.width(R.dimen.standard_dimension)
+            )
+        }
+        val view = context.applyRemoteViews(rv)
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+            assertIs<TextView>(view)
+            assertThat(view.layoutParams.width)
+                .isEqualTo(context.resources.getDimensionPixelSize(R.dimen.standard_dimension))
+        } else {
+            val textView = view.findView<TextView> { it.id == R.id.sizeView }
+            assertNotNull(textView)
+            val targetWidth = context.resources.getDimensionPixelSize(R.dimen.standard_dimension)
+            assertThat(textView.minWidth).isEqualTo(targetWidth)
+            assertThat(textView.maxWidth).isEqualTo(targetWidth)
+        }
+    }
+
+    @Test
+    fun fillWidth() = fakeCoroutineScope.runBlockingTest {
+        val rv = context.runAndTranslate {
+            Text("content", modifier = Modifier.fillMaxWidth())
+        }
+        val view = context.applyRemoteViews(rv)
+        assertIs<TextView>(view)
+        assertThat(view.layoutParams.width).isEqualTo(ViewGroup.LayoutParams.MATCH_PARENT)
+    }
+
+    @Test
+    fun wrapWidth() = fakeCoroutineScope.runBlockingTest {
+        val rv = context.runAndTranslate {
+            Text("content", modifier = Modifier.wrapContentWidth())
+        }
+        val view = context.applyRemoteViews(rv)
+        assertIs<TextView>(view)
+        assertThat(view.layoutParams.width).isEqualTo(ViewGroup.LayoutParams.WRAP_CONTENT)
+    }
+
+    @Test
+    fun expandWidth() = fakeCoroutineScope.runBlockingTest {
+        val rv = context.runAndTranslate {
+            Row {
+                Text("content", modifier = Modifier.defaultWeight())
+            }
+        }
+        val view = context.applyRemoteViews(rv)
+        assertIs<LinearLayout>(view)
+        val child = assertIs<TextView>(view.getChildAt(0))
+        val layoutParam = assertIs<LinearLayout.LayoutParams>(child.layoutParams)
+        assertThat(layoutParam.width).isEqualTo(0)
+        assertThat(layoutParam.weight).isEqualTo(1f)
+    }
+
+    @Test
+    fun fillResourceWidth() = fakeCoroutineScope.runBlockingTest {
+        val rv = context.runAndTranslate {
+            Text("content", modifier = Modifier.width(R.dimen.fill_dimension))
+        }
+        val view = context.applyRemoteViews(rv)
+        assertIs<TextView>(view)
+        assertThat(view.layoutParams.width).isEqualTo(ViewGroup.LayoutParams.MATCH_PARENT)
+    }
+
+    @Test
+    fun wrapResourceWidth() = fakeCoroutineScope.runBlockingTest {
+        val rv = context.runAndTranslate {
+            Text("content", modifier = Modifier.width(R.dimen.wrap_dimension))
+        }
+        val view = context.applyRemoteViews(rv)
+        assertIs<TextView>(view)
+        assertThat(view.layoutParams.width).isEqualTo(ViewGroup.LayoutParams.WRAP_CONTENT)
+    }
+
+    @Test
+    fun normalResourceHeight() = fakeCoroutineScope.runBlockingTest {
+        val rv = context.runAndTranslate {
+            Text(
+                "content",
+                modifier = Modifier.height(R.dimen.standard_dimension)
+            )
+        }
+        val view = context.applyRemoteViews(rv)
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+            assertIs<TextView>(view)
+            assertThat(view.layoutParams.height)
+                .isEqualTo(context.resources.getDimensionPixelSize(R.dimen.standard_dimension))
+        } else {
+            val textView = view.findView<TextView> { it.id == R.id.sizeView }
+            assertNotNull(textView)
+            val targetHeight = context.resources.getDimensionPixelSize(R.dimen.standard_dimension)
+            assertThat(textView.minHeight).isEqualTo(targetHeight)
+            assertThat(textView.maxHeight).isEqualTo(targetHeight)
+        }
+    }
+
+    @Test
+    fun fillHeight() = fakeCoroutineScope.runBlockingTest {
+        val rv = context.runAndTranslate {
+            Text("content", modifier = Modifier.fillMaxHeight())
+        }
+        val view = context.applyRemoteViews(rv)
+        assertIs<TextView>(view)
+        assertThat(view.layoutParams.height).isEqualTo(ViewGroup.LayoutParams.MATCH_PARENT)
+    }
+
+    @Test
+    fun wrapHeight() = fakeCoroutineScope.runBlockingTest {
+        val rv = context.runAndTranslate {
+            Text("content", modifier = Modifier.wrapContentHeight())
+        }
+        val view = context.applyRemoteViews(rv)
+        assertIs<TextView>(view)
+        assertThat(view.layoutParams.height).isEqualTo(ViewGroup.LayoutParams.WRAP_CONTENT)
+    }
+
+    @Test
+    fun expandHeight() = fakeCoroutineScope.runBlockingTest {
+        val rv = context.runAndTranslate {
+            Column {
+                Text("content", modifier = Modifier.defaultWeight())
+            }
+        }
+        val view = context.applyRemoteViews(rv)
+        assertIs<LinearLayout>(view)
+        val child = assertIs<TextView>(view.getChildAt(0))
+        val layoutParam = assertIs<LinearLayout.LayoutParams>(child.layoutParams)
+        assertThat(layoutParam.height).isEqualTo(0)
+        assertThat(layoutParam.weight).isEqualTo(1f)
+    }
+
+    @Test
+    fun fillResourceHeight() = fakeCoroutineScope.runBlockingTest {
+        val rv = context.runAndTranslate {
+            Text("content", modifier = Modifier.height(R.dimen.fill_dimension))
+        }
+        val view = context.applyRemoteViews(rv)
+        assertIs<TextView>(view)
+        assertThat(view.layoutParams.height).isEqualTo(ViewGroup.LayoutParams.MATCH_PARENT)
+    }
+
+    @Test
+    fun wrapResourceHeight() = fakeCoroutineScope.runBlockingTest {
+        val rv = context.runAndTranslate {
+            Text("content", modifier = Modifier.height(R.dimen.wrap_dimension))
+        }
+        val view = context.applyRemoteViews(rv)
+        assertIs<TextView>(view)
+        assertThat(view.layoutParams.height).isEqualTo(ViewGroup.LayoutParams.WRAP_CONTENT)
+    }
+}
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/RemoteViewsTranslatorKtTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/RemoteViewsTranslatorKtTest.kt
index 1abfac7..e6c1d7d 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/RemoteViewsTranslatorKtTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/RemoteViewsTranslatorKtTest.kt
@@ -17,7 +17,9 @@
 package androidx.glance.appwidget
 
 import android.annotation.TargetApi
+import android.app.Activity
 import android.content.Context
+import android.graphics.drawable.ColorDrawable
 import android.os.Build
 import android.text.SpannedString
 import android.text.style.StrikethroughSpan
@@ -34,13 +36,16 @@
 import androidx.compose.runtime.Composable
 import androidx.core.view.children
 import androidx.glance.Modifier
+import androidx.glance.action.launchActivityAction
 import androidx.glance.appwidget.layout.AndroidRemoteViews
 import androidx.glance.appwidget.layout.CheckBox
 import androidx.glance.appwidget.layout.LazyColumn
 import androidx.glance.appwidget.layout.ReservedItemIdRangeEnd
 import androidx.glance.appwidget.test.R
+import androidx.glance.background
 import androidx.glance.layout.Alignment
 import androidx.glance.layout.Box
+import androidx.glance.layout.Button
 import androidx.glance.layout.Column
 import androidx.glance.layout.Row
 import androidx.glance.layout.Text
@@ -48,6 +53,7 @@
 import androidx.glance.layout.padding
 import androidx.glance.text.TextDecoration
 import androidx.glance.text.TextStyle
+import androidx.glance.unit.Color
 import androidx.glance.unit.Dp
 import androidx.glance.unit.dp
 import androidx.test.core.app.ApplicationProvider
@@ -575,12 +581,11 @@
 
     @Test
     fun canTranslateAndroidRemoteViews() = fakeCoroutineScope.runBlockingTest {
-        val layoutDef = selectLayout(LayoutSelector.Type.Text, Modifier)
-        val providedViews = RemoteViews(context.packageName, layoutDef.layoutId).also {
-            it.setTextViewText(R.id.glanceView, "Android Remote Views")
-        }
-
         val result = runAndTranslate {
+            val providedViews = RemoteViews(context.packageName, R.layout.text_sample).also {
+                it.setTextViewText(R.id.text_view, "Android Remote Views")
+            }
+
             Box {
                 AndroidRemoteViews(providedViews)
             }
@@ -588,6 +593,7 @@
 
         val rootLayout = assertIs<ViewGroup>(context.applyRemoteViews(result))
         val actual = assertIs<TextView>(rootLayout.children.single())
+        assertThat(actual.id).isEqualTo(R.id.text_view)
         assertThat(actual.text).isEqualTo("Android Remote Views")
     }
 
@@ -673,6 +679,74 @@
         textContent.checkHasSingleTypedSpan<StrikethroughSpan> { }
     }
 
+    @Test
+    fun canTranslateButton() = fakeCoroutineScope.runBlockingTest {
+        val rv = runAndTranslate {
+            Button(
+                "Button",
+                >
+                enabled = true
+            )
+        }
+
+        val button = assertIs<android.widget.Button>(context.applyRemoteViews(rv))
+        assertThat(button.text).isEqualTo("Button")
+        assertThat(button.isEnabled).isTrue()
+        assertThat(button.hasOnClickListeners()).isTrue()
+    }
+
+    @Test
+    fun canTranslateButton_disabled() = fakeCoroutineScope.runBlockingTest {
+        val rv = runAndTranslate {
+            Button(
+                "Button",
+                >
+                enabled = false
+            )
+        }
+
+        val button = assertIs<android.widget.Button>(context.applyRemoteViews(rv))
+        assertThat(button.text).isEqualTo("Button")
+        assertThat(button.isEnabled).isFalse()
+        assertThat(button.hasOnClickListeners()).isFalse()
+    }
+
+    @Test
+    fun canTranslateBackground_red() = fakeCoroutineScope.runBlockingTest {
+        val rv = runAndTranslate {
+            Box(modifier = Modifier.background(Color.Red)) {}
+        }
+
+        val view = context.applyRemoteViews(rv)
+        val background = view.background
+        assertIs<ColorDrawable>(background)
+        assertThat(background.color).isEqualTo(android.graphics.Color.RED)
+    }
+
+    @Test
+    fun canTranslateBackground_partialColor() = fakeCoroutineScope.runBlockingTest {
+        val rv = runAndTranslate {
+            Box(modifier = Modifier.background(Color(red = 0.4f, green = 0.5f, blue = 0.6f))) {}
+        }
+
+        val view = context.applyRemoteViews(rv)
+        val background = view.background
+        assertIs<ColorDrawable>(background)
+        assertThat(background.color).isEqualTo(android.graphics.Color.argb(255, 102, 128, 153))
+    }
+
+    @Test
+    fun canTranslateBackground_transparent() = fakeCoroutineScope.runBlockingTest {
+        val rv = runAndTranslate {
+            Box(modifier = Modifier.background(Color.Transparent)) {}
+        }
+
+        val view = context.applyRemoteViews(rv)
+        val background = view.background
+        assertIs<ColorDrawable>(background)
+        assertThat(background.color).isEqualTo(android.graphics.Color.TRANSPARENT)
+    }
+
     // Check there is a single span, that it's of the correct type and passes the [check].
     private inline fun <reified T> SpannedString.checkSingleSpan(check: (T) -> Unit) {
         val spans = getSpans(0, length, Any::class.java)
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/TestUtils.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/TestUtils.kt
index 80e2d0f..4ee330d 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/TestUtils.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/TestUtils.kt
@@ -24,12 +24,14 @@
 import android.util.DisplayMetrics
 import android.util.TypedValue
 import android.view.View
+import android.view.ViewGroup
 import android.widget.FrameLayout
 import android.widget.RemoteViews
 import androidx.compose.runtime.BroadcastFrameClock
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composition
 import androidx.compose.runtime.Recomposer
+import androidx.core.view.children
 import androidx.glance.Applier
 import androidx.glance.unit.Sp
 import kotlinx.coroutines.coroutineScope
@@ -98,3 +100,24 @@
 
 internal fun Sp.toPixels(displayMetrics: DisplayMetrics) =
     TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, value, displayMetrics).toInt()
+
+inline fun <reified T : View> View.findView(noinline pred: (T) -> Boolean) =
+    findView(pred, T::class.java)
+
+inline fun <reified T : View> View.findViewByType() =
+    findView({ true }, T::class.java)
+
+fun <T : View> View.findView(predicate: (T) -> Boolean, klass: Class<T>): T? {
+    try {
+        val castView = klass.cast(this)!!
+        if (predicate(castView)) {
+            return castView
+        }
+    } catch (e: ClassCastException) {
+        // Nothing to do
+    }
+    if (this !is ViewGroup) {
+        return null
+    }
+    return children.mapNotNull { it.findView(predicate, klass) }.firstOrNull()
+}
diff --git a/glance/glance-appwidget/src/test/res/layout/raw_container.xml b/glance/glance-appwidget/src/test/res/layout/raw_container.xml
index a1b10b6..20481b6 100644
--- a/glance/glance-appwidget/src/test/res/layout/raw_container.xml
+++ b/glance/glance-appwidget/src/test/res/layout/raw_container.xml
@@ -18,6 +18,4 @@
     android:orientation="vertical"
     android:id="@+id/raw_container_view"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-</LinearLayout>
\ No newline at end of file
+    android:layout_height="match_parent" />
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/test/res/layout/text_sample.xml b/glance/glance-appwidget/src/test/res/layout/text_sample.xml
new file mode 100644
index 0000000..09f94e9
--- /dev/null
+++ b/glance/glance-appwidget/src/test/res/layout/text_sample.xml
@@ -0,0 +1,21 @@
+<?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.
+  -->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:id="@+id/text_view"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" />
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/test/res/values/dimens.xml b/glance/glance-appwidget/src/test/res/values/dimens.xml
new file mode 100644
index 0000000..f6bfa1d
--- /dev/null
+++ b/glance/glance-appwidget/src/test/res/values/dimens.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.
+  -->
+<resources>
+    <dimen name="standard_dimension">40dp</dimen>
+    <dimen name="fill_dimension">-1px</dimen>
+    <dimen name="wrap_dimension">-2px</dimen>
+</resources>
\ No newline at end of file
diff --git a/glance/glance-wear/api/current.txt b/glance/glance-wear/api/current.txt
index 635fc5a..43aefd6 100644
--- a/glance/glance-wear/api/current.txt
+++ b/glance/glance-wear/api/current.txt
@@ -33,10 +33,6 @@
     method @androidx.compose.runtime.Composable public static void AndroidLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement layoutElement);
   }
 
-  public final class BackgroundKt {
-    method public static androidx.glance.Modifier background(androidx.glance.Modifier, int color);
-  }
-
   public final class CurvedRowKt {
     method @androidx.compose.runtime.Composable public static void CurvedRow(optional androidx.glance.Modifier modifier, optional float anchorDegrees, optional int anchorType, optional int radialAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.wear.layout.CurvedRowScope,kotlin.Unit> content);
   }
diff --git a/glance/glance-wear/api/public_plus_experimental_current.txt b/glance/glance-wear/api/public_plus_experimental_current.txt
index 635fc5a..43aefd6 100644
--- a/glance/glance-wear/api/public_plus_experimental_current.txt
+++ b/glance/glance-wear/api/public_plus_experimental_current.txt
@@ -33,10 +33,6 @@
     method @androidx.compose.runtime.Composable public static void AndroidLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement layoutElement);
   }
 
-  public final class BackgroundKt {
-    method public static androidx.glance.Modifier background(androidx.glance.Modifier, int color);
-  }
-
   public final class CurvedRowKt {
     method @androidx.compose.runtime.Composable public static void CurvedRow(optional androidx.glance.Modifier modifier, optional float anchorDegrees, optional int anchorType, optional int radialAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.wear.layout.CurvedRowScope,kotlin.Unit> content);
   }
diff --git a/glance/glance-wear/api/restricted_current.txt b/glance/glance-wear/api/restricted_current.txt
index 635fc5a..43aefd6 100644
--- a/glance/glance-wear/api/restricted_current.txt
+++ b/glance/glance-wear/api/restricted_current.txt
@@ -33,10 +33,6 @@
     method @androidx.compose.runtime.Composable public static void AndroidLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement layoutElement);
   }
 
-  public final class BackgroundKt {
-    method public static androidx.glance.Modifier background(androidx.glance.Modifier, int color);
-  }
-
   public final class CurvedRowKt {
     method @androidx.compose.runtime.Composable public static void CurvedRow(optional androidx.glance.Modifier modifier, optional float anchorDegrees, optional int anchorType, optional int radialAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.wear.layout.CurvedRowScope,kotlin.Unit> content);
   }
diff --git a/glance/glance-wear/src/androidAndroidTest/kotlin/androidx/glance/wear/ScreenshotTests.kt b/glance/glance-wear/src/androidAndroidTest/kotlin/androidx/glance/wear/ScreenshotTests.kt
index 8bdd63a..fd539d8 100644
--- a/glance/glance-wear/src/androidAndroidTest/kotlin/androidx/glance/wear/ScreenshotTests.kt
+++ b/glance/glance-wear/src/androidAndroidTest/kotlin/androidx/glance/wear/ScreenshotTests.kt
@@ -28,6 +28,7 @@
 import androidx.core.content.ContextCompat
 import androidx.glance.Applier
 import androidx.glance.Modifier
+import androidx.glance.background
 import androidx.glance.layout.Alignment
 import androidx.glance.layout.Box
 import androidx.glance.layout.Column
@@ -48,7 +49,6 @@
 import androidx.glance.wear.layout.CurvedRow
 import androidx.glance.wear.layout.CurvedTextStyle
 import androidx.glance.wear.layout.RadialAlignment
-import androidx.glance.wear.layout.background
 import androidx.test.core.app.ApplicationProvider.getApplicationContext
 import androidx.test.screenshot.AndroidXScreenshotTestRule
 import androidx.test.screenshot.matchers.MSSIMMatcher
diff --git a/glance/glance-wear/src/androidMain/kotlin/androidx/glance/wear/WearCompositionTranslator.kt b/glance/glance-wear/src/androidMain/kotlin/androidx/glance/wear/WearCompositionTranslator.kt
index a83e26c..76ac337 100644
--- a/glance/glance-wear/src/androidMain/kotlin/androidx/glance/wear/WearCompositionTranslator.kt
+++ b/glance/glance-wear/src/androidMain/kotlin/androidx/glance/wear/WearCompositionTranslator.kt
@@ -17,6 +17,8 @@
 package androidx.glance.wear
 
 import android.content.Context
+import android.view.ViewGroup
+import androidx.glance.BackgroundModifier
 import androidx.glance.Emittable
 import androidx.glance.Modifier
 import androidx.glance.action.ActionModifier
@@ -25,18 +27,20 @@
 import androidx.glance.layout.Alignment
 import androidx.glance.layout.Dimension
 import androidx.glance.layout.EmittableBox
+import androidx.glance.layout.EmittableButton
 import androidx.glance.layout.EmittableColumn
 import androidx.glance.layout.EmittableRow
 import androidx.glance.layout.EmittableText
 import androidx.glance.layout.HeightModifier
 import androidx.glance.layout.PaddingModifier
+import androidx.glance.layout.toEmittableText
 import androidx.glance.layout.WidthModifier
 import androidx.glance.text.FontStyle
 import androidx.glance.text.FontWeight
 import androidx.glance.text.TextDecoration
 import androidx.glance.text.TextStyle
+import androidx.glance.unit.dp
 import androidx.glance.wear.layout.AnchorType
-import androidx.glance.wear.layout.BackgroundModifier
 import androidx.glance.wear.layout.CurvedTextStyle
 import androidx.glance.wear.layout.EmittableAndroidLayoutElement
 import androidx.glance.wear.layout.EmittableCurvedRow
@@ -129,6 +133,7 @@
         is Dimension.Expand -> expand()
         is Dimension.Fill -> expand()
         is Dimension.Dp -> dp(this.dp.value)
+        else -> throw IllegalArgumentException("The dimension should be fully resolved, not $this.")
     }
 
 @ArcAnchorType
@@ -149,13 +154,25 @@
         else -> throw IllegalArgumentException("Unknown radial alignment $this")
     }
 
+private fun Dimension.resolve(context: Context): Dimension {
+    if (this !is Dimension.Resource) return this
+    val sizePx = context.resources.getDimension(res)
+    return when (sizePx.toInt()) {
+        ViewGroup.LayoutParams.MATCH_PARENT -> Dimension.Fill
+        ViewGroup.LayoutParams.WRAP_CONTENT -> Dimension.Wrap
+        else -> Dimension.Dp((sizePx / context.resources.displayMetrics.density).dp)
+    }
+}
+
 private fun Modifier.getWidth(
+    context: Context,
     default: Dimension = Dimension.Wrap
-): Dimension = findModifier<WidthModifier>()?.width ?: default
+): Dimension = findModifier<WidthModifier>()?.width?.resolve(context) ?: default
 
 private fun Modifier.getHeight(
+    context: Context,
     default: Dimension = Dimension.Wrap
-): Dimension = findModifier<HeightModifier>()?.height ?: default
+): Dimension = findModifier<HeightModifier>()?.height?.resolve(context) ?: default
 
 private fun translateEmittableBox(
     context: Context,
@@ -164,8 +181,8 @@
     .setVerticalAlignment(element.contentAlignment.vertical.toProto())
     .setHorizontalAlignment(element.contentAlignment.horizontal.toProto())
     .setModifiers(translateModifiers(context, element.modifier))
-    .setWidth(element.modifier.getWidth().toContainerDimension())
-    .setHeight(element.modifier.getHeight().toContainerDimension())
+    .setWidth(element.modifier.getWidth(context).toContainerDimension())
+    .setHeight(element.modifier.getHeight(context).toContainerDimension())
     .also { box -> element.children.forEach { box.addContent(translateComposition(context, it)) } }
     .build()
 
@@ -173,8 +190,8 @@
     context: Context,
     element: EmittableRow
 ): LayoutElementBuilders.LayoutElement {
-    val width = element.modifier.getWidth()
-    val height = element.modifier.getHeight()
+    val width = element.modifier.getWidth(context)
+    val height = element.modifier.getHeight(context)
 
     val baseRowBuilder = LayoutElementBuilders.Row.Builder()
         .setHeight(height.toContainerDimension())
@@ -206,8 +223,8 @@
     context: Context,
     element: EmittableColumn
 ): LayoutElementBuilders.LayoutElement {
-    val width = element.modifier.getWidth()
-    val height = element.modifier.getHeight()
+    val width = element.modifier.getWidth(context)
+    val height = element.modifier.getHeight(context)
 
     val baseColumnBuilder = LayoutElementBuilders.Column.Builder()
         .setWidth(width.toContainerDimension())
@@ -281,8 +298,8 @@
     element: EmittableText
 ): LayoutElementBuilders.LayoutElement {
     // Does it have a width or height set? If so, we need to wrap it in a Box.
-    val width = element.modifier.getWidth()
-    val height = element.modifier.getHeight()
+    val width = element.modifier.getWidth(context)
+    val height = element.modifier.getHeight(context)
 
     val textBuilder = LayoutElementBuilders.Text.Builder()
         .setText(element.text)
@@ -306,8 +323,8 @@
     element: EmittableCurvedRow
 ): LayoutElementBuilders.LayoutElement {
     // Does it have a width or height set? If so, we need to wrap it in a Box.
-    val width = element.modifier.getWidth()
-    val height = element.modifier.getHeight()
+    val width = element.modifier.getWidth(context)
+    val height = element.modifier.getHeight(context)
 
     // Note: Wear Tiles uses 0 degrees = 12 o clock, but Glance / Wear Compose use 0 degrees = 3
     // o clock. Tiles supports wraparound etc though, so just add on the 90 degrees here.
@@ -398,6 +415,7 @@
         is EmittableText -> translateEmittableText(context, element)
         is EmittableCurvedRow -> translateEmittableCurvedRow(context, element)
         is EmittableAndroidLayoutElement -> translateEmittableAndroidLayoutElement(element)
+        is EmittableButton -> translateEmittableText(context, element.toEmittableText())
         else -> throw IllegalArgumentException("Unknown element $element")
     }
 }
diff --git a/glance/glance-wear/src/test/kotlin/androidx/glance/wear/WearCompositionTranslatorTest.kt b/glance/glance-wear/src/test/kotlin/androidx/glance/wear/WearCompositionTranslatorTest.kt
index b67350e..9eae920 100644
--- a/glance/glance-wear/src/test/kotlin/androidx/glance/wear/WearCompositionTranslatorTest.kt
+++ b/glance/glance-wear/src/test/kotlin/androidx/glance/wear/WearCompositionTranslatorTest.kt
@@ -20,10 +20,12 @@
 import android.content.Context
 import androidx.compose.runtime.Composable
 import androidx.glance.Modifier
+import androidx.glance.background
 import androidx.glance.action.clickable
 import androidx.glance.action.launchActivityAction
 import androidx.glance.layout.Alignment
 import androidx.glance.layout.Box
+import androidx.glance.layout.Button
 import androidx.glance.layout.Column
 import androidx.glance.layout.Row
 import androidx.glance.layout.Text
@@ -45,7 +47,7 @@
 import androidx.glance.wear.layout.CurvedRow
 import androidx.glance.wear.layout.CurvedTextStyle
 import androidx.glance.wear.layout.RadialAlignment
-import androidx.glance.wear.layout.background
+import androidx.glance.wear.test.R
 import androidx.test.core.app.ApplicationProvider.getApplicationContext
 import androidx.wear.tiles.ActionBuilders
 import androidx.wear.tiles.DimensionBuilders
@@ -438,6 +440,60 @@
             .isEqualTo(TestActivity::class.qualifiedName)
     }
 
+    @Test
+    fun canTranslateButton() = fakeCoroutineScope.runBlockingTest {
+        val content = runAndTranslate {
+            val style = TextStyle(
+                fontSize = 16.sp,
+                fontWeight = FontWeight.Bold,
+                fontStyle = FontStyle.Italic,
+                textDecoration = TextDecoration.Underline
+            )
+            Button(
+                "Hello World",
+                >
+                modifier = Modifier.padding(1.dp),
+                style = style
+            )
+        }
+
+        val box = assertIs<LayoutElementBuilders.Box>(content)
+        val innerText = assertIs<LayoutElementBuilders.Text>(box.contents[0])
+
+        assertThat(innerText.text!!.value).isEqualTo("Hello World")
+
+        assertThat(innerText.fontStyle!!.size!!.value).isEqualTo(16f)
+        assertThat(innerText.fontStyle!!.italic!!.value).isTrue()
+        assertThat(innerText.fontStyle!!.weight!!.value).isEqualTo(FONT_WEIGHT_BOLD)
+        assertThat(innerText.fontStyle!!.underline!!.value).isTrue()
+
+        assertThat(innerText.modifiers!!.clickable).isNotNull()
+        assertThat(innerText.modifiers!!.clickable!!.onClick)
+            .isInstanceOf(ActionBuilders.LaunchAction::class.java)
+    }
+
+    @Test
+    fun setSizeFromResource() = fakeCoroutineScope.runBlockingTest {
+        val content = runAndTranslate {
+            Column(
+                modifier = Modifier.width(R.dimen.dimension1)
+                    .height(R.dimen.dimension2)
+            ) {}
+        }
+
+        val innerColumn =
+            (content as LayoutElementBuilders.Box).contents[0] as LayoutElementBuilders.Column
+        val context = getApplicationContext<Context>()
+
+        // Row should inherit the size of the inner Row
+        assertThat((innerColumn.width as DimensionBuilders.DpProp).value).isEqualTo(
+            context.resources.getDimension(R.dimen.dimension1)
+        )
+        assertThat((innerColumn.height as DimensionBuilders.DpProp).value).isEqualTo(
+            context.resources.getDimension(R.dimen.dimension2)
+        )
+    }
+
     private suspend fun runAndTranslate(
         content: @Composable () -> Unit
     ): LayoutElementBuilders.LayoutElement {
@@ -447,4 +503,4 @@
     }
 }
 
-private class TestActivity : Activity()
\ No newline at end of file
+private class TestActivity : Activity()
diff --git a/glance/glance-wear/src/test/kotlin/androidx/glance/wear/layout/BackgroundTest.kt b/glance/glance-wear/src/test/kotlin/androidx/glance/wear/layout/BackgroundTest.kt
index 20eb0ed..a1ae34e 100644
--- a/glance/glance-wear/src/test/kotlin/androidx/glance/wear/layout/BackgroundTest.kt
+++ b/glance/glance-wear/src/test/kotlin/androidx/glance/wear/layout/BackgroundTest.kt
@@ -16,7 +16,9 @@
 
 package androidx.glance.wear.layout
 
+import androidx.glance.BackgroundModifier
 import androidx.glance.Modifier
+import androidx.glance.background
 import androidx.glance.findModifier
 import androidx.glance.unit.Color
 import com.google.common.truth.Truth.assertThat
diff --git a/glance/glance-wear/src/test/res/values/dimens.xml b/glance/glance-wear/src/test/res/values/dimens.xml
new file mode 100644
index 0000000..fa5bcbb
--- /dev/null
+++ b/glance/glance-wear/src/test/res/values/dimens.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<resources>
+    <dimen name="dimension1">40dp</dimen>
+    <dimen name="dimension2">60dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/glance/glance/api/current.txt b/glance/glance/api/current.txt
index b65b9fe..1db2875 100644
--- a/glance/glance/api/current.txt
+++ b/glance/glance/api/current.txt
@@ -1,6 +1,10 @@
 // Signature format: 4.0
 package androidx.glance {
 
+  public final class BackgroundKt {
+    method public static androidx.glance.Modifier background(androidx.glance.Modifier, int color);
+  }
+
   public final class CombinedModifier implements androidx.glance.Modifier {
     ctor public CombinedModifier(androidx.glance.Modifier outer, androidx.glance.Modifier inner);
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.Modifier.Element,java.lang.Boolean> predicate);
@@ -51,11 +55,20 @@
     method public static androidx.glance.Modifier clickable(androidx.glance.Modifier, androidx.glance.action.Action onClick);
   }
 
+  public interface ActionRunnable {
+    method public suspend Object? run(android.content.Context context, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+  }
+
   public final class LaunchActivityActionKt {
     method public static <T extends android.app.Activity> androidx.glance.action.Action launchActivityAction(Class<T> activity);
     method public static inline <reified T extends android.app.Activity> androidx.glance.action.Action! launchActivityAction();
   }
 
+  public final class UpdateActionKt {
+    method public static <T extends androidx.glance.action.ActionRunnable> androidx.glance.action.Action updateContentAction(Class<T> runnable);
+    method public static inline <reified T extends androidx.glance.action.ActionRunnable> androidx.glance.action.Action! updateContentAction();
+  }
+
 }
 
 package androidx.glance.layout {
@@ -132,6 +145,10 @@
     method @androidx.compose.runtime.Composable public static void Box(optional androidx.glance.Modifier modifier, optional androidx.glance.layout.Alignment contentAlignment, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
+  public final class ButtonKt {
+    method @androidx.compose.runtime.Composable public static void Button(String text, androidx.glance.action.Action onClick, optional androidx.glance.Modifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style);
+  }
+
   public final class ColumnKt {
     method @androidx.compose.runtime.Composable public static void Column(optional androidx.glance.Modifier modifier, optional int verticalAlignment, optional int horizontalAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.layout.ColumnScope,kotlin.Unit> content);
   }
@@ -145,9 +162,11 @@
     method public static androidx.glance.Modifier fillMaxSize(androidx.glance.Modifier);
     method public static androidx.glance.Modifier fillMaxWidth(androidx.glance.Modifier);
     method public static androidx.glance.Modifier height(androidx.glance.Modifier, float height);
+    method public static androidx.glance.Modifier height(androidx.glance.Modifier, @DimenRes int height);
     method public static androidx.glance.Modifier size(androidx.glance.Modifier, float size);
     method public static androidx.glance.Modifier size(androidx.glance.Modifier, float width, float height);
     method public static androidx.glance.Modifier width(androidx.glance.Modifier, float width);
+    method public static androidx.glance.Modifier width(androidx.glance.Modifier, @DimenRes int width);
     method public static androidx.glance.Modifier wrapContentHeight(androidx.glance.Modifier);
     method public static androidx.glance.Modifier wrapContentSize(androidx.glance.Modifier);
     method public static androidx.glance.Modifier wrapContentWidth(androidx.glance.Modifier);
diff --git a/glance/glance/api/public_plus_experimental_current.txt b/glance/glance/api/public_plus_experimental_current.txt
index b65b9fe..1db2875 100644
--- a/glance/glance/api/public_plus_experimental_current.txt
+++ b/glance/glance/api/public_plus_experimental_current.txt
@@ -1,6 +1,10 @@
 // Signature format: 4.0
 package androidx.glance {
 
+  public final class BackgroundKt {
+    method public static androidx.glance.Modifier background(androidx.glance.Modifier, int color);
+  }
+
   public final class CombinedModifier implements androidx.glance.Modifier {
     ctor public CombinedModifier(androidx.glance.Modifier outer, androidx.glance.Modifier inner);
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.Modifier.Element,java.lang.Boolean> predicate);
@@ -51,11 +55,20 @@
     method public static androidx.glance.Modifier clickable(androidx.glance.Modifier, androidx.glance.action.Action onClick);
   }
 
+  public interface ActionRunnable {
+    method public suspend Object? run(android.content.Context context, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+  }
+
   public final class LaunchActivityActionKt {
     method public static <T extends android.app.Activity> androidx.glance.action.Action launchActivityAction(Class<T> activity);
     method public static inline <reified T extends android.app.Activity> androidx.glance.action.Action! launchActivityAction();
   }
 
+  public final class UpdateActionKt {
+    method public static <T extends androidx.glance.action.ActionRunnable> androidx.glance.action.Action updateContentAction(Class<T> runnable);
+    method public static inline <reified T extends androidx.glance.action.ActionRunnable> androidx.glance.action.Action! updateContentAction();
+  }
+
 }
 
 package androidx.glance.layout {
@@ -132,6 +145,10 @@
     method @androidx.compose.runtime.Composable public static void Box(optional androidx.glance.Modifier modifier, optional androidx.glance.layout.Alignment contentAlignment, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
+  public final class ButtonKt {
+    method @androidx.compose.runtime.Composable public static void Button(String text, androidx.glance.action.Action onClick, optional androidx.glance.Modifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style);
+  }
+
   public final class ColumnKt {
     method @androidx.compose.runtime.Composable public static void Column(optional androidx.glance.Modifier modifier, optional int verticalAlignment, optional int horizontalAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.layout.ColumnScope,kotlin.Unit> content);
   }
@@ -145,9 +162,11 @@
     method public static androidx.glance.Modifier fillMaxSize(androidx.glance.Modifier);
     method public static androidx.glance.Modifier fillMaxWidth(androidx.glance.Modifier);
     method public static androidx.glance.Modifier height(androidx.glance.Modifier, float height);
+    method public static androidx.glance.Modifier height(androidx.glance.Modifier, @DimenRes int height);
     method public static androidx.glance.Modifier size(androidx.glance.Modifier, float size);
     method public static androidx.glance.Modifier size(androidx.glance.Modifier, float width, float height);
     method public static androidx.glance.Modifier width(androidx.glance.Modifier, float width);
+    method public static androidx.glance.Modifier width(androidx.glance.Modifier, @DimenRes int width);
     method public static androidx.glance.Modifier wrapContentHeight(androidx.glance.Modifier);
     method public static androidx.glance.Modifier wrapContentSize(androidx.glance.Modifier);
     method public static androidx.glance.Modifier wrapContentWidth(androidx.glance.Modifier);
diff --git a/glance/glance/api/restricted_current.txt b/glance/glance/api/restricted_current.txt
index b65b9fe..1db2875 100644
--- a/glance/glance/api/restricted_current.txt
+++ b/glance/glance/api/restricted_current.txt
@@ -1,6 +1,10 @@
 // Signature format: 4.0
 package androidx.glance {
 
+  public final class BackgroundKt {
+    method public static androidx.glance.Modifier background(androidx.glance.Modifier, int color);
+  }
+
   public final class CombinedModifier implements androidx.glance.Modifier {
     ctor public CombinedModifier(androidx.glance.Modifier outer, androidx.glance.Modifier inner);
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.Modifier.Element,java.lang.Boolean> predicate);
@@ -51,11 +55,20 @@
     method public static androidx.glance.Modifier clickable(androidx.glance.Modifier, androidx.glance.action.Action onClick);
   }
 
+  public interface ActionRunnable {
+    method public suspend Object? run(android.content.Context context, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+  }
+
   public final class LaunchActivityActionKt {
     method public static <T extends android.app.Activity> androidx.glance.action.Action launchActivityAction(Class<T> activity);
     method public static inline <reified T extends android.app.Activity> androidx.glance.action.Action! launchActivityAction();
   }
 
+  public final class UpdateActionKt {
+    method public static <T extends androidx.glance.action.ActionRunnable> androidx.glance.action.Action updateContentAction(Class<T> runnable);
+    method public static inline <reified T extends androidx.glance.action.ActionRunnable> androidx.glance.action.Action! updateContentAction();
+  }
+
 }
 
 package androidx.glance.layout {
@@ -132,6 +145,10 @@
     method @androidx.compose.runtime.Composable public static void Box(optional androidx.glance.Modifier modifier, optional androidx.glance.layout.Alignment contentAlignment, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
+  public final class ButtonKt {
+    method @androidx.compose.runtime.Composable public static void Button(String text, androidx.glance.action.Action onClick, optional androidx.glance.Modifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style);
+  }
+
   public final class ColumnKt {
     method @androidx.compose.runtime.Composable public static void Column(optional androidx.glance.Modifier modifier, optional int verticalAlignment, optional int horizontalAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.layout.ColumnScope,kotlin.Unit> content);
   }
@@ -145,9 +162,11 @@
     method public static androidx.glance.Modifier fillMaxSize(androidx.glance.Modifier);
     method public static androidx.glance.Modifier fillMaxWidth(androidx.glance.Modifier);
     method public static androidx.glance.Modifier height(androidx.glance.Modifier, float height);
+    method public static androidx.glance.Modifier height(androidx.glance.Modifier, @DimenRes int height);
     method public static androidx.glance.Modifier size(androidx.glance.Modifier, float size);
     method public static androidx.glance.Modifier size(androidx.glance.Modifier, float width, float height);
     method public static androidx.glance.Modifier width(androidx.glance.Modifier, float width);
+    method public static androidx.glance.Modifier width(androidx.glance.Modifier, @DimenRes int width);
     method public static androidx.glance.Modifier wrapContentHeight(androidx.glance.Modifier);
     method public static androidx.glance.Modifier wrapContentSize(androidx.glance.Modifier);
     method public static androidx.glance.Modifier wrapContentWidth(androidx.glance.Modifier);
diff --git a/glance/glance/build.gradle b/glance/glance/build.gradle
index dcad28f..347d319 100644
--- a/glance/glance/build.gradle
+++ b/glance/glance/build.gradle
@@ -33,6 +33,7 @@
     kotlinPlugin(project(":compose:compiler:compiler"))
 
     api("androidx.compose.runtime:runtime:1.0.1")
+    api("androidx.annotation:annotation:1.2.0")
 
     implementation("androidx.annotation:annotation:1.1.0")
     implementation(libs.kotlinStdlib)
diff --git a/glance/glance-wear/src/androidMain/kotlin/androidx/glance/wear/layout/Background.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/Background.kt
similarity index 83%
rename from glance/glance-wear/src/androidMain/kotlin/androidx/glance/wear/layout/Background.kt
rename to glance/glance/src/androidMain/kotlin/androidx/glance/Background.kt
index 2a76d45..b5e3632 100644
--- a/glance/glance-wear/src/androidMain/kotlin/androidx/glance/wear/layout/Background.kt
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/Background.kt
@@ -14,12 +14,14 @@
  * limitations under the License.
  */
 
-package androidx.glance.wear.layout
+package androidx.glance
 
-import androidx.glance.Modifier
+import androidx.annotation.RestrictTo
 import androidx.glance.unit.Color
 
-internal class BackgroundModifier(public val color: Color) : Modifier.Element {
+/** @suppress */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public class BackgroundModifier(public val color: Color) : Modifier.Element {
     override fun toString(): String = "BackgroundModifier(color=$color)"
 }
 
diff --git a/glance/glance/src/androidMain/kotlin/androidx/glance/action/UpdateAction.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/action/UpdateAction.kt
new file mode 100644
index 0000000..660929f
--- /dev/null
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/action/UpdateAction.kt
@@ -0,0 +1,61 @@
+/*
+ * 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.glance.action
+
+import android.content.Context
+import androidx.annotation.RestrictTo
+
+/** @suppress */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class UpdateAction(val runnableClass: Class<out ActionRunnable>) : Action {
+    companion object {
+
+        public suspend fun run(context: Context, className: String) {
+            val workClass = Class.forName(className)
+
+            if (!ActionRunnable::class.java.isAssignableFrom(workClass)) {
+                error("Runnable class must implement ActionRunnable.")
+            }
+
+            val work = workClass.newInstance()
+            (work as ActionRunnable).run(context)
+        }
+    }
+}
+
+/**
+ * A runnable task executed in response to the user action, before the content is updated. The
+ * implementing class must have a public zero argument constructor, this is used to instantiate
+ * the class at runtime.
+ */
+interface ActionRunnable {
+    suspend fun run(context: Context)
+}
+
+/**
+ * Creates an [Action] that executes a custom [ActionRunnable] and then updates the component view.
+ */
+public fun <T : ActionRunnable> updateContentAction(runnable: Class<T>): Action =
+    UpdateAction(runnable)
+
+@Suppress("MissingNullability") /* Shouldn't need to specify @NonNull. b/199284086 */
+/**
+ * Creates an [Action] that executes a custom [ActionRunnable] and then updates the component view.
+ */
+// TODO(b/201418282): Add the UI update path
+public inline fun <reified T : ActionRunnable> updateContentAction(): Action =
+    updateContentAction(T::class.java)
diff --git a/glance/glance/src/androidMain/kotlin/androidx/glance/layout/Button.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/layout/Button.kt
new file mode 100644
index 0000000..2834957
--- /dev/null
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/layout/Button.kt
@@ -0,0 +1,76 @@
+/*
+ * 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.glance.layout
+
+import androidx.annotation.RestrictTo
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.ComposeNode
+import androidx.glance.Applier
+import androidx.glance.Emittable
+import androidx.glance.Modifier
+import androidx.glance.action.Action
+import androidx.glance.action.clickable
+import androidx.glance.text.TextStyle
+
+/**
+ * Adds a button view to the glance view.
+ *
+ * @param text The text that this button will show.
+ * @param onClick The action to be performed when this button is clicked.
+ * @param modifier The modifier to be applied to this button.
+ * @param enabled If false, the button will not be clickable.
+ * @param style The style to be applied to the text in this button.
+ */
+@Composable
+fun Button(
+    text: String,
+    onClick: Action,
+    modifier: Modifier = Modifier,
+    enabled: Boolean = true,
+    style: TextStyle? = null
+) {
+    val finalModifier = if (enabled) modifier.clickable(onClick) else modifier
+    ComposeNode<EmittableButton, Applier>(
+        factory = ::EmittableButton,
+        update = {
+            this.set(text) { this.text = it }
+            this.set(finalModifier) { this.modifier = it }
+            this.set(style) { this.style = it }
+            this.set(enabled) { this.enabled = it }
+        }
+    )
+}
+
+/** @suppress */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class EmittableButton : Emittable {
+    override var modifier: Modifier = Modifier
+    var text: String = ""
+    var style: TextStyle? = null
+    var enabled: Boolean = true
+
+    override fun toString(): String = "EmittableButton('$text', enabled=$enabled, style=$style, " +
+        "modifier=$modifier)"
+}
+
+/** @suppress */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+fun EmittableButton.toEmittableText() = EmittableText().also {
+    it.modifier = modifier
+    it.text = text
+    it.style = style
+}
diff --git a/glance/glance/src/androidMain/kotlin/androidx/glance/layout/Dimension.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/layout/Dimension.kt
index f429f3a..11dd2b8 100644
--- a/glance/glance/src/androidMain/kotlin/androidx/glance/layout/Dimension.kt
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/layout/Dimension.kt
@@ -16,6 +16,7 @@
 
 package androidx.glance.layout
 
+import androidx.annotation.DimenRes
 import androidx.annotation.RestrictTo
 import androidx.glance.Modifier
 import androidx.glance.unit.Dp
@@ -34,6 +35,7 @@
     public object Wrap : Dimension()
     public object Fill : Dimension()
     public object Expand : Dimension()
+    public class Resource(@DimenRes public val res: Int) : Dimension()
 }
 
 /**
@@ -47,6 +49,10 @@
 /** Sets the absolute width of an element, in [Dp]. */
 public fun Modifier.width(width: Dp): Modifier = this.then(WidthModifier(Dimension.Dp(width)))
 
+/** Set the width of a view from the value of a resource. */
+public fun Modifier.width(@DimenRes width: Int): Modifier =
+    this.then(WidthModifier(Dimension.Resource(width)))
+
 /** Specifies that the width of the element should wrap its contents. */
 public fun Modifier.wrapContentWidth(): Modifier = this.then(WidthModifier(Dimension.Wrap))
 
@@ -68,6 +74,10 @@
 /** Sets the absolute height of an element, in [Dp]. */
 public fun Modifier.height(height: Dp): Modifier = this.then(HeightModifier(Dimension.Dp(height)))
 
+/** Set the height of the view from a resource. */
+public fun Modifier.height(@DimenRes height: Int): Modifier =
+    this.then(HeightModifier(Dimension.Resource(height)))
+
 /** Specifies that the height of the element should wrap its contents. */
 public fun Modifier.wrapContentHeight(): Modifier = this.then(HeightModifier(Dimension.Wrap))
 
diff --git a/glance/glance/src/test/kotlin/androidx/glance/action/ActionTest.kt b/glance/glance/src/test/kotlin/androidx/glance/action/ActionTest.kt
index 0eb4918..fd8d514 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/action/ActionTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/action/ActionTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.glance.action
 
+import android.content.Context
 import androidx.glance.Modifier
 import androidx.glance.findModifier
 import org.junit.Test
@@ -23,9 +24,20 @@
 
 class ActionTest {
     @Test
-    fun test() {
+    fun testLaunch() {
         val modifiers = Modifier.clickable(launchActivityAction(TestActivity::class.java))
         val modifier = checkNotNull(modifiers.findModifier<ActionModifier>())
         assertIs<LaunchActivityAction>(modifier.action)
     }
+
+    @Test
+    fun testUpdate() {
+        val modifiers = Modifier.clickable(updateContentAction<TestRunnable>())
+        val modifier = checkNotNull(modifiers.findModifier<ActionModifier>())
+        assertIs<UpdateAction>(modifier.action)
+    }
+}
+
+class TestRunnable : ActionRunnable {
+    override suspend fun run(context: Context) { }
 }
\ No newline at end of file
diff --git a/glance/glance/src/test/kotlin/androidx/glance/layout/ButtonTest.kt b/glance/glance/src/test/kotlin/androidx/glance/layout/ButtonTest.kt
new file mode 100644
index 0000000..db37f7b
--- /dev/null
+++ b/glance/glance/src/test/kotlin/androidx/glance/layout/ButtonTest.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.glance.layout
+
+import android.app.Activity
+import androidx.glance.action.ActionModifier
+import androidx.glance.action.LaunchActivityAction
+import androidx.glance.action.launchActivityAction
+import androidx.glance.findModifier
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestCoroutineScope
+import kotlinx.coroutines.test.runBlockingTest
+import org.junit.Before
+import org.junit.Test
+import kotlin.test.assertIs
+
+@OptIn(ExperimentalCoroutinesApi::class)
+class ButtonTest {
+    private lateinit var fakeCoroutineScope: TestCoroutineScope
+
+    @Before
+    fun setUp() {
+        fakeCoroutineScope = TestCoroutineScope()
+    }
+
+    @Test
+    fun createComposableButton() = fakeCoroutineScope.runBlockingTest {
+        val root = runTestingComposition {
+            Button(text = "button",  enabled = true)
+        }
+
+        assertThat(root.children).hasSize(1)
+        val child = assertIs<EmittableButton>(root.children[0])
+        assertThat(child.text).isEqualTo("button")
+        assertIs<LaunchActivityAction>(child.modifier.findModifier<ActionModifier>()?.action)
+        assertThat(child.enabled).isTrue()
+    }
+
+    @Test
+    fun createDisabledButton() = fakeCoroutineScope.runBlockingTest {
+        val root = runTestingComposition {
+            Button(text = "button",  enabled = false)
+        }
+
+        assertThat(root.children).hasSize(1)
+        val child = assertIs<EmittableButton>(root.children[0])
+        assertThat(child.text).isEqualTo("button")
+        assertThat(child.modifier.findModifier<ActionModifier>()).isNull()
+        assertThat(child.enabled).isFalse()
+    }
+}
diff --git a/glance/glance/src/test/kotlin/androidx/glance/layout/DimensionTest.kt b/glance/glance/src/test/kotlin/androidx/glance/layout/DimensionTest.kt
index 398c936..43deeae 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/layout/DimensionTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/layout/DimensionTest.kt
@@ -125,4 +125,24 @@
         assertThat(widthModifier.width).isSameInstanceAs(Dimension.Wrap)
         assertThat(heightModifier.height).isSameInstanceAs(Dimension.Wrap)
     }
+
+    @Test
+    fun resourceWidthModifier() {
+        val modifier = Modifier.width(123)
+
+        val widthModifier = checkNotNull(modifier.findModifier<WidthModifier>())
+
+        val width = assertIs<Dimension.Resource>(widthModifier.width)
+        assertThat(width.res).isEqualTo(123)
+    }
+
+    @Test
+    fun resourceHeightModifier() {
+        val modifier = Modifier.height(123)
+
+        val heightModifier = checkNotNull(modifier.findModifier<HeightModifier>())
+
+        val height = assertIs<Dimension.Resource>(heightModifier.height)
+        assertThat(height.res).isEqualTo(123)
+    }
 }
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/NavBackStackEntry.kt b/navigation/navigation-common/src/main/java/androidx/navigation/NavBackStackEntry.kt
index b6b6415..9df286c 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/NavBackStackEntry.kt
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/NavBackStackEntry.kt
@@ -207,6 +207,7 @@
     override fun equals(other: Any?): Boolean {
         if (other == null || other !is NavBackStackEntry) return false
         return id == other.id && destination == other.destination &&
+            lifecycle == other.lifecycle && savedStateRegistry == other.savedStateRegistry &&
             (
                 arguments == other.arguments ||
                     arguments?.keySet()
@@ -220,6 +221,8 @@
         arguments?.keySet()?.forEach {
             result = 31 * result + arguments.get(it).hashCode()
         }
+        result = 31 * result + lifecycle.hashCode()
+        result = 31 * result + savedStateRegistry.hashCode()
         return result
     }
 
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/NavigatorState.kt b/navigation/navigation-common/src/main/java/androidx/navigation/NavigatorState.kt
index 2bc7062..9c0772b 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/NavigatorState.kt
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/NavigatorState.kt
@@ -142,8 +142,7 @@
     public open fun onLaunchSingleTop(backStackEntry: NavBackStackEntry) {
         // We update the back stack here because we don't want to leave it to the navigator since
         // it might be using transitions.
-        _backStack.value = _backStack.value - _backStack.value.last()
-        _backStack.value = _backStack.value + backStackEntry
+        _backStack.value = _backStack.value - _backStack.value.last() + backStackEntry
     }
 
     /**
@@ -159,6 +158,6 @@
      * @see popWithTransition
      */
     public open fun markTransitionComplete(entry: NavBackStackEntry) {
-        _transitionsInProgress.value = _transitionsInProgress.value.filter { it != entry }
+        _transitionsInProgress.value = _transitionsInProgress.value - entry
     }
 }
diff --git a/navigation/navigation-compose/src/main/java/androidx/navigation/compose/NavHostController.kt b/navigation/navigation-compose/src/main/java/androidx/navigation/compose/NavHostController.kt
index 92d04f4..60ca1e9 100644
--- a/navigation/navigation-compose/src/main/java/androidx/navigation/compose/NavHostController.kt
+++ b/navigation/navigation-compose/src/main/java/androidx/navigation/compose/NavHostController.kt
@@ -19,11 +19,9 @@
 import android.content.Context
 import android.os.Bundle
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.State
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
+import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.saveable.Saver
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.platform.LocalContext
@@ -42,20 +40,7 @@
  */
 @Composable
 public fun NavController.currentBackStackEntryAsState(): State<NavBackStackEntry?> {
-    val currentNavBackStackEntry = remember { mutableStateOf(currentBackStackEntry) }
-    // setup the onDestinationChangedListener responsible for detecting when the
-    // current back stack entry changes
-    DisposableEffect(this) {
-        val callback = NavController.OnDestinationChangedListener { controller, _, _ ->
-            currentNavBackStackEntry.value = controller.currentBackStackEntry
-        }
-        addOnDestinationChangedListener(callback)
-        // remove the navController on dispose (i.e. when the composable is destroyed)
-        onDispose {
-            removeOnDestinationChangedListener(callback)
-        }
-    }
-    return currentNavBackStackEntry
+    return currentBackStackEntryFlow.collectAsState(null)
 }
 
 /**
diff --git a/navigation/navigation-fragment/api/api_lint.ignore b/navigation/navigation-fragment/api/api_lint.ignore
index f0a1f88..ff18170 100644
--- a/navigation/navigation-fragment/api/api_lint.ignore
+++ b/navigation/navigation-fragment/api/api_lint.ignore
@@ -3,6 +3,8 @@
     Method FragmentNavArgsLazyKt.navArgs appears to be throwing java.lang.IllegalStateException; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
 
 
+MissingNullability: androidx.navigation.NavGraphViewModelLazyKt#navGraphViewModels(androidx.fragment.app.Fragment, String, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>):
+    Missing nullability on method `navGraphViewModels` return
 MissingNullability: androidx.navigation.NavGraphViewModelLazyKt#navGraphViewModels(androidx.fragment.app.Fragment, int, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>):
     Missing nullability on method `navGraphViewModels` return
 MissingNullability: androidx.navigation.fragment.FragmentNavArgsLazyKt#navArgs(androidx.fragment.app.Fragment):
diff --git a/navigation/navigation-fragment/api/current.txt b/navigation/navigation-fragment/api/current.txt
index 209bb31..f2297ab 100644
--- a/navigation/navigation-fragment/api/current.txt
+++ b/navigation/navigation-fragment/api/current.txt
@@ -3,6 +3,7 @@
 
   public final class NavGraphViewModelLazyKt {
     method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, String navGraphRoute, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
   }
 
 }
diff --git a/navigation/navigation-fragment/api/public_plus_experimental_current.txt b/navigation/navigation-fragment/api/public_plus_experimental_current.txt
index 209bb31..f2297ab 100644
--- a/navigation/navigation-fragment/api/public_plus_experimental_current.txt
+++ b/navigation/navigation-fragment/api/public_plus_experimental_current.txt
@@ -3,6 +3,7 @@
 
   public final class NavGraphViewModelLazyKt {
     method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, String navGraphRoute, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
   }
 
 }
diff --git a/navigation/navigation-fragment/api/restricted_current.txt b/navigation/navigation-fragment/api/restricted_current.txt
index 209bb31..f2297ab 100644
--- a/navigation/navigation-fragment/api/restricted_current.txt
+++ b/navigation/navigation-fragment/api/restricted_current.txt
@@ -3,6 +3,7 @@
 
   public final class NavGraphViewModelLazyKt {
     method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, String navGraphRoute, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
   }
 
 }
diff --git a/navigation/navigation-fragment/src/androidTest/AndroidManifest.xml b/navigation/navigation-fragment/src/androidTest/AndroidManifest.xml
index 1efa139..a6db1e1 100644
--- a/navigation/navigation-fragment/src/androidTest/AndroidManifest.xml
+++ b/navigation/navigation-fragment/src/androidTest/AndroidManifest.xml
@@ -30,5 +30,6 @@
         <activity android:name="androidx.navigation.fragment.EmptyActivity" />
         <activity android:name="androidx.navigation.fragment.TestActivity" />
         <activity android:name="androidx.navigation.fragment.NavGraphActivity" />
+        <activity android:name="androidx.navigation.fragment.NavGraphRouteActivity" />
     </application>
 </manifest>
diff --git a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/DialogFragmentNavigatorTest.kt b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/DialogFragmentNavigatorTest.kt
index 39bc126..8162236 100644
--- a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/DialogFragmentNavigatorTest.kt
+++ b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/DialogFragmentNavigatorTest.kt
@@ -44,6 +44,7 @@
 
     companion object {
         private const val INITIAL_FRAGMENT = 1
+        private const val SECOND_FRAGMENT = 2
     }
 
     @Suppress("DEPRECATION")
@@ -139,6 +140,97 @@
         assertWithMessage("Pop should dismiss the DialogFragment")
             .that(dialogFragment.requireDialog().isShowing)
             .isFalse()
+        fragmentManager.executePendingTransactions()
+        assertWithMessage("Dismiss should remove the dialog")
+            .that(dialogFragment.dialog)
+            .isNull()
+        assertWithMessage("Dismissed DialogFragment should be removed from the FragmentManager")
+            .that(fragmentManager.fragments)
+            .doesNotContain(dialogFragment)
+    }
+
+    @UiThreadTest
+    @Test
+    fun testDismiss() {
+        lateinit var dialogFragment: DialogFragment
+        fragmentManager.fragmentFactory = object : FragmentFactory() {
+            override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
+                return super.instantiate(classLoader, className).also { fragment ->
+                    if (fragment is DialogFragment) {
+                        dialogFragment = fragment
+                    }
+                }
+            }
+        }
+        val entry = createBackStackEntry()
+
+        dialogNavigator.navigate(listOf(entry), null, null)
+        assertThat(navigatorState.backStack.value)
+            .containsExactly(entry)
+        fragmentManager.executePendingTransactions()
+        assertWithMessage("Dialog should be shown")
+            .that(dialogFragment.requireDialog().isShowing)
+            .isTrue()
+
+        dialogFragment.dismiss()
+        fragmentManager.executePendingTransactions()
+        assertWithMessage("Dismiss should remove the dialog from the back stack")
+            .that(navigatorState.backStack.value)
+            .isEmpty()
+        assertWithMessage("Dismiss should remove the dialog")
+            .that(dialogFragment.dialog)
+            .isNull()
+        assertWithMessage("Dismissed DialogFragment should be removed from the FragmentManager")
+            .that(fragmentManager.fragments)
+            .doesNotContain(dialogFragment)
+    }
+
+    @UiThreadTest
+    @Test
+    fun testDismissAndNavigate() {
+        val dialogFragments = mutableListOf<DialogFragment>()
+        fragmentManager.fragmentFactory = object : FragmentFactory() {
+            override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
+                return super.instantiate(classLoader, className).also { fragment ->
+                    if (fragment is DialogFragment) {
+                        dialogFragments += fragment
+                    }
+                }
+            }
+        }
+        val entry = createBackStackEntry()
+
+        dialogNavigator.navigate(listOf(entry), null, null)
+        assertThat(navigatorState.backStack.value)
+            .containsExactly(entry)
+        fragmentManager.executePendingTransactions()
+        assertWithMessage("Dialog should be shown")
+            .that(dialogFragments[0].requireDialog().isShowing)
+            .isTrue()
+
+        val secondEntry = createBackStackEntry(SECOND_FRAGMENT)
+
+        // Call dismiss and, before executing pending transactions, call navigate()
+        dialogFragments[0].dismiss()
+        dialogNavigator.navigate(listOf(secondEntry), null, null)
+        assertThat(navigatorState.backStack.value)
+            .containsExactly(entry, secondEntry).inOrder()
+        fragmentManager.executePendingTransactions()
+        assertWithMessage("Dismiss should remove the dialogs from the back stack")
+            .that(navigatorState.backStack.value)
+            .isEmpty()
+        assertWithMessage("Dismiss should remove the dialog")
+            .that(dialogFragments[0].dialog)
+            .isNull()
+        assertWithMessage("Dismissed DialogFragment should be removed from the FragmentManager")
+            .that(fragmentManager.fragments)
+            .doesNotContain(dialogFragments[0])
+        assertWithMessage("Dismiss should remove the second dialog")
+            .that(dialogFragments[1].dialog)
+            .isNull()
+        assertWithMessage("Second DialogFragment should be removed from the FragmentManager")
+            .that(fragmentManager.fragments)
+            .doesNotContain(dialogFragments[1])
     }
 
     private fun createBackStackEntry(
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 73b3b9bf..70496b2 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
@@ -30,6 +30,7 @@
 import androidx.lifecycle.ViewModelStore
 import androidx.navigation.NavHostController
 import androidx.navigation.Navigation
+import androidx.navigation.createGraph
 import androidx.navigation.findNavController
 import androidx.navigation.fragment.test.R
 import androidx.navigation.navGraphViewModels
@@ -138,10 +139,90 @@
             assertThat(recreatedValue).isEqualTo("test")
         }
     }
+
+    @Test
+    fun sameViewModelAcrossFragmentsWithRoutes() {
+        with(ActivityScenario.launch(NavGraphRouteActivity::class.java)) {
+            val navController = withActivity { findNavController(R.id.nav_host) }
+            val firstFragment: TestRouteVMFragment = withActivity {
+                val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host)!!
+                navHostFragment.childFragmentManager.primaryNavigationFragment
+                    as TestRouteVMFragment
+            }
+            val viewModel = withActivity { firstFragment.viewModel }
+            val savedStateViewModel = withActivity { firstFragment.savedStateViewModel }
+            assertThat(viewModel).isNotNull()
+            assertThat(savedStateViewModel).isNotNull()
+
+            // First assert that we don't have any default value since the
+            // navigation graph wasn't sent any arguments
+            val initialState: String? = savedStateViewModel.savedStateHandle["test"]
+            assertThat(initialState).isNull()
+
+            // Now set arguments
+            savedStateViewModel.savedStateHandle.set("test", "test")
+
+            // Navigate to the second destination and ensure it
+            // gets the same ViewModels and data
+            withActivity {
+                navController.navigate("second_destination")
+            }
+            val secondFragment: TestRouteVMFragment = withActivity {
+                val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host)!!
+                navHostFragment.childFragmentManager.primaryNavigationFragment
+                    as TestRouteVMFragment
+            }
+            assertThat(secondFragment.viewModel)
+                .isSameInstanceAs(viewModel)
+            assertThat(secondFragment.savedStateViewModel)
+                .isSameInstanceAs(savedStateViewModel)
+            val savedValue: String? = secondFragment.savedStateViewModel
+                .savedStateHandle["test"]
+            assertThat(savedValue).isEqualTo("test")
+
+            // Now recreate the Activity and ensure that when we
+            // first request the nav graph ViewModel on the second destination
+            // that we get the same ViewModel and data back
+            recreate()
+            val recreatedFragment: TestRouteVMFragment = withActivity {
+                val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host)!!
+                navHostFragment.childFragmentManager.primaryNavigationFragment
+                    as TestRouteVMFragment
+            }
+            assertThat(recreatedFragment.viewModel)
+                .isSameInstanceAs(viewModel)
+            assertThat(recreatedFragment.savedStateViewModel)
+                .isSameInstanceAs(savedStateViewModel)
+            val recreatedValue: String? = recreatedFragment.savedStateViewModel
+                .savedStateHandle["test"]
+            assertThat(recreatedValue).isEqualTo("test")
+        }
+    }
 }
 
 class NavGraphActivity : FragmentActivity(R.layout.activity_nav_graph)
 
+class NavGraphRouteActivity : FragmentActivity(R.layout.navigation_activity_no_graph) {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        val navHostFragment =
+            supportFragmentManager.findFragmentById(R.id.nav_host) as NavHostFragment
+        navHostFragment.navController.apply {
+            graph = createGraph(
+                "start_destination",
+                "vm_graph"
+            ) {
+                fragment<TestRouteVMFragment>("start_destination") {
+                    argument("test") { defaultValue = "first" }
+                }
+                fragment<TestRouteVMFragment>("second_destination") {
+                    argument("test") { defaultValue = "second" }
+                }
+            }
+        }
+    }
+}
+
 class TestVMFragment : Fragment() {
     val viewModel: TestViewModel by navGraphViewModels(R.id.vm_graph)
     val savedStateViewModel: TestSavedStateViewModel by navGraphViewModels(R.id.vm_graph)
@@ -154,5 +235,17 @@
     }
 }
 
+class TestRouteVMFragment : Fragment() {
+    val viewModel: TestViewModel by navGraphViewModels("vm_graph")
+    val savedStateViewModel: TestSavedStateViewModel by navGraphViewModels("vm_graph")
+    override fun onCreateView(
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View? {
+        return View(activity)
+    }
+}
+
 class TestViewModel : ViewModel()
 class TestSavedStateViewModel(val savedStateHandle: SavedStateHandle) : ViewModel()
diff --git a/navigation/navigation-fragment/src/main/java/androidx/navigation/NavGraphViewModelLazy.kt b/navigation/navigation-fragment/src/main/java/androidx/navigation/NavGraphViewModelLazy.kt
index 2cb13b7..53c5c67 100644
--- a/navigation/navigation-fragment/src/main/java/androidx/navigation/NavGraphViewModelLazy.kt
+++ b/navigation/navigation-fragment/src/main/java/androidx/navigation/NavGraphViewModelLazy.kt
@@ -64,4 +64,45 @@
             factoryProducer?.invoke() ?: backStackEntry.defaultViewModelProviderFactory
         }
     )
+}
+
+/**
+ * Returns a property delegate to access a [ViewModel] scoped to a navigation graph present on the
+ * {@link NavController} back stack:
+ * ```
+ * class MyFragment : Fragment() {
+ *     val viewModel: MainViewModel by navGraphViewModels("main")
+ * }
+ * ```
+ *
+ * Custom [ViewModelProvider.Factory] can be defined via [factoryProducer] parameter,
+ * factory returned by it will be used to create [ViewModel]:
+ * ```
+ * class MyFragment : Fragment() {
+ *     val viewModel: MainViewModel by navGraphViewModels("main") { myFactory }
+ * }
+ * ```
+ *
+ * This property can be accessed only after this NavGraph is on the NavController back stack,
+ * and an attempt access prior to that will result in an IllegalArgumentException.
+ *
+ * @param navGraphRoute route of a NavGraph that exists on the [NavController] back stack
+ */
+@MainThread
+public inline fun <reified VM : ViewModel> Fragment.navGraphViewModels(
+    navGraphRoute: String,
+    noinline factoryProducer: (() -> ViewModelProvider.Factory)? = null
+): Lazy<VM> {
+    val backStackEntry by lazy {
+        findNavController().getBackStackEntry(navGraphRoute)
+    }
+    val storeProducer: () -> ViewModelStore = {
+        backStackEntry.viewModelStore
+    }
+    return createViewModelLazy(
+        VM::class, storeProducer,
+        {
+            factoryProducer?.invoke() ?: backStackEntry.defaultViewModelProviderFactory
+        }
+    )
 }
\ No newline at end of file
diff --git a/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/DialogFragmentNavigator.kt b/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/DialogFragmentNavigator.kt
index 4d07a84..286089b 100644
--- a/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/DialogFragmentNavigator.kt
+++ b/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/DialogFragmentNavigator.kt
@@ -48,9 +48,20 @@
         if (event == Lifecycle.Event.ON_STOP) {
             val dialogFragment = source as DialogFragment
             if (!dialogFragment.requireDialog().isShowing) {
-                // Update the NavigatorState to indicate that the Dialog was popped
-                val entry = state.backStack.value.first { it.id == dialogFragment.tag }
-                state.pop(entry, false)
+                val beforePopList = state.backStack.value
+                val poppedEntry = checkNotNull(beforePopList.lastOrNull {
+                    it.id == dialogFragment.tag
+                }) {
+                    "Dialog $dialogFragment has already been popped off of the Navigation " +
+                        "back stack"
+                }
+                if (beforePopList.lastOrNull() != poppedEntry) {
+                    Log.i(
+                        TAG, "Dialog $dialogFragment was dismissed while it was not the top " +
+                            "of the back stack, popping all dialogs above this dismissed dialog"
+                    )
+                }
+                popBackStack(poppedEntry, false)
             }
         }
     }
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 c77a771..fa14a8b 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryLifecycleTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryLifecycleTest.kt
@@ -30,6 +30,7 @@
 import androidx.test.filters.MediumTest
 import androidx.testutils.TestNavigator
 import androidx.testutils.test
+import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
 import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.onEach
@@ -262,6 +263,30 @@
             .isEqualTo(Lifecycle.State.DESTROYED)
     }
 
+    @UiThreadTest
+    @Test
+    fun testNavigateOptionSingleTopNestedGraph() {
+        val navController = createNavController()
+        navController.setGraph(R.navigation.nav_multiple_navigation)
+        assertThat(navController.currentDestination?.id ?: 0)
+            .isEqualTo(R.id.simple_child_start_test)
+        val navigator = navController.navigatorProvider.getNavigator(TestNavigator::class.java)
+        assertThat(navigator.backStack.size).isEqualTo(1)
+
+        val graphEntry = navController.getBackStackEntry(R.id.simple_child_start)
+
+        navController.navigate(
+            R.id.simple_child_start_test, null,
+            navOptions {
+                launchSingleTop = true
+            }
+        )
+
+        navController.popBackStack()
+
+        assertThat(graphEntry.lifecycle.currentState).isEqualTo(Lifecycle.State.DESTROYED)
+    }
+
     /**
      * Test that navigating from within a nested navigation graph to one of the graph's
      * FloatingWindow siblings correctly moves both the previous destination and its graph to
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 25f2d60..ec92699 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryTest.kt
@@ -111,7 +111,8 @@
             restoredNavController.restoreState(savedState)
             withActivity { restoredNavController.graph = navGraph }
 
-            assertThat(restoredNavController.currentBackStackEntry).isEqualTo(entry)
+            assertThat(restoredNavController.currentBackStackEntry?.id).isEqualTo(entry?.id)
+            assertThat(restoredNavController.currentBackStackEntry).isNotEqualTo(entry)
         }
     }
 
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 5cc2805..f382026 100644
--- a/navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.kt
+++ b/navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.kt
@@ -337,7 +337,7 @@
                 if (entry.lifecycle.currentState.isAtLeast(Lifecycle.State.CREATED)) {
                     entry.maxLifecycle = Lifecycle.State.DESTROYED
                 }
-                if (!savedState) {
+                if (backQueue.none { it.id == entry.id } && !savedState) {
                     viewModel?.clear(entry.id)
                 }
                 updateBackStackLifecycle()
@@ -1662,9 +1662,13 @@
             if (navOptions?.shouldLaunchSingleTop() == true &&
                 node.id == currentBackStackEntry?.destination?.id
             ) {
-                backQueue.removeLast()
+                unlinkChildFromParent(backQueue.removeLast())
                 val newEntry = NavBackStackEntry(currentBackStackEntry, finalArgs)
                 backQueue.addLast(newEntry)
+                val parent = newEntry.destination.parent
+                if (parent != null) {
+                    linkChildToParent(newEntry, getBackStackEntry(parent.id))
+                }
                 navigator.onLaunchSingleTop(newEntry)
                 launchSingleTop = true
             } else {
diff --git a/navigation/navigation-testing/src/androidTest/java/androidx/navigation/testing/TestNavigatorStateTest.kt b/navigation/navigation-testing/src/androidTest/java/androidx/navigation/testing/TestNavigatorStateTest.kt
index 8cf19f5..0203eda 100644
--- a/navigation/navigation-testing/src/androidTest/java/androidx/navigation/testing/TestNavigatorStateTest.kt
+++ b/navigation/navigation-testing/src/androidTest/java/androidx/navigation/testing/TestNavigatorStateTest.kt
@@ -154,6 +154,7 @@
         val firstEntry = state.createBackStackEntry(navigator.createDestination(), null)
 
         navigator.navigate(listOf(firstEntry), null, null)
+        state.markTransitionComplete(firstEntry)
 
         val secondEntry = state.createBackStackEntry(navigator.createDestination(), null)
         navigator.navigate(listOf(secondEntry), null, null)
@@ -165,6 +166,8 @@
         navigator.popBackStack(secondEntry, true)
         assertThat(state.transitionsInProgress.value.contains(firstEntry)).isTrue()
         assertThat(state.transitionsInProgress.value.contains(secondEntry)).isTrue()
+        state.markTransitionComplete(firstEntry)
+        state.markTransitionComplete(secondEntry)
         val restoredSecondEntry = state.restoreBackStackEntry(secondEntry)
         navigator.navigate(listOf(restoredSecondEntry), null, null)
         assertThat(
diff --git a/navigation/navigation-testing/src/main/java/androidx/navigation/testing/TestNavigatorState.kt b/navigation/navigation-testing/src/main/java/androidx/navigation/testing/TestNavigatorState.kt
index 3e57ebe..c146ce31 100644
--- a/navigation/navigation-testing/src/main/java/androidx/navigation/testing/TestNavigatorState.kt
+++ b/navigation/navigation-testing/src/main/java/androidx/navigation/testing/TestNavigatorState.kt
@@ -112,9 +112,7 @@
         val savedState = entrySavedState[entry] == true
         super.markTransitionComplete(entry)
         entrySavedState.remove(entry)
-        if (!backStack.value.contains(entry) ||
-            backStack.value[backStack.value.indexOf(entry)] !== entry
-        ) {
+        if (!backStack.value.contains(entry)) {
             updateMaxLifecycle(listOf(entry), savedState)
         } else {
             updateMaxLifecycle()
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/dao/BooksDao.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/dao/BooksDao.kt
index 7842512..2f097a2 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/dao/BooksDao.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/dao/BooksDao.kt
@@ -46,6 +46,7 @@
 import io.reactivex.Maybe
 import io.reactivex.Single
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.runBlocking
 import java.util.Date
 
 @Dao
@@ -434,6 +435,18 @@
 
     suspend fun concreteSuspendFunctionWithParams(num: Int, text: String) = "$num - $text"
 
+    @Transaction
+    fun functionWithSuspendFunctionalParam(
+        input: Book,
+        action: suspend (input: Book) -> Book
+    ): Book = runBlocking { action(input) }
+
+    @Transaction
+    suspend fun suspendFunctionWithSuspendFunctionalParam(
+        input: Book,
+        action: suspend (input: Book) -> Book
+    ): Book = action(input)
+
     // This is a private method to validate b/194706278
     private fun getNullAuthor(): Author? = null
 }
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingQueryTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingQueryTest.kt
index 1bae59f..4ac4f3a 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingQueryTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingQueryTest.kt
@@ -31,6 +31,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
 import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.ObsoleteCoroutinesApi
 import kotlinx.coroutines.async
@@ -875,4 +876,100 @@
             }
         }
     }
-}
\ No newline at end of file
+
+    @Test
+    fun transactionFunctionWithSuspendFunctionalParamCommits() = runBlocking {
+        // GIVEN a database with a book
+        val bookPublisher = TestUtil.PUBLISHER
+        val addedBook = TestUtil.BOOK_1.copy(bookPublisherId = bookPublisher.publisherId)
+        booksDao.addPublishers(bookPublisher)
+        booksDao.addBooks(addedBook)
+
+        // WHEN a transaction is run
+        val output = kotlin.runCatching {
+            booksDao.functionWithSuspendFunctionalParam(addedBook) { book ->
+                booksDao.deleteBookSuspend(book)
+                return@functionWithSuspendFunctionalParam book
+            }
+        }
+
+        // THEN the change has been committed
+        assertWithMessage("The higher-order fun ran successfully")
+            .that(output.isSuccess)
+            .isEqualTo(true)
+        assertThat(booksDao.getBooksSuspend())
+            .doesNotContain(addedBook)
+    }
+
+    @Test
+    fun transactionFunctionWithSuspendFunctionalParamDoesntCommitWhenError() = runBlocking {
+        // GIVEN a database with a book
+        val bookPublisher = TestUtil.PUBLISHER
+        val addedBook = TestUtil.BOOK_1.copy(bookPublisherId = bookPublisher.publisherId)
+        booksDao.addPublishers(bookPublisher)
+        booksDao.addBooks(addedBook)
+
+        // WHEN a transaction is started and then fails before completing
+        val output = kotlin.runCatching {
+            booksDao.functionWithSuspendFunctionalParam(addedBook) { book ->
+                booksDao.deleteBookSuspend(book)
+                error("Fake error in transaction")
+            }
+        }
+
+        // THEN the change hasn't been committed
+        assertWithMessage("RunCatching caught the thrown error")
+            .that(output.isFailure)
+            .isEqualTo(true)
+        assertThat(booksDao.getBooksSuspend())
+            .contains(addedBook)
+    }
+
+    @Test
+    fun suspendTransactionFunctionWithSuspendFunctionalParamCommits() = runBlocking {
+        // GIVEN a database with a book
+        val bookPublisher = TestUtil.PUBLISHER
+        val addedBook = TestUtil.BOOK_1.copy(bookPublisherId = bookPublisher.publisherId)
+        booksDao.addPublishers(bookPublisher)
+        booksDao.addBooks(addedBook)
+
+        // WHEN a transaction is run
+        val output = kotlin.runCatching {
+            booksDao.functionWithSuspendFunctionalParam(addedBook) { book ->
+                booksDao.deleteBookSuspend(book)
+                return@functionWithSuspendFunctionalParam book
+            }
+        }
+
+        // THEN the change has been committed
+        assertWithMessage("The higher-order fun ran successfully")
+            .that(output.isSuccess)
+            .isEqualTo(true)
+        assertThat(booksDao.getBooksSuspend())
+            .doesNotContain(addedBook)
+    }
+
+    @Test
+    fun suspendTransactionFunctionWithSuspendFunctionalParamDoesntCommitWhenError() = runBlocking {
+        // GIVEN a database with a book
+        val bookPublisher = TestUtil.PUBLISHER
+        val addedBook = TestUtil.BOOK_1.copy(bookPublisherId = bookPublisher.publisherId)
+        booksDao.addPublishers(bookPublisher)
+        booksDao.addBooks(addedBook)
+
+        // WHEN a transaction is started and then fails before completing
+        val output = runCatching {
+            booksDao.suspendFunctionWithSuspendFunctionalParam(addedBook) { book ->
+                booksDao.deleteBookSuspend(book)
+                error("Fake error in transaction")
+            }
+        }
+
+        // THEN the change hasn't been committed
+        assertWithMessage("RunCatching caught the thrown error")
+            .that(output.isFailure)
+            .isEqualTo(true)
+        assertThat(booksDao.getBooksSuspend())
+            .contains(addedBook)
+    }
+}
diff --git a/room/room-common/api/2.4.0-beta01.txt b/room/room-common/api/2.4.0-beta01.txt
new file mode 100644
index 0000000..74796f1
--- /dev/null
+++ b/room/room-common/api/2.4.0-beta01.txt
@@ -0,0 +1,276 @@
+// Signature format: 4.0
+package androidx.room {
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface AutoMigration {
+    method public abstract int from();
+    method public abstract Class<?> spec() default java.lang.Object.class;
+    method public abstract int to();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({}) public @interface BuiltInTypeConverters {
+    method public abstract androidx.room.BuiltInTypeConverters.State enums() default androidx.room.BuiltInTypeConverters.State.INHERITED;
+    method public abstract androidx.room.BuiltInTypeConverters.State uuid() default androidx.room.BuiltInTypeConverters.State.INHERITED;
+  }
+
+  public enum BuiltInTypeConverters.State {
+    enum_constant public static final androidx.room.BuiltInTypeConverters.State DISABLED;
+    enum_constant public static final androidx.room.BuiltInTypeConverters.State ENABLED;
+    enum_constant public static final androidx.room.BuiltInTypeConverters.State INHERITED;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public @interface ColumnInfo {
+    method @androidx.room.ColumnInfo.Collate public abstract int collate() default androidx.room.ColumnInfo.UNSPECIFIED;
+    method public abstract String defaultValue() default androidx.room.ColumnInfo.VALUE_UNSPECIFIED;
+    method public abstract boolean index() default false;
+    method public abstract String name() default androidx.room.ColumnInfo.INHERIT_FIELD_NAME;
+    method @androidx.room.ColumnInfo.SQLiteTypeAffinity public abstract int typeAffinity() default androidx.room.ColumnInfo.UNDEFINED;
+    field public static final int BINARY = 2; // 0x2
+    field public static final int BLOB = 5; // 0x5
+    field public static final String INHERIT_FIELD_NAME = "[field-name]";
+    field public static final int INTEGER = 3; // 0x3
+    field @RequiresApi(21) public static final int LOCALIZED = 5; // 0x5
+    field public static final int NOCASE = 3; // 0x3
+    field public static final int REAL = 4; // 0x4
+    field public static final int RTRIM = 4; // 0x4
+    field public static final int TEXT = 2; // 0x2
+    field public static final int UNDEFINED = 1; // 0x1
+    field @RequiresApi(21) public static final int UNICODE = 6; // 0x6
+    field public static final int UNSPECIFIED = 1; // 0x1
+    field public static final String VALUE_UNSPECIFIED = "[value-unspecified]";
+  }
+
+  @IntDef({androidx.room.ColumnInfo.UNSPECIFIED, androidx.room.ColumnInfo.BINARY, androidx.room.ColumnInfo.NOCASE, androidx.room.ColumnInfo.RTRIM, androidx.room.ColumnInfo.LOCALIZED, androidx.room.ColumnInfo.UNICODE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface ColumnInfo.Collate {
+  }
+
+  @IntDef({androidx.room.ColumnInfo.UNDEFINED, androidx.room.ColumnInfo.TEXT, androidx.room.ColumnInfo.INTEGER, androidx.room.ColumnInfo.REAL, androidx.room.ColumnInfo.BLOB}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface ColumnInfo.SQLiteTypeAffinity {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Dao {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Database {
+    method public abstract androidx.room.AutoMigration[] autoMigrations() default {};
+    method public abstract Class<?>[] entities();
+    method public abstract boolean exportSchema() default true;
+    method public abstract int version();
+    method public abstract Class<?>[] views() default {};
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface DatabaseView {
+    method public abstract String value() default "";
+    method public abstract String viewName() default "";
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface Delete {
+    method public abstract Class<?> entity() default java.lang.Object.class;
+  }
+
+  @java.lang.annotation.Repeatable(DeleteColumn.Entries.class) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface DeleteColumn {
+    method public abstract String columnName();
+    method public abstract String tableName();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public static @interface DeleteColumn.Entries {
+    method public abstract androidx.room.DeleteColumn[] value();
+  }
+
+  @java.lang.annotation.Repeatable(DeleteTable.Entries.class) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface DeleteTable {
+    method public abstract String tableName();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public static @interface DeleteTable.Entries {
+    method public abstract androidx.room.DeleteTable[] value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public @interface Embedded {
+    method public abstract String prefix() default "";
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Entity {
+    method public abstract androidx.room.ForeignKey[] foreignKeys() default {};
+    method public abstract String[] ignoredColumns() default {};
+    method public abstract androidx.room.Index[] indices() default {};
+    method public abstract boolean inheritSuperIndices() default false;
+    method public abstract String[] primaryKeys() default {};
+    method public abstract String tableName() default "";
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({}) public @interface ForeignKey {
+    method public abstract String[] childColumns();
+    method public abstract boolean deferred() default false;
+    method public abstract Class<?> entity();
+    method @androidx.room.ForeignKey.Action public abstract int onDelete() default androidx.room.ForeignKey.NO_ACTION;
+    method @androidx.room.ForeignKey.Action public abstract int onUpdate() default androidx.room.ForeignKey.NO_ACTION;
+    method public abstract String[] parentColumns();
+    field public static final int CASCADE = 5; // 0x5
+    field public static final int NO_ACTION = 1; // 0x1
+    field public static final int RESTRICT = 2; // 0x2
+    field public static final int SET_DEFAULT = 4; // 0x4
+    field public static final int SET_NULL = 3; // 0x3
+  }
+
+  @IntDef({androidx.room.ForeignKey.NO_ACTION, androidx.room.ForeignKey.RESTRICT, androidx.room.ForeignKey.SET_NULL, androidx.room.ForeignKey.SET_DEFAULT, androidx.room.ForeignKey.CASCADE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface ForeignKey.Action {
+  }
+
+  @RequiresApi(16) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Fts3 {
+    method public abstract String tokenizer() default androidx.room.FtsOptions.TOKENIZER_SIMPLE;
+    method public abstract String[] tokenizerArgs() default {};
+  }
+
+  @RequiresApi(16) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Fts4 {
+    method public abstract Class<?> contentEntity() default java.lang.Object.class;
+    method public abstract String languageId() default "";
+    method public abstract androidx.room.FtsOptions.MatchInfo matchInfo() default androidx.room.FtsOptions.MatchInfo.FTS4;
+    method public abstract String[] notIndexed() default {};
+    method public abstract androidx.room.FtsOptions.Order order() default androidx.room.FtsOptions.Order.ASC;
+    method public abstract int[] prefix() default {};
+    method public abstract String tokenizer() default androidx.room.FtsOptions.TOKENIZER_SIMPLE;
+    method public abstract String[] tokenizerArgs() default {};
+  }
+
+  public class FtsOptions {
+    field public static final String TOKENIZER_ICU = "icu";
+    field public static final String TOKENIZER_PORTER = "porter";
+    field public static final String TOKENIZER_SIMPLE = "simple";
+    field @RequiresApi(21) public static final String TOKENIZER_UNICODE61 = "unicode61";
+  }
+
+  public enum FtsOptions.MatchInfo {
+    enum_constant public static final androidx.room.FtsOptions.MatchInfo FTS3;
+    enum_constant public static final androidx.room.FtsOptions.MatchInfo FTS4;
+  }
+
+  public enum FtsOptions.Order {
+    enum_constant public static final androidx.room.FtsOptions.Order ASC;
+    enum_constant public static final androidx.room.FtsOptions.Order DESC;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.CONSTRUCTOR}) public @interface Ignore {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({}) public @interface Index {
+    method public abstract String name() default "";
+    method public abstract androidx.room.Index.Order[] orders() default {};
+    method public abstract boolean unique() default false;
+    method public abstract String[] value();
+  }
+
+  public enum Index.Order {
+    enum_constant public static final androidx.room.Index.Order ASC;
+    enum_constant public static final androidx.room.Index.Order DESC;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface Insert {
+    method public abstract Class<?> entity() default java.lang.Object.class;
+    method @androidx.room.OnConflictStrategy public abstract int onConflict() default androidx.room.OnConflictStrategy.ABORT;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({}) public @interface Junction {
+    method public abstract String entityColumn() default "";
+    method public abstract String parentColumn() default "";
+    method public abstract Class<?> value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface MapInfo {
+    method public abstract String keyColumn() default "";
+    method public abstract String valueColumn() default "";
+  }
+
+  @IntDef({androidx.room.OnConflictStrategy.REPLACE, androidx.room.OnConflictStrategy.ROLLBACK, androidx.room.OnConflictStrategy.ABORT, androidx.room.OnConflictStrategy.FAIL, androidx.room.OnConflictStrategy.IGNORE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface OnConflictStrategy {
+    field public static final int ABORT = 3; // 0x3
+    field @Deprecated public static final int FAIL = 4; // 0x4
+    field public static final int IGNORE = 5; // 0x5
+    field public static final int REPLACE = 1; // 0x1
+    field @Deprecated public static final int ROLLBACK = 2; // 0x2
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public @interface PrimaryKey {
+    method public abstract boolean autoGenerate() default false;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface ProvidedAutoMigrationSpec {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface ProvidedTypeConverter {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface Query {
+    method public abstract String value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface RawQuery {
+    method public abstract Class<?>[] observedEntities() default {};
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public @interface Relation {
+    method public abstract androidx.room.Junction associateBy() default @androidx.room.Junction;
+    method public abstract Class<?> entity() default java.lang.Object.class;
+    method public abstract String entityColumn();
+    method public abstract String parentColumn();
+    method public abstract String[] projection() default {};
+  }
+
+  @java.lang.annotation.Repeatable(RenameColumn.Entries.class) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface RenameColumn {
+    method public abstract String fromColumnName();
+    method public abstract String tableName();
+    method public abstract String toColumnName();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public static @interface RenameColumn.Entries {
+    method public abstract androidx.room.RenameColumn[] value();
+  }
+
+  @java.lang.annotation.Repeatable(RenameTable.Entries.class) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface RenameTable {
+    method public abstract String fromTableName();
+    method public abstract String toTableName();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public static @interface RenameTable.Entries {
+    method public abstract androidx.room.RenameTable[] value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE}) public @interface RewriteQueriesToDropUnusedColumns {
+  }
+
+  public class RoomWarnings {
+    ctor @Deprecated public RoomWarnings();
+    field public static final String CANNOT_CREATE_VERIFICATION_DATABASE = "ROOM_CANNOT_CREATE_VERIFICATION_DATABASE";
+    field public static final String CURSOR_MISMATCH = "ROOM_CURSOR_MISMATCH";
+    field public static final String DEFAULT_CONSTRUCTOR = "ROOM_DEFAULT_CONSTRUCTOR";
+    field public static final String DOES_NOT_IMPLEMENT_EQUALS_HASHCODE = "ROOM_TYPE_DOES_NOT_IMPLEMENT_EQUALS_HASHCODE";
+    field public static final String INDEX_FROM_EMBEDDED_ENTITY_IS_DROPPED = "ROOM_EMBEDDED_ENTITY_INDEX_IS_DROPPED";
+    field public static final String INDEX_FROM_EMBEDDED_FIELD_IS_DROPPED = "ROOM_EMBEDDED_INDEX_IS_DROPPED";
+    field public static final String INDEX_FROM_PARENT_FIELD_IS_DROPPED = "ROOM_PARENT_FIELD_INDEX_IS_DROPPED";
+    field public static final String INDEX_FROM_PARENT_IS_DROPPED = "ROOM_PARENT_INDEX_IS_DROPPED";
+    field public static final String MISMATCHED_GETTER = "ROOM_MISMATCHED_GETTER_TYPE";
+    field public static final String MISMATCHED_SETTER = "ROOM_MISMATCHED_SETTER_TYPE";
+    field public static final String MISSING_INDEX_ON_FOREIGN_KEY_CHILD = "ROOM_MISSING_FOREIGN_KEY_CHILD_INDEX";
+    field public static final String MISSING_INDEX_ON_JUNCTION = "MISSING_INDEX_ON_JUNCTION";
+    field public static final String MISSING_JAVA_TMP_DIR = "ROOM_MISSING_JAVA_TMP_DIR";
+    field public static final String MISSING_SCHEMA_LOCATION = "ROOM_MISSING_SCHEMA_LOCATION";
+    field public static final String PRIMARY_KEY_FROM_EMBEDDED_IS_DROPPED = "ROOM_EMBEDDED_PRIMARY_KEY_IS_DROPPED";
+    field public static final String RELATION_QUERY_WITHOUT_TRANSACTION = "ROOM_RELATION_QUERY_WITHOUT_TRANSACTION";
+    field public static final String RELATION_TYPE_MISMATCH = "ROOM_RELATION_TYPE_MISMATCH";
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE}) public @interface SkipQueryVerification {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface Transaction {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface TypeConverter {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) public @interface TypeConverters {
+    method public abstract androidx.room.BuiltInTypeConverters builtInTypeConverters() default @androidx.room.BuiltInTypeConverters;
+    method public abstract Class<?>[] value() default {};
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Update {
+    method public abstract Class<?> entity() default java.lang.Object.class;
+    method @androidx.room.OnConflictStrategy public abstract int onConflict() default androidx.room.OnConflictStrategy.ABORT;
+  }
+
+}
+
diff --git a/room/room-common/api/public_plus_experimental_2.4.0-beta01.txt b/room/room-common/api/public_plus_experimental_2.4.0-beta01.txt
new file mode 100644
index 0000000..74796f1
--- /dev/null
+++ b/room/room-common/api/public_plus_experimental_2.4.0-beta01.txt
@@ -0,0 +1,276 @@
+// Signature format: 4.0
+package androidx.room {
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface AutoMigration {
+    method public abstract int from();
+    method public abstract Class<?> spec() default java.lang.Object.class;
+    method public abstract int to();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({}) public @interface BuiltInTypeConverters {
+    method public abstract androidx.room.BuiltInTypeConverters.State enums() default androidx.room.BuiltInTypeConverters.State.INHERITED;
+    method public abstract androidx.room.BuiltInTypeConverters.State uuid() default androidx.room.BuiltInTypeConverters.State.INHERITED;
+  }
+
+  public enum BuiltInTypeConverters.State {
+    enum_constant public static final androidx.room.BuiltInTypeConverters.State DISABLED;
+    enum_constant public static final androidx.room.BuiltInTypeConverters.State ENABLED;
+    enum_constant public static final androidx.room.BuiltInTypeConverters.State INHERITED;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public @interface ColumnInfo {
+    method @androidx.room.ColumnInfo.Collate public abstract int collate() default androidx.room.ColumnInfo.UNSPECIFIED;
+    method public abstract String defaultValue() default androidx.room.ColumnInfo.VALUE_UNSPECIFIED;
+    method public abstract boolean index() default false;
+    method public abstract String name() default androidx.room.ColumnInfo.INHERIT_FIELD_NAME;
+    method @androidx.room.ColumnInfo.SQLiteTypeAffinity public abstract int typeAffinity() default androidx.room.ColumnInfo.UNDEFINED;
+    field public static final int BINARY = 2; // 0x2
+    field public static final int BLOB = 5; // 0x5
+    field public static final String INHERIT_FIELD_NAME = "[field-name]";
+    field public static final int INTEGER = 3; // 0x3
+    field @RequiresApi(21) public static final int LOCALIZED = 5; // 0x5
+    field public static final int NOCASE = 3; // 0x3
+    field public static final int REAL = 4; // 0x4
+    field public static final int RTRIM = 4; // 0x4
+    field public static final int TEXT = 2; // 0x2
+    field public static final int UNDEFINED = 1; // 0x1
+    field @RequiresApi(21) public static final int UNICODE = 6; // 0x6
+    field public static final int UNSPECIFIED = 1; // 0x1
+    field public static final String VALUE_UNSPECIFIED = "[value-unspecified]";
+  }
+
+  @IntDef({androidx.room.ColumnInfo.UNSPECIFIED, androidx.room.ColumnInfo.BINARY, androidx.room.ColumnInfo.NOCASE, androidx.room.ColumnInfo.RTRIM, androidx.room.ColumnInfo.LOCALIZED, androidx.room.ColumnInfo.UNICODE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface ColumnInfo.Collate {
+  }
+
+  @IntDef({androidx.room.ColumnInfo.UNDEFINED, androidx.room.ColumnInfo.TEXT, androidx.room.ColumnInfo.INTEGER, androidx.room.ColumnInfo.REAL, androidx.room.ColumnInfo.BLOB}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface ColumnInfo.SQLiteTypeAffinity {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Dao {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Database {
+    method public abstract androidx.room.AutoMigration[] autoMigrations() default {};
+    method public abstract Class<?>[] entities();
+    method public abstract boolean exportSchema() default true;
+    method public abstract int version();
+    method public abstract Class<?>[] views() default {};
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface DatabaseView {
+    method public abstract String value() default "";
+    method public abstract String viewName() default "";
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface Delete {
+    method public abstract Class<?> entity() default java.lang.Object.class;
+  }
+
+  @java.lang.annotation.Repeatable(DeleteColumn.Entries.class) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface DeleteColumn {
+    method public abstract String columnName();
+    method public abstract String tableName();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public static @interface DeleteColumn.Entries {
+    method public abstract androidx.room.DeleteColumn[] value();
+  }
+
+  @java.lang.annotation.Repeatable(DeleteTable.Entries.class) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface DeleteTable {
+    method public abstract String tableName();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public static @interface DeleteTable.Entries {
+    method public abstract androidx.room.DeleteTable[] value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public @interface Embedded {
+    method public abstract String prefix() default "";
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Entity {
+    method public abstract androidx.room.ForeignKey[] foreignKeys() default {};
+    method public abstract String[] ignoredColumns() default {};
+    method public abstract androidx.room.Index[] indices() default {};
+    method public abstract boolean inheritSuperIndices() default false;
+    method public abstract String[] primaryKeys() default {};
+    method public abstract String tableName() default "";
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({}) public @interface ForeignKey {
+    method public abstract String[] childColumns();
+    method public abstract boolean deferred() default false;
+    method public abstract Class<?> entity();
+    method @androidx.room.ForeignKey.Action public abstract int onDelete() default androidx.room.ForeignKey.NO_ACTION;
+    method @androidx.room.ForeignKey.Action public abstract int onUpdate() default androidx.room.ForeignKey.NO_ACTION;
+    method public abstract String[] parentColumns();
+    field public static final int CASCADE = 5; // 0x5
+    field public static final int NO_ACTION = 1; // 0x1
+    field public static final int RESTRICT = 2; // 0x2
+    field public static final int SET_DEFAULT = 4; // 0x4
+    field public static final int SET_NULL = 3; // 0x3
+  }
+
+  @IntDef({androidx.room.ForeignKey.NO_ACTION, androidx.room.ForeignKey.RESTRICT, androidx.room.ForeignKey.SET_NULL, androidx.room.ForeignKey.SET_DEFAULT, androidx.room.ForeignKey.CASCADE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface ForeignKey.Action {
+  }
+
+  @RequiresApi(16) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Fts3 {
+    method public abstract String tokenizer() default androidx.room.FtsOptions.TOKENIZER_SIMPLE;
+    method public abstract String[] tokenizerArgs() default {};
+  }
+
+  @RequiresApi(16) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Fts4 {
+    method public abstract Class<?> contentEntity() default java.lang.Object.class;
+    method public abstract String languageId() default "";
+    method public abstract androidx.room.FtsOptions.MatchInfo matchInfo() default androidx.room.FtsOptions.MatchInfo.FTS4;
+    method public abstract String[] notIndexed() default {};
+    method public abstract androidx.room.FtsOptions.Order order() default androidx.room.FtsOptions.Order.ASC;
+    method public abstract int[] prefix() default {};
+    method public abstract String tokenizer() default androidx.room.FtsOptions.TOKENIZER_SIMPLE;
+    method public abstract String[] tokenizerArgs() default {};
+  }
+
+  public class FtsOptions {
+    field public static final String TOKENIZER_ICU = "icu";
+    field public static final String TOKENIZER_PORTER = "porter";
+    field public static final String TOKENIZER_SIMPLE = "simple";
+    field @RequiresApi(21) public static final String TOKENIZER_UNICODE61 = "unicode61";
+  }
+
+  public enum FtsOptions.MatchInfo {
+    enum_constant public static final androidx.room.FtsOptions.MatchInfo FTS3;
+    enum_constant public static final androidx.room.FtsOptions.MatchInfo FTS4;
+  }
+
+  public enum FtsOptions.Order {
+    enum_constant public static final androidx.room.FtsOptions.Order ASC;
+    enum_constant public static final androidx.room.FtsOptions.Order DESC;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.CONSTRUCTOR}) public @interface Ignore {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({}) public @interface Index {
+    method public abstract String name() default "";
+    method public abstract androidx.room.Index.Order[] orders() default {};
+    method public abstract boolean unique() default false;
+    method public abstract String[] value();
+  }
+
+  public enum Index.Order {
+    enum_constant public static final androidx.room.Index.Order ASC;
+    enum_constant public static final androidx.room.Index.Order DESC;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface Insert {
+    method public abstract Class<?> entity() default java.lang.Object.class;
+    method @androidx.room.OnConflictStrategy public abstract int onConflict() default androidx.room.OnConflictStrategy.ABORT;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({}) public @interface Junction {
+    method public abstract String entityColumn() default "";
+    method public abstract String parentColumn() default "";
+    method public abstract Class<?> value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface MapInfo {
+    method public abstract String keyColumn() default "";
+    method public abstract String valueColumn() default "";
+  }
+
+  @IntDef({androidx.room.OnConflictStrategy.REPLACE, androidx.room.OnConflictStrategy.ROLLBACK, androidx.room.OnConflictStrategy.ABORT, androidx.room.OnConflictStrategy.FAIL, androidx.room.OnConflictStrategy.IGNORE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface OnConflictStrategy {
+    field public static final int ABORT = 3; // 0x3
+    field @Deprecated public static final int FAIL = 4; // 0x4
+    field public static final int IGNORE = 5; // 0x5
+    field public static final int REPLACE = 1; // 0x1
+    field @Deprecated public static final int ROLLBACK = 2; // 0x2
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public @interface PrimaryKey {
+    method public abstract boolean autoGenerate() default false;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface ProvidedAutoMigrationSpec {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface ProvidedTypeConverter {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface Query {
+    method public abstract String value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface RawQuery {
+    method public abstract Class<?>[] observedEntities() default {};
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public @interface Relation {
+    method public abstract androidx.room.Junction associateBy() default @androidx.room.Junction;
+    method public abstract Class<?> entity() default java.lang.Object.class;
+    method public abstract String entityColumn();
+    method public abstract String parentColumn();
+    method public abstract String[] projection() default {};
+  }
+
+  @java.lang.annotation.Repeatable(RenameColumn.Entries.class) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface RenameColumn {
+    method public abstract String fromColumnName();
+    method public abstract String tableName();
+    method public abstract String toColumnName();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public static @interface RenameColumn.Entries {
+    method public abstract androidx.room.RenameColumn[] value();
+  }
+
+  @java.lang.annotation.Repeatable(RenameTable.Entries.class) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface RenameTable {
+    method public abstract String fromTableName();
+    method public abstract String toTableName();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public static @interface RenameTable.Entries {
+    method public abstract androidx.room.RenameTable[] value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE}) public @interface RewriteQueriesToDropUnusedColumns {
+  }
+
+  public class RoomWarnings {
+    ctor @Deprecated public RoomWarnings();
+    field public static final String CANNOT_CREATE_VERIFICATION_DATABASE = "ROOM_CANNOT_CREATE_VERIFICATION_DATABASE";
+    field public static final String CURSOR_MISMATCH = "ROOM_CURSOR_MISMATCH";
+    field public static final String DEFAULT_CONSTRUCTOR = "ROOM_DEFAULT_CONSTRUCTOR";
+    field public static final String DOES_NOT_IMPLEMENT_EQUALS_HASHCODE = "ROOM_TYPE_DOES_NOT_IMPLEMENT_EQUALS_HASHCODE";
+    field public static final String INDEX_FROM_EMBEDDED_ENTITY_IS_DROPPED = "ROOM_EMBEDDED_ENTITY_INDEX_IS_DROPPED";
+    field public static final String INDEX_FROM_EMBEDDED_FIELD_IS_DROPPED = "ROOM_EMBEDDED_INDEX_IS_DROPPED";
+    field public static final String INDEX_FROM_PARENT_FIELD_IS_DROPPED = "ROOM_PARENT_FIELD_INDEX_IS_DROPPED";
+    field public static final String INDEX_FROM_PARENT_IS_DROPPED = "ROOM_PARENT_INDEX_IS_DROPPED";
+    field public static final String MISMATCHED_GETTER = "ROOM_MISMATCHED_GETTER_TYPE";
+    field public static final String MISMATCHED_SETTER = "ROOM_MISMATCHED_SETTER_TYPE";
+    field public static final String MISSING_INDEX_ON_FOREIGN_KEY_CHILD = "ROOM_MISSING_FOREIGN_KEY_CHILD_INDEX";
+    field public static final String MISSING_INDEX_ON_JUNCTION = "MISSING_INDEX_ON_JUNCTION";
+    field public static final String MISSING_JAVA_TMP_DIR = "ROOM_MISSING_JAVA_TMP_DIR";
+    field public static final String MISSING_SCHEMA_LOCATION = "ROOM_MISSING_SCHEMA_LOCATION";
+    field public static final String PRIMARY_KEY_FROM_EMBEDDED_IS_DROPPED = "ROOM_EMBEDDED_PRIMARY_KEY_IS_DROPPED";
+    field public static final String RELATION_QUERY_WITHOUT_TRANSACTION = "ROOM_RELATION_QUERY_WITHOUT_TRANSACTION";
+    field public static final String RELATION_TYPE_MISMATCH = "ROOM_RELATION_TYPE_MISMATCH";
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE}) public @interface SkipQueryVerification {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface Transaction {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface TypeConverter {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) public @interface TypeConverters {
+    method public abstract androidx.room.BuiltInTypeConverters builtInTypeConverters() default @androidx.room.BuiltInTypeConverters;
+    method public abstract Class<?>[] value() default {};
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Update {
+    method public abstract Class<?> entity() default java.lang.Object.class;
+    method @androidx.room.OnConflictStrategy public abstract int onConflict() default androidx.room.OnConflictStrategy.ABORT;
+  }
+
+}
+
diff --git a/room/room-common/api/restricted_2.4.0-beta01.txt b/room/room-common/api/restricted_2.4.0-beta01.txt
new file mode 100644
index 0000000..51036df
--- /dev/null
+++ b/room/room-common/api/restricted_2.4.0-beta01.txt
@@ -0,0 +1,285 @@
+// Signature format: 4.0
+package androidx.room {
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface AutoMigration {
+    method public abstract int from();
+    method public abstract Class<?> spec() default java.lang.Object.class;
+    method public abstract int to();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({}) public @interface BuiltInTypeConverters {
+    method public abstract androidx.room.BuiltInTypeConverters.State enums() default androidx.room.BuiltInTypeConverters.State.INHERITED;
+    method public abstract androidx.room.BuiltInTypeConverters.State uuid() default androidx.room.BuiltInTypeConverters.State.INHERITED;
+  }
+
+  public enum BuiltInTypeConverters.State {
+    enum_constant public static final androidx.room.BuiltInTypeConverters.State DISABLED;
+    enum_constant public static final androidx.room.BuiltInTypeConverters.State ENABLED;
+    enum_constant public static final androidx.room.BuiltInTypeConverters.State INHERITED;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public @interface ColumnInfo {
+    method @androidx.room.ColumnInfo.Collate public abstract int collate() default androidx.room.ColumnInfo.UNSPECIFIED;
+    method public abstract String defaultValue() default androidx.room.ColumnInfo.VALUE_UNSPECIFIED;
+    method public abstract boolean index() default false;
+    method public abstract String name() default androidx.room.ColumnInfo.INHERIT_FIELD_NAME;
+    method @androidx.room.ColumnInfo.SQLiteTypeAffinity public abstract int typeAffinity() default androidx.room.ColumnInfo.UNDEFINED;
+    field public static final int BINARY = 2; // 0x2
+    field public static final int BLOB = 5; // 0x5
+    field public static final String INHERIT_FIELD_NAME = "[field-name]";
+    field public static final int INTEGER = 3; // 0x3
+    field @RequiresApi(21) public static final int LOCALIZED = 5; // 0x5
+    field public static final int NOCASE = 3; // 0x3
+    field public static final int REAL = 4; // 0x4
+    field public static final int RTRIM = 4; // 0x4
+    field public static final int TEXT = 2; // 0x2
+    field public static final int UNDEFINED = 1; // 0x1
+    field @RequiresApi(21) public static final int UNICODE = 6; // 0x6
+    field public static final int UNSPECIFIED = 1; // 0x1
+    field public static final String VALUE_UNSPECIFIED = "[value-unspecified]";
+  }
+
+  @IntDef({androidx.room.ColumnInfo.UNSPECIFIED, androidx.room.ColumnInfo.BINARY, androidx.room.ColumnInfo.NOCASE, androidx.room.ColumnInfo.RTRIM, androidx.room.ColumnInfo.LOCALIZED, androidx.room.ColumnInfo.UNICODE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface ColumnInfo.Collate {
+  }
+
+  @IntDef({androidx.room.ColumnInfo.UNDEFINED, androidx.room.ColumnInfo.TEXT, androidx.room.ColumnInfo.INTEGER, androidx.room.ColumnInfo.REAL, androidx.room.ColumnInfo.BLOB}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface ColumnInfo.SQLiteTypeAffinity {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Dao {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Database {
+    method public abstract androidx.room.AutoMigration[] autoMigrations() default {};
+    method public abstract Class<?>[] entities();
+    method public abstract boolean exportSchema() default true;
+    method public abstract int version();
+    method public abstract Class<?>[] views() default {};
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface DatabaseView {
+    method public abstract String value() default "";
+    method public abstract String viewName() default "";
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface Delete {
+    method public abstract Class<?> entity() default java.lang.Object.class;
+  }
+
+  @java.lang.annotation.Repeatable(DeleteColumn.Entries.class) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface DeleteColumn {
+    method public abstract String columnName();
+    method public abstract String tableName();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public static @interface DeleteColumn.Entries {
+    method public abstract androidx.room.DeleteColumn[] value();
+  }
+
+  @java.lang.annotation.Repeatable(DeleteTable.Entries.class) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface DeleteTable {
+    method public abstract String tableName();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public static @interface DeleteTable.Entries {
+    method public abstract androidx.room.DeleteTable[] value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public @interface Embedded {
+    method public abstract String prefix() default "";
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Entity {
+    method public abstract androidx.room.ForeignKey[] foreignKeys() default {};
+    method public abstract String[] ignoredColumns() default {};
+    method public abstract androidx.room.Index[] indices() default {};
+    method public abstract boolean inheritSuperIndices() default false;
+    method public abstract String[] primaryKeys() default {};
+    method public abstract String tableName() default "";
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({}) public @interface ForeignKey {
+    method public abstract String[] childColumns();
+    method public abstract boolean deferred() default false;
+    method public abstract Class<?> entity();
+    method @androidx.room.ForeignKey.Action public abstract int onDelete() default androidx.room.ForeignKey.NO_ACTION;
+    method @androidx.room.ForeignKey.Action public abstract int onUpdate() default androidx.room.ForeignKey.NO_ACTION;
+    method public abstract String[] parentColumns();
+    field public static final int CASCADE = 5; // 0x5
+    field public static final int NO_ACTION = 1; // 0x1
+    field public static final int RESTRICT = 2; // 0x2
+    field public static final int SET_DEFAULT = 4; // 0x4
+    field public static final int SET_NULL = 3; // 0x3
+  }
+
+  @IntDef({androidx.room.ForeignKey.NO_ACTION, androidx.room.ForeignKey.RESTRICT, androidx.room.ForeignKey.SET_NULL, androidx.room.ForeignKey.SET_DEFAULT, androidx.room.ForeignKey.CASCADE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface ForeignKey.Action {
+  }
+
+  @RequiresApi(16) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Fts3 {
+    method public abstract String tokenizer() default androidx.room.FtsOptions.TOKENIZER_SIMPLE;
+    method public abstract String[] tokenizerArgs() default {};
+  }
+
+  @RequiresApi(16) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface Fts4 {
+    method public abstract Class<?> contentEntity() default java.lang.Object.class;
+    method public abstract String languageId() default "";
+    method public abstract androidx.room.FtsOptions.MatchInfo matchInfo() default androidx.room.FtsOptions.MatchInfo.FTS4;
+    method public abstract String[] notIndexed() default {};
+    method public abstract androidx.room.FtsOptions.Order order() default androidx.room.FtsOptions.Order.ASC;
+    method public abstract int[] prefix() default {};
+    method public abstract String tokenizer() default androidx.room.FtsOptions.TOKENIZER_SIMPLE;
+    method public abstract String[] tokenizerArgs() default {};
+  }
+
+  public class FtsOptions {
+    field public static final String TOKENIZER_ICU = "icu";
+    field public static final String TOKENIZER_PORTER = "porter";
+    field public static final String TOKENIZER_SIMPLE = "simple";
+    field @RequiresApi(21) public static final String TOKENIZER_UNICODE61 = "unicode61";
+  }
+
+  public enum FtsOptions.MatchInfo {
+    enum_constant public static final androidx.room.FtsOptions.MatchInfo FTS3;
+    enum_constant public static final androidx.room.FtsOptions.MatchInfo FTS4;
+  }
+
+  public enum FtsOptions.Order {
+    enum_constant public static final androidx.room.FtsOptions.Order ASC;
+    enum_constant public static final androidx.room.FtsOptions.Order DESC;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.CONSTRUCTOR}) public @interface Ignore {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({}) public @interface Index {
+    method public abstract String name() default "";
+    method public abstract androidx.room.Index.Order[] orders() default {};
+    method public abstract boolean unique() default false;
+    method public abstract String[] value();
+  }
+
+  public enum Index.Order {
+    enum_constant public static final androidx.room.Index.Order ASC;
+    enum_constant public static final androidx.room.Index.Order DESC;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface Insert {
+    method public abstract Class<?> entity() default java.lang.Object.class;
+    method @androidx.room.OnConflictStrategy public abstract int onConflict() default androidx.room.OnConflictStrategy.ABORT;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({}) public @interface Junction {
+    method public abstract String entityColumn() default "";
+    method public abstract String parentColumn() default "";
+    method public abstract Class<?> value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface MapInfo {
+    method public abstract String keyColumn() default "";
+    method public abstract String valueColumn() default "";
+  }
+
+  @IntDef({androidx.room.OnConflictStrategy.REPLACE, androidx.room.OnConflictStrategy.ROLLBACK, androidx.room.OnConflictStrategy.ABORT, androidx.room.OnConflictStrategy.FAIL, androidx.room.OnConflictStrategy.IGNORE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface OnConflictStrategy {
+    field public static final int ABORT = 3; // 0x3
+    field @Deprecated public static final int FAIL = 4; // 0x4
+    field public static final int IGNORE = 5; // 0x5
+    field public static final int REPLACE = 1; // 0x1
+    field @Deprecated public static final int ROLLBACK = 2; // 0x2
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public @interface PrimaryKey {
+    method public abstract boolean autoGenerate() default false;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface ProvidedAutoMigrationSpec {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface ProvidedTypeConverter {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface Query {
+    method public abstract String value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface RawQuery {
+    method public abstract Class<?>[] observedEntities() default {};
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public @interface Relation {
+    method public abstract androidx.room.Junction associateBy() default @androidx.room.Junction;
+    method public abstract Class<?> entity() default java.lang.Object.class;
+    method public abstract String entityColumn();
+    method public abstract String parentColumn();
+    method public abstract String[] projection() default {};
+  }
+
+  @java.lang.annotation.Repeatable(RenameColumn.Entries.class) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface RenameColumn {
+    method public abstract String fromColumnName();
+    method public abstract String tableName();
+    method public abstract String toColumnName();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public static @interface RenameColumn.Entries {
+    method public abstract androidx.room.RenameColumn[] value();
+  }
+
+  @java.lang.annotation.Repeatable(RenameTable.Entries.class) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface RenameTable {
+    method public abstract String fromTableName();
+    method public abstract String toTableName();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public static @interface RenameTable.Entries {
+    method public abstract androidx.room.RenameTable[] value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE}) public @interface RewriteQueriesToDropUnusedColumns {
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class RoomMasterTable {
+    method public static String! createInsertQuery(String!);
+    field public static final String CREATE_QUERY = "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)";
+    field public static final String DEFAULT_ID = "42";
+    field public static final String NAME = "room_master_table";
+    field public static final String READ_QUERY = "SELECT identity_hash FROM room_master_table WHERE id = 42 LIMIT 1";
+    field public static final String TABLE_NAME = "room_master_table";
+  }
+
+  public class RoomWarnings {
+    ctor @Deprecated public RoomWarnings();
+    field public static final String CANNOT_CREATE_VERIFICATION_DATABASE = "ROOM_CANNOT_CREATE_VERIFICATION_DATABASE";
+    field public static final String CURSOR_MISMATCH = "ROOM_CURSOR_MISMATCH";
+    field public static final String DEFAULT_CONSTRUCTOR = "ROOM_DEFAULT_CONSTRUCTOR";
+    field public static final String DOES_NOT_IMPLEMENT_EQUALS_HASHCODE = "ROOM_TYPE_DOES_NOT_IMPLEMENT_EQUALS_HASHCODE";
+    field public static final String INDEX_FROM_EMBEDDED_ENTITY_IS_DROPPED = "ROOM_EMBEDDED_ENTITY_INDEX_IS_DROPPED";
+    field public static final String INDEX_FROM_EMBEDDED_FIELD_IS_DROPPED = "ROOM_EMBEDDED_INDEX_IS_DROPPED";
+    field public static final String INDEX_FROM_PARENT_FIELD_IS_DROPPED = "ROOM_PARENT_FIELD_INDEX_IS_DROPPED";
+    field public static final String INDEX_FROM_PARENT_IS_DROPPED = "ROOM_PARENT_INDEX_IS_DROPPED";
+    field public static final String MISMATCHED_GETTER = "ROOM_MISMATCHED_GETTER_TYPE";
+    field public static final String MISMATCHED_SETTER = "ROOM_MISMATCHED_SETTER_TYPE";
+    field public static final String MISSING_INDEX_ON_FOREIGN_KEY_CHILD = "ROOM_MISSING_FOREIGN_KEY_CHILD_INDEX";
+    field public static final String MISSING_INDEX_ON_JUNCTION = "MISSING_INDEX_ON_JUNCTION";
+    field public static final String MISSING_JAVA_TMP_DIR = "ROOM_MISSING_JAVA_TMP_DIR";
+    field public static final String MISSING_SCHEMA_LOCATION = "ROOM_MISSING_SCHEMA_LOCATION";
+    field public static final String PRIMARY_KEY_FROM_EMBEDDED_IS_DROPPED = "ROOM_EMBEDDED_PRIMARY_KEY_IS_DROPPED";
+    field public static final String RELATION_QUERY_WITHOUT_TRANSACTION = "ROOM_RELATION_QUERY_WITHOUT_TRANSACTION";
+    field public static final String RELATION_TYPE_MISMATCH = "ROOM_RELATION_TYPE_MISMATCH";
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE}) public @interface SkipQueryVerification {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface Transaction {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface TypeConverter {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) public @interface TypeConverters {
+    method public abstract androidx.room.BuiltInTypeConverters builtInTypeConverters() default @androidx.room.BuiltInTypeConverters;
+    method public abstract Class<?>[] value() default {};
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Update {
+    method public abstract Class<?> entity() default java.lang.Object.class;
+    method @androidx.room.OnConflictStrategy public abstract int onConflict() default androidx.room.OnConflictStrategy.ABORT;
+  }
+
+}
+
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/DeclarationCollector.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/DeclarationCollector.kt
index f0b7ed5..7dd33ea2 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/DeclarationCollector.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/DeclarationCollector.kt
@@ -24,21 +24,23 @@
 ): Sequence<XFieldElement> {
     return sequence {
         val existingFieldNames = mutableSetOf<String>()
-
-        // yield all fields declared directly on this type
-        xTypeElement.getDeclaredFields().forEach {
-            if (existingFieldNames.add(it.name)) {
-                yield(it)
-            }
-        }
-        // yield all fields on the parents
-        xTypeElement.superType?.typeElement?.let { parent ->
-            parent.getAllFieldsIncludingPrivateSupers().forEach {
+        suspend fun SequenceScope<XFieldElement>.yieldAllFields(type: XTypeElement) {
+            // yield all fields declared directly on this type
+            type.getDeclaredFields().forEach {
                 if (existingFieldNames.add(it.name)) {
-                    yield(it.copyTo(xTypeElement))
+                    if (type == xTypeElement) {
+                        yield(it)
+                    } else {
+                        yield(it.copyTo(xTypeElement))
+                    }
                 }
             }
+            // visit all declared fields on super types
+            type.superType?.typeElement?.let { parent ->
+                yieldAllFields(parent)
+            }
         }
+        yieldAllFields(xTypeElement)
     }
 }
 
@@ -51,15 +53,14 @@
     return sequence {
         // group methods by name for faster override checks
         val methodsByName = mutableMapOf<String, LinkedHashSet<XMethodElement>>()
-        val visitedTypes = mutableSetOf<XTypeElement>()
+        val visitedInterfaces = mutableSetOf<XTypeElement>()
         fun collectAllMethodsByName(type: XTypeElement) {
-            if (!visitedTypes.add(type)) {
-                // Just return if we've already visited the methods in this type.
-                return
-            }
             // First, visit all super interface methods.
             type.getSuperInterfaceElements().forEach {
-                collectAllMethodsByName(it)
+                // Skip if we've already visited the methods in this interface.
+                if (visitedInterfaces.add(it)) {
+                    collectAllMethodsByName(it)
+                }
             }
             // Next, visit all super class methods.
             type.superType?.typeElement?.let {
@@ -96,8 +97,8 @@
                     methods.subList(i + 1, methods.size).forEach { methodTwo ->
                         if (methodTwo.overrides(methodOne, xTypeElement)) {
                             overridden.add(methodOne)
-                            // Once we've added methodI, we can break out of this inner loop since
-                            // additional checks would only try to add methodI again.
+                            // Once we've added methodOne, we can break out of this inner loop since
+                            // additional checks would only try to add methodOne again.
                             return@forEachIndexed
                         }
                     }
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
index f8c7623..8e89adfe 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
@@ -37,7 +37,7 @@
 import com.squareup.javapoet.TypeName
 import com.squareup.javapoet.TypeVariableName
 import com.squareup.javapoet.WildcardTypeName
-import kotlin.IllegalStateException
+import kotlin.coroutines.Continuation
 
 // Catch-all type name when we cannot resolve to anything. This is what KAPT uses as error type
 // and we use the same type in KSP for consistency.
@@ -184,15 +184,21 @@
     typeArgumentTypeLookup: TypeArgumentTypeLookup
 ): TypeName {
     return if (this.arguments.isNotEmpty()) {
-        val args: Array<TypeName> = this.arguments.mapIndexed { index, typeArg ->
-            typeArg.typeName(
-                param = this.declaration.typeParameters[index],
-                resolver = resolver,
-                typeArgumentTypeLookup = typeArgumentTypeLookup
-            )
-        }.map {
-            it.tryBox()
-        }.toTypedArray()
+        val args: Array<TypeName> = this.arguments
+            .mapIndexed { index, typeArg ->
+                typeArg.typeName(
+                    param = this.declaration.typeParameters[index],
+                    resolver = resolver,
+                    typeArgumentTypeLookup = typeArgumentTypeLookup
+                )
+            }
+            .map { it.tryBox() }
+            .let { args ->
+                if (this.isSuspendFunctionType) args.convertToSuspendSignature()
+                else args
+            }
+            .toTypedArray()
+
         when (
             val typeName = declaration
                 .typeName(resolver, typeArgumentTypeLookup).tryBox()
@@ -210,6 +216,29 @@
 }
 
 /**
+ * Transforms [this] list of arguments to a suspend signature. For a [suspend] functional type, we
+ * need to transform it to be a FunctionX with a [Continuation] with the correct return type. A
+ * transformed SuspendFunction looks like this:
+ *
+ * FunctionX<[? super $params], ? super Continuation<? super $ReturnType>, ?>
+ */
+private fun List<TypeName>.convertToSuspendSignature(): List<TypeName> {
+    val args = this
+
+    // The last arg is the return type, so take everything except the last arg
+    val actualArgs = args.subList(0, args.size - 1)
+    val continuationReturnType = WildcardTypeName.supertypeOf(args.last())
+    val continuationType = ParameterizedTypeName.get(
+        ClassName.get(Continuation::class.java),
+        continuationReturnType
+    )
+    return actualArgs + listOf(
+        WildcardTypeName.supertypeOf(continuationType),
+        WildcardTypeName.subtypeOf(TypeName.OBJECT)
+    )
+}
+
+/**
  * Root package comes as <root> instead of "" so we work around it here.
  */
 internal fun KSDeclaration.getNormalizedPackageName(): String {
@@ -275,4 +304,4 @@
 ): TypeVariableName = typeVarNameConstructor.newInstance(
     name,
     bounds
-) as TypeVariableName
\ No newline at end of file
+) as TypeVariableName
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/MethodSpecHelperTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/MethodSpecHelperTest.kt
index f76ad64..43a0b27 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/MethodSpecHelperTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/MethodSpecHelperTest.kt
@@ -190,6 +190,22 @@
                 }
                 fun singleArg_returnsInterface(operation: (Int) -> MyInterface) {
                 }
+
+                fun noArg_suspend_returnsUnit(operation: suspend () -> Unit) {
+                }
+
+                suspend fun suspend_noArg_suspend_returnsUnit(operation: suspend () -> Unit) {
+                }
+                suspend fun suspend_no_arg_suspend_returnsString(operation: suspend () -> String) {
+                }
+                suspend fun suspend_singleArg_suspend_returnsUnit(operation: suspend (arg: String) -> Unit) {
+                }
+                suspend fun suspend_threeArgs_suspend_returnsUnit(operation: suspend (one: String, two: Int, three: Boolean) -> Unit) {
+                }
+                suspend fun suspend_singleArg_suspend_returnsString(operation: suspend (arg: String) -> String) {
+                }
+                suspend fun suspend_threeArgs_suspend_returnsString(operation: suspend (one: String, two: Int, three: Boolean) -> String) {
+                }
             }
             """.trimIndent()
         )
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/parser/SqlParser.kt b/room/room-compiler/src/main/kotlin/androidx/room/parser/SqlParser.kt
index a9eeb8c..5241975 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/parser/SqlParser.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/parser/SqlParser.kt
@@ -256,7 +256,7 @@
     REAL,
     BLOB;
 
-    fun getTypeMirrors(env: XProcessingEnv): List<XType> {
+    fun getTypeMirrors(env: XProcessingEnv): List<XType>? {
         return when (this) {
             TEXT -> withBoxedAndNullableTypes(env, CommonTypeNames.STRING)
             INTEGER -> withBoxedAndNullableTypes(
@@ -265,7 +265,7 @@
             )
             REAL -> withBoxedAndNullableTypes(env, TypeName.DOUBLE, TypeName.FLOAT)
             BLOB -> withBoxedAndNullableTypes(env, ArrayTypeName.of(TypeName.BYTE))
-            else -> emptyList()
+            else -> null
         }
     }
 
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt b/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
index db3b91e..7af6697 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
@@ -122,9 +122,8 @@
      * first type adapter has the highest priority
      */
     private val columnTypeAdapters: List<ColumnTypeAdapter>,
-
-    private val typeConverterStore: TypeConverterStore,
-
+    @VisibleForTesting
+    internal val typeConverterStore: TypeConverterStore,
     private val builtInConverterFlags: BuiltInConverterFlags
 ) {
 
@@ -177,7 +176,10 @@
                 .forEach(::addTypeConverter)
             return TypeAdapterStore(
                 context = context, columnTypeAdapters = adapters,
-                typeConverterStore = TypeConverterStore(converters),
+                typeConverterStore = TypeConverterStore(
+                    typeConverters = converters,
+                    knownColumnTypes = adapters.map { it.out }
+                ),
                 builtInConverterFlags = builtInConverterFlags
             )
         }
@@ -218,11 +220,6 @@
             add(InstantDeleteOrUpdateMethodBinderProvider(context))
         }
 
-    // type mirrors that be converted into columns w/o an extra converter
-    private val knownColumnTypeMirrors by lazy {
-        columnTypeAdapters.map { it.out }
-    }
-
     /**
      * Searches 1 way to bind a value into a statement.
      */
@@ -239,8 +236,11 @@
         }
 
         fun findTypeConverterAdapter(): ColumnTypeAdapter? {
-            val targetTypes = targetTypeMirrorsFor(affinity)
-            val binder = findTypeConverter(input, targetTypes) ?: return null
+            val targetTypes = affinity?.getTypeMirrors(context.processingEnv)
+            val binder = typeConverterStore.findConverterIntoStatement(
+                input = input,
+                columnTypes = targetTypes
+            ) ?: return null
             // columnAdapter should not be null but we are receiving errors on crash in `first()` so
             // this safeguard allows us to dispatch the real problem to the user (e.g. why we couldn't
             // find the right adapter)
@@ -260,18 +260,6 @@
     }
 
     /**
-     * Returns which entities targets the given affinity.
-     */
-    private fun targetTypeMirrorsFor(affinity: SQLTypeAffinity?): List<XType> {
-        val specifiedTargets = affinity?.getTypeMirrors(context.processingEnv)
-        return if (specifiedTargets == null || specifiedTargets.isEmpty()) {
-            knownColumnTypeMirrors
-        } else {
-            specifiedTargets
-        }
-    }
-
-    /**
      * Searches 1 way to read it from cursor
      */
     fun findCursorValueReader(output: XType, affinity: SQLTypeAffinity?): CursorValueReader? {
@@ -285,8 +273,11 @@
         }
 
         fun findTypeConverterAdapter(): ColumnTypeAdapter? {
-            val targetTypes = targetTypeMirrorsFor(affinity)
-            val converter = findTypeConverter(targetTypes, output) ?: return null
+            val targetTypes = affinity?.getTypeMirrors(context.processingEnv)
+            val converter = typeConverterStore.findConverterFromCursor(
+                columnTypes = targetTypes,
+                output = output
+            ) ?: return null
             return CompositeAdapter(
                 output,
                 getAllColumnAdapters(converter.from).first(), null, converter
@@ -308,14 +299,6 @@
     }
 
     /**
-     * Tries to reverse the converter going through the same nodes, if possible.
-     */
-    @VisibleForTesting
-    fun reverse(converter: TypeConverter): TypeConverter? {
-        return typeConverterStore.reverse(converter)
-    }
-
-    /**
      * Finds a two way converter, if you need 1 way, use findStatementValueBinder or
      * findCursorValueReader.
      */
@@ -333,11 +316,14 @@
         }
 
         fun findTypeConverterAdapter(): ColumnTypeAdapter? {
-            val targetTypes = targetTypeMirrorsFor(affinity)
-            val intoStatement = findTypeConverter(out, targetTypes) ?: return null
+            val targetTypes = affinity?.getTypeMirrors(context.processingEnv)
+            val intoStatement = typeConverterStore.findConverterIntoStatement(
+                input = out,
+                columnTypes = targetTypes
+            ) ?: return null
             // ok found a converter, try the reverse now
-            val fromCursor = reverse(intoStatement)
-                ?: findTypeConverter(intoStatement.to, out) ?: return null
+            val fromCursor = typeConverterStore.reverse(intoStatement)
+                ?: typeConverterStore.findTypeConverter(intoStatement.to, out) ?: return null
             return CompositeAdapter(
                 out, getAllColumnAdapters(intoStatement.to).first(), intoStatement, fromCursor
             )
@@ -377,10 +363,6 @@
         }
     }
 
-    fun findTypeConverter(input: XType, output: XType): TypeConverter? {
-        return typeConverterStore.findTypeConverter(listOf(input), listOf(output))
-    }
-
     fun findDeleteOrUpdateMethodBinder(typeMirror: XType): DeleteOrUpdateMethodBinder {
         return deleteOrUpdateBinderProvider.first {
             it.matches(typeMirror)
@@ -811,14 +793,6 @@
         }
     }
 
-    private fun findTypeConverter(input: XType, outputs: List<XType>): TypeConverter? {
-        return typeConverterStore.findTypeConverter(listOf(input), outputs)
-    }
-
-    private fun findTypeConverter(input: List<XType>, output: XType): TypeConverter? {
-        return typeConverterStore.findTypeConverter(input, listOf(output))
-    }
-
     private fun getAllColumnAdapters(input: XType): List<ColumnTypeAdapter> {
         return columnTypeAdapters.filter {
             input.isSameType(it.out)
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeConverterStore.kt b/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeConverterStore.kt
index 43ac3e3..c1184c5 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeConverterStore.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeConverterStore.kt
@@ -28,15 +28,58 @@
  * provided type converters.
  */
 class TypeConverterStore(
-    private val typeConverters: List<TypeConverter>
+    /**
+     * Available TypeConverters
+     */
+    private val typeConverters: List<TypeConverter>,
+    /**
+     * List of types that can be saved into db/read from without a converter.
+     */
+    private val knownColumnTypes: List<XType>
 ) {
     /**
-     * Finds a type converter that can conver one of the input valuese to one of the output values.
+     * Finds a [TypeConverter] (might be composite) that can convert the given [input] type into
+     * one of the given [columnTypes]. If [columnTypes] is not specified, targets all
+     * [knownColumnTypes].
+     */
+    fun findConverterIntoStatement(
+        input: XType,
+        columnTypes: List<XType>? = null
+    ) = findTypeConverter(
+        inputs = listOf(input),
+        outputs = columnTypes ?: knownColumnTypes
+    )
+
+    /**
+     * Finds a [TypeConverter] (might be composite) that can convert the given [columnTypes] into
+     * the [output] type. If [columnTypes] is not specified, uses all [knownColumnTypes].
+     */
+    fun findConverterFromCursor(
+        columnTypes: List<XType>? = null,
+        output: XType
+    ) = findTypeConverter(
+        inputs = columnTypes ?: knownColumnTypes,
+        outputs = listOf(output)
+    )
+
+    /**
+     * Finds a [TypeConverter] from [input] to [output].
+     */
+    fun findTypeConverter(
+        input: XType,
+        output: XType
+    ) = findTypeConverter(
+        inputs = listOf(input),
+        outputs = listOf(output)
+    )
+
+    /**
+     * Finds a type converter that can convert one of the input values to one of the output values.
      *
      * When multiple conversion paths are possible, shortest path (least amount of conversion) is
      * preferred.
      */
-    fun findTypeConverter(
+    private fun findTypeConverter(
         inputs: List<XType>,
         outputs: List<XType>
     ): TypeConverter? {
@@ -119,6 +162,7 @@
             }
         }
     }
+
     /**
      * Tries to reverse the converter going through the same nodes, if possible.
      */
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/verifier/ColumnInfo.kt b/room/room-compiler/src/main/kotlin/androidx/room/verifier/ColumnInfo.kt
index 788beaf..b7f937b 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/verifier/ColumnInfo.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/verifier/ColumnInfo.kt
@@ -21,4 +21,8 @@
 /**
  * Represents a column in a query response
  */
-data class ColumnInfo(val name: String, val type: SQLTypeAffinity)
+data class ColumnInfo(
+    val name: String,
+    val type: SQLTypeAffinity,
+    val originTable: String?,
+)
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/verifier/jdbc_ext.kt b/room/room-compiler/src/main/kotlin/androidx/room/verifier/jdbc_ext.kt
index a5da941..bd3b351 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/verifier/jdbc_ext.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/verifier/jdbc_ext.kt
@@ -61,5 +61,11 @@
 
 internal fun PreparedStatement.columnInfo(): List<ColumnInfo> {
     // see: http://sqlite.1065341.n5.nabble.com/Column-order-in-resultset-td23127.html
-    return map { index, data -> ColumnInfo(data.getColumnName(index), tryGetAffinity(index)) }
+    return map { index, data ->
+        ColumnInfo(
+            name = data.getColumnName(index),
+            type = tryGetAffinity(index),
+            originTable = data.getTableName(index)?.ifEmpty { null }
+        )
+    }
 }
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/parser/SQLTypeAffinityTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/parser/SQLTypeAffinityTest.kt
index 9f3f8d6..fff0299 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/parser/SQLTypeAffinityTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/parser/SQLTypeAffinityTest.kt
@@ -49,7 +49,7 @@
             }
 
             val result = SQLTypeAffinity.values().associate {
-                it to it.getTypeMirrors(invocation.processingEnv).map(XType::toSignature)
+                it to it.getTypeMirrors(invocation.processingEnv)?.map(XType::toSignature)
             }
             assertThat(result).containsExactlyEntriesIn(
                 if (invocation.isKsp) KSP_MAPPING
@@ -60,7 +60,7 @@
 
     companion object {
         private val KSP_MAPPING = mapOf(
-            SQLTypeAffinity.NULL to listOf(),
+            SQLTypeAffinity.NULL to null,
             SQLTypeAffinity.TEXT to listOf(
                 "java.lang.String!!",
                 "java.lang.String?"
@@ -89,7 +89,7 @@
             )
         )
         private val JAVAC_MAPPING = mapOf(
-            SQLTypeAffinity.NULL to listOf(),
+            SQLTypeAffinity.NULL to null,
             SQLTypeAffinity.TEXT to listOf(
                 "java.lang.String"
             ),
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseViewProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseViewProcessorTest.kt
index 8e5d448..93870ff 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseViewProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseViewProcessorTest.kt
@@ -90,8 +90,8 @@
             val resultInfo = view.query.resultInfo!!
             assertThat(resultInfo.columns).hasSize(2)
             assertThat(resultInfo.columns).containsAtLeast(
-                ColumnInfo("id", SQLTypeAffinity.INTEGER),
-                ColumnInfo("name", SQLTypeAffinity.TEXT)
+                ColumnInfo("id", SQLTypeAffinity.INTEGER, "Team"),
+                ColumnInfo("name", SQLTypeAffinity.TEXT, "Team")
             )
             assertThat(view.viewName).isEqualTo("MyView")
         }
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeAdapterStoreTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeAdapterStoreTest.kt
index 8919793..5a958c7 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeAdapterStoreTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeAdapterStoreTest.kt
@@ -421,12 +421,12 @@
                 )
             )
 
-            val converter = store.findTypeConverter(
+            val converter = store.typeConverterStore.findTypeConverter(
                 binders[0].from,
                 invocation.context.COMMON_TYPES.STRING
             )
             assertThat(converter, notNullValue())
-            assertThat(store.reverse(converter!!), `is`(binders[1]))
+            assertThat(store.typeConverterStore.reverse(converter!!), `is`(binders[1]))
         }
     }
 
@@ -449,12 +449,12 @@
             val stmtBinder = store.findStatementValueBinder(binders[0].from, null)
             assertThat(stmtBinder, notNullValue())
 
-            val converter = store.findTypeConverter(
+            val converter = store.typeConverterStore.findTypeConverter(
                 binders[0].from,
                 invocation.context.COMMON_TYPES.STRING
             )
             assertThat(converter, notNullValue())
-            assertThat(store.reverse(converter!!), nullValue())
+            assertThat(store.typeConverterStore.reverse(converter!!), nullValue())
         }
     }
 
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterStoreTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterStoreTest.kt
index 001b1b2..18c67d2 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterStoreTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterStoreTest.kt
@@ -70,7 +70,7 @@
                 invocation.context,
                 BuiltInConverterFlags.DEFAULT,
                 converters.map(::CustomTypeConverterWrapper)
-            )
+            ).typeConverterStore
 
             fun findConverter(from: String, to: String): String? {
                 val input = invocation.processingEnv.requireType(from)
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/verifier/DatabaseVerifierTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/verifier/DatabaseVerifierTest.kt
index 51c6f6a..0b66837 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/verifier/DatabaseVerifierTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/verifier/DatabaseVerifierTest.kt
@@ -85,10 +85,10 @@
                 `is`(
                     QueryResultInfo(
                         listOf(
-                            ColumnInfo("id", SQLTypeAffinity.INTEGER),
-                            ColumnInfo("name", SQLTypeAffinity.TEXT),
-                            ColumnInfo("lastName", SQLTypeAffinity.TEXT),
-                            ColumnInfo("ratio", SQLTypeAffinity.REAL)
+                            ColumnInfo("id", SQLTypeAffinity.INTEGER, "User"),
+                            ColumnInfo("name", SQLTypeAffinity.TEXT, "User"),
+                            ColumnInfo("lastName", SQLTypeAffinity.TEXT, "User"),
+                            ColumnInfo("ratio", SQLTypeAffinity.REAL, "User")
                         )
                     )
                 )
@@ -104,8 +104,48 @@
                 `is`(
                     QueryResultInfo(
                         listOf(
-                            ColumnInfo("id", SQLTypeAffinity.INTEGER),
-                            ColumnInfo("lastName", SQLTypeAffinity.TEXT)
+                            ColumnInfo("id", SQLTypeAffinity.INTEGER, "User"),
+                            ColumnInfo("lastName", SQLTypeAffinity.TEXT, "User")
+                        )
+                    )
+                )
+            )
+        }
+    }
+
+    @Test
+    fun testFlattenQuery() {
+        validQueryTest("SELECT id, lastName FROM (select * from User)") {
+            assertThat(
+                it,
+                `is`(
+                    QueryResultInfo(
+                        listOf(
+                            ColumnInfo("id", SQLTypeAffinity.INTEGER, "User"),
+                            ColumnInfo("lastName", SQLTypeAffinity.TEXT, "User"),
+                        )
+                    )
+                )
+            )
+        }
+    }
+
+    @Test
+    fun testColumnSubquery() {
+        validQueryTest("""
+            SELECT
+                lastName,
+                (SELECT COUNT(*) FROM user AS iu WHERE iu.lastName = u.lastName) = 1 AS isUnique
+            FROM user AS u
+            GROUP BY lastName
+            """.trimIndent()) {
+            assertThat(
+                it,
+                `is`(
+                    QueryResultInfo(
+                        listOf(
+                            ColumnInfo("lastName", SQLTypeAffinity.TEXT, "User"),
+                            ColumnInfo("isUnique", SQLTypeAffinity.NULL, null),
                         )
                     )
                 )
@@ -121,8 +161,8 @@
                 `is`(
                     QueryResultInfo(
                         listOf(
-                            ColumnInfo("myId", SQLTypeAffinity.INTEGER),
-                            ColumnInfo("lastName", SQLTypeAffinity.TEXT)
+                            ColumnInfo("myId", SQLTypeAffinity.INTEGER, "User"),
+                            ColumnInfo("lastName", SQLTypeAffinity.TEXT, "User")
                         )
                     )
                 )
@@ -139,7 +179,7 @@
                     QueryResultInfo(
                         listOf(
                             // unfortunately, we don't get this information
-                            ColumnInfo("MAX(ratio)", SQLTypeAffinity.NULL)
+                            ColumnInfo("MAX(ratio)", SQLTypeAffinity.NULL, null)
                         )
                     )
                 )
@@ -156,7 +196,7 @@
                     QueryResultInfo(
                         listOf(
                             // unfortunately, we don't get this information
-                            ColumnInfo("mergedName", SQLTypeAffinity.NULL)
+                            ColumnInfo("mergedName", SQLTypeAffinity.NULL, null)
                         )
                     )
                 )
@@ -172,9 +212,9 @@
                 `is`(
                     QueryResultInfo(
                         listOf(
+                            ColumnInfo("id", SQLTypeAffinity.INTEGER, "User"),
                             // unfortunately, we don't get this information
-                            ColumnInfo("id", SQLTypeAffinity.INTEGER),
-                            ColumnInfo("mergedName", SQLTypeAffinity.NULL)
+                            ColumnInfo("mergedName", SQLTypeAffinity.NULL, null)
                         )
                     )
                 )
@@ -213,9 +253,8 @@
                 `is`(
                     QueryResultInfo(
                         listOf(
-                            // unfortunately, we don't get this information
-                            ColumnInfo("id", SQLTypeAffinity.INTEGER),
-                            ColumnInfo("name", SQLTypeAffinity.TEXT)
+                            ColumnInfo("id", SQLTypeAffinity.INTEGER, "User"),
+                            ColumnInfo("name", SQLTypeAffinity.TEXT, "User")
                         )
                     )
                 )
@@ -242,8 +281,8 @@
                 `is`(
                     QueryResultInfo(
                         listOf(
-                            ColumnInfo("id", SQLTypeAffinity.INTEGER),
-                            ColumnInfo("name", SQLTypeAffinity.TEXT)
+                            ColumnInfo("id", SQLTypeAffinity.INTEGER, "User"),
+                            ColumnInfo("name", SQLTypeAffinity.TEXT, "User")
                         )
                     )
                 )
diff --git a/room/room-guava/api/2.4.0-beta01.txt b/room/room-guava/api/2.4.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/room/room-guava/api/2.4.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/room/room-guava/api/public_plus_experimental_2.4.0-beta01.txt b/room/room-guava/api/public_plus_experimental_2.4.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/room/room-guava/api/public_plus_experimental_2.4.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/room/room-guava/api/res-2.4.0-beta01.txt b/room/room-guava/api/res-2.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/room/room-guava/api/res-2.4.0-beta01.txt
diff --git a/room/room-guava/api/restricted_2.4.0-beta01.txt b/room/room-guava/api/restricted_2.4.0-beta01.txt
new file mode 100644
index 0000000..1c04602
--- /dev/null
+++ b/room/room-guava/api/restricted_2.4.0-beta01.txt
@@ -0,0 +1,14 @@
+// Signature format: 4.0
+package androidx.room.guava {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class GuavaRoom {
+    method @Deprecated public static <T> com.google.common.util.concurrent.ListenableFuture<T!>! createListenableFuture(java.util.concurrent.Callable<T!>!, androidx.room.RoomSQLiteQuery!, boolean);
+    method @Deprecated public static <T> com.google.common.util.concurrent.ListenableFuture<T!>! createListenableFuture(androidx.room.RoomDatabase!, java.util.concurrent.Callable<T!>!, androidx.room.RoomSQLiteQuery!, boolean);
+    method public static <T> com.google.common.util.concurrent.ListenableFuture<T!>! createListenableFuture(androidx.room.RoomDatabase!, boolean, java.util.concurrent.Callable<T!>!, androidx.room.RoomSQLiteQuery!, boolean);
+    method public static <T> com.google.common.util.concurrent.ListenableFuture<T!> createListenableFuture(androidx.room.RoomDatabase, boolean, java.util.concurrent.Callable<T!>, androidx.room.RoomSQLiteQuery, boolean, android.os.CancellationSignal?);
+    method @Deprecated public static <T> com.google.common.util.concurrent.ListenableFuture<T!> createListenableFuture(androidx.room.RoomDatabase, java.util.concurrent.Callable<T!>);
+    method public static <T> com.google.common.util.concurrent.ListenableFuture<T!> createListenableFuture(androidx.room.RoomDatabase, boolean, java.util.concurrent.Callable<T!>);
+  }
+
+}
+
diff --git a/room/room-ktx/api/2.4.0-beta01.txt b/room/room-ktx/api/2.4.0-beta01.txt
new file mode 100644
index 0000000..418c567
--- /dev/null
+++ b/room/room-ktx/api/2.4.0-beta01.txt
@@ -0,0 +1,20 @@
+// Signature format: 4.0
+package androidx.room {
+
+  public final class CoroutinesRoomKt {
+  }
+
+  public final class RoomDatabaseKt {
+    method public static suspend <R> Object? withTransaction(androidx.room.RoomDatabase, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R> p);
+  }
+
+}
+
+package androidx.room.migration {
+
+  public final class MigrationKt {
+    method public static androidx.room.migration.Migration Migration(int startVersion, int endVersion, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,kotlin.Unit> migrate);
+  }
+
+}
+
diff --git a/room/room-ktx/api/public_plus_experimental_2.4.0-beta01.txt b/room/room-ktx/api/public_plus_experimental_2.4.0-beta01.txt
new file mode 100644
index 0000000..418c567
--- /dev/null
+++ b/room/room-ktx/api/public_plus_experimental_2.4.0-beta01.txt
@@ -0,0 +1,20 @@
+// Signature format: 4.0
+package androidx.room {
+
+  public final class CoroutinesRoomKt {
+  }
+
+  public final class RoomDatabaseKt {
+    method public static suspend <R> Object? withTransaction(androidx.room.RoomDatabase, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R> p);
+  }
+
+}
+
+package androidx.room.migration {
+
+  public final class MigrationKt {
+    method public static androidx.room.migration.Migration Migration(int startVersion, int endVersion, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,kotlin.Unit> migrate);
+  }
+
+}
+
diff --git a/room/room-ktx/api/res-2.4.0-beta01.txt b/room/room-ktx/api/res-2.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/room/room-ktx/api/res-2.4.0-beta01.txt
diff --git a/room/room-ktx/api/restricted_2.4.0-beta01.txt b/room/room-ktx/api/restricted_2.4.0-beta01.txt
new file mode 100644
index 0000000..30647b2
--- /dev/null
+++ b/room/room-ktx/api/restricted_2.4.0-beta01.txt
@@ -0,0 +1,33 @@
+// Signature format: 4.0
+package androidx.room {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class CoroutinesRoom {
+    method public static <R> kotlinx.coroutines.flow.Flow<R> createFlow(androidx.room.RoomDatabase db, boolean inTransaction, String![] tableNames, java.util.concurrent.Callable<R> callable);
+    method public static suspend <R> Object? execute(androidx.room.RoomDatabase db, boolean inTransaction, java.util.concurrent.Callable<R> callable, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend <R> Object? execute(androidx.room.RoomDatabase db, boolean inTransaction, android.os.CancellationSignal cancellationSignal, java.util.concurrent.Callable<R> callable, kotlin.coroutines.Continuation<? super R> p);
+    field public static final androidx.room.CoroutinesRoom.Companion Companion;
+  }
+
+  public static final class CoroutinesRoom.Companion {
+    method public <R> kotlinx.coroutines.flow.Flow<R> createFlow(androidx.room.RoomDatabase db, boolean inTransaction, String![] tableNames, java.util.concurrent.Callable<R> callable);
+    method public suspend <R> Object? execute(androidx.room.RoomDatabase db, boolean inTransaction, java.util.concurrent.Callable<R> callable, kotlin.coroutines.Continuation<? super R> p);
+    method public suspend <R> Object? execute(androidx.room.RoomDatabase db, boolean inTransaction, android.os.CancellationSignal cancellationSignal, java.util.concurrent.Callable<R> callable, kotlin.coroutines.Continuation<? super R> p);
+  }
+
+  public final class CoroutinesRoomKt {
+  }
+
+  public final class RoomDatabaseKt {
+    method public static suspend <R> Object? withTransaction(androidx.room.RoomDatabase, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R> p);
+  }
+
+}
+
+package androidx.room.migration {
+
+  public final class MigrationKt {
+    method public static androidx.room.migration.Migration Migration(int startVersion, int endVersion, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,kotlin.Unit> migrate);
+  }
+
+}
+
diff --git a/room/room-migration/api/2.4.0-beta01.txt b/room/room-migration/api/2.4.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/room/room-migration/api/2.4.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/room/room-migration/api/public_plus_experimental_2.4.0-beta01.txt b/room/room-migration/api/public_plus_experimental_2.4.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/room/room-migration/api/public_plus_experimental_2.4.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/room/room-migration/api/restricted_2.4.0-beta01.txt b/room/room-migration/api/restricted_2.4.0-beta01.txt
new file mode 100644
index 0000000..50f8227
--- /dev/null
+++ b/room/room-migration/api/restricted_2.4.0-beta01.txt
@@ -0,0 +1,110 @@
+// Signature format: 4.0
+package androidx.room.migration.bundle {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class BundleUtil {
+    field public static final String TABLE_NAME_PLACEHOLDER = "${TABLE_NAME}";
+    field public static final String VIEW_NAME_PLACEHOLDER = "${VIEW_NAME}";
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class DatabaseBundle {
+    ctor public DatabaseBundle(int, String!, java.util.List<androidx.room.migration.bundle.EntityBundle!>!, java.util.List<androidx.room.migration.bundle.DatabaseViewBundle!>!, java.util.List<java.lang.String!>!);
+    ctor public DatabaseBundle();
+    method public java.util.List<java.lang.String!>! buildCreateQueries();
+    method public java.util.List<androidx.room.migration.bundle.EntityBundle!>! getEntities();
+    method public java.util.Map<java.lang.String!,androidx.room.migration.bundle.EntityBundle!>! getEntitiesByTableName();
+    method public String! getIdentityHash();
+    method public int getVersion();
+    method public java.util.List<androidx.room.migration.bundle.DatabaseViewBundle!>! getViews();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.DatabaseBundle!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class DatabaseViewBundle {
+    ctor public DatabaseViewBundle(String!, String!);
+    method public String! createView();
+    method public String! getCreateSql();
+    method public String! getViewName();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.DatabaseViewBundle!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class EntityBundle {
+    ctor public EntityBundle(String!, String!, java.util.List<androidx.room.migration.bundle.FieldBundle!>!, androidx.room.migration.bundle.PrimaryKeyBundle!, java.util.List<androidx.room.migration.bundle.IndexBundle!>!, java.util.List<androidx.room.migration.bundle.ForeignKeyBundle!>!);
+    method public java.util.Collection<java.lang.String!>! buildCreateQueries();
+    method public String! createNewTable();
+    method public String! createTable();
+    method public String! getCreateSql();
+    method public java.util.List<androidx.room.migration.bundle.FieldBundle!>! getFields();
+    method public java.util.Map<java.lang.String!,androidx.room.migration.bundle.FieldBundle!>! getFieldsByColumnName();
+    method public java.util.List<androidx.room.migration.bundle.ForeignKeyBundle!>! getForeignKeys();
+    method public java.util.List<androidx.room.migration.bundle.IndexBundle!>! getIndices();
+    method public String! getNewTableName();
+    method public androidx.room.migration.bundle.PrimaryKeyBundle! getPrimaryKey();
+    method public String! getTableName();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.EntityBundle!);
+    method public String renameToOriginal();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class FieldBundle {
+    ctor @Deprecated public FieldBundle(String!, String!, String!, boolean);
+    ctor public FieldBundle(String!, String!, String!, boolean, String!);
+    method public String! getAffinity();
+    method public String! getColumnName();
+    method public String! getDefaultValue();
+    method public String! getFieldPath();
+    method public boolean isNonNull();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.FieldBundle!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ForeignKeyBundle {
+    ctor public ForeignKeyBundle(String!, String!, String!, java.util.List<java.lang.String!>!, java.util.List<java.lang.String!>!);
+    method public java.util.List<java.lang.String!>! getColumns();
+    method public String! getOnDelete();
+    method public String! getOnUpdate();
+    method public java.util.List<java.lang.String!>! getReferencedColumns();
+    method public String! getTable();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.ForeignKeyBundle!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class FtsEntityBundle extends androidx.room.migration.bundle.EntityBundle {
+    ctor public FtsEntityBundle(String!, String!, java.util.List<androidx.room.migration.bundle.FieldBundle!>!, androidx.room.migration.bundle.PrimaryKeyBundle!, String!, androidx.room.migration.bundle.FtsOptionsBundle!, java.util.List<java.lang.String!>!);
+    method public androidx.room.migration.bundle.FtsOptionsBundle! getFtsOptions();
+    method public java.util.List<java.lang.String!>! getShadowTableNames();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class FtsOptionsBundle {
+    ctor public FtsOptionsBundle(String!, java.util.List<java.lang.String!>!, String!, String!, String!, java.util.List<java.lang.String!>!, java.util.List<java.lang.Integer!>!, String!);
+    method public String! getContentTable();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.FtsOptionsBundle!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class IndexBundle {
+    ctor @Deprecated public IndexBundle(String!, boolean, java.util.List<java.lang.String!>!, String!);
+    ctor public IndexBundle(String!, boolean, java.util.List<java.lang.String!>!, java.util.List<java.lang.String!>!, String!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public String! create(String);
+    method public java.util.List<java.lang.String!>! getColumnNames();
+    method public String! getCreateSql(String!);
+    method public String! getName();
+    method public java.util.List<java.lang.String!>! getOrders();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.IndexBundle);
+    method public boolean isUnique();
+    field public static final String DEFAULT_PREFIX = "index_";
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class PrimaryKeyBundle {
+    ctor public PrimaryKeyBundle(boolean, java.util.List<java.lang.String!>!);
+    method public java.util.List<java.lang.String!>! getColumnNames();
+    method public boolean isAutoGenerate();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.PrimaryKeyBundle!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class SchemaBundle {
+    ctor public SchemaBundle(int, androidx.room.migration.bundle.DatabaseBundle!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.room.migration.bundle.SchemaBundle deserialize(java.io.InputStream!) throws java.io.UnsupportedEncodingException;
+    method public androidx.room.migration.bundle.DatabaseBundle! getDatabase();
+    method public int getFormatVersion();
+    method public boolean isSchemaEqual(androidx.room.migration.bundle.SchemaBundle!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void serialize(androidx.room.migration.bundle.SchemaBundle!, java.io.File!) throws java.io.IOException;
+    field public static final int LATEST_FORMAT = 1; // 0x1
+  }
+
+}
+
diff --git a/room/room-paging/api/2.4.0-beta01.txt b/room/room-paging/api/2.4.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/room/room-paging/api/2.4.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/room/room-paging/api/public_plus_experimental_2.4.0-beta01.txt b/room/room-paging/api/public_plus_experimental_2.4.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/room/room-paging/api/public_plus_experimental_2.4.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/room/room-paging/api/res-2.4.0-beta01.txt b/room/room-paging/api/res-2.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/room/room-paging/api/res-2.4.0-beta01.txt
diff --git a/room/room-paging/api/restricted_2.4.0-beta01.txt b/room/room-paging/api/restricted_2.4.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/room/room-paging/api/restricted_2.4.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/room/room-runtime/api/2.4.0-beta01.txt b/room/room-runtime/api/2.4.0-beta01.txt
new file mode 100644
index 0000000..c6616ad
--- /dev/null
+++ b/room/room-runtime/api/2.4.0-beta01.txt
@@ -0,0 +1,143 @@
+// Signature format: 4.0
+package androidx.room {
+
+  public class DatabaseConfiguration {
+    method public boolean isMigrationRequired(int, int);
+    method @Deprecated public boolean isMigrationRequiredFrom(int);
+    field public final boolean allowDestructiveMigrationOnDowngrade;
+    field public final boolean allowMainThreadQueries;
+    field public final java.util.List<androidx.room.migration.AutoMigrationSpec!> autoMigrationSpecs;
+    field public final java.util.List<androidx.room.RoomDatabase.Callback!>? callbacks;
+    field public final android.content.Context context;
+    field public final String? copyFromAssetPath;
+    field public final java.io.File? copyFromFile;
+    field public final java.util.concurrent.Callable<java.io.InputStream!>? copyFromInputStream;
+    field public final androidx.room.RoomDatabase.JournalMode! journalMode;
+    field public final androidx.room.RoomDatabase.MigrationContainer migrationContainer;
+    field public final boolean multiInstanceInvalidation;
+    field public final String? name;
+    field public final androidx.room.RoomDatabase.PrepackagedDatabaseCallback? prepackagedDatabaseCallback;
+    field public final java.util.concurrent.Executor queryExecutor;
+    field public final boolean requireMigration;
+    field public final androidx.sqlite.db.SupportSQLiteOpenHelper.Factory sqliteOpenHelperFactory;
+    field public final java.util.concurrent.Executor transactionExecutor;
+    field public final java.util.List<java.lang.Object!> typeConverters;
+  }
+
+  public class InvalidationTracker {
+    method @WorkerThread public void addObserver(androidx.room.InvalidationTracker.Observer);
+    method public void refreshVersionsAsync();
+    method @WorkerThread public void removeObserver(androidx.room.InvalidationTracker.Observer);
+  }
+
+  public abstract static class InvalidationTracker.Observer {
+    ctor protected InvalidationTracker.Observer(String, java.lang.String!...);
+    ctor public InvalidationTracker.Observer(String![]);
+    method public abstract void onInvalidated(java.util.Set<java.lang.String!>);
+  }
+
+  public class Room {
+    ctor @Deprecated public Room();
+    method public static <T extends androidx.room.RoomDatabase> androidx.room.RoomDatabase.Builder<T!> databaseBuilder(android.content.Context, Class<T!>, String);
+    method public static <T extends androidx.room.RoomDatabase> androidx.room.RoomDatabase.Builder<T!> inMemoryDatabaseBuilder(android.content.Context, Class<T!>);
+    field public static final String MASTER_TABLE_NAME = "room_master_table";
+  }
+
+  public abstract class RoomDatabase {
+    ctor public RoomDatabase();
+    method @Deprecated public void beginTransaction();
+    method @WorkerThread public abstract void clearAllTables();
+    method public void close();
+    method public androidx.sqlite.db.SupportSQLiteStatement! compileStatement(String);
+    method protected abstract androidx.room.InvalidationTracker createInvalidationTracker();
+    method protected abstract androidx.sqlite.db.SupportSQLiteOpenHelper createOpenHelper(androidx.room.DatabaseConfiguration!);
+    method @Deprecated public void endTransaction();
+    method public androidx.room.InvalidationTracker getInvalidationTracker();
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper getOpenHelper();
+    method public java.util.concurrent.Executor getQueryExecutor();
+    method public java.util.concurrent.Executor getTransactionExecutor();
+    method public <T> T? getTypeConverter(Class<T!>);
+    method public boolean inTransaction();
+    method @CallSuper public void init(androidx.room.DatabaseConfiguration);
+    method protected void internalInitInvalidationTracker(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public boolean isOpen();
+    method public android.database.Cursor query(String, Object![]?);
+    method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery);
+    method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery, android.os.CancellationSignal?);
+    method public void runInTransaction(Runnable);
+    method public <V> V! runInTransaction(java.util.concurrent.Callable<V!>);
+    method @Deprecated public void setTransactionSuccessful();
+    field @Deprecated protected volatile androidx.sqlite.db.SupportSQLiteDatabase! mDatabase;
+  }
+
+  public static class RoomDatabase.Builder<T extends androidx.room.RoomDatabase> {
+    method public androidx.room.RoomDatabase.Builder<T!> addAutoMigrationSpec(androidx.room.migration.AutoMigrationSpec);
+    method public androidx.room.RoomDatabase.Builder<T!> addCallback(androidx.room.RoomDatabase.Callback);
+    method public androidx.room.RoomDatabase.Builder<T!> addMigrations(androidx.room.migration.Migration!...);
+    method public androidx.room.RoomDatabase.Builder<T!> addTypeConverter(Object);
+    method public androidx.room.RoomDatabase.Builder<T!> allowMainThreadQueries();
+    method public T build();
+    method public androidx.room.RoomDatabase.Builder<T!> createFromAsset(String);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromAsset(String, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromFile(java.io.File);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromFile(java.io.File, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream!>);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream!>, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
+    method public androidx.room.RoomDatabase.Builder<T!> enableMultiInstanceInvalidation();
+    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigration();
+    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationFrom(int...);
+    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationOnDowngrade();
+    method public androidx.room.RoomDatabase.Builder<T!> openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory?);
+    method public androidx.room.RoomDatabase.Builder<T!> setJournalMode(androidx.room.RoomDatabase.JournalMode);
+    method public androidx.room.RoomDatabase.Builder<T!> setQueryCallback(androidx.room.RoomDatabase.QueryCallback, java.util.concurrent.Executor);
+    method public androidx.room.RoomDatabase.Builder<T!> setQueryExecutor(java.util.concurrent.Executor);
+    method public androidx.room.RoomDatabase.Builder<T!> setTransactionExecutor(java.util.concurrent.Executor);
+  }
+
+  public abstract static class RoomDatabase.Callback {
+    ctor public RoomDatabase.Callback();
+    method public void onCreate(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onDestructiveMigration(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase);
+  }
+
+  public enum RoomDatabase.JournalMode {
+    enum_constant public static final androidx.room.RoomDatabase.JournalMode AUTOMATIC;
+    enum_constant public static final androidx.room.RoomDatabase.JournalMode TRUNCATE;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.JELLY_BEAN) public static final androidx.room.RoomDatabase.JournalMode WRITE_AHEAD_LOGGING;
+  }
+
+  public static class RoomDatabase.MigrationContainer {
+    ctor public RoomDatabase.MigrationContainer();
+    method public void addMigrations(androidx.room.migration.Migration!...);
+    method public void addMigrations(java.util.List<androidx.room.migration.Migration!>);
+    method public java.util.List<androidx.room.migration.Migration!>? findMigrationPath(int, int);
+    method public java.util.Map<java.lang.Integer!,java.util.Map<java.lang.Integer!,androidx.room.migration.Migration!>!> getMigrations();
+  }
+
+  public abstract static class RoomDatabase.PrepackagedDatabaseCallback {
+    ctor public RoomDatabase.PrepackagedDatabaseCallback();
+    method public void onOpenPrepackagedDatabase(androidx.sqlite.db.SupportSQLiteDatabase);
+  }
+
+  public static interface RoomDatabase.QueryCallback {
+    method public void onQuery(String, java.util.List<java.lang.Object!>);
+  }
+
+}
+
+package androidx.room.migration {
+
+  public interface AutoMigrationSpec {
+    method public default void onPostMigrate(androidx.sqlite.db.SupportSQLiteDatabase);
+  }
+
+  public abstract class Migration {
+    ctor public Migration(int, int);
+    method public abstract void migrate(androidx.sqlite.db.SupportSQLiteDatabase);
+    field public final int endVersion;
+    field public final int startVersion;
+  }
+
+}
+
diff --git a/room/room-runtime/api/public_plus_experimental_2.4.0-beta01.txt b/room/room-runtime/api/public_plus_experimental_2.4.0-beta01.txt
new file mode 100644
index 0000000..8484f3c
--- /dev/null
+++ b/room/room-runtime/api/public_plus_experimental_2.4.0-beta01.txt
@@ -0,0 +1,153 @@
+// Signature format: 4.0
+package androidx.room {
+
+  public class DatabaseConfiguration {
+    method public boolean isMigrationRequired(int, int);
+    method @Deprecated public boolean isMigrationRequiredFrom(int);
+    field public final boolean allowDestructiveMigrationOnDowngrade;
+    field public final boolean allowMainThreadQueries;
+    field public final java.util.List<androidx.room.migration.AutoMigrationSpec!> autoMigrationSpecs;
+    field public final java.util.List<androidx.room.RoomDatabase.Callback!>? callbacks;
+    field public final android.content.Context context;
+    field public final String? copyFromAssetPath;
+    field public final java.io.File? copyFromFile;
+    field public final java.util.concurrent.Callable<java.io.InputStream!>? copyFromInputStream;
+    field public final androidx.room.RoomDatabase.JournalMode! journalMode;
+    field public final androidx.room.RoomDatabase.MigrationContainer migrationContainer;
+    field public final boolean multiInstanceInvalidation;
+    field public final String? name;
+    field public final androidx.room.RoomDatabase.PrepackagedDatabaseCallback? prepackagedDatabaseCallback;
+    field public final java.util.concurrent.Executor queryExecutor;
+    field public final boolean requireMigration;
+    field public final androidx.sqlite.db.SupportSQLiteOpenHelper.Factory sqliteOpenHelperFactory;
+    field public final java.util.concurrent.Executor transactionExecutor;
+    field public final java.util.List<java.lang.Object!> typeConverters;
+  }
+
+  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.METHOD}) public @interface ExperimentalRoomApi {
+  }
+
+  public class InvalidationTracker {
+    method @WorkerThread public void addObserver(androidx.room.InvalidationTracker.Observer);
+    method public void refreshVersionsAsync();
+    method @WorkerThread public void removeObserver(androidx.room.InvalidationTracker.Observer);
+  }
+
+  public abstract static class InvalidationTracker.Observer {
+    ctor protected InvalidationTracker.Observer(String, java.lang.String!...);
+    ctor public InvalidationTracker.Observer(String![]);
+    method public abstract void onInvalidated(java.util.Set<java.lang.String!>);
+  }
+
+  @androidx.room.ExperimentalRoomApi public class MultiInstanceInvalidationService extends android.app.Service {
+    ctor public MultiInstanceInvalidationService();
+    method public android.os.IBinder? onBind(android.content.Intent);
+  }
+
+  public class Room {
+    ctor @Deprecated public Room();
+    method public static <T extends androidx.room.RoomDatabase> androidx.room.RoomDatabase.Builder<T!> databaseBuilder(android.content.Context, Class<T!>, String);
+    method public static <T extends androidx.room.RoomDatabase> androidx.room.RoomDatabase.Builder<T!> inMemoryDatabaseBuilder(android.content.Context, Class<T!>);
+    field public static final String MASTER_TABLE_NAME = "room_master_table";
+  }
+
+  public abstract class RoomDatabase {
+    ctor public RoomDatabase();
+    method @Deprecated public void beginTransaction();
+    method @WorkerThread public abstract void clearAllTables();
+    method public void close();
+    method public androidx.sqlite.db.SupportSQLiteStatement! compileStatement(String);
+    method protected abstract androidx.room.InvalidationTracker createInvalidationTracker();
+    method protected abstract androidx.sqlite.db.SupportSQLiteOpenHelper createOpenHelper(androidx.room.DatabaseConfiguration!);
+    method @Deprecated public void endTransaction();
+    method public androidx.room.InvalidationTracker getInvalidationTracker();
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper getOpenHelper();
+    method public java.util.concurrent.Executor getQueryExecutor();
+    method public java.util.concurrent.Executor getTransactionExecutor();
+    method public <T> T? getTypeConverter(Class<T!>);
+    method public boolean inTransaction();
+    method @CallSuper public void init(androidx.room.DatabaseConfiguration);
+    method protected void internalInitInvalidationTracker(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public boolean isOpen();
+    method public android.database.Cursor query(String, Object![]?);
+    method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery);
+    method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery, android.os.CancellationSignal?);
+    method public void runInTransaction(Runnable);
+    method public <V> V! runInTransaction(java.util.concurrent.Callable<V!>);
+    method @Deprecated public void setTransactionSuccessful();
+    field @Deprecated protected volatile androidx.sqlite.db.SupportSQLiteDatabase! mDatabase;
+  }
+
+  public static class RoomDatabase.Builder<T extends androidx.room.RoomDatabase> {
+    method public androidx.room.RoomDatabase.Builder<T!> addAutoMigrationSpec(androidx.room.migration.AutoMigrationSpec);
+    method public androidx.room.RoomDatabase.Builder<T!> addCallback(androidx.room.RoomDatabase.Callback);
+    method public androidx.room.RoomDatabase.Builder<T!> addMigrations(androidx.room.migration.Migration!...);
+    method public androidx.room.RoomDatabase.Builder<T!> addTypeConverter(Object);
+    method public androidx.room.RoomDatabase.Builder<T!> allowMainThreadQueries();
+    method public T build();
+    method public androidx.room.RoomDatabase.Builder<T!> createFromAsset(String);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromAsset(String, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromFile(java.io.File);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromFile(java.io.File, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream!>);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream!>, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
+    method public androidx.room.RoomDatabase.Builder<T!> enableMultiInstanceInvalidation();
+    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigration();
+    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationFrom(int...);
+    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationOnDowngrade();
+    method public androidx.room.RoomDatabase.Builder<T!> openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory?);
+    method @androidx.room.ExperimentalRoomApi public androidx.room.RoomDatabase.Builder<T!> setAutoCloseTimeout(@IntRange(from=0) long, java.util.concurrent.TimeUnit);
+    method public androidx.room.RoomDatabase.Builder<T!> setJournalMode(androidx.room.RoomDatabase.JournalMode);
+    method @androidx.room.ExperimentalRoomApi public androidx.room.RoomDatabase.Builder<T!> setMultiInstanceInvalidationServiceIntent(android.content.Intent);
+    method public androidx.room.RoomDatabase.Builder<T!> setQueryCallback(androidx.room.RoomDatabase.QueryCallback, java.util.concurrent.Executor);
+    method public androidx.room.RoomDatabase.Builder<T!> setQueryExecutor(java.util.concurrent.Executor);
+    method public androidx.room.RoomDatabase.Builder<T!> setTransactionExecutor(java.util.concurrent.Executor);
+  }
+
+  public abstract static class RoomDatabase.Callback {
+    ctor public RoomDatabase.Callback();
+    method public void onCreate(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onDestructiveMigration(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase);
+  }
+
+  public enum RoomDatabase.JournalMode {
+    enum_constant public static final androidx.room.RoomDatabase.JournalMode AUTOMATIC;
+    enum_constant public static final androidx.room.RoomDatabase.JournalMode TRUNCATE;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.JELLY_BEAN) public static final androidx.room.RoomDatabase.JournalMode WRITE_AHEAD_LOGGING;
+  }
+
+  public static class RoomDatabase.MigrationContainer {
+    ctor public RoomDatabase.MigrationContainer();
+    method public void addMigrations(androidx.room.migration.Migration!...);
+    method public void addMigrations(java.util.List<androidx.room.migration.Migration!>);
+    method public java.util.List<androidx.room.migration.Migration!>? findMigrationPath(int, int);
+    method public java.util.Map<java.lang.Integer!,java.util.Map<java.lang.Integer!,androidx.room.migration.Migration!>!> getMigrations();
+  }
+
+  public abstract static class RoomDatabase.PrepackagedDatabaseCallback {
+    ctor public RoomDatabase.PrepackagedDatabaseCallback();
+    method public void onOpenPrepackagedDatabase(androidx.sqlite.db.SupportSQLiteDatabase);
+  }
+
+  public static interface RoomDatabase.QueryCallback {
+    method public void onQuery(String, java.util.List<java.lang.Object!>);
+  }
+
+}
+
+package androidx.room.migration {
+
+  public interface AutoMigrationSpec {
+    method public default void onPostMigrate(androidx.sqlite.db.SupportSQLiteDatabase);
+  }
+
+  public abstract class Migration {
+    ctor public Migration(int, int);
+    method public abstract void migrate(androidx.sqlite.db.SupportSQLiteDatabase);
+    field public final int endVersion;
+    field public final int startVersion;
+  }
+
+}
+
diff --git a/room/room-runtime/api/public_plus_experimental_current.txt b/room/room-runtime/api/public_plus_experimental_current.txt
index 5a24224..8484f3c 100644
--- a/room/room-runtime/api/public_plus_experimental_current.txt
+++ b/room/room-runtime/api/public_plus_experimental_current.txt
@@ -24,7 +24,7 @@
     field public final java.util.List<java.lang.Object!> typeConverters;
   }
 
-  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface ExperimentalRoomApi {
+  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.METHOD}) public @interface ExperimentalRoomApi {
   }
 
   public class InvalidationTracker {
@@ -39,6 +39,11 @@
     method public abstract void onInvalidated(java.util.Set<java.lang.String!>);
   }
 
+  @androidx.room.ExperimentalRoomApi public class MultiInstanceInvalidationService extends android.app.Service {
+    ctor public MultiInstanceInvalidationService();
+    method public android.os.IBinder? onBind(android.content.Intent);
+  }
+
   public class Room {
     ctor @Deprecated public Room();
     method public static <T extends androidx.room.RoomDatabase> androidx.room.RoomDatabase.Builder<T!> databaseBuilder(android.content.Context, Class<T!>, String);
@@ -93,6 +98,7 @@
     method public androidx.room.RoomDatabase.Builder<T!> openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory?);
     method @androidx.room.ExperimentalRoomApi public androidx.room.RoomDatabase.Builder<T!> setAutoCloseTimeout(@IntRange(from=0) long, java.util.concurrent.TimeUnit);
     method public androidx.room.RoomDatabase.Builder<T!> setJournalMode(androidx.room.RoomDatabase.JournalMode);
+    method @androidx.room.ExperimentalRoomApi public androidx.room.RoomDatabase.Builder<T!> setMultiInstanceInvalidationServiceIntent(android.content.Intent);
     method public androidx.room.RoomDatabase.Builder<T!> setQueryCallback(androidx.room.RoomDatabase.QueryCallback, java.util.concurrent.Executor);
     method public androidx.room.RoomDatabase.Builder<T!> setQueryExecutor(java.util.concurrent.Executor);
     method public androidx.room.RoomDatabase.Builder<T!> setTransactionExecutor(java.util.concurrent.Executor);
diff --git a/room/room-runtime/api/res-2.4.0-beta01.txt b/room/room-runtime/api/res-2.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/room/room-runtime/api/res-2.4.0-beta01.txt
diff --git a/room/room-runtime/api/restricted_2.4.0-beta01.txt b/room/room-runtime/api/restricted_2.4.0-beta01.txt
new file mode 100644
index 0000000..17a238e
--- /dev/null
+++ b/room/room-runtime/api/restricted_2.4.0-beta01.txt
@@ -0,0 +1,352 @@
+// Signature format: 4.0
+package androidx.room {
+
+  public class DatabaseConfiguration {
+    ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode!, java.util.concurrent.Executor, boolean, java.util.Set<java.lang.Integer!>?);
+    ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode!, java.util.concurrent.Executor, java.util.concurrent.Executor, boolean, boolean, boolean, java.util.Set<java.lang.Integer!>?);
+    ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode!, java.util.concurrent.Executor, java.util.concurrent.Executor, boolean, boolean, boolean, java.util.Set<java.lang.Integer!>?, String?, java.io.File?);
+    ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode, java.util.concurrent.Executor, java.util.concurrent.Executor, boolean, boolean, boolean, java.util.Set<java.lang.Integer!>?, String?, java.io.File?, java.util.concurrent.Callable<java.io.InputStream!>?);
+    ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode, java.util.concurrent.Executor, java.util.concurrent.Executor, boolean, boolean, boolean, java.util.Set<java.lang.Integer!>?, String?, java.io.File?, java.util.concurrent.Callable<java.io.InputStream!>?, androidx.room.RoomDatabase.PrepackagedDatabaseCallback?);
+    ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode, java.util.concurrent.Executor, java.util.concurrent.Executor, boolean, boolean, boolean, java.util.Set<java.lang.Integer!>?, String?, java.io.File?, java.util.concurrent.Callable<java.io.InputStream!>?, androidx.room.RoomDatabase.PrepackagedDatabaseCallback?, java.util.List<java.lang.Object!>?);
+    ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode, java.util.concurrent.Executor, java.util.concurrent.Executor, boolean, boolean, boolean, java.util.Set<java.lang.Integer!>?, String?, java.io.File?, java.util.concurrent.Callable<java.io.InputStream!>?, androidx.room.RoomDatabase.PrepackagedDatabaseCallback?, java.util.List<java.lang.Object!>?, java.util.List<androidx.room.migration.AutoMigrationSpec!>?);
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode, java.util.concurrent.Executor, java.util.concurrent.Executor, android.content.Intent?, boolean, boolean, java.util.Set<java.lang.Integer!>?, String?, java.io.File?, java.util.concurrent.Callable<java.io.InputStream!>?, androidx.room.RoomDatabase.PrepackagedDatabaseCallback?, java.util.List<java.lang.Object!>?, java.util.List<androidx.room.migration.AutoMigrationSpec!>?);
+    method public boolean isMigrationRequired(int, int);
+    method @Deprecated public boolean isMigrationRequiredFrom(int);
+    field public final boolean allowDestructiveMigrationOnDowngrade;
+    field public final boolean allowMainThreadQueries;
+    field public final java.util.List<androidx.room.migration.AutoMigrationSpec!> autoMigrationSpecs;
+    field public final java.util.List<androidx.room.RoomDatabase.Callback!>? callbacks;
+    field public final android.content.Context context;
+    field public final String? copyFromAssetPath;
+    field public final java.io.File? copyFromFile;
+    field public final java.util.concurrent.Callable<java.io.InputStream!>? copyFromInputStream;
+    field public final androidx.room.RoomDatabase.JournalMode! journalMode;
+    field public final androidx.room.RoomDatabase.MigrationContainer migrationContainer;
+    field public final boolean multiInstanceInvalidation;
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final android.content.Intent! multiInstanceInvalidationServiceIntent;
+    field public final String? name;
+    field public final androidx.room.RoomDatabase.PrepackagedDatabaseCallback? prepackagedDatabaseCallback;
+    field public final java.util.concurrent.Executor queryExecutor;
+    field public final boolean requireMigration;
+    field public final androidx.sqlite.db.SupportSQLiteOpenHelper.Factory sqliteOpenHelperFactory;
+    field public final java.util.concurrent.Executor transactionExecutor;
+    field public final java.util.List<java.lang.Object!> typeConverters;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class EntityDeletionOrUpdateAdapter<T> extends androidx.room.SharedSQLiteStatement {
+    ctor public EntityDeletionOrUpdateAdapter(androidx.room.RoomDatabase!);
+    method protected abstract void bind(androidx.sqlite.db.SupportSQLiteStatement!, T!);
+    method public final int handle(T!);
+    method public final int handleMultiple(Iterable<? extends T>!);
+    method public final int handleMultiple(T![]!);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class EntityInsertionAdapter<T> extends androidx.room.SharedSQLiteStatement {
+    ctor public EntityInsertionAdapter(androidx.room.RoomDatabase!);
+    method protected abstract void bind(androidx.sqlite.db.SupportSQLiteStatement!, T!);
+    method public final void insert(T!);
+    method public final void insert(T![]!);
+    method public final void insert(Iterable<? extends T>!);
+    method public final long insertAndReturnId(T!);
+    method public final long[]! insertAndReturnIdsArray(java.util.Collection<? extends T>!);
+    method public final long[]! insertAndReturnIdsArray(T![]!);
+    method public final Long![]! insertAndReturnIdsArrayBox(java.util.Collection<? extends T>!);
+    method public final Long![]! insertAndReturnIdsArrayBox(T![]!);
+    method public final java.util.List<java.lang.Long!>! insertAndReturnIdsList(T![]!);
+    method public final java.util.List<java.lang.Long!>! insertAndReturnIdsList(java.util.Collection<? extends T>!);
+  }
+
+  public class InvalidationTracker {
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public InvalidationTracker(androidx.room.RoomDatabase!, java.lang.String!...);
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public InvalidationTracker(androidx.room.RoomDatabase!, java.util.Map<java.lang.String!,java.lang.String!>!, java.util.Map<java.lang.String!,java.util.Set<java.lang.String!>!>!, java.lang.String!...);
+    method @WorkerThread public void addObserver(androidx.room.InvalidationTracker.Observer);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void addWeakObserver(androidx.room.InvalidationTracker.Observer!);
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public <T> androidx.lifecycle.LiveData<T!>! createLiveData(String![]!, java.util.concurrent.Callable<T!>!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public <T> androidx.lifecycle.LiveData<T!>! createLiveData(String![]!, boolean, java.util.concurrent.Callable<T!>!);
+    method public void refreshVersionsAsync();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @WorkerThread public void refreshVersionsSync();
+    method @WorkerThread public void removeObserver(androidx.room.InvalidationTracker.Observer);
+  }
+
+  public abstract static class InvalidationTracker.Observer {
+    ctor protected InvalidationTracker.Observer(String, java.lang.String!...);
+    ctor public InvalidationTracker.Observer(String![]);
+    method public abstract void onInvalidated(java.util.Set<java.lang.String!>);
+  }
+
+  public class Room {
+    ctor @Deprecated public Room();
+    method public static <T extends androidx.room.RoomDatabase> androidx.room.RoomDatabase.Builder<T!> databaseBuilder(android.content.Context, Class<T!>, String);
+    method public static <T extends androidx.room.RoomDatabase> androidx.room.RoomDatabase.Builder<T!> inMemoryDatabaseBuilder(android.content.Context, Class<T!>);
+    field public static final String MASTER_TABLE_NAME = "room_master_table";
+  }
+
+  public abstract class RoomDatabase {
+    ctor public RoomDatabase();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void assertNotMainThread();
+    method @Deprecated public void beginTransaction();
+    method @WorkerThread public abstract void clearAllTables();
+    method public void close();
+    method public androidx.sqlite.db.SupportSQLiteStatement! compileStatement(String);
+    method protected abstract androidx.room.InvalidationTracker createInvalidationTracker();
+    method protected abstract androidx.sqlite.db.SupportSQLiteOpenHelper createOpenHelper(androidx.room.DatabaseConfiguration!);
+    method @Deprecated public void endTransaction();
+    method public androidx.room.InvalidationTracker getInvalidationTracker();
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper getOpenHelper();
+    method public java.util.concurrent.Executor getQueryExecutor();
+    method public java.util.concurrent.Executor getTransactionExecutor();
+    method public <T> T? getTypeConverter(Class<T!>);
+    method public boolean inTransaction();
+    method @CallSuper public void init(androidx.room.DatabaseConfiguration);
+    method protected void internalInitInvalidationTracker(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public boolean isOpen();
+    method public android.database.Cursor query(String, Object![]?);
+    method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery);
+    method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery, android.os.CancellationSignal?);
+    method public void runInTransaction(Runnable);
+    method public <V> V! runInTransaction(java.util.concurrent.Callable<V!>);
+    method @Deprecated public void setTransactionSuccessful();
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final int MAX_BIND_PARAMETER_CNT = 999; // 0x3e7
+    field @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) protected java.util.List<androidx.room.RoomDatabase.Callback!>? mCallbacks;
+    field @Deprecated protected volatile androidx.sqlite.db.SupportSQLiteDatabase! mDatabase;
+  }
+
+  public static class RoomDatabase.Builder<T extends androidx.room.RoomDatabase> {
+    method public androidx.room.RoomDatabase.Builder<T!> addAutoMigrationSpec(androidx.room.migration.AutoMigrationSpec);
+    method public androidx.room.RoomDatabase.Builder<T!> addCallback(androidx.room.RoomDatabase.Callback);
+    method public androidx.room.RoomDatabase.Builder<T!> addMigrations(androidx.room.migration.Migration!...);
+    method public androidx.room.RoomDatabase.Builder<T!> addTypeConverter(Object);
+    method public androidx.room.RoomDatabase.Builder<T!> allowMainThreadQueries();
+    method public T build();
+    method public androidx.room.RoomDatabase.Builder<T!> createFromAsset(String);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromAsset(String, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromFile(java.io.File);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromFile(java.io.File, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream!>);
+    method public androidx.room.RoomDatabase.Builder<T!> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream!>, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
+    method public androidx.room.RoomDatabase.Builder<T!> enableMultiInstanceInvalidation();
+    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigration();
+    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationFrom(int...);
+    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationOnDowngrade();
+    method public androidx.room.RoomDatabase.Builder<T!> openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory?);
+    method public androidx.room.RoomDatabase.Builder<T!> setJournalMode(androidx.room.RoomDatabase.JournalMode);
+    method public androidx.room.RoomDatabase.Builder<T!> setQueryCallback(androidx.room.RoomDatabase.QueryCallback, java.util.concurrent.Executor);
+    method public androidx.room.RoomDatabase.Builder<T!> setQueryExecutor(java.util.concurrent.Executor);
+    method public androidx.room.RoomDatabase.Builder<T!> setTransactionExecutor(java.util.concurrent.Executor);
+  }
+
+  public abstract static class RoomDatabase.Callback {
+    ctor public RoomDatabase.Callback();
+    method public void onCreate(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onDestructiveMigration(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase);
+  }
+
+  public enum RoomDatabase.JournalMode {
+    enum_constant public static final androidx.room.RoomDatabase.JournalMode AUTOMATIC;
+    enum_constant public static final androidx.room.RoomDatabase.JournalMode TRUNCATE;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.JELLY_BEAN) public static final androidx.room.RoomDatabase.JournalMode WRITE_AHEAD_LOGGING;
+  }
+
+  public static class RoomDatabase.MigrationContainer {
+    ctor public RoomDatabase.MigrationContainer();
+    method public void addMigrations(androidx.room.migration.Migration!...);
+    method public void addMigrations(java.util.List<androidx.room.migration.Migration!>);
+    method public java.util.List<androidx.room.migration.Migration!>? findMigrationPath(int, int);
+    method public java.util.Map<java.lang.Integer!,java.util.Map<java.lang.Integer!,androidx.room.migration.Migration!>!> getMigrations();
+  }
+
+  public abstract static class RoomDatabase.PrepackagedDatabaseCallback {
+    ctor public RoomDatabase.PrepackagedDatabaseCallback();
+    method public void onOpenPrepackagedDatabase(androidx.sqlite.db.SupportSQLiteDatabase);
+  }
+
+  public static interface RoomDatabase.QueryCallback {
+    method public void onQuery(String, java.util.List<java.lang.Object!>);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class RoomOpenHelper extends androidx.sqlite.db.SupportSQLiteOpenHelper.Callback {
+    ctor public RoomOpenHelper(androidx.room.DatabaseConfiguration, androidx.room.RoomOpenHelper.Delegate, String, String);
+    ctor public RoomOpenHelper(androidx.room.DatabaseConfiguration, androidx.room.RoomOpenHelper.Delegate, String);
+    method public void onCreate(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method public void onUpgrade(androidx.sqlite.db.SupportSQLiteDatabase!, int, int);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract static class RoomOpenHelper.Delegate {
+    ctor public RoomOpenHelper.Delegate(int);
+    method protected abstract void createAllTables(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method protected abstract void dropAllTables(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method protected abstract void onCreate(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method protected abstract void onOpen(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method protected void onPostMigrate(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method protected void onPreMigrate(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method protected androidx.room.RoomOpenHelper.ValidationResult onValidateSchema(androidx.sqlite.db.SupportSQLiteDatabase);
+    method @Deprecated protected void validateMigration(androidx.sqlite.db.SupportSQLiteDatabase!);
+    field public final int version;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static class RoomOpenHelper.ValidationResult {
+    ctor public RoomOpenHelper.ValidationResult(boolean, String?);
+    field public final String? expectedFoundMsg;
+    field public final boolean isValid;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class RoomSQLiteQuery implements androidx.sqlite.db.SupportSQLiteProgram androidx.sqlite.db.SupportSQLiteQuery {
+    method public static androidx.room.RoomSQLiteQuery! acquire(String!, int);
+    method public void bindBlob(int, byte[]!);
+    method public void bindDouble(int, double);
+    method public void bindLong(int, long);
+    method public void bindNull(int);
+    method public void bindString(int, String!);
+    method public void bindTo(androidx.sqlite.db.SupportSQLiteProgram!);
+    method public void clearBindings();
+    method public void close();
+    method public void copyArgumentsFrom(androidx.room.RoomSQLiteQuery!);
+    method public static androidx.room.RoomSQLiteQuery! copyFrom(androidx.sqlite.db.SupportSQLiteQuery!);
+    method public int getArgCount();
+    method public String! getSql();
+    method public void release();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class SharedSQLiteStatement {
+    ctor public SharedSQLiteStatement(androidx.room.RoomDatabase!);
+    method public androidx.sqlite.db.SupportSQLiteStatement! acquire();
+    method protected void assertNotMainThread();
+    method protected abstract String! createQuery();
+    method public void release(androidx.sqlite.db.SupportSQLiteStatement!);
+  }
+
+}
+
+package androidx.room.migration {
+
+  public interface AutoMigrationSpec {
+    method public default void onPostMigrate(androidx.sqlite.db.SupportSQLiteDatabase);
+  }
+
+  public abstract class Migration {
+    ctor public Migration(int, int);
+    method public abstract void migrate(androidx.sqlite.db.SupportSQLiteDatabase);
+    field public final int endVersion;
+    field public final int startVersion;
+  }
+
+}
+
+package androidx.room.paging {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class LimitOffsetDataSource<T> extends androidx.paging.PositionalDataSource<T> {
+    ctor protected LimitOffsetDataSource(androidx.room.RoomDatabase, androidx.sqlite.db.SupportSQLiteQuery, boolean, java.lang.String!...);
+    ctor protected LimitOffsetDataSource(androidx.room.RoomDatabase, androidx.sqlite.db.SupportSQLiteQuery, boolean, boolean, java.lang.String!...);
+    ctor protected LimitOffsetDataSource(androidx.room.RoomDatabase, androidx.room.RoomSQLiteQuery, boolean, java.lang.String!...);
+    ctor protected LimitOffsetDataSource(androidx.room.RoomDatabase, androidx.room.RoomSQLiteQuery, boolean, boolean, java.lang.String!...);
+    method protected abstract java.util.List<T!> convertRows(android.database.Cursor);
+    method public void loadInitial(androidx.paging.PositionalDataSource.LoadInitialParams, androidx.paging.PositionalDataSource.LoadInitialCallback<T!>);
+    method public void loadRange(androidx.paging.PositionalDataSource.LoadRangeParams, androidx.paging.PositionalDataSource.LoadRangeCallback<T!>);
+  }
+
+}
+
+package androidx.room.util {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class CopyLock {
+    ctor public CopyLock(String, java.io.File, boolean);
+    method public void lock();
+    method public void unlock();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class CursorUtil {
+    method public static android.database.Cursor copyAndClose(android.database.Cursor);
+    method public static int getColumnIndex(android.database.Cursor, String);
+    method public static int getColumnIndexOrThrow(android.database.Cursor, String);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class DBUtil {
+    method public static android.os.CancellationSignal? createCancellationSignal();
+    method public static void dropFtsSyncTriggers(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method public static void foreignKeyCheck(androidx.sqlite.db.SupportSQLiteDatabase, String);
+    method @Deprecated public static android.database.Cursor query(androidx.room.RoomDatabase!, androidx.sqlite.db.SupportSQLiteQuery!, boolean);
+    method public static android.database.Cursor query(androidx.room.RoomDatabase, androidx.sqlite.db.SupportSQLiteQuery, boolean, android.os.CancellationSignal?);
+    method public static int readVersion(java.io.File) throws java.io.IOException;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class FileUtil {
+    method public static void copy(java.nio.channels.ReadableByteChannel, java.nio.channels.FileChannel) throws java.io.IOException;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class FtsTableInfo {
+    ctor public FtsTableInfo(String!, java.util.Set<java.lang.String!>!, java.util.Set<java.lang.String!>!);
+    ctor public FtsTableInfo(String!, java.util.Set<java.lang.String!>!, String!);
+    method public static androidx.room.util.FtsTableInfo! read(androidx.sqlite.db.SupportSQLiteDatabase!, String!);
+    field public final java.util.Set<java.lang.String!>! columns;
+    field public final String! name;
+    field public final java.util.Set<java.lang.String!>! options;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class StringUtil {
+    method public static void appendPlaceholders(StringBuilder!, int);
+    method public static String? joinIntoString(java.util.List<java.lang.Integer!>?);
+    method public static StringBuilder! newStringBuilder();
+    method public static java.util.List<java.lang.Integer!>? splitToIntList(String?);
+    field public static final String![]! EMPTY_STRING_ARRAY;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class TableInfo {
+    ctor public TableInfo(String!, java.util.Map<java.lang.String!,androidx.room.util.TableInfo.Column!>!, java.util.Set<androidx.room.util.TableInfo.ForeignKey!>!, java.util.Set<androidx.room.util.TableInfo.Index!>!);
+    ctor public TableInfo(String!, java.util.Map<java.lang.String!,androidx.room.util.TableInfo.Column!>!, java.util.Set<androidx.room.util.TableInfo.ForeignKey!>!);
+    method public static androidx.room.util.TableInfo! read(androidx.sqlite.db.SupportSQLiteDatabase!, String!);
+    field public static final int CREATED_FROM_DATABASE = 2; // 0x2
+    field public static final int CREATED_FROM_ENTITY = 1; // 0x1
+    field public static final int CREATED_FROM_UNKNOWN = 0; // 0x0
+    field public final java.util.Map<java.lang.String!,androidx.room.util.TableInfo.Column!>! columns;
+    field public final java.util.Set<androidx.room.util.TableInfo.ForeignKey!>! foreignKeys;
+    field public final java.util.Set<androidx.room.util.TableInfo.Index!>? indices;
+    field public final String! name;
+  }
+
+  public static final class TableInfo.Column {
+    ctor @Deprecated public TableInfo.Column(String!, String!, boolean, int);
+    ctor public TableInfo.Column(String!, String!, boolean, int, String!, int);
+    method public static boolean defaultValueEquals(String, String?);
+    method public boolean isPrimaryKey();
+    field @androidx.room.ColumnInfo.SQLiteTypeAffinity public final int affinity;
+    field public final String! defaultValue;
+    field public final String! name;
+    field public final boolean notNull;
+    field public final int primaryKeyPosition;
+    field public final String! type;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final class TableInfo.ForeignKey {
+    ctor public TableInfo.ForeignKey(String, String, String, java.util.List<java.lang.String!>, java.util.List<java.lang.String!>);
+    field public final java.util.List<java.lang.String!> columnNames;
+    field public final String onDelete;
+    field public final String onUpdate;
+    field public final java.util.List<java.lang.String!> referenceColumnNames;
+    field public final String referenceTable;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final class TableInfo.Index {
+    ctor @Deprecated public TableInfo.Index(String!, boolean, java.util.List<java.lang.String!>!);
+    ctor public TableInfo.Index(String!, boolean, java.util.List<java.lang.String!>!, java.util.List<java.lang.String!>!);
+    field public static final String DEFAULT_PREFIX = "index_";
+    field public final java.util.List<java.lang.String!>! columns;
+    field public final String! name;
+    field public final java.util.List<java.lang.String!>! orders;
+    field public final boolean unique;
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class UUIDUtil {
+    method public static java.util.UUID convertByteToUUID(byte[]);
+    method public static byte[] convertUUIDToByte(java.util.UUID);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class ViewInfo {
+    ctor public ViewInfo(String!, String!);
+    method public static androidx.room.util.ViewInfo! read(androidx.sqlite.db.SupportSQLiteDatabase!, String!);
+    field public final String! name;
+    field public final String! sql;
+  }
+
+}
+
diff --git a/room/room-runtime/api/restricted_current.ignore b/room/room-runtime/api/restricted_current.ignore
index 6984c60..aeb6a9e 100644
--- a/room/room-runtime/api/restricted_current.ignore
+++ b/room/room-runtime/api/restricted_current.ignore
@@ -1,19 +1,3 @@
 // Baseline format: 1.0
-ChangedType: androidx.room.InvalidationTracker#createLiveData(String[], boolean, java.util.concurrent.Callable<T>):
-    Method androidx.room.InvalidationTracker.createLiveData has changed return type from LiveData<T> to androidx.lifecycle.LiveData<T>
-ChangedType: androidx.room.InvalidationTracker#createLiveData(String[], java.util.concurrent.Callable<T>):
-    Method androidx.room.InvalidationTracker.createLiveData has changed return type from LiveData<T> to androidx.lifecycle.LiveData<T>
-
-
-InvalidNullConversion: androidx.room.InvalidationTracker#createLiveData(String[], boolean, java.util.concurrent.Callable<T>):
-    Attempted to remove @NonNull annotation from method androidx.room.InvalidationTracker.createLiveData(String[],boolean,java.util.concurrent.Callable<T>)
-InvalidNullConversion: androidx.room.InvalidationTracker#createLiveData(String[], java.util.concurrent.Callable<T>):
-    Attempted to remove @NonNull annotation from method androidx.room.InvalidationTracker.createLiveData(String[],java.util.concurrent.Callable<T>)
-
-
-RemovedMethod: androidx.room.paging.LimitOffsetDataSource#isInvalid():
-    Removed method androidx.room.paging.LimitOffsetDataSource.isInvalid()
-RemovedMethod: androidx.room.paging.LimitOffsetDataSource#loadInitial(LoadInitialParams, LoadInitialCallback<T>):
-    Removed method androidx.room.paging.LimitOffsetDataSource.loadInitial(LoadInitialParams,LoadInitialCallback<T>)
-RemovedMethod: androidx.room.paging.LimitOffsetDataSource#loadRange(LoadRangeParams, LoadRangeCallback<T>):
-    Removed method androidx.room.paging.LimitOffsetDataSource.loadRange(LoadRangeParams,LoadRangeCallback<T>)
+RemovedClass: androidx.room.MultiInstanceInvalidationService:
+    Removed class androidx.room.MultiInstanceInvalidationService
diff --git a/room/room-runtime/api/restricted_current.txt b/room/room-runtime/api/restricted_current.txt
index 19a1975..17a238e 100644
--- a/room/room-runtime/api/restricted_current.txt
+++ b/room/room-runtime/api/restricted_current.txt
@@ -8,7 +8,8 @@
     ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode, java.util.concurrent.Executor, java.util.concurrent.Executor, boolean, boolean, boolean, java.util.Set<java.lang.Integer!>?, String?, java.io.File?, java.util.concurrent.Callable<java.io.InputStream!>?);
     ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode, java.util.concurrent.Executor, java.util.concurrent.Executor, boolean, boolean, boolean, java.util.Set<java.lang.Integer!>?, String?, java.io.File?, java.util.concurrent.Callable<java.io.InputStream!>?, androidx.room.RoomDatabase.PrepackagedDatabaseCallback?);
     ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode, java.util.concurrent.Executor, java.util.concurrent.Executor, boolean, boolean, boolean, java.util.Set<java.lang.Integer!>?, String?, java.io.File?, java.util.concurrent.Callable<java.io.InputStream!>?, androidx.room.RoomDatabase.PrepackagedDatabaseCallback?, java.util.List<java.lang.Object!>?);
-    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode, java.util.concurrent.Executor, java.util.concurrent.Executor, boolean, boolean, boolean, java.util.Set<java.lang.Integer!>?, String?, java.io.File?, java.util.concurrent.Callable<java.io.InputStream!>?, androidx.room.RoomDatabase.PrepackagedDatabaseCallback?, java.util.List<java.lang.Object!>?, java.util.List<androidx.room.migration.AutoMigrationSpec!>?);
+    ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode, java.util.concurrent.Executor, java.util.concurrent.Executor, boolean, boolean, boolean, java.util.Set<java.lang.Integer!>?, String?, java.io.File?, java.util.concurrent.Callable<java.io.InputStream!>?, androidx.room.RoomDatabase.PrepackagedDatabaseCallback?, java.util.List<java.lang.Object!>?, java.util.List<androidx.room.migration.AutoMigrationSpec!>?);
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public DatabaseConfiguration(android.content.Context, String?, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory, androidx.room.RoomDatabase.MigrationContainer, java.util.List<androidx.room.RoomDatabase.Callback!>?, boolean, androidx.room.RoomDatabase.JournalMode, java.util.concurrent.Executor, java.util.concurrent.Executor, android.content.Intent?, boolean, boolean, java.util.Set<java.lang.Integer!>?, String?, java.io.File?, java.util.concurrent.Callable<java.io.InputStream!>?, androidx.room.RoomDatabase.PrepackagedDatabaseCallback?, java.util.List<java.lang.Object!>?, java.util.List<androidx.room.migration.AutoMigrationSpec!>?);
     method public boolean isMigrationRequired(int, int);
     method @Deprecated public boolean isMigrationRequiredFrom(int);
     field public final boolean allowDestructiveMigrationOnDowngrade;
@@ -22,6 +23,7 @@
     field public final androidx.room.RoomDatabase.JournalMode! journalMode;
     field public final androidx.room.RoomDatabase.MigrationContainer migrationContainer;
     field public final boolean multiInstanceInvalidation;
+    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final android.content.Intent! multiInstanceInvalidationServiceIntent;
     field public final String? name;
     field public final androidx.room.RoomDatabase.PrepackagedDatabaseCallback? prepackagedDatabaseCallback;
     field public final java.util.concurrent.Executor queryExecutor;
@@ -72,11 +74,6 @@
     method public abstract void onInvalidated(java.util.Set<java.lang.String!>);
   }
 
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class MultiInstanceInvalidationService extends android.app.Service {
-    ctor public MultiInstanceInvalidationService();
-    method public android.os.IBinder? onBind(android.content.Intent!);
-  }
-
   public class Room {
     ctor @Deprecated public Room();
     method public static <T extends androidx.room.RoomDatabase> androidx.room.RoomDatabase.Builder<T!> databaseBuilder(android.content.Context, Class<T!>, String);
diff --git a/room/room-runtime/build.gradle b/room/room-runtime/build.gradle
index 8bd2c15..48cdb86 100644
--- a/room/room-runtime/build.gradle
+++ b/room/room-runtime/build.gradle
@@ -34,8 +34,8 @@
 
 dependencies {
     api(project(":room:room-common"))
-    api("androidx.sqlite:sqlite-framework:2.2.0-alpha02")
-    api("androidx.sqlite:sqlite:2.2.0-alpha02")
+    api(project(":sqlite:sqlite-framework"))
+    api(project(":sqlite:sqlite"))
     implementation("androidx.arch.core:core-runtime:2.0.1")
     compileOnly("androidx.paging:paging-common:2.0.0")
     compileOnly("androidx.lifecycle:lifecycle-livedata-core:2.0.0")
diff --git a/room/room-runtime/src/main/java/androidx/room/DatabaseConfiguration.java b/room/room-runtime/src/main/java/androidx/room/DatabaseConfiguration.java
index 1861836..01e96bc 100644
--- a/room/room-runtime/src/main/java/androidx/room/DatabaseConfiguration.java
+++ b/room/room-runtime/src/main/java/androidx/room/DatabaseConfiguration.java
@@ -18,6 +18,7 @@
 
 import android.annotation.SuppressLint;
 import android.content.Context;
+import android.content.Intent;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -103,6 +104,15 @@
     public final boolean multiInstanceInvalidation;
 
     /**
+     * Intent that should be bound to acquire the invalidation service or {@code null} if not used.
+     *
+     * @see {@link #multiInstanceInvalidation}
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
+    public final Intent multiInstanceInvalidationServiceIntent;
+
+    /**
      * If true, Room should crash if a migration is missing.
      */
     public final boolean requireMigration;
@@ -142,8 +152,8 @@
      *
      * @deprecated Use {@link #DatabaseConfiguration(Context, String,
      * SupportSQLiteOpenHelper.Factory, RoomDatabase.MigrationContainer, List, boolean,
-     * RoomDatabase.JournalMode, Executor, Executor, boolean, boolean, boolean, Set, String, File,
-     * Callable, RoomDatabase.PrepackagedDatabaseCallback, List<Object>, List<AutoMigrationSpec>)}
+     * RoomDatabase.JournalMode, Executor, Executor, Intent, boolean, boolean, Set, String, File,
+     * Callable, RoomDatabase.PrepackagedDatabaseCallback, List, List)}
      *
      * @param context The application context.
      * @param name Name of the database, can be null if it is in memory.
@@ -182,8 +192,8 @@
      *
      * @deprecated Use {@link #DatabaseConfiguration(Context, String,
      * SupportSQLiteOpenHelper.Factory, RoomDatabase.MigrationContainer, List, boolean,
-     * RoomDatabase.JournalMode, Executor, Executor, boolean, boolean, boolean, Set, String, File,
-     * Callable, RoomDatabase.PrepackagedDatabaseCallback, List<Object>, List<AutoMigrationSpec>)}
+     * RoomDatabase.JournalMode, Executor, Executor, Intent, boolean, boolean, Set, String, File,
+     * Callable, RoomDatabase.PrepackagedDatabaseCallback, List, List)}
      *
      * @param context The application context.
      * @param name Name of the database, can be null if it is in memory.
@@ -228,8 +238,8 @@
      *
      * @deprecated Use {@link #DatabaseConfiguration(Context, String,
      * SupportSQLiteOpenHelper.Factory, RoomDatabase.MigrationContainer, List, boolean,
-     * RoomDatabase.JournalMode, Executor, Executor, boolean, boolean, boolean, Set, String, File,
-     * Callable, RoomDatabase.PrepackagedDatabaseCallback, List<Object>, List<AutoMigrationSpec>)}
+     * RoomDatabase.JournalMode, Executor, Executor, Intent, boolean, boolean, Set, String, File,
+     * Callable, RoomDatabase.PrepackagedDatabaseCallback, List, List)}
      *
      * @param context The application context.
      * @param name Name of the database, can be null if it is in memory.
@@ -278,8 +288,8 @@
      *
      * @deprecated Use {@link #DatabaseConfiguration(Context, String,
      * SupportSQLiteOpenHelper.Factory, RoomDatabase.MigrationContainer, List, boolean,
-     * RoomDatabase.JournalMode, Executor, Executor, boolean, boolean, boolean, Set, String, File,
-     * Callable, RoomDatabase.PrepackagedDatabaseCallback, List<Object>, List<AutoMigrationSpec>)}
+     * RoomDatabase.JournalMode, Executor, Executor, Intent, boolean, boolean, Set, String, File,
+     * Callable, RoomDatabase.PrepackagedDatabaseCallback, List, List)}
      *
      * @param context The application context.
      * @param name Name of the database, can be null if it is in memory.
@@ -332,8 +342,8 @@
      *
      * @deprecated Use {@link #DatabaseConfiguration(Context, String,
      * SupportSQLiteOpenHelper.Factory, RoomDatabase.MigrationContainer, List, boolean,
-     * RoomDatabase.JournalMode, Executor, Executor, boolean, boolean, boolean, Set, String, File,
-     * Callable, RoomDatabase.PrepackagedDatabaseCallback, List<Object>, List<AutoMigrationSpec>)}
+     * RoomDatabase.JournalMode, Executor, Executor, Intent, boolean, boolean, Set, String, File,
+     * Callable, RoomDatabase.PrepackagedDatabaseCallback, List, List)}
      *
      * @param context The application context.
      * @param name Name of the database, can be null if it is in memory.
@@ -389,8 +399,8 @@
      *
      * @deprecated Use {@link #DatabaseConfiguration(Context, String,
      * SupportSQLiteOpenHelper.Factory, RoomDatabase.MigrationContainer, List, boolean,
-     * RoomDatabase.JournalMode, Executor, Executor, boolean, boolean, boolean, Set, String, File,
-     * Callable, RoomDatabase.PrepackagedDatabaseCallback, List<Object>, List<AutoMigrationSpec>)}
+     * RoomDatabase.JournalMode, Executor, Executor, Intent, boolean, boolean, Set, String, File,
+     * Callable, RoomDatabase.PrepackagedDatabaseCallback, List, List)}
      *
      * @param context The application context.
      * @param name Name of the database, can be null if it is in memory.
@@ -446,6 +456,11 @@
     /**
      * Creates a database configuration with the given values.
      *
+     * @deprecated Use {@link #DatabaseConfiguration(Context, String,
+     * SupportSQLiteOpenHelper.Factory, RoomDatabase.MigrationContainer, List, boolean,
+     * RoomDatabase.JournalMode, Executor, Executor, Intent, boolean, boolean, Set, String, File,
+     * Callable, RoomDatabase.PrepackagedDatabaseCallback, List, List)}
+     *
      * @param context The application context.
      * @param name Name of the database, can be null if it is in memory.
      * @param sqliteOpenHelperFactory The open helper factory to use.
@@ -471,6 +486,7 @@
      *
      * @hide
      */
+    @Deprecated
     @SuppressLint("LambdaLast")
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
     public DatabaseConfiguration(@NonNull Context context, @Nullable String name,
@@ -491,6 +507,65 @@
             @Nullable RoomDatabase.PrepackagedDatabaseCallback prepackagedDatabaseCallback,
             @Nullable List<Object> typeConverters,
             @Nullable List<AutoMigrationSpec> autoMigrationSpecs) {
+        this(context, name, sqliteOpenHelperFactory, migrationContainer, callbacks,
+                allowMainThreadQueries, journalMode, queryExecutor, transactionExecutor,
+                multiInstanceInvalidation ? new Intent(context,
+                MultiInstanceInvalidationService.class) : null,
+                requireMigration, allowDestructiveMigrationOnDowngrade, migrationNotRequiredFrom,
+                copyFromAssetPath, copyFromFile, copyFromInputStream, prepackagedDatabaseCallback,
+                typeConverters, autoMigrationSpecs);
+    }
+
+    /**
+     * Creates a database configuration with the given values.
+     *
+     * @param context The application context.
+     * @param name Name of the database, can be null if it is in memory.
+     * @param sqliteOpenHelperFactory The open helper factory to use.
+     * @param migrationContainer The migration container for migrations.
+     * @param callbacks The list of callbacks for database events.
+     * @param allowMainThreadQueries Whether to allow main thread reads/writes or not.
+     * @param journalMode The journal mode. This has to be either TRUNCATE or WRITE_AHEAD_LOGGING.
+     * @param queryExecutor The Executor used to execute asynchronous queries.
+     * @param transactionExecutor The Executor used to execute asynchronous transactions.
+     * @param multiInstanceInvalidationServiceIntent The intent to use to bind to the
+     *                                               invalidation service or {@code null} if not
+     *                                               used.
+     * @param requireMigration True if Room should require a valid migration if version changes,
+     * @param allowDestructiveMigrationOnDowngrade True if Room should recreate tables if no
+     *                                             migration is supplied during a downgrade.
+     * @param migrationNotRequiredFrom The collection of schema versions from which migrations
+     *                                 aren't required.
+     * @param copyFromAssetPath The assets path to the pre-packaged database.
+     * @param copyFromFile The pre-packaged database file.
+     * @param copyFromInputStream The callable to get the input stream from which a
+     *                            pre-package database file will be copied from.
+     * @param prepackagedDatabaseCallback The pre-packaged callback.
+     * @param typeConverters The type converters.
+     * @param autoMigrationSpecs The auto migration specs.
+     *
+     * @hide
+     */
+    @SuppressLint("LambdaLast")
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
+    public DatabaseConfiguration(@NonNull Context context, @Nullable String name,
+            @NonNull SupportSQLiteOpenHelper.Factory sqliteOpenHelperFactory,
+            @NonNull RoomDatabase.MigrationContainer migrationContainer,
+            @Nullable List<RoomDatabase.Callback> callbacks,
+            boolean allowMainThreadQueries,
+            @NonNull RoomDatabase.JournalMode journalMode,
+            @NonNull Executor queryExecutor,
+            @NonNull Executor transactionExecutor,
+            @Nullable Intent multiInstanceInvalidationServiceIntent,
+            boolean requireMigration,
+            boolean allowDestructiveMigrationOnDowngrade,
+            @Nullable Set<Integer> migrationNotRequiredFrom,
+            @Nullable String copyFromAssetPath,
+            @Nullable File copyFromFile,
+            @Nullable Callable<InputStream> copyFromInputStream,
+            @Nullable RoomDatabase.PrepackagedDatabaseCallback prepackagedDatabaseCallback,
+            @Nullable List<Object> typeConverters,
+            @Nullable List<AutoMigrationSpec> autoMigrationSpecs) {
         this.sqliteOpenHelperFactory = sqliteOpenHelperFactory;
         this.context = context;
         this.name = name;
@@ -500,7 +575,9 @@
         this.journalMode = journalMode;
         this.queryExecutor = queryExecutor;
         this.transactionExecutor = transactionExecutor;
-        this.multiInstanceInvalidation = multiInstanceInvalidation;
+        this.multiInstanceInvalidationServiceIntent =
+                multiInstanceInvalidationServiceIntent;
+        this.multiInstanceInvalidation = multiInstanceInvalidationServiceIntent != null;
         this.requireMigration = requireMigration;
         this.allowDestructiveMigrationOnDowngrade = allowDestructiveMigrationOnDowngrade;
         this.mMigrationNotRequiredFrom = migrationNotRequiredFrom;
diff --git a/room/room-runtime/src/main/java/androidx/room/ExperimentalRoomApi.java b/room/room-runtime/src/main/java/androidx/room/ExperimentalRoomApi.java
index 729a4a9..14896bf 100644
--- a/room/room-runtime/src/main/java/androidx/room/ExperimentalRoomApi.java
+++ b/room/room-runtime/src/main/java/androidx/room/ExperimentalRoomApi.java
@@ -24,6 +24,6 @@
 /**
  * APIs marked with ExperimentalRoomApi are experimental and may change.
  */
-@Target({ElementType.METHOD})
+@Target({ElementType.TYPE, ElementType.METHOD})
 @RequiresOptIn()
 public @interface ExperimentalRoomApi {}
diff --git a/room/room-runtime/src/main/java/androidx/room/InvalidationTracker.java b/room/room-runtime/src/main/java/androidx/room/InvalidationTracker.java
index de59d64..fe0ae9a 100644
--- a/room/room-runtime/src/main/java/androidx/room/InvalidationTracker.java
+++ b/room/room-runtime/src/main/java/androidx/room/InvalidationTracker.java
@@ -18,6 +18,7 @@
 
 import android.annotation.SuppressLint;
 import android.content.Context;
+import android.content.Intent;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteException;
 import android.os.Build;
@@ -210,9 +211,9 @@
         }
     }
 
-    void startMultiInstanceInvalidation(Context context, String name) {
-        mMultiInstanceInvalidationClient = new MultiInstanceInvalidationClient(context, name, this,
-                mDatabase.getQueryExecutor());
+    void startMultiInstanceInvalidation(Context context, String name, Intent serviceIntent) {
+        mMultiInstanceInvalidationClient = new MultiInstanceInvalidationClient(context, name,
+                serviceIntent, this, mDatabase.getQueryExecutor());
     }
 
     void stopMultiInstanceInvalidation() {
diff --git a/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationClient.java b/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationClient.java
index c8a7b5d..cd847acc 100644
--- a/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationClient.java
+++ b/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationClient.java
@@ -142,10 +142,12 @@
      * @param context             The Context to be used for binding
      *                            {@link IMultiInstanceInvalidationService}.
      * @param name                The name of the database file.
+     * @param serviceIntent       The {@link Intent} used for binding
+     *                            {@link IMultiInstanceInvalidationService}.
      * @param invalidationTracker The {@link InvalidationTracker}
      * @param executor            The background executor.
      */
-    MultiInstanceInvalidationClient(Context context, String name,
+    MultiInstanceInvalidationClient(Context context, String name, Intent serviceIntent,
             InvalidationTracker invalidationTracker, Executor executor) {
         mAppContext = context.getApplicationContext();
         mName = name;
@@ -174,8 +176,7 @@
                 return true;
             }
         };
-        Intent intent = new Intent(mAppContext, MultiInstanceInvalidationService.class);
-        mAppContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
+        mAppContext.bindService(serviceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
     }
 
     void stop() {
diff --git a/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationService.java b/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationService.java
index 2e98f12..0c82f93 100644
--- a/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationService.java
+++ b/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationService.java
@@ -23,8 +23,8 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RestrictTo;
 
 import java.util.HashMap;
 
@@ -33,9 +33,12 @@
  * This service runs in the main app process. All the instances of {@link InvalidationTracker}
  * (potentially in other processes) has to connect to this service.
  *
- * @hide
+ * <p>The intent to launch it can be specified by
+ * {@link RoomDatabase.Builder#setMultiInstanceInvalidationServiceIntent}, although the service is
+ * defined in the manifest by default so there should be no need to override it in a normal
+ * situation.
  */
-@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
+@ExperimentalRoomApi
 public class MultiInstanceInvalidationService extends Service {
 
     // synthetic access
@@ -128,7 +131,7 @@
 
     @Nullable
     @Override
-    public IBinder onBind(Intent intent) {
+    public IBinder onBind(@NonNull Intent intent) {
         return mBinder;
     }
 }
diff --git a/room/room-runtime/src/main/java/androidx/room/RoomDatabase.java b/room/room-runtime/src/main/java/androidx/room/RoomDatabase.java
index 1b5ef23..54427d6 100644
--- a/room/room-runtime/src/main/java/androidx/room/RoomDatabase.java
+++ b/room/room-runtime/src/main/java/androidx/room/RoomDatabase.java
@@ -19,6 +19,7 @@
 import android.annotation.SuppressLint;
 import android.app.ActivityManager;
 import android.content.Context;
+import android.content.Intent;
 import android.database.Cursor;
 import android.os.Build;
 import android.os.CancellationSignal;
@@ -263,9 +264,9 @@
         mTransactionExecutor = new TransactionExecutor(configuration.transactionExecutor);
         mAllowMainThreadQueries = configuration.allowMainThreadQueries;
         mWriteAheadLoggingEnabled = wal;
-        if (configuration.multiInstanceInvalidation) {
+        if (configuration.multiInstanceInvalidationServiceIntent != null) {
             mInvalidationTracker.startMultiInstanceInvalidation(configuration.context,
-                    configuration.name);
+                    configuration.name, configuration.multiInstanceInvalidationServiceIntent);
         }
 
         Map<Class<?>, List<Class<?>>> requiredFactories = getRequiredTypeConverters();
@@ -781,7 +782,7 @@
         private SupportSQLiteOpenHelper.Factory mFactory;
         private boolean mAllowMainThreadQueries;
         private JournalMode mJournalMode;
-        private boolean mMultiInstanceInvalidation;
+        private Intent mMultiInstanceInvalidationIntent;
         private boolean mRequireMigration;
         private boolean mAllowDestructiveMigrationOnDowngrade;
 
@@ -1167,7 +1168,33 @@
          */
         @NonNull
         public Builder<T> enableMultiInstanceInvalidation() {
-            mMultiInstanceInvalidation = mName != null;
+            mMultiInstanceInvalidationIntent = mName != null ? new Intent(mContext,
+                    MultiInstanceInvalidationService.class) : null;
+            return this;
+        }
+
+        /**
+         * Sets whether table invalidation in this instance of {@link RoomDatabase} should be
+         * broadcast and synchronized with other instances of the same {@link RoomDatabase},
+         * including those in a separate process. In order to enable multi-instance invalidation,
+         * this has to be turned on both ends and need to point to the same
+         * {@link MultiInstanceInvalidationService}.
+         * <p>
+         * This is not enabled by default.
+         * <p>
+         * This does not work for in-memory databases. This does not work between database instances
+         * targeting different database files.
+         *
+         * @return This {@link Builder} instance.
+         * @param invalidationServiceIntent Intent to bind to the
+         * {@link MultiInstanceInvalidationService}.
+         */
+        @SuppressWarnings("MissingGetterMatchingBuilder")
+        @NonNull
+        @ExperimentalRoomApi
+        public Builder<T> setMultiInstanceInvalidationServiceIntent(
+                @NonNull Intent invalidationServiceIntent) {
+            mMultiInstanceInvalidationIntent = mName != null ? invalidationServiceIntent : null;
             return this;
         }
 
@@ -1446,7 +1473,7 @@
                             mJournalMode.resolve(mContext),
                             mQueryExecutor,
                             mTransactionExecutor,
-                            mMultiInstanceInvalidation,
+                            mMultiInstanceInvalidationIntent,
                             mRequireMigration,
                             mAllowDestructiveMigrationOnDowngrade,
                             mMigrationsNotRequiredFrom,
diff --git a/room/room-rxjava2/api/2.4.0-beta01.txt b/room/room-rxjava2/api/2.4.0-beta01.txt
new file mode 100644
index 0000000..64b6fe4
--- /dev/null
+++ b/room/room-rxjava2/api/2.4.0-beta01.txt
@@ -0,0 +1,16 @@
+// Signature format: 4.0
+package androidx.room {
+
+  public class EmptyResultSetException extends java.lang.RuntimeException {
+    ctor public EmptyResultSetException(String!);
+  }
+
+  public class RxRoom {
+    ctor @Deprecated public RxRoom();
+    method public static io.reactivex.Flowable<java.lang.Object!>! createFlowable(androidx.room.RoomDatabase!, java.lang.String!...);
+    method public static io.reactivex.Observable<java.lang.Object!>! createObservable(androidx.room.RoomDatabase!, java.lang.String!...);
+    field public static final Object! NOTHING;
+  }
+
+}
+
diff --git a/room/room-rxjava2/api/public_plus_experimental_2.4.0-beta01.txt b/room/room-rxjava2/api/public_plus_experimental_2.4.0-beta01.txt
new file mode 100644
index 0000000..64b6fe4
--- /dev/null
+++ b/room/room-rxjava2/api/public_plus_experimental_2.4.0-beta01.txt
@@ -0,0 +1,16 @@
+// Signature format: 4.0
+package androidx.room {
+
+  public class EmptyResultSetException extends java.lang.RuntimeException {
+    ctor public EmptyResultSetException(String!);
+  }
+
+  public class RxRoom {
+    ctor @Deprecated public RxRoom();
+    method public static io.reactivex.Flowable<java.lang.Object!>! createFlowable(androidx.room.RoomDatabase!, java.lang.String!...);
+    method public static io.reactivex.Observable<java.lang.Object!>! createObservable(androidx.room.RoomDatabase!, java.lang.String!...);
+    field public static final Object! NOTHING;
+  }
+
+}
+
diff --git a/room/room-rxjava2/api/res-2.4.0-beta01.txt b/room/room-rxjava2/api/res-2.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/room/room-rxjava2/api/res-2.4.0-beta01.txt
diff --git a/room/room-rxjava2/api/restricted_2.4.0-beta01.txt b/room/room-rxjava2/api/restricted_2.4.0-beta01.txt
new file mode 100644
index 0000000..5505f93
--- /dev/null
+++ b/room/room-rxjava2/api/restricted_2.4.0-beta01.txt
@@ -0,0 +1,21 @@
+// Signature format: 4.0
+package androidx.room {
+
+  public class EmptyResultSetException extends java.lang.RuntimeException {
+    ctor public EmptyResultSetException(String!);
+  }
+
+  public class RxRoom {
+    ctor @Deprecated public RxRoom();
+    method public static io.reactivex.Flowable<java.lang.Object!>! createFlowable(androidx.room.RoomDatabase!, java.lang.String!...);
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static <T> io.reactivex.Flowable<T!>! createFlowable(androidx.room.RoomDatabase!, String![]!, java.util.concurrent.Callable<T!>!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static <T> io.reactivex.Flowable<T!>! createFlowable(androidx.room.RoomDatabase!, boolean, String![]!, java.util.concurrent.Callable<T!>!);
+    method public static io.reactivex.Observable<java.lang.Object!>! createObservable(androidx.room.RoomDatabase!, java.lang.String!...);
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static <T> io.reactivex.Observable<T!>! createObservable(androidx.room.RoomDatabase!, String![]!, java.util.concurrent.Callable<T!>!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static <T> io.reactivex.Observable<T!>! createObservable(androidx.room.RoomDatabase!, boolean, String![]!, java.util.concurrent.Callable<T!>!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static <T> io.reactivex.Single<T!>! createSingle(java.util.concurrent.Callable<T!>!);
+    field public static final Object! NOTHING;
+  }
+
+}
+
diff --git a/room/room-rxjava3/api/2.4.0-beta01.txt b/room/room-rxjava3/api/2.4.0-beta01.txt
new file mode 100644
index 0000000..6b78281
--- /dev/null
+++ b/room/room-rxjava3/api/2.4.0-beta01.txt
@@ -0,0 +1,15 @@
+// Signature format: 4.0
+package androidx.room.rxjava3 {
+
+  public final class EmptyResultSetException extends java.lang.RuntimeException {
+    ctor public EmptyResultSetException(String);
+  }
+
+  public final class RxRoom {
+    method public static io.reactivex.rxjava3.core.Flowable<java.lang.Object!> createFlowable(androidx.room.RoomDatabase, java.lang.String!...);
+    method public static io.reactivex.rxjava3.core.Observable<java.lang.Object!> createObservable(androidx.room.RoomDatabase, java.lang.String!...);
+    field public static final Object NOTHING;
+  }
+
+}
+
diff --git a/room/room-rxjava3/api/public_plus_experimental_2.4.0-beta01.txt b/room/room-rxjava3/api/public_plus_experimental_2.4.0-beta01.txt
new file mode 100644
index 0000000..6b78281
--- /dev/null
+++ b/room/room-rxjava3/api/public_plus_experimental_2.4.0-beta01.txt
@@ -0,0 +1,15 @@
+// Signature format: 4.0
+package androidx.room.rxjava3 {
+
+  public final class EmptyResultSetException extends java.lang.RuntimeException {
+    ctor public EmptyResultSetException(String);
+  }
+
+  public final class RxRoom {
+    method public static io.reactivex.rxjava3.core.Flowable<java.lang.Object!> createFlowable(androidx.room.RoomDatabase, java.lang.String!...);
+    method public static io.reactivex.rxjava3.core.Observable<java.lang.Object!> createObservable(androidx.room.RoomDatabase, java.lang.String!...);
+    field public static final Object NOTHING;
+  }
+
+}
+
diff --git a/room/room-rxjava3/api/res-2.4.0-beta01.txt b/room/room-rxjava3/api/res-2.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/room/room-rxjava3/api/res-2.4.0-beta01.txt
diff --git a/room/room-rxjava3/api/restricted_2.4.0-beta01.txt b/room/room-rxjava3/api/restricted_2.4.0-beta01.txt
new file mode 100644
index 0000000..0680710
--- /dev/null
+++ b/room/room-rxjava3/api/restricted_2.4.0-beta01.txt
@@ -0,0 +1,18 @@
+// Signature format: 4.0
+package androidx.room.rxjava3 {
+
+  public final class EmptyResultSetException extends java.lang.RuntimeException {
+    ctor public EmptyResultSetException(String);
+  }
+
+  public final class RxRoom {
+    method public static io.reactivex.rxjava3.core.Flowable<java.lang.Object!> createFlowable(androidx.room.RoomDatabase, java.lang.String!...);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static <T> io.reactivex.rxjava3.core.Flowable<T!> createFlowable(androidx.room.RoomDatabase, boolean, String![], java.util.concurrent.Callable<T!>);
+    method public static io.reactivex.rxjava3.core.Observable<java.lang.Object!> createObservable(androidx.room.RoomDatabase, java.lang.String!...);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static <T> io.reactivex.rxjava3.core.Observable<T!> createObservable(androidx.room.RoomDatabase, boolean, String![], java.util.concurrent.Callable<T!>);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static <T> io.reactivex.rxjava3.core.Single<T!> createSingle(java.util.concurrent.Callable<T!>);
+    field public static final Object NOTHING;
+  }
+
+}
+
diff --git a/room/room-testing/api/2.4.0-beta01.txt b/room/room-testing/api/2.4.0-beta01.txt
new file mode 100644
index 0000000..ea0639e
--- /dev/null
+++ b/room/room-testing/api/2.4.0-beta01.txt
@@ -0,0 +1,17 @@
+// Signature format: 4.0
+package androidx.room.testing {
+
+  public class MigrationTestHelper extends org.junit.rules.TestWatcher {
+    ctor @Deprecated public MigrationTestHelper(android.app.Instrumentation!, String!);
+    ctor @Deprecated public MigrationTestHelper(android.app.Instrumentation!, String!, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory!);
+    ctor public MigrationTestHelper(android.app.Instrumentation, Class<? extends androidx.room.RoomDatabase>);
+    ctor public MigrationTestHelper(android.app.Instrumentation, Class<? extends androidx.room.RoomDatabase>, java.util.List<androidx.room.migration.AutoMigrationSpec!>);
+    ctor public MigrationTestHelper(android.app.Instrumentation, Class<? extends androidx.room.RoomDatabase>, java.util.List<androidx.room.migration.AutoMigrationSpec!>, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory);
+    method public void closeWhenFinished(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method public void closeWhenFinished(androidx.room.RoomDatabase!);
+    method public androidx.sqlite.db.SupportSQLiteDatabase! createDatabase(String!, int) throws java.io.IOException;
+    method public androidx.sqlite.db.SupportSQLiteDatabase! runMigrationsAndValidate(String!, int, boolean, androidx.room.migration.Migration!...) throws java.io.IOException;
+  }
+
+}
+
diff --git a/room/room-testing/api/public_plus_experimental_2.4.0-beta01.txt b/room/room-testing/api/public_plus_experimental_2.4.0-beta01.txt
new file mode 100644
index 0000000..ea0639e
--- /dev/null
+++ b/room/room-testing/api/public_plus_experimental_2.4.0-beta01.txt
@@ -0,0 +1,17 @@
+// Signature format: 4.0
+package androidx.room.testing {
+
+  public class MigrationTestHelper extends org.junit.rules.TestWatcher {
+    ctor @Deprecated public MigrationTestHelper(android.app.Instrumentation!, String!);
+    ctor @Deprecated public MigrationTestHelper(android.app.Instrumentation!, String!, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory!);
+    ctor public MigrationTestHelper(android.app.Instrumentation, Class<? extends androidx.room.RoomDatabase>);
+    ctor public MigrationTestHelper(android.app.Instrumentation, Class<? extends androidx.room.RoomDatabase>, java.util.List<androidx.room.migration.AutoMigrationSpec!>);
+    ctor public MigrationTestHelper(android.app.Instrumentation, Class<? extends androidx.room.RoomDatabase>, java.util.List<androidx.room.migration.AutoMigrationSpec!>, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory);
+    method public void closeWhenFinished(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method public void closeWhenFinished(androidx.room.RoomDatabase!);
+    method public androidx.sqlite.db.SupportSQLiteDatabase! createDatabase(String!, int) throws java.io.IOException;
+    method public androidx.sqlite.db.SupportSQLiteDatabase! runMigrationsAndValidate(String!, int, boolean, androidx.room.migration.Migration!...) throws java.io.IOException;
+  }
+
+}
+
diff --git a/room/room-testing/api/res-2.4.0-beta01.txt b/room/room-testing/api/res-2.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/room/room-testing/api/res-2.4.0-beta01.txt
diff --git a/room/room-testing/api/restricted_2.4.0-beta01.txt b/room/room-testing/api/restricted_2.4.0-beta01.txt
new file mode 100644
index 0000000..ea0639e
--- /dev/null
+++ b/room/room-testing/api/restricted_2.4.0-beta01.txt
@@ -0,0 +1,17 @@
+// Signature format: 4.0
+package androidx.room.testing {
+
+  public class MigrationTestHelper extends org.junit.rules.TestWatcher {
+    ctor @Deprecated public MigrationTestHelper(android.app.Instrumentation!, String!);
+    ctor @Deprecated public MigrationTestHelper(android.app.Instrumentation!, String!, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory!);
+    ctor public MigrationTestHelper(android.app.Instrumentation, Class<? extends androidx.room.RoomDatabase>);
+    ctor public MigrationTestHelper(android.app.Instrumentation, Class<? extends androidx.room.RoomDatabase>, java.util.List<androidx.room.migration.AutoMigrationSpec!>);
+    ctor public MigrationTestHelper(android.app.Instrumentation, Class<? extends androidx.room.RoomDatabase>, java.util.List<androidx.room.migration.AutoMigrationSpec!>, androidx.sqlite.db.SupportSQLiteOpenHelper.Factory);
+    method public void closeWhenFinished(androidx.sqlite.db.SupportSQLiteDatabase!);
+    method public void closeWhenFinished(androidx.room.RoomDatabase!);
+    method public androidx.sqlite.db.SupportSQLiteDatabase! createDatabase(String!, int) throws java.io.IOException;
+    method public androidx.sqlite.db.SupportSQLiteDatabase! runMigrationsAndValidate(String!, int, boolean, androidx.room.migration.Migration!...) throws java.io.IOException;
+  }
+
+}
+
diff --git a/room/room-testing/build.gradle b/room/room-testing/build.gradle
index d64b045..1c0acde 100644
--- a/room/room-testing/build.gradle
+++ b/room/room-testing/build.gradle
@@ -25,8 +25,8 @@
 dependencies {
     api(project(":room:room-common"))
     api(project(":room:room-runtime"))
-    api("androidx.sqlite:sqlite:2.2.0-alpha02")
-    api("androidx.sqlite:sqlite-framework:2.2.0-alpha02")
+    api(project(":sqlite:sqlite"))
+    api(project(":sqlite:sqlite-framework"))
     api(project(":room:room-migration"))
     implementation("androidx.arch.core:core-runtime:2.0.1")
     api(libs.junit)
diff --git a/room/room-testing/src/main/java/androidx/room/testing/MigrationTestHelper.java b/room/room-testing/src/main/java/androidx/room/testing/MigrationTestHelper.java
index 1431498..4f0e4569 100644
--- a/room/room-testing/src/main/java/androidx/room/testing/MigrationTestHelper.java
+++ b/room/room-testing/src/main/java/androidx/room/testing/MigrationTestHelper.java
@@ -247,7 +247,7 @@
                 RoomDatabase.JournalMode.TRUNCATE,
                 ArchTaskExecutor.getIOThreadExecutor(),
                 ArchTaskExecutor.getIOThreadExecutor(),
-                false,
+                null,
                 true,
                 false,
                 Collections.<Integer>emptySet(),
@@ -312,7 +312,7 @@
                 RoomDatabase.JournalMode.TRUNCATE,
                 ArchTaskExecutor.getIOThreadExecutor(),
                 ArchTaskExecutor.getIOThreadExecutor(),
-                false,
+                null,
                 true,
                 false,
                 Collections.<Integer>emptySet(),
diff --git a/sqlite/sqlite-framework/api/2.2.0-beta01.txt b/sqlite/sqlite-framework/api/2.2.0-beta01.txt
new file mode 100644
index 0000000..526c565
--- /dev/null
+++ b/sqlite/sqlite-framework/api/2.2.0-beta01.txt
@@ -0,0 +1,10 @@
+// Signature format: 4.0
+package androidx.sqlite.db.framework {
+
+  public final class FrameworkSQLiteOpenHelperFactory implements androidx.sqlite.db.SupportSQLiteOpenHelper.Factory {
+    ctor public FrameworkSQLiteOpenHelperFactory();
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration);
+  }
+
+}
+
diff --git a/sqlite/sqlite-framework/api/public_plus_experimental_2.2.0-beta01.txt b/sqlite/sqlite-framework/api/public_plus_experimental_2.2.0-beta01.txt
new file mode 100644
index 0000000..526c565
--- /dev/null
+++ b/sqlite/sqlite-framework/api/public_plus_experimental_2.2.0-beta01.txt
@@ -0,0 +1,10 @@
+// Signature format: 4.0
+package androidx.sqlite.db.framework {
+
+  public final class FrameworkSQLiteOpenHelperFactory implements androidx.sqlite.db.SupportSQLiteOpenHelper.Factory {
+    ctor public FrameworkSQLiteOpenHelperFactory();
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration);
+  }
+
+}
+
diff --git a/sqlite/sqlite-framework/api/res-2.2.0-beta01.txt b/sqlite/sqlite-framework/api/res-2.2.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sqlite/sqlite-framework/api/res-2.2.0-beta01.txt
diff --git a/sqlite/sqlite-framework/api/restricted_2.2.0-beta01.txt b/sqlite/sqlite-framework/api/restricted_2.2.0-beta01.txt
new file mode 100644
index 0000000..526c565
--- /dev/null
+++ b/sqlite/sqlite-framework/api/restricted_2.2.0-beta01.txt
@@ -0,0 +1,10 @@
+// Signature format: 4.0
+package androidx.sqlite.db.framework {
+
+  public final class FrameworkSQLiteOpenHelperFactory implements androidx.sqlite.db.SupportSQLiteOpenHelper.Factory {
+    ctor public FrameworkSQLiteOpenHelperFactory();
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration);
+  }
+
+}
+
diff --git a/sqlite/sqlite-ktx/api/2.2.0-beta01.txt b/sqlite/sqlite-ktx/api/2.2.0-beta01.txt
new file mode 100644
index 0000000..26086b4
--- /dev/null
+++ b/sqlite/sqlite-ktx/api/2.2.0-beta01.txt
@@ -0,0 +1,9 @@
+// Signature format: 4.0
+package androidx.sqlite.db {
+
+  public final class SupportSQLiteDatabaseKt {
+    method public static inline <T> T! transaction(androidx.sqlite.db.SupportSQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,? extends T> body);
+  }
+
+}
+
diff --git a/sqlite/sqlite-ktx/api/public_plus_experimental_2.2.0-beta01.txt b/sqlite/sqlite-ktx/api/public_plus_experimental_2.2.0-beta01.txt
new file mode 100644
index 0000000..26086b4
--- /dev/null
+++ b/sqlite/sqlite-ktx/api/public_plus_experimental_2.2.0-beta01.txt
@@ -0,0 +1,9 @@
+// Signature format: 4.0
+package androidx.sqlite.db {
+
+  public final class SupportSQLiteDatabaseKt {
+    method public static inline <T> T! transaction(androidx.sqlite.db.SupportSQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,? extends T> body);
+  }
+
+}
+
diff --git a/sqlite/sqlite-ktx/api/res-2.2.0-beta01.txt b/sqlite/sqlite-ktx/api/res-2.2.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sqlite/sqlite-ktx/api/res-2.2.0-beta01.txt
diff --git a/sqlite/sqlite-ktx/api/restricted_2.2.0-beta01.txt b/sqlite/sqlite-ktx/api/restricted_2.2.0-beta01.txt
new file mode 100644
index 0000000..26086b4
--- /dev/null
+++ b/sqlite/sqlite-ktx/api/restricted_2.2.0-beta01.txt
@@ -0,0 +1,9 @@
+// Signature format: 4.0
+package androidx.sqlite.db {
+
+  public final class SupportSQLiteDatabaseKt {
+    method public static inline <T> T! transaction(androidx.sqlite.db.SupportSQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,? extends T> body);
+  }
+
+}
+
diff --git a/sqlite/sqlite/api/2.2.0-beta01.txt b/sqlite/sqlite/api/2.2.0-beta01.txt
new file mode 100644
index 0000000..dbdea61
--- /dev/null
+++ b/sqlite/sqlite/api/2.2.0-beta01.txt
@@ -0,0 +1,130 @@
+// Signature format: 4.0
+package androidx.sqlite.db {
+
+  public final class SimpleSQLiteQuery implements androidx.sqlite.db.SupportSQLiteQuery {
+    ctor public SimpleSQLiteQuery(String!, Object![]?);
+    ctor public SimpleSQLiteQuery(String!);
+    method public static void bind(androidx.sqlite.db.SupportSQLiteProgram!, Object![]!);
+    method public void bindTo(androidx.sqlite.db.SupportSQLiteProgram!);
+    method public int getArgCount();
+    method public String! getSql();
+  }
+
+  public interface SupportSQLiteDatabase extends java.io.Closeable {
+    method public void beginTransaction();
+    method public void beginTransactionNonExclusive();
+    method public void beginTransactionWithListener(android.database.sqlite.SQLiteTransactionListener!);
+    method public void beginTransactionWithListenerNonExclusive(android.database.sqlite.SQLiteTransactionListener!);
+    method public androidx.sqlite.db.SupportSQLiteStatement! compileStatement(String!);
+    method public int delete(String!, String!, Object![]!);
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public void disableWriteAheadLogging();
+    method public boolean enableWriteAheadLogging();
+    method public void endTransaction();
+    method public default void execPerConnectionSQL(String, Object![]?);
+    method public void execSQL(String!) throws android.database.SQLException;
+    method public void execSQL(String!, Object![]!) throws android.database.SQLException;
+    method public java.util.List<android.util.Pair<java.lang.String!,java.lang.String!>!>! getAttachedDbs();
+    method public long getMaximumSize();
+    method public long getPageSize();
+    method public String! getPath();
+    method public int getVersion();
+    method public boolean inTransaction();
+    method public long insert(String!, int, android.content.ContentValues!) throws android.database.SQLException;
+    method public boolean isDatabaseIntegrityOk();
+    method public boolean isDbLockedByCurrentThread();
+    method public default boolean isExecPerConnectionSQLSupported();
+    method public boolean isOpen();
+    method public boolean isReadOnly();
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public boolean isWriteAheadLoggingEnabled();
+    method public boolean needUpgrade(int);
+    method public android.database.Cursor! query(String!);
+    method public android.database.Cursor! query(String!, Object![]!);
+    method public android.database.Cursor! query(androidx.sqlite.db.SupportSQLiteQuery!);
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public android.database.Cursor! query(androidx.sqlite.db.SupportSQLiteQuery!, android.os.CancellationSignal!);
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public void setForeignKeyConstraintsEnabled(boolean);
+    method public void setLocale(java.util.Locale!);
+    method public void setMaxSqlCacheSize(int);
+    method public long setMaximumSize(long);
+    method public void setPageSize(long);
+    method public void setTransactionSuccessful();
+    method public void setVersion(int);
+    method public int update(String!, int, android.content.ContentValues!, String!, Object![]!);
+    method public boolean yieldIfContendedSafely();
+    method public boolean yieldIfContendedSafely(long);
+  }
+
+  public interface SupportSQLiteOpenHelper extends java.io.Closeable {
+    method public void close();
+    method public String? getDatabaseName();
+    method public androidx.sqlite.db.SupportSQLiteDatabase! getReadableDatabase();
+    method public androidx.sqlite.db.SupportSQLiteDatabase! getWritableDatabase();
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public void setWriteAheadLoggingEnabled(boolean);
+  }
+
+  public abstract static class SupportSQLiteOpenHelper.Callback {
+    ctor public SupportSQLiteOpenHelper.Callback(int);
+    method public void onConfigure(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onCorruption(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public abstract void onCreate(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onDowngrade(androidx.sqlite.db.SupportSQLiteDatabase, int, int);
+    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public abstract void onUpgrade(androidx.sqlite.db.SupportSQLiteDatabase, int, int);
+    field public final int version;
+  }
+
+  public static class SupportSQLiteOpenHelper.Configuration {
+    method public static androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder builder(android.content.Context);
+    field public final androidx.sqlite.db.SupportSQLiteOpenHelper.Callback callback;
+    field public final android.content.Context context;
+    field public final String? name;
+    field public final boolean useNoBackupDirectory;
+  }
+
+  public static class SupportSQLiteOpenHelper.Configuration.Builder {
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration build();
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder callback(androidx.sqlite.db.SupportSQLiteOpenHelper.Callback);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder name(String?);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder noBackupDirectory(boolean);
+  }
+
+  public static interface SupportSQLiteOpenHelper.Factory {
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration);
+  }
+
+  public interface SupportSQLiteProgram extends java.io.Closeable {
+    method public void bindBlob(int, byte[]!);
+    method public void bindDouble(int, double);
+    method public void bindLong(int, long);
+    method public void bindNull(int);
+    method public void bindString(int, String!);
+    method public void clearBindings();
+  }
+
+  public interface SupportSQLiteQuery {
+    method public void bindTo(androidx.sqlite.db.SupportSQLiteProgram!);
+    method public int getArgCount();
+    method public String! getSql();
+  }
+
+  public final class SupportSQLiteQueryBuilder {
+    method public static androidx.sqlite.db.SupportSQLiteQueryBuilder! builder(String!);
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! columns(String![]!);
+    method public androidx.sqlite.db.SupportSQLiteQuery! create();
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! distinct();
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! groupBy(String!);
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! having(String!);
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! limit(String!);
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! orderBy(String!);
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! selection(String!, Object![]!);
+  }
+
+  public interface SupportSQLiteStatement extends androidx.sqlite.db.SupportSQLiteProgram {
+    method public void execute();
+    method public long executeInsert();
+    method public int executeUpdateDelete();
+    method public long simpleQueryForLong();
+    method public String! simpleQueryForString();
+  }
+
+}
+
diff --git a/sqlite/sqlite/api/public_plus_experimental_2.2.0-beta01.txt b/sqlite/sqlite/api/public_plus_experimental_2.2.0-beta01.txt
new file mode 100644
index 0000000..dbdea61
--- /dev/null
+++ b/sqlite/sqlite/api/public_plus_experimental_2.2.0-beta01.txt
@@ -0,0 +1,130 @@
+// Signature format: 4.0
+package androidx.sqlite.db {
+
+  public final class SimpleSQLiteQuery implements androidx.sqlite.db.SupportSQLiteQuery {
+    ctor public SimpleSQLiteQuery(String!, Object![]?);
+    ctor public SimpleSQLiteQuery(String!);
+    method public static void bind(androidx.sqlite.db.SupportSQLiteProgram!, Object![]!);
+    method public void bindTo(androidx.sqlite.db.SupportSQLiteProgram!);
+    method public int getArgCount();
+    method public String! getSql();
+  }
+
+  public interface SupportSQLiteDatabase extends java.io.Closeable {
+    method public void beginTransaction();
+    method public void beginTransactionNonExclusive();
+    method public void beginTransactionWithListener(android.database.sqlite.SQLiteTransactionListener!);
+    method public void beginTransactionWithListenerNonExclusive(android.database.sqlite.SQLiteTransactionListener!);
+    method public androidx.sqlite.db.SupportSQLiteStatement! compileStatement(String!);
+    method public int delete(String!, String!, Object![]!);
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public void disableWriteAheadLogging();
+    method public boolean enableWriteAheadLogging();
+    method public void endTransaction();
+    method public default void execPerConnectionSQL(String, Object![]?);
+    method public void execSQL(String!) throws android.database.SQLException;
+    method public void execSQL(String!, Object![]!) throws android.database.SQLException;
+    method public java.util.List<android.util.Pair<java.lang.String!,java.lang.String!>!>! getAttachedDbs();
+    method public long getMaximumSize();
+    method public long getPageSize();
+    method public String! getPath();
+    method public int getVersion();
+    method public boolean inTransaction();
+    method public long insert(String!, int, android.content.ContentValues!) throws android.database.SQLException;
+    method public boolean isDatabaseIntegrityOk();
+    method public boolean isDbLockedByCurrentThread();
+    method public default boolean isExecPerConnectionSQLSupported();
+    method public boolean isOpen();
+    method public boolean isReadOnly();
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public boolean isWriteAheadLoggingEnabled();
+    method public boolean needUpgrade(int);
+    method public android.database.Cursor! query(String!);
+    method public android.database.Cursor! query(String!, Object![]!);
+    method public android.database.Cursor! query(androidx.sqlite.db.SupportSQLiteQuery!);
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public android.database.Cursor! query(androidx.sqlite.db.SupportSQLiteQuery!, android.os.CancellationSignal!);
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public void setForeignKeyConstraintsEnabled(boolean);
+    method public void setLocale(java.util.Locale!);
+    method public void setMaxSqlCacheSize(int);
+    method public long setMaximumSize(long);
+    method public void setPageSize(long);
+    method public void setTransactionSuccessful();
+    method public void setVersion(int);
+    method public int update(String!, int, android.content.ContentValues!, String!, Object![]!);
+    method public boolean yieldIfContendedSafely();
+    method public boolean yieldIfContendedSafely(long);
+  }
+
+  public interface SupportSQLiteOpenHelper extends java.io.Closeable {
+    method public void close();
+    method public String? getDatabaseName();
+    method public androidx.sqlite.db.SupportSQLiteDatabase! getReadableDatabase();
+    method public androidx.sqlite.db.SupportSQLiteDatabase! getWritableDatabase();
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public void setWriteAheadLoggingEnabled(boolean);
+  }
+
+  public abstract static class SupportSQLiteOpenHelper.Callback {
+    ctor public SupportSQLiteOpenHelper.Callback(int);
+    method public void onConfigure(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onCorruption(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public abstract void onCreate(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onDowngrade(androidx.sqlite.db.SupportSQLiteDatabase, int, int);
+    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public abstract void onUpgrade(androidx.sqlite.db.SupportSQLiteDatabase, int, int);
+    field public final int version;
+  }
+
+  public static class SupportSQLiteOpenHelper.Configuration {
+    method public static androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder builder(android.content.Context);
+    field public final androidx.sqlite.db.SupportSQLiteOpenHelper.Callback callback;
+    field public final android.content.Context context;
+    field public final String? name;
+    field public final boolean useNoBackupDirectory;
+  }
+
+  public static class SupportSQLiteOpenHelper.Configuration.Builder {
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration build();
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder callback(androidx.sqlite.db.SupportSQLiteOpenHelper.Callback);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder name(String?);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder noBackupDirectory(boolean);
+  }
+
+  public static interface SupportSQLiteOpenHelper.Factory {
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration);
+  }
+
+  public interface SupportSQLiteProgram extends java.io.Closeable {
+    method public void bindBlob(int, byte[]!);
+    method public void bindDouble(int, double);
+    method public void bindLong(int, long);
+    method public void bindNull(int);
+    method public void bindString(int, String!);
+    method public void clearBindings();
+  }
+
+  public interface SupportSQLiteQuery {
+    method public void bindTo(androidx.sqlite.db.SupportSQLiteProgram!);
+    method public int getArgCount();
+    method public String! getSql();
+  }
+
+  public final class SupportSQLiteQueryBuilder {
+    method public static androidx.sqlite.db.SupportSQLiteQueryBuilder! builder(String!);
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! columns(String![]!);
+    method public androidx.sqlite.db.SupportSQLiteQuery! create();
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! distinct();
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! groupBy(String!);
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! having(String!);
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! limit(String!);
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! orderBy(String!);
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! selection(String!, Object![]!);
+  }
+
+  public interface SupportSQLiteStatement extends androidx.sqlite.db.SupportSQLiteProgram {
+    method public void execute();
+    method public long executeInsert();
+    method public int executeUpdateDelete();
+    method public long simpleQueryForLong();
+    method public String! simpleQueryForString();
+  }
+
+}
+
diff --git a/sqlite/sqlite/api/res-2.2.0-beta01.txt b/sqlite/sqlite/api/res-2.2.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sqlite/sqlite/api/res-2.2.0-beta01.txt
diff --git a/sqlite/sqlite/api/restricted_2.2.0-beta01.txt b/sqlite/sqlite/api/restricted_2.2.0-beta01.txt
new file mode 100644
index 0000000..dbdea61
--- /dev/null
+++ b/sqlite/sqlite/api/restricted_2.2.0-beta01.txt
@@ -0,0 +1,130 @@
+// Signature format: 4.0
+package androidx.sqlite.db {
+
+  public final class SimpleSQLiteQuery implements androidx.sqlite.db.SupportSQLiteQuery {
+    ctor public SimpleSQLiteQuery(String!, Object![]?);
+    ctor public SimpleSQLiteQuery(String!);
+    method public static void bind(androidx.sqlite.db.SupportSQLiteProgram!, Object![]!);
+    method public void bindTo(androidx.sqlite.db.SupportSQLiteProgram!);
+    method public int getArgCount();
+    method public String! getSql();
+  }
+
+  public interface SupportSQLiteDatabase extends java.io.Closeable {
+    method public void beginTransaction();
+    method public void beginTransactionNonExclusive();
+    method public void beginTransactionWithListener(android.database.sqlite.SQLiteTransactionListener!);
+    method public void beginTransactionWithListenerNonExclusive(android.database.sqlite.SQLiteTransactionListener!);
+    method public androidx.sqlite.db.SupportSQLiteStatement! compileStatement(String!);
+    method public int delete(String!, String!, Object![]!);
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public void disableWriteAheadLogging();
+    method public boolean enableWriteAheadLogging();
+    method public void endTransaction();
+    method public default void execPerConnectionSQL(String, Object![]?);
+    method public void execSQL(String!) throws android.database.SQLException;
+    method public void execSQL(String!, Object![]!) throws android.database.SQLException;
+    method public java.util.List<android.util.Pair<java.lang.String!,java.lang.String!>!>! getAttachedDbs();
+    method public long getMaximumSize();
+    method public long getPageSize();
+    method public String! getPath();
+    method public int getVersion();
+    method public boolean inTransaction();
+    method public long insert(String!, int, android.content.ContentValues!) throws android.database.SQLException;
+    method public boolean isDatabaseIntegrityOk();
+    method public boolean isDbLockedByCurrentThread();
+    method public default boolean isExecPerConnectionSQLSupported();
+    method public boolean isOpen();
+    method public boolean isReadOnly();
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public boolean isWriteAheadLoggingEnabled();
+    method public boolean needUpgrade(int);
+    method public android.database.Cursor! query(String!);
+    method public android.database.Cursor! query(String!, Object![]!);
+    method public android.database.Cursor! query(androidx.sqlite.db.SupportSQLiteQuery!);
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public android.database.Cursor! query(androidx.sqlite.db.SupportSQLiteQuery!, android.os.CancellationSignal!);
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public void setForeignKeyConstraintsEnabled(boolean);
+    method public void setLocale(java.util.Locale!);
+    method public void setMaxSqlCacheSize(int);
+    method public long setMaximumSize(long);
+    method public void setPageSize(long);
+    method public void setTransactionSuccessful();
+    method public void setVersion(int);
+    method public int update(String!, int, android.content.ContentValues!, String!, Object![]!);
+    method public boolean yieldIfContendedSafely();
+    method public boolean yieldIfContendedSafely(long);
+  }
+
+  public interface SupportSQLiteOpenHelper extends java.io.Closeable {
+    method public void close();
+    method public String? getDatabaseName();
+    method public androidx.sqlite.db.SupportSQLiteDatabase! getReadableDatabase();
+    method public androidx.sqlite.db.SupportSQLiteDatabase! getWritableDatabase();
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN) public void setWriteAheadLoggingEnabled(boolean);
+  }
+
+  public abstract static class SupportSQLiteOpenHelper.Callback {
+    ctor public SupportSQLiteOpenHelper.Callback(int);
+    method public void onConfigure(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onCorruption(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public abstract void onCreate(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public void onDowngrade(androidx.sqlite.db.SupportSQLiteDatabase, int, int);
+    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase);
+    method public abstract void onUpgrade(androidx.sqlite.db.SupportSQLiteDatabase, int, int);
+    field public final int version;
+  }
+
+  public static class SupportSQLiteOpenHelper.Configuration {
+    method public static androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder builder(android.content.Context);
+    field public final androidx.sqlite.db.SupportSQLiteOpenHelper.Callback callback;
+    field public final android.content.Context context;
+    field public final String? name;
+    field public final boolean useNoBackupDirectory;
+  }
+
+  public static class SupportSQLiteOpenHelper.Configuration.Builder {
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration build();
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder callback(androidx.sqlite.db.SupportSQLiteOpenHelper.Callback);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder name(String?);
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder noBackupDirectory(boolean);
+  }
+
+  public static interface SupportSQLiteOpenHelper.Factory {
+    method public androidx.sqlite.db.SupportSQLiteOpenHelper create(androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration);
+  }
+
+  public interface SupportSQLiteProgram extends java.io.Closeable {
+    method public void bindBlob(int, byte[]!);
+    method public void bindDouble(int, double);
+    method public void bindLong(int, long);
+    method public void bindNull(int);
+    method public void bindString(int, String!);
+    method public void clearBindings();
+  }
+
+  public interface SupportSQLiteQuery {
+    method public void bindTo(androidx.sqlite.db.SupportSQLiteProgram!);
+    method public int getArgCount();
+    method public String! getSql();
+  }
+
+  public final class SupportSQLiteQueryBuilder {
+    method public static androidx.sqlite.db.SupportSQLiteQueryBuilder! builder(String!);
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! columns(String![]!);
+    method public androidx.sqlite.db.SupportSQLiteQuery! create();
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! distinct();
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! groupBy(String!);
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! having(String!);
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! limit(String!);
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! orderBy(String!);
+    method public androidx.sqlite.db.SupportSQLiteQueryBuilder! selection(String!, Object![]!);
+  }
+
+  public interface SupportSQLiteStatement extends androidx.sqlite.db.SupportSQLiteProgram {
+    method public void execute();
+    method public long executeInsert();
+    method public int executeUpdateDelete();
+    method public long simpleQueryForLong();
+    method public String! simpleQueryForString();
+  }
+
+}
+
diff --git a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/SwipeableTest.kt b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/SwipeableTest.kt
new file mode 100644
index 0000000..05b8c1a
--- /dev/null
+++ b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/SwipeableTest.kt
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.Orientation.Horizontal
+import androidx.compose.foundation.gestures.Orientation.Vertical
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.requiredSize
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Size
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.LocalViewConfiguration
+import androidx.compose.ui.platform.ViewConfiguration
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.semantics.SemanticsProperties.HorizontalScrollAxisRange
+import androidx.compose.ui.semantics.SemanticsProperties.VerticalScrollAxisRange
+import androidx.compose.ui.semantics.getOrNull
+import androidx.compose.ui.test.SemanticsMatcher
+import androidx.compose.ui.test.SemanticsMatcher.Companion.keyNotDefined
+import androidx.compose.ui.test.assert
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.performTouchInput
+import androidx.compose.ui.unit.dp
+import androidx.wear.compose.material.ExperimentalWearMaterialApi
+import androidx.wear.compose.material.SwipeableState
+import androidx.wear.compose.material.swipeable
+import org.junit.Rule
+import org.junit.Test
+import kotlin.math.absoluteValue
+
+// TODO(b/201009199) Some of these tests may need specific values adjusted when swipeable
+//  supports property nested scrolling, but the tests should all still be valid.
+@OptIn(ExperimentalWearMaterialApi::class)
+class SwipeableTest {
+    @get:Rule
+    val rule = createComposeRule()
+
+    @Test
+    fun hasHorizontalScrollSemantics_atMaxValue_whenUnswiped() {
+        rule.setContent {
+            SimpleSwipeableBox { size ->
+                Modifier.swipeable(
+                    state = SwipeableState(false),
+                    anchors = mapOf(0f to false, size.width to true),
+                    orientation = Horizontal,
+                )
+            }
+        }
+
+        rule.onNodeWithTag(TEST_TAG)
+            .assert(hasScrollRangeCloseTo(Horizontal, value = 1f, maxValue = 1f))
+            .assert(keyNotDefined(VerticalScrollAxisRange))
+    }
+
+    @Test
+    fun hasVerticalScrollSemantics_atMaxValue_whenUnswiped() {
+        rule.setContent {
+            SimpleSwipeableBox { size ->
+                Modifier.swipeable(
+                    state = SwipeableState(false),
+                    anchors = mapOf(0f to false, size.height to true),
+                    orientation = Vertical,
+                )
+            }
+        }
+
+        rule.onNodeWithTag(TEST_TAG)
+            .assert(hasScrollRangeCloseTo(Vertical, value = 1f, maxValue = 1f))
+            .assert(keyNotDefined(HorizontalScrollAxisRange))
+    }
+
+    @Test
+    fun hasScrollSemantics_whenSwiped() {
+        rule.setContent {
+            SimpleSwipeableBox { size ->
+                Modifier.swipeable(
+                    state = SwipeableState(false),
+                    anchors = mapOf(0f to false, size.width to true),
+                    orientation = Horizontal,
+                )
+            }
+        }
+
+        rule.onNodeWithTag(TEST_TAG)
+            .performTouchInput {
+                down(centerLeft)
+                moveTo(centerLeft + percentOffset(.25f, 0f))
+            }
+        rule.onNodeWithTag(TEST_TAG)
+            .assert(hasScrollRangeCloseTo(Horizontal, value = 0.75f, maxValue = 1f))
+
+        rule.onNodeWithTag(TEST_TAG)
+            .performTouchInput {
+                moveTo(center)
+            }
+        rule.onNodeWithTag(TEST_TAG)
+            .assert(hasScrollRangeCloseTo(Horizontal, value = 0.5f, maxValue = 1f))
+    }
+
+    @Test
+    fun hasScrollSemantics_whenSwipedWithReverseDirection() {
+        rule.setContent {
+            SimpleSwipeableBox { size ->
+                Modifier.swipeable(
+                    state = SwipeableState(false),
+                    anchors = mapOf(0f to false, size.width to true),
+                    orientation = Horizontal,
+                    reverseDirection = true
+                )
+            }
+        }
+
+        rule.onNodeWithTag(TEST_TAG)
+            .performTouchInput {
+                down(centerRight)
+                moveTo(centerRight - percentOffset(.25f, 0f))
+            }
+        rule.onNodeWithTag(TEST_TAG)
+            .assert(
+                hasScrollRangeCloseTo(
+                    orientation = Horizontal,
+                    value = 0.75f,
+                    maxValue = 1f,
+                    reverseScrolling = true
+                )
+            )
+
+        rule.onNodeWithTag(TEST_TAG)
+            .performTouchInput {
+                moveTo(center)
+            }
+        rule.onNodeWithTag(TEST_TAG)
+            .assert(
+                hasScrollRangeCloseTo(
+                    orientation = Horizontal,
+                    value = 0.5f,
+                    maxValue = 1f,
+                    reverseScrolling = true
+                )
+            )
+    }
+
+    @Test
+    fun hasNoScrollSemantics_whenDisabled() {
+        rule.setContent {
+            SimpleSwipeableBox { size ->
+                Modifier.swipeable(
+                    state = SwipeableState(false),
+                    anchors = mapOf(0f to false, size.width to true),
+                    orientation = Horizontal,
+                    enabled = false
+                )
+            }
+        }
+
+        rule.onNodeWithTag(TEST_TAG)
+            .assert(keyNotDefined(HorizontalScrollAxisRange))
+            .assert(keyNotDefined(VerticalScrollAxisRange))
+    }
+
+    /**
+     * A square [Box] has the [TEST_TAG] test tag. Touch slop is disabled to make swipe calculations
+     * more exact.
+     */
+    @Composable
+    private fun SimpleSwipeableBox(swipeableModifier: (Size) -> Modifier) {
+        val originalViewConfiguration = LocalViewConfiguration.current
+        val viewConfiguration = remember(originalViewConfiguration) {
+            object : ViewConfiguration by originalViewConfiguration {
+                override val touchSlop: Float = 0f
+            }
+        }
+
+        with(LocalDensity.current) {
+            val size = 100.dp
+            val sizePx = size.toPx()
+
+            CompositionLocalProvider(LocalViewConfiguration provides viewConfiguration) {
+                Box(
+                    Modifier
+                        .testTag(TEST_TAG)
+                        .requiredSize(size)
+                        .then(remember { swipeableModifier(Size(sizePx, sizePx)) })
+                )
+            }
+        }
+    }
+
+    /**
+     * Matches either a [HorizontalScrollAxisRange] or [VerticalScrollAxisRange] that has the given
+     * [maxValue] and [reverseScrolling], and a `value` that is within a small threshold of [value].
+     */
+    private fun hasScrollRangeCloseTo(
+        orientation: Orientation,
+        value: Float,
+        maxValue: Float,
+        reverseScrolling: Boolean = false
+    ): SemanticsMatcher = SemanticsMatcher(
+        "has $orientation scroll range [0,$maxValue] with " +
+            "value=$value" + if (reverseScrolling) " (reversed)" else ""
+    ) { node ->
+        val threshold = .1f
+        val property = when (orientation) {
+            Horizontal -> HorizontalScrollAxisRange
+            Vertical -> VerticalScrollAxisRange
+        }
+        node.config.getOrNull(property)?.let { range ->
+            (range.value() - value).absoluteValue <= threshold &&
+                range.maxValue() == maxValue &&
+                range.reverseScrolling == reverseScrolling
+        } ?: false
+    }
+}
+
+private const val TEST_TAG = "swipeable"
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/SwipeToDismissBox.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/SwipeToDismissBox.kt
index 200a3b4..fd0b9c3 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/SwipeToDismissBox.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/SwipeToDismissBox.kt
@@ -51,10 +51,6 @@
  * Wear Material [SwipeToDismissBox] that handles the swipe-to-dismiss gesture. Takes a single
  * slot for the background (only displayed during the swipe gesture) and the foreground content.
  *
- * [SwipeToDismissBox] has not yet been integrated with Android's
- * default handling for swipe to dismiss on Wear applications. Until that is completed,
- * applications using [SwipeToDismissBox] must disable android:windowSwipeToDismiss.
- *
  * Example usage:
  * @sample androidx.wear.compose.material.samples.SimpleSwipeToDismissBox
  *
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Swipeable.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Swipeable.kt
index 8d9b273..7c55973 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Swipeable.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Swipeable.kt
@@ -39,6 +39,10 @@
 import androidx.compose.ui.composed
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.debugInspectorInfo
+import androidx.compose.ui.semantics.ScrollAxisRange
+import androidx.compose.ui.semantics.horizontalScrollAxisRange
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.verticalScrollAxisRange
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
@@ -553,7 +557,39 @@
         state.processNewAnchors(oldAnchors, anchors)
     }
 
-    Modifier.draggable(
+    // Swipeables publish scroll range semantics so they look like they can scroll between values
+    // of 0 and 1, inclusive, so that AndroidComposeView can report a value from its canScroll
+    // methods that correctly tells the system's ScrollDismissLayout whether it should intercept
+    // touch values (see b/199908428). This logic is *not* duplicated in the non-Wear swipeable
+    // because it's a bit of a hack to fix navigation in WearOS. Once swipeable implements proper
+    // nested scrolling, and the two swipeable implementations are merged, this fake scrolling stuff
+    // should be gone anyway. Also note that the regular Android swipe-to-go-back gesture works very
+    // differently than the wear gesture so we don't need this workaround to support it.
+    // TODO(b/201009199): Modifier.swipeable should coordinate with the nested scrolling system.
+    val semantics = if (!enabled) Modifier else Modifier.semantics {
+        // Set a fake scroll range axis so that the AndroidComposeView can correctly report whether
+        // scrolling is supported via canScroll{Horizontally,Vertically}.
+        val range = ScrollAxisRange(
+            value = value@{
+                // Avoid dividing by 0.
+                if (state.minBound == state.maxBound) return@value 0f
+                val clampedOffset = state.offset.value.coerceIn(state.minBound, state.maxBound)
+                // [0f, 1f] representing the fraction between the swipe bounds.
+                val swipeFraction =
+                    (clampedOffset - state.minBound) / (state.maxBound - state.minBound)
+                // Invert the swipe fraction.
+                1f - swipeFraction
+            },
+            maxValue = { 1f },
+            reverseScrolling = reverseDirection
+        )
+        when (orientation) {
+            Orientation.Horizontal -> horizontalScrollAxisRange = range
+            Orientation.Vertical -> verticalScrollAxisRange = range
+        }
+    }
+
+    Modifier.then(semantics).draggable(
         orientation = orientation,
         enabled = enabled,
         reverseDirection = reverseDirection,
diff --git a/wear/compose/compose-navigation/build.gradle b/wear/compose/compose-navigation/build.gradle
index 1b067a0..effbc0e 100644
--- a/wear/compose/compose-navigation/build.gradle
+++ b/wear/compose/compose-navigation/build.gradle
@@ -30,11 +30,11 @@
 
     api(project(":compose:ui:ui"))
     api(project(":compose:runtime:runtime"))
-    api(project(":navigation:navigation-runtime"))
+    api("androidx.navigation:navigation-runtime:2.4.0-alpha10")
     api(project(":wear:compose:compose-material"))
 
     implementation(libs.kotlinStdlib)
-    implementation(project(":navigation:navigation-compose"))
+    implementation("androidx.navigation:navigation-compose:2.4.0-alpha10")
 
     androidTestImplementation project(path: ':compose:ui:ui-test')
     androidTestImplementation project(path: ':compose:ui:ui-test-junit4')
diff --git a/wear/compose/compose-navigation/src/main/java/androidx/wear/compose/navigation/SwipeDismissableNavHost.kt b/wear/compose/compose-navigation/src/main/java/androidx/wear/compose/navigation/SwipeDismissableNavHost.kt
index a91eb3e5d..ea19da0 100644
--- a/wear/compose/compose-navigation/src/main/java/androidx/wear/compose/navigation/SwipeDismissableNavHost.kt
+++ b/wear/compose/compose-navigation/src/main/java/androidx/wear/compose/navigation/SwipeDismissableNavHost.kt
@@ -54,9 +54,7 @@
  *
  * Content is displayed within a [SwipeToDismissBox], showing the current navigation level.
  * During a swipe-to-dismiss gesture, the previous navigation level (if any) is shown in
- * the background. [SwipeToDismissBox] has not yet been integrated with Android's
- * default handling for swipe to dismiss on Wear applications - until that is completed,
- * android:windowSwipeToDismiss must be disabled for applications using [SwipeDismissableNavHost].
+ * the background.
  *
  * @param navController The navController for this host
  * @param startDestination The route for the start destination
@@ -93,9 +91,7 @@
  *
  * Content is displayed within a [SwipeToDismissBox], showing the current navigation level.
  * During a swipe-to-dismiss gesture, the previous navigation level (if any) is shown in
- * the background. [SwipeToDismissBox] has not yet been integrated with Android's
- * default handling for swipe to dismiss on Wear applications - until that is completed,
- * android:windowSwipeToDismiss must be disabled for applications using [SwipeDismissableNavHost].
+ * the background.
  *
  * @param navController [NavHostController] for this host
  * @param graph Graph for this host
diff --git a/wear/compose/integration-tests/demos/src/main/AndroidManifest.xml b/wear/compose/integration-tests/demos/src/main/AndroidManifest.xml
index 9a2a047..5202ad2 100644
--- a/wear/compose/integration-tests/demos/src/main/AndroidManifest.xml
+++ b/wear/compose/integration-tests/demos/src/main/AndroidManifest.xml
@@ -26,7 +26,7 @@
         android:theme="@android:style/Theme.DeviceDefault">
         <activity
             android:name=".DemoActivity"
-            android:theme="@style/AppThemeNoSwipe"
+            android:theme="@android:style/Theme.DeviceDefault"
             android:exported="true"
             android:label="@string/app_name">
             <intent-filter>
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/FoundationDemos.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/FoundationDemos.kt
index 54102a5..e7bf854 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/FoundationDemos.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/FoundationDemos.kt
@@ -27,5 +27,7 @@
         ComposableDemo("Alignment") { CurvedRowAlignmentDemo() },
         ComposableDemo("Curved Text") { BasicCurvedTextDemo() },
         ComposableDemo("Curved and Normal Text") { CurvedAndNormalText() },
+        ComposableDemo("Scrollable Column") { ScrollableColumnDemo() },
+        ComposableDemo("Scrollable Row") { ScrollableRowDemo() },
     ),
 )
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ScrollableColumnDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ScrollableColumnDemo.kt
new file mode 100644
index 0000000..fdee274
--- /dev/null
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ScrollableColumnDemo.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.compose.integration.demos
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.foundation.layout.wrapContentWidth
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
+import androidx.wear.compose.material.Text
+
+@Composable
+fun ScrollableColumnDemo() {
+    Row {
+        NotScrollableLabel(Modifier.weight(1f))
+        Column(
+            verticalArrangement = Arrangement.spacedBy(8.dp),
+            modifier = Modifier
+                .fillMaxHeight()
+                .wrapContentWidth()
+                .verticalScroll(rememberScrollState())
+                .background(Color.Green.copy(alpha = 0.1f))
+                .padding(horizontal = 24.dp)
+        ) {
+            for (i in 0 until 100) {
+                Text("$i")
+            }
+        }
+        NotScrollableLabel(Modifier.weight(1f))
+    }
+}
+
+@Composable
+private fun NotScrollableLabel(modifier: Modifier) {
+    Text(
+        "Not scrollable",
+        color = Color.Red,
+        textAlign = TextAlign.Center,
+        modifier = modifier
+            .fillMaxSize()
+            .background(Color.Red.copy(alpha = 0.1f))
+            .wrapContentSize()
+    )
+}
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ScrollableRowDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ScrollableRowDemo.kt
new file mode 100644
index 0000000..a63a72e
--- /dev/null
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ScrollableRowDemo.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.compose.integration.demos
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.horizontalScroll
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.wrapContentHeight
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalTextInputService
+import androidx.compose.ui.unit.dp
+import androidx.wear.compose.material.Text
+
+/**
+ * A screen that includes a partial-height row that is horizontally-scrollable, in order to
+ * demonstrate swipe-to-dismiss handling on a screen that contains both scrollable and
+ * non-scrollable sections.
+ */
+// TODO(b/200699800) Does not support swipe-to-dismiss on the row, we need explicit edge-swiping
+//  support.
+@Composable
+fun ScrollableRowDemo() {
+    LocalTextInputService
+    Column {
+        NotScrollableLabel(Modifier.weight(1f))
+        Row(
+            horizontalArrangement = Arrangement.spacedBy(8.dp),
+            modifier = Modifier
+                .fillMaxWidth()
+                .wrapContentHeight()
+                .horizontalScroll(rememberScrollState())
+                .background(Color.Green.copy(alpha = 0.1f))
+                .padding(vertical = 24.dp)
+        ) {
+            for (i in 0 until 100) {
+                Text("$i")
+            }
+        }
+        NotScrollableLabel(Modifier.weight(1f))
+    }
+}
+
+@Composable
+private fun NotScrollableLabel(modifier: Modifier) {
+    Text(
+        "Not scrollable",
+        color = Color.Red,
+        modifier = modifier
+            .fillMaxSize()
+            .background(Color.Red.copy(alpha = 0.1f))
+            .wrapContentSize()
+    )
+}
diff --git a/wear/compose/integration-tests/demos/src/main/res/values/resources.xml b/wear/compose/integration-tests/demos/src/main/res/values/resources.xml
index 5abd265..8086034 100644
--- a/wear/compose/integration-tests/demos/src/main/res/values/resources.xml
+++ b/wear/compose/integration-tests/demos/src/main/res/values/resources.xml
@@ -1,6 +1,3 @@
 <resources>
     <string name="app_name">Wear Compose Integration Demos</string>
-    <style name="AppThemeNoSwipe" parent="@android:style/Theme.DeviceDefault">
-        <item name="android:windowSwipeToDismiss">false</item>
-    </style>
 </resources>
\ No newline at end of file
diff --git a/wear/compose/integration-tests/macrobenchmark-target/src/main/AndroidManifest.xml b/wear/compose/integration-tests/macrobenchmark-target/src/main/AndroidManifest.xml
index 1047c79..10bf9d8 100644
--- a/wear/compose/integration-tests/macrobenchmark-target/src/main/AndroidManifest.xml
+++ b/wear/compose/integration-tests/macrobenchmark-target/src/main/AndroidManifest.xml
@@ -48,7 +48,7 @@
 
         <activity
             android:name=".SwipeActivity"
-            android:theme="@style/AppThemeNoSwipe"
+            android:theme="@style/AppTheme"
             android:exported="true">
             <intent-filter>
                 <action android:name=
@@ -59,7 +59,7 @@
 
         <activity
             android:name=".ScrollActivity"
-            android:theme="@style/AppThemeNoSwipe"
+            android:theme="@style/AppTheme"
             android:exported="true">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/wear/compose/integration-tests/macrobenchmark-target/src/main/res/values/resources.xml b/wear/compose/integration-tests/macrobenchmark-target/src/main/res/values/resources.xml
index c4a6cfc..7832ab0 100644
--- a/wear/compose/integration-tests/macrobenchmark-target/src/main/res/values/resources.xml
+++ b/wear/compose/integration-tests/macrobenchmark-target/src/main/res/values/resources.xml
@@ -1,6 +1,4 @@
 <resources>
     <string name="app_name">Wear Compose Integration Macrobenchmark Target</string>
-    <style name="AppThemeNoSwipe" parent="@android:style/Theme.DeviceDefault">
-        <item name="android:windowSwipeToDismiss">false</item>
-    </style>
+    <style name="AppTheme" parent="@android:style/Theme.DeviceDefault"/>
 </resources>
\ No newline at end of file
diff --git a/wear/compose/integration-tests/navigation/src/main/AndroidManifest.xml b/wear/compose/integration-tests/navigation/src/main/AndroidManifest.xml
index 5958fc4..f477c51 100644
--- a/wear/compose/integration-tests/navigation/src/main/AndroidManifest.xml
+++ b/wear/compose/integration-tests/navigation/src/main/AndroidManifest.xml
@@ -26,7 +26,7 @@
         android:theme="@android:style/Theme.DeviceDefault">
         <activity
             android:name=".MainActivity"
-            android:theme="@style/AppThemeNoSwipe"
+            android:theme="@android:style/Theme.DeviceDefault"
             android:exported="true"
             android:label="@string/app_name">
             <intent-filter>
diff --git a/wear/compose/integration-tests/navigation/src/main/res/values/resources.xml b/wear/compose/integration-tests/navigation/src/main/res/values/resources.xml
index 8e3b007..87ad7f4 100644
--- a/wear/compose/integration-tests/navigation/src/main/res/values/resources.xml
+++ b/wear/compose/integration-tests/navigation/src/main/res/values/resources.xml
@@ -1,6 +1,3 @@
 <resources>
     <string name="app_name">Wear Compose Navigation Integration Test</string>
-    <style name="AppThemeNoSwipe" parent="@android:style/Theme.DeviceDefault">
-        <item name="android:windowSwipeToDismiss">false</item>
-    </style>
 </resources>
\ No newline at end of file
diff --git a/wear/tiles/tiles-renderer/api/1.0.0-beta01.txt b/wear/tiles/tiles-renderer/api/1.0.0-beta01.txt
new file mode 100644
index 0000000..a162ceb
--- /dev/null
+++ b/wear/tiles/tiles-renderer/api/1.0.0-beta01.txt
@@ -0,0 +1,80 @@
+// Signature format: 4.0
+package androidx.wear.tiles.client {
+
+  public interface TileClient {
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> requestApiVersion();
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources!> requestResources(androidx.wear.tiles.RequestBuilders.ResourcesRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile!> requestTile(androidx.wear.tiles.RequestBuilders.TileRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileAddedEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileEnterEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileLeaveEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileRemovedEvent();
+  }
+
+}
+
+package androidx.wear.tiles.connection {
+
+  public final class DefaultTileClient implements androidx.wear.tiles.client.TileClient {
+    ctor public DefaultTileClient(android.content.Context context, android.content.ComponentName componentName, kotlinx.coroutines.CoroutineScope coroutineScope, kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
+    ctor public DefaultTileClient(android.content.Context context, android.content.ComponentName componentName, java.util.concurrent.Executor executor);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> requestApiVersion();
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources> requestResources(androidx.wear.tiles.RequestBuilders.ResourcesRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile> requestTile(androidx.wear.tiles.RequestBuilders.TileRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileAddedEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileEnterEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileLeaveEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileRemovedEvent();
+  }
+
+}
+
+package androidx.wear.tiles.manager {
+
+  public final class TileUiClient implements java.lang.AutoCloseable {
+    ctor public TileUiClient(android.content.Context context, android.content.ComponentName component, android.view.ViewGroup parentView);
+    method @MainThread public void close();
+    method @MainThread public void connect();
+  }
+
+}
+
+package androidx.wear.tiles.renderer {
+
+  public final class TileRenderer {
+    ctor public TileRenderer(android.content.Context, androidx.wear.tiles.LayoutElementBuilders.Layout, androidx.wear.tiles.ResourceBuilders.Resources, java.util.concurrent.Executor, androidx.wear.tiles.renderer.TileRenderer.LoadActionListener);
+    ctor public TileRenderer(android.content.Context, androidx.wear.tiles.LayoutElementBuilders.Layout, @StyleRes int, androidx.wear.tiles.ResourceBuilders.Resources, java.util.concurrent.Executor, androidx.wear.tiles.renderer.TileRenderer.LoadActionListener);
+    method public android.view.View? inflate(android.view.ViewGroup);
+  }
+
+  public static interface TileRenderer.LoadActionListener {
+    method public void onClick(androidx.wear.tiles.StateBuilders.State);
+  }
+
+}
+
+package androidx.wear.tiles.timeline {
+
+  public final class TilesTimelineCache {
+    ctor public TilesTimelineCache(androidx.wear.tiles.TimelineBuilders.Timeline);
+    method @MainThread public androidx.wear.tiles.TimelineBuilders.TimelineEntry? findClosestTimelineEntry(long);
+    method @MainThread public long findCurrentTimelineEntryExpiry(androidx.wear.tiles.TimelineBuilders.TimelineEntry, long);
+    method @MainThread public androidx.wear.tiles.TimelineBuilders.TimelineEntry? findTimelineEntryForTime(long);
+  }
+
+  public class TilesTimelineManager implements java.lang.AutoCloseable {
+    ctor public TilesTimelineManager(android.app.AlarmManager, androidx.wear.tiles.timeline.TilesTimelineManager.Clock, androidx.wear.tiles.TimelineBuilders.Timeline, int, java.util.concurrent.Executor, androidx.wear.tiles.timeline.TilesTimelineManager.Listener);
+    method public void close();
+    method public void init();
+  }
+
+  public static interface TilesTimelineManager.Clock {
+    method public long getCurrentTimeMillis();
+  }
+
+  public static interface TilesTimelineManager.Listener {
+    method public void onLayoutUpdate(int, androidx.wear.tiles.LayoutElementBuilders.Layout);
+  }
+
+}
+
diff --git a/wear/tiles/tiles-renderer/api/public_plus_experimental_1.0.0-beta01.txt b/wear/tiles/tiles-renderer/api/public_plus_experimental_1.0.0-beta01.txt
new file mode 100644
index 0000000..a162ceb
--- /dev/null
+++ b/wear/tiles/tiles-renderer/api/public_plus_experimental_1.0.0-beta01.txt
@@ -0,0 +1,80 @@
+// Signature format: 4.0
+package androidx.wear.tiles.client {
+
+  public interface TileClient {
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> requestApiVersion();
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources!> requestResources(androidx.wear.tiles.RequestBuilders.ResourcesRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile!> requestTile(androidx.wear.tiles.RequestBuilders.TileRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileAddedEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileEnterEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileLeaveEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileRemovedEvent();
+  }
+
+}
+
+package androidx.wear.tiles.connection {
+
+  public final class DefaultTileClient implements androidx.wear.tiles.client.TileClient {
+    ctor public DefaultTileClient(android.content.Context context, android.content.ComponentName componentName, kotlinx.coroutines.CoroutineScope coroutineScope, kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
+    ctor public DefaultTileClient(android.content.Context context, android.content.ComponentName componentName, java.util.concurrent.Executor executor);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> requestApiVersion();
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources> requestResources(androidx.wear.tiles.RequestBuilders.ResourcesRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile> requestTile(androidx.wear.tiles.RequestBuilders.TileRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileAddedEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileEnterEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileLeaveEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileRemovedEvent();
+  }
+
+}
+
+package androidx.wear.tiles.manager {
+
+  public final class TileUiClient implements java.lang.AutoCloseable {
+    ctor public TileUiClient(android.content.Context context, android.content.ComponentName component, android.view.ViewGroup parentView);
+    method @MainThread public void close();
+    method @MainThread public void connect();
+  }
+
+}
+
+package androidx.wear.tiles.renderer {
+
+  public final class TileRenderer {
+    ctor public TileRenderer(android.content.Context, androidx.wear.tiles.LayoutElementBuilders.Layout, androidx.wear.tiles.ResourceBuilders.Resources, java.util.concurrent.Executor, androidx.wear.tiles.renderer.TileRenderer.LoadActionListener);
+    ctor public TileRenderer(android.content.Context, androidx.wear.tiles.LayoutElementBuilders.Layout, @StyleRes int, androidx.wear.tiles.ResourceBuilders.Resources, java.util.concurrent.Executor, androidx.wear.tiles.renderer.TileRenderer.LoadActionListener);
+    method public android.view.View? inflate(android.view.ViewGroup);
+  }
+
+  public static interface TileRenderer.LoadActionListener {
+    method public void onClick(androidx.wear.tiles.StateBuilders.State);
+  }
+
+}
+
+package androidx.wear.tiles.timeline {
+
+  public final class TilesTimelineCache {
+    ctor public TilesTimelineCache(androidx.wear.tiles.TimelineBuilders.Timeline);
+    method @MainThread public androidx.wear.tiles.TimelineBuilders.TimelineEntry? findClosestTimelineEntry(long);
+    method @MainThread public long findCurrentTimelineEntryExpiry(androidx.wear.tiles.TimelineBuilders.TimelineEntry, long);
+    method @MainThread public androidx.wear.tiles.TimelineBuilders.TimelineEntry? findTimelineEntryForTime(long);
+  }
+
+  public class TilesTimelineManager implements java.lang.AutoCloseable {
+    ctor public TilesTimelineManager(android.app.AlarmManager, androidx.wear.tiles.timeline.TilesTimelineManager.Clock, androidx.wear.tiles.TimelineBuilders.Timeline, int, java.util.concurrent.Executor, androidx.wear.tiles.timeline.TilesTimelineManager.Listener);
+    method public void close();
+    method public void init();
+  }
+
+  public static interface TilesTimelineManager.Clock {
+    method public long getCurrentTimeMillis();
+  }
+
+  public static interface TilesTimelineManager.Listener {
+    method public void onLayoutUpdate(int, androidx.wear.tiles.LayoutElementBuilders.Layout);
+  }
+
+}
+
diff --git a/wear/tiles/tiles-renderer/api/res-1.0.0-beta01.txt b/wear/tiles/tiles-renderer/api/res-1.0.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/wear/tiles/tiles-renderer/api/res-1.0.0-beta01.txt
diff --git a/wear/tiles/tiles-renderer/api/restricted_1.0.0-beta01.txt b/wear/tiles/tiles-renderer/api/restricted_1.0.0-beta01.txt
new file mode 100644
index 0000000..a162ceb
--- /dev/null
+++ b/wear/tiles/tiles-renderer/api/restricted_1.0.0-beta01.txt
@@ -0,0 +1,80 @@
+// Signature format: 4.0
+package androidx.wear.tiles.client {
+
+  public interface TileClient {
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> requestApiVersion();
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources!> requestResources(androidx.wear.tiles.RequestBuilders.ResourcesRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile!> requestTile(androidx.wear.tiles.RequestBuilders.TileRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileAddedEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileEnterEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileLeaveEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileRemovedEvent();
+  }
+
+}
+
+package androidx.wear.tiles.connection {
+
+  public final class DefaultTileClient implements androidx.wear.tiles.client.TileClient {
+    ctor public DefaultTileClient(android.content.Context context, android.content.ComponentName componentName, kotlinx.coroutines.CoroutineScope coroutineScope, kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
+    ctor public DefaultTileClient(android.content.Context context, android.content.ComponentName componentName, java.util.concurrent.Executor executor);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> requestApiVersion();
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources> requestResources(androidx.wear.tiles.RequestBuilders.ResourcesRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile> requestTile(androidx.wear.tiles.RequestBuilders.TileRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileAddedEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileEnterEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileLeaveEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileRemovedEvent();
+  }
+
+}
+
+package androidx.wear.tiles.manager {
+
+  public final class TileUiClient implements java.lang.AutoCloseable {
+    ctor public TileUiClient(android.content.Context context, android.content.ComponentName component, android.view.ViewGroup parentView);
+    method @MainThread public void close();
+    method @MainThread public void connect();
+  }
+
+}
+
+package androidx.wear.tiles.renderer {
+
+  public final class TileRenderer {
+    ctor public TileRenderer(android.content.Context, androidx.wear.tiles.LayoutElementBuilders.Layout, androidx.wear.tiles.ResourceBuilders.Resources, java.util.concurrent.Executor, androidx.wear.tiles.renderer.TileRenderer.LoadActionListener);
+    ctor public TileRenderer(android.content.Context, androidx.wear.tiles.LayoutElementBuilders.Layout, @StyleRes int, androidx.wear.tiles.ResourceBuilders.Resources, java.util.concurrent.Executor, androidx.wear.tiles.renderer.TileRenderer.LoadActionListener);
+    method public android.view.View? inflate(android.view.ViewGroup);
+  }
+
+  public static interface TileRenderer.LoadActionListener {
+    method public void onClick(androidx.wear.tiles.StateBuilders.State);
+  }
+
+}
+
+package androidx.wear.tiles.timeline {
+
+  public final class TilesTimelineCache {
+    ctor public TilesTimelineCache(androidx.wear.tiles.TimelineBuilders.Timeline);
+    method @MainThread public androidx.wear.tiles.TimelineBuilders.TimelineEntry? findClosestTimelineEntry(long);
+    method @MainThread public long findCurrentTimelineEntryExpiry(androidx.wear.tiles.TimelineBuilders.TimelineEntry, long);
+    method @MainThread public androidx.wear.tiles.TimelineBuilders.TimelineEntry? findTimelineEntryForTime(long);
+  }
+
+  public class TilesTimelineManager implements java.lang.AutoCloseable {
+    ctor public TilesTimelineManager(android.app.AlarmManager, androidx.wear.tiles.timeline.TilesTimelineManager.Clock, androidx.wear.tiles.TimelineBuilders.Timeline, int, java.util.concurrent.Executor, androidx.wear.tiles.timeline.TilesTimelineManager.Listener);
+    method public void close();
+    method public void init();
+  }
+
+  public static interface TilesTimelineManager.Clock {
+    method public long getCurrentTimeMillis();
+  }
+
+  public static interface TilesTimelineManager.Listener {
+    method public void onLayoutUpdate(int, androidx.wear.tiles.LayoutElementBuilders.Layout);
+  }
+
+}
+
diff --git a/wear/tiles/tiles-testing/api/1.0.0-beta01.txt b/wear/tiles/tiles-testing/api/1.0.0-beta01.txt
new file mode 100644
index 0000000..353b0c6
--- /dev/null
+++ b/wear/tiles/tiles-testing/api/1.0.0-beta01.txt
@@ -0,0 +1,17 @@
+// Signature format: 4.0
+package androidx.wear.tiles.testing {
+
+  public final class TestTileClient<T extends androidx.wear.tiles.TileService> implements androidx.wear.tiles.client.TileClient {
+    ctor public TestTileClient(T service, kotlinx.coroutines.CoroutineScope coroutineScope, kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
+    ctor public TestTileClient(T service, java.util.concurrent.Executor executor);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> requestApiVersion();
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources> requestResources(androidx.wear.tiles.RequestBuilders.ResourcesRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile> requestTile(androidx.wear.tiles.RequestBuilders.TileRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileAddedEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileEnterEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileLeaveEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileRemovedEvent();
+  }
+
+}
+
diff --git a/wear/tiles/tiles-testing/api/public_plus_experimental_1.0.0-beta01.txt b/wear/tiles/tiles-testing/api/public_plus_experimental_1.0.0-beta01.txt
new file mode 100644
index 0000000..353b0c6
--- /dev/null
+++ b/wear/tiles/tiles-testing/api/public_plus_experimental_1.0.0-beta01.txt
@@ -0,0 +1,17 @@
+// Signature format: 4.0
+package androidx.wear.tiles.testing {
+
+  public final class TestTileClient<T extends androidx.wear.tiles.TileService> implements androidx.wear.tiles.client.TileClient {
+    ctor public TestTileClient(T service, kotlinx.coroutines.CoroutineScope coroutineScope, kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
+    ctor public TestTileClient(T service, java.util.concurrent.Executor executor);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> requestApiVersion();
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources> requestResources(androidx.wear.tiles.RequestBuilders.ResourcesRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile> requestTile(androidx.wear.tiles.RequestBuilders.TileRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileAddedEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileEnterEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileLeaveEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileRemovedEvent();
+  }
+
+}
+
diff --git a/wear/tiles/tiles-testing/api/res-1.0.0-beta01.txt b/wear/tiles/tiles-testing/api/res-1.0.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/wear/tiles/tiles-testing/api/res-1.0.0-beta01.txt
diff --git a/wear/tiles/tiles-testing/api/restricted_1.0.0-beta01.txt b/wear/tiles/tiles-testing/api/restricted_1.0.0-beta01.txt
new file mode 100644
index 0000000..353b0c6
--- /dev/null
+++ b/wear/tiles/tiles-testing/api/restricted_1.0.0-beta01.txt
@@ -0,0 +1,17 @@
+// Signature format: 4.0
+package androidx.wear.tiles.testing {
+
+  public final class TestTileClient<T extends androidx.wear.tiles.TileService> implements androidx.wear.tiles.client.TileClient {
+    ctor public TestTileClient(T service, kotlinx.coroutines.CoroutineScope coroutineScope, kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
+    ctor public TestTileClient(T service, java.util.concurrent.Executor executor);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> requestApiVersion();
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources> requestResources(androidx.wear.tiles.RequestBuilders.ResourcesRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile> requestTile(androidx.wear.tiles.RequestBuilders.TileRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileAddedEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileEnterEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileLeaveEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileRemovedEvent();
+  }
+
+}
+
diff --git a/wear/tiles/tiles/api/1.0.0-beta01.txt b/wear/tiles/tiles/api/1.0.0-beta01.txt
new file mode 100644
index 0000000..6c21e92
--- /dev/null
+++ b/wear/tiles/tiles/api/1.0.0-beta01.txt
@@ -0,0 +1,1066 @@
+// Signature format: 4.0
+package androidx.wear.tiles {
+
+  public final class ActionBuilders {
+    method public static androidx.wear.tiles.ActionBuilders.AndroidBooleanExtra booleanExtra(boolean);
+    method public static androidx.wear.tiles.ActionBuilders.AndroidDoubleExtra doubleExtra(double);
+    method public static androidx.wear.tiles.ActionBuilders.AndroidIntExtra intExtra(int);
+    method public static androidx.wear.tiles.ActionBuilders.AndroidLongExtra longExtra(long);
+    method public static androidx.wear.tiles.ActionBuilders.AndroidStringExtra stringExtra(String);
+  }
+
+  public static interface ActionBuilders.Action {
+  }
+
+  public static interface ActionBuilders.Action.Builder {
+    method public androidx.wear.tiles.ActionBuilders.Action build();
+  }
+
+  public static final class ActionBuilders.AndroidActivity {
+    method public String getClassName();
+    method public java.util.Map<java.lang.String!,androidx.wear.tiles.ActionBuilders.AndroidExtra!> getKeyToExtraMapping();
+    method public String getPackageName();
+  }
+
+  public static final class ActionBuilders.AndroidActivity.Builder {
+    ctor public ActionBuilders.AndroidActivity.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidActivity.Builder addKeyToExtraMapping(String, androidx.wear.tiles.ActionBuilders.AndroidExtra);
+    method public androidx.wear.tiles.ActionBuilders.AndroidActivity build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidActivity.Builder setClassName(String);
+    method public androidx.wear.tiles.ActionBuilders.AndroidActivity.Builder setPackageName(String);
+  }
+
+  public static final class ActionBuilders.AndroidBooleanExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method public boolean getValue();
+  }
+
+  public static final class ActionBuilders.AndroidBooleanExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor public ActionBuilders.AndroidBooleanExtra.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidBooleanExtra build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidBooleanExtra.Builder setValue(boolean);
+  }
+
+  public static final class ActionBuilders.AndroidDoubleExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method public double getValue();
+  }
+
+  public static final class ActionBuilders.AndroidDoubleExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor public ActionBuilders.AndroidDoubleExtra.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidDoubleExtra build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidDoubleExtra.Builder setValue(double);
+  }
+
+  public static interface ActionBuilders.AndroidExtra {
+  }
+
+  public static interface ActionBuilders.AndroidExtra.Builder {
+    method public androidx.wear.tiles.ActionBuilders.AndroidExtra build();
+  }
+
+  public static final class ActionBuilders.AndroidIntExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method public int getValue();
+  }
+
+  public static final class ActionBuilders.AndroidIntExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor public ActionBuilders.AndroidIntExtra.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidIntExtra build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidIntExtra.Builder setValue(int);
+  }
+
+  public static final class ActionBuilders.AndroidLongExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method public long getValue();
+  }
+
+  public static final class ActionBuilders.AndroidLongExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor public ActionBuilders.AndroidLongExtra.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidLongExtra build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidLongExtra.Builder setValue(long);
+  }
+
+  public static final class ActionBuilders.AndroidStringExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method public String getValue();
+  }
+
+  public static final class ActionBuilders.AndroidStringExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor public ActionBuilders.AndroidStringExtra.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidStringExtra build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidStringExtra.Builder setValue(String);
+  }
+
+  public static final class ActionBuilders.LaunchAction implements androidx.wear.tiles.ActionBuilders.Action {
+    method public androidx.wear.tiles.ActionBuilders.AndroidActivity? getAndroidActivity();
+  }
+
+  public static final class ActionBuilders.LaunchAction.Builder implements androidx.wear.tiles.ActionBuilders.Action.Builder {
+    ctor public ActionBuilders.LaunchAction.Builder();
+    method public androidx.wear.tiles.ActionBuilders.LaunchAction build();
+    method public androidx.wear.tiles.ActionBuilders.LaunchAction.Builder setAndroidActivity(androidx.wear.tiles.ActionBuilders.AndroidActivity);
+  }
+
+  public static final class ActionBuilders.LoadAction implements androidx.wear.tiles.ActionBuilders.Action {
+    method public androidx.wear.tiles.StateBuilders.State? getRequestState();
+  }
+
+  public static final class ActionBuilders.LoadAction.Builder implements androidx.wear.tiles.ActionBuilders.Action.Builder {
+    ctor public ActionBuilders.LoadAction.Builder();
+    method public androidx.wear.tiles.ActionBuilders.LoadAction build();
+    method public androidx.wear.tiles.ActionBuilders.LoadAction.Builder setRequestState(androidx.wear.tiles.StateBuilders.State);
+  }
+
+  public final class ColorBuilders {
+    method public static androidx.wear.tiles.ColorBuilders.ColorProp argb(@ColorInt int);
+  }
+
+  public static final class ColorBuilders.ColorProp {
+    method @ColorInt public int getArgb();
+  }
+
+  public static final class ColorBuilders.ColorProp.Builder {
+    ctor public ColorBuilders.ColorProp.Builder();
+    method public androidx.wear.tiles.ColorBuilders.ColorProp build();
+    method public androidx.wear.tiles.ColorBuilders.ColorProp.Builder setArgb(@ColorInt int);
+  }
+
+  public final class DeviceParametersBuilders {
+    field public static final int DEVICE_PLATFORM_UNDEFINED = 0; // 0x0
+    field public static final int DEVICE_PLATFORM_WEAR_OS = 1; // 0x1
+    field public static final int SCREEN_SHAPE_RECT = 2; // 0x2
+    field public static final int SCREEN_SHAPE_ROUND = 1; // 0x1
+    field public static final int SCREEN_SHAPE_UNDEFINED = 0; // 0x0
+  }
+
+  public static final class DeviceParametersBuilders.DeviceParameters {
+    method public int getDevicePlatform();
+    method @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) public float getScreenDensity();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenHeightDp();
+    method public int getScreenShape();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenWidthDp();
+  }
+
+  public static final class DeviceParametersBuilders.DeviceParameters.Builder {
+    ctor public DeviceParametersBuilders.DeviceParameters.Builder();
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters build();
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setDevicePlatform(int);
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenDensity(@FloatRange(from=0.0, fromInclusive=false, toInclusive=false) float);
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenHeightDp(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenShape(int);
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenWidthDp(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+  }
+
+  public final class DimensionBuilders {
+    method public static androidx.wear.tiles.DimensionBuilders.DegreesProp degrees(float);
+    method public static androidx.wear.tiles.DimensionBuilders.DpProp dp(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method public static androidx.wear.tiles.DimensionBuilders.EmProp em(int);
+    method public static androidx.wear.tiles.DimensionBuilders.ExpandedDimensionProp expand();
+    method public static androidx.wear.tiles.DimensionBuilders.SpProp sp(@Dimension(unit=androidx.annotation.Dimension.SP) float);
+    method public static androidx.wear.tiles.DimensionBuilders.WrappedDimensionProp wrap();
+  }
+
+  public static interface DimensionBuilders.ContainerDimension {
+  }
+
+  public static interface DimensionBuilders.ContainerDimension.Builder {
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension build();
+  }
+
+  public static final class DimensionBuilders.DegreesProp {
+    method public float getValue();
+  }
+
+  public static final class DimensionBuilders.DegreesProp.Builder {
+    ctor public DimensionBuilders.DegreesProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.DegreesProp build();
+    method public androidx.wear.tiles.DimensionBuilders.DegreesProp.Builder setValue(float);
+  }
+
+  public static final class DimensionBuilders.DpProp implements androidx.wear.tiles.DimensionBuilders.ContainerDimension androidx.wear.tiles.DimensionBuilders.ImageDimension androidx.wear.tiles.DimensionBuilders.SpacerDimension {
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
+  }
+
+  public static final class DimensionBuilders.DpProp.Builder implements androidx.wear.tiles.DimensionBuilders.ContainerDimension.Builder androidx.wear.tiles.DimensionBuilders.ImageDimension.Builder androidx.wear.tiles.DimensionBuilders.SpacerDimension.Builder {
+    ctor public DimensionBuilders.DpProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp build();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp.Builder setValue(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  public static final class DimensionBuilders.EmProp {
+    method public float getValue();
+  }
+
+  public static final class DimensionBuilders.EmProp.Builder {
+    ctor public DimensionBuilders.EmProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.EmProp build();
+    method public androidx.wear.tiles.DimensionBuilders.EmProp.Builder setValue(float);
+  }
+
+  public static final class DimensionBuilders.ExpandedDimensionProp implements androidx.wear.tiles.DimensionBuilders.ContainerDimension androidx.wear.tiles.DimensionBuilders.ImageDimension {
+  }
+
+  public static final class DimensionBuilders.ExpandedDimensionProp.Builder implements androidx.wear.tiles.DimensionBuilders.ContainerDimension.Builder androidx.wear.tiles.DimensionBuilders.ImageDimension.Builder {
+    ctor public DimensionBuilders.ExpandedDimensionProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.ExpandedDimensionProp build();
+  }
+
+  public static interface DimensionBuilders.ImageDimension {
+  }
+
+  public static interface DimensionBuilders.ImageDimension.Builder {
+    method public androidx.wear.tiles.DimensionBuilders.ImageDimension build();
+  }
+
+  public static final class DimensionBuilders.ProportionalDimensionProp implements androidx.wear.tiles.DimensionBuilders.ImageDimension {
+    method @IntRange(from=0) public int getAspectRatioHeight();
+    method @IntRange(from=0) public int getAspectRatioWidth();
+  }
+
+  public static final class DimensionBuilders.ProportionalDimensionProp.Builder implements androidx.wear.tiles.DimensionBuilders.ImageDimension.Builder {
+    ctor public DimensionBuilders.ProportionalDimensionProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.ProportionalDimensionProp build();
+    method public androidx.wear.tiles.DimensionBuilders.ProportionalDimensionProp.Builder setAspectRatioHeight(@IntRange(from=0) int);
+    method public androidx.wear.tiles.DimensionBuilders.ProportionalDimensionProp.Builder setAspectRatioWidth(@IntRange(from=0) int);
+  }
+
+  public static final class DimensionBuilders.SpProp {
+    method @Dimension(unit=androidx.annotation.Dimension.SP) public float getValue();
+  }
+
+  public static final class DimensionBuilders.SpProp.Builder {
+    ctor public DimensionBuilders.SpProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.SpProp build();
+    method public androidx.wear.tiles.DimensionBuilders.SpProp.Builder setValue(@Dimension(unit=androidx.annotation.Dimension.SP) float);
+  }
+
+  public static interface DimensionBuilders.SpacerDimension {
+  }
+
+  public static interface DimensionBuilders.SpacerDimension.Builder {
+    method public androidx.wear.tiles.DimensionBuilders.SpacerDimension build();
+  }
+
+  public static final class DimensionBuilders.WrappedDimensionProp implements androidx.wear.tiles.DimensionBuilders.ContainerDimension {
+  }
+
+  public static final class DimensionBuilders.WrappedDimensionProp.Builder implements androidx.wear.tiles.DimensionBuilders.ContainerDimension.Builder {
+    ctor public DimensionBuilders.WrappedDimensionProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.WrappedDimensionProp build();
+  }
+
+  public final class EventBuilders {
+  }
+
+  public static final class EventBuilders.TileAddEvent {
+  }
+
+  public static final class EventBuilders.TileAddEvent.Builder {
+    ctor public EventBuilders.TileAddEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileAddEvent build();
+  }
+
+  public static final class EventBuilders.TileEnterEvent {
+  }
+
+  public static final class EventBuilders.TileEnterEvent.Builder {
+    ctor public EventBuilders.TileEnterEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileEnterEvent build();
+  }
+
+  public static final class EventBuilders.TileLeaveEvent {
+  }
+
+  public static final class EventBuilders.TileLeaveEvent.Builder {
+    ctor public EventBuilders.TileLeaveEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileLeaveEvent build();
+  }
+
+  public static final class EventBuilders.TileRemoveEvent {
+  }
+
+  public static final class EventBuilders.TileRemoveEvent.Builder {
+    ctor public EventBuilders.TileRemoveEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileRemoveEvent build();
+  }
+
+  public final class LayoutElementBuilders {
+    field public static final int ARC_ANCHOR_CENTER = 2; // 0x2
+    field public static final int ARC_ANCHOR_END = 3; // 0x3
+    field public static final int ARC_ANCHOR_START = 1; // 0x1
+    field public static final int ARC_ANCHOR_UNDEFINED = 0; // 0x0
+    field public static final int CONTENT_SCALE_MODE_CROP = 2; // 0x2
+    field public static final int CONTENT_SCALE_MODE_FILL_BOUNDS = 3; // 0x3
+    field public static final int CONTENT_SCALE_MODE_FIT = 1; // 0x1
+    field public static final int CONTENT_SCALE_MODE_UNDEFINED = 0; // 0x0
+    field public static final int FONT_VARIANT_BODY = 2; // 0x2
+    field public static final int FONT_VARIANT_TITLE = 1; // 0x1
+    field public static final int FONT_VARIANT_UNDEFINED = 0; // 0x0
+    field public static final int FONT_WEIGHT_BOLD = 700; // 0x2bc
+    field public static final int FONT_WEIGHT_NORMAL = 400; // 0x190
+    field public static final int FONT_WEIGHT_UNDEFINED = 0; // 0x0
+    field public static final int HORIZONTAL_ALIGN_CENTER = 2; // 0x2
+    field public static final int HORIZONTAL_ALIGN_END = 5; // 0x5
+    field public static final int HORIZONTAL_ALIGN_LEFT = 1; // 0x1
+    field public static final int HORIZONTAL_ALIGN_RIGHT = 3; // 0x3
+    field public static final int HORIZONTAL_ALIGN_START = 4; // 0x4
+    field public static final int HORIZONTAL_ALIGN_UNDEFINED = 0; // 0x0
+    field public static final int SPAN_VERTICAL_ALIGN_BOTTOM = 1; // 0x1
+    field public static final int SPAN_VERTICAL_ALIGN_TEXT_BASELINE = 2; // 0x2
+    field public static final int SPAN_VERTICAL_ALIGN_UNDEFINED = 0; // 0x0
+    field public static final int TEXT_ALIGN_CENTER = 2; // 0x2
+    field public static final int TEXT_ALIGN_END = 3; // 0x3
+    field public static final int TEXT_ALIGN_START = 1; // 0x1
+    field public static final int TEXT_ALIGN_UNDEFINED = 0; // 0x0
+    field public static final int TEXT_OVERFLOW_ELLIPSIZE_END = 2; // 0x2
+    field public static final int TEXT_OVERFLOW_TRUNCATE = 1; // 0x1
+    field public static final int TEXT_OVERFLOW_UNDEFINED = 0; // 0x0
+    field public static final int VERTICAL_ALIGN_BOTTOM = 3; // 0x3
+    field public static final int VERTICAL_ALIGN_CENTER = 2; // 0x2
+    field public static final int VERTICAL_ALIGN_TOP = 1; // 0x1
+    field public static final int VERTICAL_ALIGN_UNDEFINED = 0; // 0x0
+  }
+
+  public static final class LayoutElementBuilders.Arc implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.tiles.DimensionBuilders.DegreesProp? getAnchorAngle();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp? getAnchorType();
+    method public java.util.List<androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement!> getContents();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlign();
+  }
+
+  public static final class LayoutElementBuilders.Arc.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Arc.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setAnchorAngle(androidx.wear.tiles.DimensionBuilders.DegreesProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setAnchorType(androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setAnchorType(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setVerticalAlign(androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setVerticalAlign(int);
+  }
+
+  public static final class LayoutElementBuilders.ArcAdapter implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getContent();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp? getRotateContents();
+  }
+
+  public static final class LayoutElementBuilders.ArcAdapter.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor public LayoutElementBuilders.ArcAdapter.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter.Builder setContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter.Builder setRotateContents(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter.Builder setRotateContents(boolean);
+  }
+
+  public static final class LayoutElementBuilders.ArcAnchorTypeProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.ArcAnchorTypeProp.Builder {
+    ctor public LayoutElementBuilders.ArcAnchorTypeProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp.Builder setValue(int);
+  }
+
+  public static interface LayoutElementBuilders.ArcLayoutElement {
+  }
+
+  public static interface LayoutElementBuilders.ArcLayoutElement.Builder {
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement build();
+  }
+
+  public static final class LayoutElementBuilders.ArcLine implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.tiles.DimensionBuilders.DegreesProp? getLength();
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getThickness();
+  }
+
+  public static final class LayoutElementBuilders.ArcLine.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor public LayoutElementBuilders.ArcLine.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLine build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setLength(androidx.wear.tiles.DimensionBuilders.DegreesProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.ArcModifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setThickness(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class LayoutElementBuilders.ArcSpacer implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.tiles.DimensionBuilders.DegreesProp? getLength();
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getThickness();
+  }
+
+  public static final class LayoutElementBuilders.ArcSpacer.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor public LayoutElementBuilders.ArcSpacer.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer.Builder setLength(androidx.wear.tiles.DimensionBuilders.DegreesProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.ArcModifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer.Builder setThickness(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class LayoutElementBuilders.ArcText implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.tiles.TypeBuilders.StringProp? getText();
+  }
+
+  public static final class LayoutElementBuilders.ArcText.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor public LayoutElementBuilders.ArcText.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcText build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setFontStyle(androidx.wear.tiles.LayoutElementBuilders.FontStyle);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.ArcModifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setText(androidx.wear.tiles.TypeBuilders.StringProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setText(String);
+  }
+
+  public static final class LayoutElementBuilders.Box implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Box.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Box.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setHorizontalAlignment(androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setHorizontalAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setVerticalAlignment(androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setVerticalAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+  }
+
+  public static final class LayoutElementBuilders.ColorFilter {
+    method public androidx.wear.tiles.ColorBuilders.ColorProp? getTint();
+  }
+
+  public static final class LayoutElementBuilders.ColorFilter.Builder {
+    ctor public LayoutElementBuilders.ColorFilter.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ColorFilter build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ColorFilter.Builder setTint(androidx.wear.tiles.ColorBuilders.ColorProp);
+  }
+
+  public static final class LayoutElementBuilders.Column implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Column.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Column.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.tiles.LayoutElementBuilders.Column build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setHorizontalAlignment(androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setHorizontalAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+  }
+
+  public static final class LayoutElementBuilders.ContentScaleModeProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.ContentScaleModeProp.Builder {
+    ctor public LayoutElementBuilders.ContentScaleModeProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.FontStyle {
+    method public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp? getItalic();
+    method public androidx.wear.tiles.DimensionBuilders.EmProp? getLetterSpacing();
+    method public androidx.wear.tiles.DimensionBuilders.SpProp? getSize();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp? getUnderline();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontWeightProp? getWeight();
+  }
+
+  public static final class LayoutElementBuilders.FontStyle.Builder {
+    ctor public LayoutElementBuilders.FontStyle.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle build();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setItalic(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setItalic(boolean);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setLetterSpacing(androidx.wear.tiles.DimensionBuilders.EmProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setSize(androidx.wear.tiles.DimensionBuilders.SpProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setUnderline(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setUnderline(boolean);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setWeight(androidx.wear.tiles.LayoutElementBuilders.FontWeightProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setWeight(int);
+  }
+
+  public static class LayoutElementBuilders.FontStyles {
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder body1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder body2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder button(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder caption1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder caption2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder display1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder display2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder display3(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder title1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder title2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder title3(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+  }
+
+  public static final class LayoutElementBuilders.FontWeightProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.FontWeightProp.Builder {
+    ctor public LayoutElementBuilders.FontWeightProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontWeightProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontWeightProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.HorizontalAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.HorizontalAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.HorizontalAlignmentProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.Image implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp? getContentScaleMode();
+    method public androidx.wear.tiles.DimensionBuilders.ImageDimension? getHeight();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.TypeBuilders.StringProp? getResourceId();
+    method public androidx.wear.tiles.DimensionBuilders.ImageDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Image.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Image.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Image build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setContentScaleMode(androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setContentScaleMode(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ImageDimension);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setResourceId(androidx.wear.tiles.TypeBuilders.StringProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setResourceId(String);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ImageDimension);
+  }
+
+  public static final class LayoutElementBuilders.Layout {
+    method public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getRoot();
+  }
+
+  public static final class LayoutElementBuilders.Layout.Builder {
+    ctor public LayoutElementBuilders.Layout.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Layout build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Layout.Builder setRoot(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+  }
+
+  public static interface LayoutElementBuilders.LayoutElement {
+  }
+
+  public static interface LayoutElementBuilders.LayoutElement.Builder {
+    method public androidx.wear.tiles.LayoutElementBuilders.LayoutElement build();
+  }
+
+  public static final class LayoutElementBuilders.Row implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Row.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Row.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.tiles.LayoutElementBuilders.Row build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setVerticalAlignment(androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setVerticalAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+  }
+
+  public static final class LayoutElementBuilders.Spacer implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.tiles.DimensionBuilders.SpacerDimension? getHeight();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.DimensionBuilders.SpacerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Spacer.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Spacer.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Spacer build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Spacer.Builder setHeight(androidx.wear.tiles.DimensionBuilders.SpacerDimension);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spacer.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spacer.Builder setWidth(androidx.wear.tiles.DimensionBuilders.SpacerDimension);
+  }
+
+  public static interface LayoutElementBuilders.Span {
+  }
+
+  public static interface LayoutElementBuilders.Span.Builder {
+    method public androidx.wear.tiles.LayoutElementBuilders.Span build();
+  }
+
+  public static final class LayoutElementBuilders.SpanImage implements androidx.wear.tiles.LayoutElementBuilders.Span {
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp? getAlignment();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getHeight();
+    method public androidx.wear.tiles.ModifiersBuilders.SpanModifiers? getModifiers();
+    method public androidx.wear.tiles.TypeBuilders.StringProp? getResourceId();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.SpanImage.Builder implements androidx.wear.tiles.LayoutElementBuilders.Span.Builder {
+    ctor public LayoutElementBuilders.SpanImage.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage build();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setAlignment(androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setHeight(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.SpanModifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setResourceId(androidx.wear.tiles.TypeBuilders.StringProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setResourceId(String);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setWidth(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class LayoutElementBuilders.SpanText implements androidx.wear.tiles.LayoutElementBuilders.Span {
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.tiles.ModifiersBuilders.SpanModifiers? getModifiers();
+    method public androidx.wear.tiles.TypeBuilders.StringProp? getText();
+  }
+
+  public static final class LayoutElementBuilders.SpanText.Builder implements androidx.wear.tiles.LayoutElementBuilders.Span.Builder {
+    ctor public LayoutElementBuilders.SpanText.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanText build();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setFontStyle(androidx.wear.tiles.LayoutElementBuilders.FontStyle);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.SpanModifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setText(androidx.wear.tiles.TypeBuilders.StringProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setText(String);
+  }
+
+  public static final class LayoutElementBuilders.SpanVerticalAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.SpanVerticalAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.SpanVerticalAlignmentProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.Spannable implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.tiles.DimensionBuilders.SpProp? getLineHeight();
+    method public androidx.wear.tiles.TypeBuilders.Int32Prop? getMaxLines();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp? getMultilineAlignment();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method public java.util.List<androidx.wear.tiles.LayoutElementBuilders.Span!> getSpans();
+  }
+
+  public static final class LayoutElementBuilders.Spannable.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Spannable.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder addSpan(androidx.wear.tiles.LayoutElementBuilders.Span);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setLineHeight(androidx.wear.tiles.DimensionBuilders.SpProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMaxLines(androidx.wear.tiles.TypeBuilders.Int32Prop);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMaxLines(@IntRange(from=1) int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMultilineAlignment(androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMultilineAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setOverflow(androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setOverflow(int);
+  }
+
+  public static final class LayoutElementBuilders.Text implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.tiles.DimensionBuilders.SpProp? getLineHeight();
+    method public androidx.wear.tiles.TypeBuilders.Int32Prop? getMaxLines();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp? getMultilineAlignment();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method public androidx.wear.tiles.TypeBuilders.StringProp? getText();
+  }
+
+  public static final class LayoutElementBuilders.Text.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Text.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Text build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setFontStyle(androidx.wear.tiles.LayoutElementBuilders.FontStyle);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setLineHeight(androidx.wear.tiles.DimensionBuilders.SpProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMaxLines(androidx.wear.tiles.TypeBuilders.Int32Prop);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMaxLines(@IntRange(from=1) int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMultilineAlignment(androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMultilineAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setOverflow(androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setOverflow(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setText(androidx.wear.tiles.TypeBuilders.StringProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setText(String);
+  }
+
+  public static final class LayoutElementBuilders.TextAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.TextAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.TextAlignmentProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.TextOverflowProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.TextOverflowProp.Builder {
+    ctor public LayoutElementBuilders.TextOverflowProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.VerticalAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.VerticalAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.VerticalAlignmentProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp.Builder setValue(int);
+  }
+
+  public final class ModifiersBuilders {
+  }
+
+  public static final class ModifiersBuilders.ArcModifiers {
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable? getClickable();
+    method public androidx.wear.tiles.ModifiersBuilders.Semantics? getSemantics();
+  }
+
+  public static final class ModifiersBuilders.ArcModifiers.Builder {
+    ctor public ModifiersBuilders.ArcModifiers.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers build();
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers.Builder setClickable(androidx.wear.tiles.ModifiersBuilders.Clickable);
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers.Builder setSemantics(androidx.wear.tiles.ModifiersBuilders.Semantics);
+  }
+
+  public static final class ModifiersBuilders.Background {
+    method public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.tiles.ModifiersBuilders.Corner? getCorner();
+  }
+
+  public static final class ModifiersBuilders.Background.Builder {
+    ctor public ModifiersBuilders.Background.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Background build();
+    method public androidx.wear.tiles.ModifiersBuilders.Background.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Background.Builder setCorner(androidx.wear.tiles.ModifiersBuilders.Corner);
+  }
+
+  public static final class ModifiersBuilders.Border {
+    method public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getWidth();
+  }
+
+  public static final class ModifiersBuilders.Border.Builder {
+    ctor public ModifiersBuilders.Border.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Border build();
+    method public androidx.wear.tiles.ModifiersBuilders.Border.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Border.Builder setWidth(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class ModifiersBuilders.Clickable {
+    method public String getId();
+    method public androidx.wear.tiles.ActionBuilders.Action? getOnClick();
+  }
+
+  public static final class ModifiersBuilders.Clickable.Builder {
+    ctor public ModifiersBuilders.Clickable.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable build();
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable.Builder setId(String);
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable.Builder setOnClick(androidx.wear.tiles.ActionBuilders.Action);
+  }
+
+  public static final class ModifiersBuilders.Corner {
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getRadius();
+  }
+
+  public static final class ModifiersBuilders.Corner.Builder {
+    ctor public ModifiersBuilders.Corner.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Corner build();
+    method public androidx.wear.tiles.ModifiersBuilders.Corner.Builder setRadius(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class ModifiersBuilders.Modifiers {
+    method public androidx.wear.tiles.ModifiersBuilders.Background? getBackground();
+    method public androidx.wear.tiles.ModifiersBuilders.Border? getBorder();
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable? getClickable();
+    method public androidx.wear.tiles.ModifiersBuilders.Padding? getPadding();
+    method public androidx.wear.tiles.ModifiersBuilders.Semantics? getSemantics();
+  }
+
+  public static final class ModifiersBuilders.Modifiers.Builder {
+    ctor public ModifiersBuilders.Modifiers.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers build();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setBackground(androidx.wear.tiles.ModifiersBuilders.Background);
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setBorder(androidx.wear.tiles.ModifiersBuilders.Border);
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setClickable(androidx.wear.tiles.ModifiersBuilders.Clickable);
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setPadding(androidx.wear.tiles.ModifiersBuilders.Padding);
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setSemantics(androidx.wear.tiles.ModifiersBuilders.Semantics);
+  }
+
+  public static final class ModifiersBuilders.Padding {
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getBottom();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getEnd();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp? getRtlAware();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getStart();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getTop();
+  }
+
+  public static final class ModifiersBuilders.Padding.Builder {
+    ctor public ModifiersBuilders.Padding.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Padding build();
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setAll(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setBottom(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setEnd(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setRtlAware(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setRtlAware(boolean);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setStart(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setTop(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class ModifiersBuilders.Semantics {
+    method public String getContentDescription();
+  }
+
+  public static final class ModifiersBuilders.Semantics.Builder {
+    ctor public ModifiersBuilders.Semantics.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Semantics build();
+    method public androidx.wear.tiles.ModifiersBuilders.Semantics.Builder setContentDescription(String);
+  }
+
+  public static final class ModifiersBuilders.SpanModifiers {
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable? getClickable();
+  }
+
+  public static final class ModifiersBuilders.SpanModifiers.Builder {
+    ctor public ModifiersBuilders.SpanModifiers.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.SpanModifiers build();
+    method public androidx.wear.tiles.ModifiersBuilders.SpanModifiers.Builder setClickable(androidx.wear.tiles.ModifiersBuilders.Clickable);
+  }
+
+  public final class RequestBuilders {
+  }
+
+  public static final class RequestBuilders.ResourcesRequest {
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters? getDeviceParameters();
+    method public java.util.List<java.lang.String!> getResourceIds();
+    method public String getVersion();
+  }
+
+  public static final class RequestBuilders.ResourcesRequest.Builder {
+    ctor public RequestBuilders.ResourcesRequest.Builder();
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder addResourceId(String);
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest build();
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setDeviceParameters(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setVersion(String);
+  }
+
+  public static final class RequestBuilders.TileRequest {
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters? getDeviceParameters();
+    method public androidx.wear.tiles.StateBuilders.State? getState();
+  }
+
+  public static final class RequestBuilders.TileRequest.Builder {
+    ctor public RequestBuilders.TileRequest.Builder();
+    method public androidx.wear.tiles.RequestBuilders.TileRequest build();
+    method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setDeviceParameters(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setState(androidx.wear.tiles.StateBuilders.State);
+  }
+
+  public final class ResourceBuilders {
+    field public static final int IMAGE_FORMAT_RGB_565 = 1; // 0x1
+    field public static final int IMAGE_FORMAT_UNDEFINED = 0; // 0x0
+  }
+
+  public static final class ResourceBuilders.AndroidImageResourceByResId {
+    method @DrawableRes public int getResourceId();
+  }
+
+  public static final class ResourceBuilders.AndroidImageResourceByResId.Builder {
+    ctor public ResourceBuilders.AndroidImageResourceByResId.Builder();
+    method public androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId build();
+    method public androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId.Builder setResourceId(@DrawableRes int);
+  }
+
+  public static final class ResourceBuilders.ImageResource {
+    method public androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId? getAndroidResourceByResId();
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource? getInlineResource();
+  }
+
+  public static final class ResourceBuilders.ImageResource.Builder {
+    ctor public ResourceBuilders.ImageResource.Builder();
+    method public androidx.wear.tiles.ResourceBuilders.ImageResource build();
+    method public androidx.wear.tiles.ResourceBuilders.ImageResource.Builder setAndroidResourceByResId(androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId);
+    method public androidx.wear.tiles.ResourceBuilders.ImageResource.Builder setInlineResource(androidx.wear.tiles.ResourceBuilders.InlineImageResource);
+  }
+
+  public static final class ResourceBuilders.InlineImageResource {
+    method public byte[] getData();
+    method public int getFormat();
+    method @Dimension(unit=androidx.annotation.Dimension.PX) public int getHeightPx();
+    method @Dimension(unit=androidx.annotation.Dimension.PX) public int getWidthPx();
+  }
+
+  public static final class ResourceBuilders.InlineImageResource.Builder {
+    ctor public ResourceBuilders.InlineImageResource.Builder();
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource build();
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setData(byte[]);
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setFormat(int);
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setHeightPx(@Dimension(unit=androidx.annotation.Dimension.PX) int);
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setWidthPx(@Dimension(unit=androidx.annotation.Dimension.PX) int);
+  }
+
+  public static final class ResourceBuilders.Resources {
+    method public java.util.Map<java.lang.String!,androidx.wear.tiles.ResourceBuilders.ImageResource!> getIdToImageMapping();
+    method public String getVersion();
+  }
+
+  public static final class ResourceBuilders.Resources.Builder {
+    ctor public ResourceBuilders.Resources.Builder();
+    method public androidx.wear.tiles.ResourceBuilders.Resources.Builder addIdToImageMapping(String, androidx.wear.tiles.ResourceBuilders.ImageResource);
+    method public androidx.wear.tiles.ResourceBuilders.Resources build();
+    method public androidx.wear.tiles.ResourceBuilders.Resources.Builder setVersion(String);
+  }
+
+  public final class StateBuilders {
+  }
+
+  public static final class StateBuilders.State {
+    method public String getLastClickableId();
+  }
+
+  public static final class StateBuilders.State.Builder {
+    ctor public StateBuilders.State.Builder();
+    method public androidx.wear.tiles.StateBuilders.State build();
+  }
+
+  public final class TileBuilders {
+  }
+
+  public static final class TileBuilders.Tile {
+    method public long getFreshnessIntervalMillis();
+    method public String getResourcesVersion();
+    method public androidx.wear.tiles.TimelineBuilders.Timeline? getTimeline();
+  }
+
+  public static final class TileBuilders.Tile.Builder {
+    ctor public TileBuilders.Tile.Builder();
+    method public androidx.wear.tiles.TileBuilders.Tile build();
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setFreshnessIntervalMillis(long);
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setResourcesVersion(String);
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setTimeline(androidx.wear.tiles.TimelineBuilders.Timeline);
+  }
+
+  public abstract class TileService extends android.app.Service {
+    ctor public TileService();
+    method public static androidx.wear.tiles.TileUpdateRequester getUpdater(android.content.Context);
+    method public android.os.IBinder? onBind(android.content.Intent);
+    method @MainThread protected abstract com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources!> onResourcesRequest(androidx.wear.tiles.RequestBuilders.ResourcesRequest);
+    method @MainThread protected void onTileAddEvent(androidx.wear.tiles.EventBuilders.TileAddEvent);
+    method @MainThread protected void onTileEnterEvent(androidx.wear.tiles.EventBuilders.TileEnterEvent);
+    method @MainThread protected void onTileLeaveEvent(androidx.wear.tiles.EventBuilders.TileLeaveEvent);
+    method @MainThread protected void onTileRemoveEvent(androidx.wear.tiles.EventBuilders.TileRemoveEvent);
+    method @MainThread protected abstract com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile!> onTileRequest(androidx.wear.tiles.RequestBuilders.TileRequest);
+    field public static final String ACTION_BIND_TILE_PROVIDER = "androidx.wear.tiles.action.BIND_TILE_PROVIDER";
+    field public static final String EXTRA_CLICKABLE_ID = "androidx.wear.tiles.extra.CLICKABLE_ID";
+    field public static final String METADATA_PREVIEW_KEY = "androidx.wear.tiles.PREVIEW";
+  }
+
+  public interface TileUpdateRequester {
+    method public void requestUpdate(Class<? extends androidx.wear.tiles.TileService>);
+  }
+
+  public final class TimelineBuilders {
+  }
+
+  public static final class TimelineBuilders.TimeInterval {
+    method public long getEndMillis();
+    method public long getStartMillis();
+  }
+
+  public static final class TimelineBuilders.TimeInterval.Builder {
+    ctor public TimelineBuilders.TimeInterval.Builder();
+    method public androidx.wear.tiles.TimelineBuilders.TimeInterval build();
+    method public androidx.wear.tiles.TimelineBuilders.TimeInterval.Builder setEndMillis(long);
+    method public androidx.wear.tiles.TimelineBuilders.TimeInterval.Builder setStartMillis(long);
+  }
+
+  public static final class TimelineBuilders.Timeline {
+    method public java.util.List<androidx.wear.tiles.TimelineBuilders.TimelineEntry!> getTimelineEntries();
+  }
+
+  public static final class TimelineBuilders.Timeline.Builder {
+    ctor public TimelineBuilders.Timeline.Builder();
+    method public androidx.wear.tiles.TimelineBuilders.Timeline.Builder addTimelineEntry(androidx.wear.tiles.TimelineBuilders.TimelineEntry);
+    method public androidx.wear.tiles.TimelineBuilders.Timeline build();
+  }
+
+  public static final class TimelineBuilders.TimelineEntry {
+    method public androidx.wear.tiles.LayoutElementBuilders.Layout? getLayout();
+    method public androidx.wear.tiles.TimelineBuilders.TimeInterval? getValidity();
+  }
+
+  public static final class TimelineBuilders.TimelineEntry.Builder {
+    ctor public TimelineBuilders.TimelineEntry.Builder();
+    method public androidx.wear.tiles.TimelineBuilders.TimelineEntry build();
+    method public androidx.wear.tiles.TimelineBuilders.TimelineEntry.Builder setLayout(androidx.wear.tiles.LayoutElementBuilders.Layout);
+    method public androidx.wear.tiles.TimelineBuilders.TimelineEntry.Builder setValidity(androidx.wear.tiles.TimelineBuilders.TimeInterval);
+  }
+
+  public final class TypeBuilders {
+  }
+
+  public static final class TypeBuilders.BoolProp {
+    method public boolean getValue();
+  }
+
+  public static final class TypeBuilders.BoolProp.Builder {
+    ctor public TypeBuilders.BoolProp.Builder();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp build();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp.Builder setValue(boolean);
+  }
+
+  public static final class TypeBuilders.FloatProp {
+    method public float getValue();
+  }
+
+  public static final class TypeBuilders.FloatProp.Builder {
+    ctor public TypeBuilders.FloatProp.Builder();
+    method public androidx.wear.tiles.TypeBuilders.FloatProp build();
+    method public androidx.wear.tiles.TypeBuilders.FloatProp.Builder setValue(float);
+  }
+
+  public static final class TypeBuilders.Int32Prop {
+    method public int getValue();
+  }
+
+  public static final class TypeBuilders.Int32Prop.Builder {
+    ctor public TypeBuilders.Int32Prop.Builder();
+    method public androidx.wear.tiles.TypeBuilders.Int32Prop build();
+    method public androidx.wear.tiles.TypeBuilders.Int32Prop.Builder setValue(int);
+  }
+
+  public static final class TypeBuilders.StringProp {
+    method public String getValue();
+  }
+
+  public static final class TypeBuilders.StringProp.Builder {
+    ctor public TypeBuilders.StringProp.Builder();
+    method public androidx.wear.tiles.TypeBuilders.StringProp build();
+    method public androidx.wear.tiles.TypeBuilders.StringProp.Builder setValue(String);
+  }
+
+}
+
diff --git a/wear/tiles/tiles/api/public_plus_experimental_1.0.0-beta01.txt b/wear/tiles/tiles/api/public_plus_experimental_1.0.0-beta01.txt
new file mode 100644
index 0000000..499702d
--- /dev/null
+++ b/wear/tiles/tiles/api/public_plus_experimental_1.0.0-beta01.txt
@@ -0,0 +1,1085 @@
+// Signature format: 4.0
+package androidx.wear.tiles {
+
+  public final class ActionBuilders {
+    method public static androidx.wear.tiles.ActionBuilders.AndroidBooleanExtra booleanExtra(boolean);
+    method public static androidx.wear.tiles.ActionBuilders.AndroidDoubleExtra doubleExtra(double);
+    method public static androidx.wear.tiles.ActionBuilders.AndroidIntExtra intExtra(int);
+    method public static androidx.wear.tiles.ActionBuilders.AndroidLongExtra longExtra(long);
+    method public static androidx.wear.tiles.ActionBuilders.AndroidStringExtra stringExtra(String);
+  }
+
+  public static interface ActionBuilders.Action {
+  }
+
+  public static interface ActionBuilders.Action.Builder {
+    method public androidx.wear.tiles.ActionBuilders.Action build();
+  }
+
+  public static final class ActionBuilders.AndroidActivity {
+    method public String getClassName();
+    method public java.util.Map<java.lang.String!,androidx.wear.tiles.ActionBuilders.AndroidExtra!> getKeyToExtraMapping();
+    method public String getPackageName();
+  }
+
+  public static final class ActionBuilders.AndroidActivity.Builder {
+    ctor public ActionBuilders.AndroidActivity.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidActivity.Builder addKeyToExtraMapping(String, androidx.wear.tiles.ActionBuilders.AndroidExtra);
+    method public androidx.wear.tiles.ActionBuilders.AndroidActivity build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidActivity.Builder setClassName(String);
+    method public androidx.wear.tiles.ActionBuilders.AndroidActivity.Builder setPackageName(String);
+  }
+
+  public static final class ActionBuilders.AndroidBooleanExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method public boolean getValue();
+  }
+
+  public static final class ActionBuilders.AndroidBooleanExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor public ActionBuilders.AndroidBooleanExtra.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidBooleanExtra build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidBooleanExtra.Builder setValue(boolean);
+  }
+
+  public static final class ActionBuilders.AndroidDoubleExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method public double getValue();
+  }
+
+  public static final class ActionBuilders.AndroidDoubleExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor public ActionBuilders.AndroidDoubleExtra.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidDoubleExtra build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidDoubleExtra.Builder setValue(double);
+  }
+
+  public static interface ActionBuilders.AndroidExtra {
+  }
+
+  public static interface ActionBuilders.AndroidExtra.Builder {
+    method public androidx.wear.tiles.ActionBuilders.AndroidExtra build();
+  }
+
+  public static final class ActionBuilders.AndroidIntExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method public int getValue();
+  }
+
+  public static final class ActionBuilders.AndroidIntExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor public ActionBuilders.AndroidIntExtra.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidIntExtra build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidIntExtra.Builder setValue(int);
+  }
+
+  public static final class ActionBuilders.AndroidLongExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method public long getValue();
+  }
+
+  public static final class ActionBuilders.AndroidLongExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor public ActionBuilders.AndroidLongExtra.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidLongExtra build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidLongExtra.Builder setValue(long);
+  }
+
+  public static final class ActionBuilders.AndroidStringExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method public String getValue();
+  }
+
+  public static final class ActionBuilders.AndroidStringExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor public ActionBuilders.AndroidStringExtra.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidStringExtra build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidStringExtra.Builder setValue(String);
+  }
+
+  public static final class ActionBuilders.LaunchAction implements androidx.wear.tiles.ActionBuilders.Action {
+    method public androidx.wear.tiles.ActionBuilders.AndroidActivity? getAndroidActivity();
+  }
+
+  public static final class ActionBuilders.LaunchAction.Builder implements androidx.wear.tiles.ActionBuilders.Action.Builder {
+    ctor public ActionBuilders.LaunchAction.Builder();
+    method public androidx.wear.tiles.ActionBuilders.LaunchAction build();
+    method public androidx.wear.tiles.ActionBuilders.LaunchAction.Builder setAndroidActivity(androidx.wear.tiles.ActionBuilders.AndroidActivity);
+  }
+
+  public static final class ActionBuilders.LoadAction implements androidx.wear.tiles.ActionBuilders.Action {
+    method public androidx.wear.tiles.StateBuilders.State? getRequestState();
+  }
+
+  public static final class ActionBuilders.LoadAction.Builder implements androidx.wear.tiles.ActionBuilders.Action.Builder {
+    ctor public ActionBuilders.LoadAction.Builder();
+    method public androidx.wear.tiles.ActionBuilders.LoadAction build();
+    method public androidx.wear.tiles.ActionBuilders.LoadAction.Builder setRequestState(androidx.wear.tiles.StateBuilders.State);
+  }
+
+  public final class ColorBuilders {
+    method public static androidx.wear.tiles.ColorBuilders.ColorProp argb(@ColorInt int);
+  }
+
+  public static final class ColorBuilders.ColorProp {
+    method @ColorInt public int getArgb();
+  }
+
+  public static final class ColorBuilders.ColorProp.Builder {
+    ctor public ColorBuilders.ColorProp.Builder();
+    method public androidx.wear.tiles.ColorBuilders.ColorProp build();
+    method public androidx.wear.tiles.ColorBuilders.ColorProp.Builder setArgb(@ColorInt int);
+  }
+
+  public final class DeviceParametersBuilders {
+    field public static final int DEVICE_PLATFORM_UNDEFINED = 0; // 0x0
+    field public static final int DEVICE_PLATFORM_WEAR_OS = 1; // 0x1
+    field public static final int SCREEN_SHAPE_RECT = 2; // 0x2
+    field public static final int SCREEN_SHAPE_ROUND = 1; // 0x1
+    field public static final int SCREEN_SHAPE_UNDEFINED = 0; // 0x0
+  }
+
+  public static final class DeviceParametersBuilders.DeviceParameters {
+    method public int getDevicePlatform();
+    method @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) public float getScreenDensity();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenHeightDp();
+    method public int getScreenShape();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenWidthDp();
+  }
+
+  public static final class DeviceParametersBuilders.DeviceParameters.Builder {
+    ctor public DeviceParametersBuilders.DeviceParameters.Builder();
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters build();
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setDevicePlatform(int);
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenDensity(@FloatRange(from=0.0, fromInclusive=false, toInclusive=false) float);
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenHeightDp(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenShape(int);
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenWidthDp(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+  }
+
+  public final class DimensionBuilders {
+    method public static androidx.wear.tiles.DimensionBuilders.DegreesProp degrees(float);
+    method public static androidx.wear.tiles.DimensionBuilders.DpProp dp(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method public static androidx.wear.tiles.DimensionBuilders.EmProp em(int);
+    method public static androidx.wear.tiles.DimensionBuilders.ExpandedDimensionProp expand();
+    method public static androidx.wear.tiles.DimensionBuilders.SpProp sp(@Dimension(unit=androidx.annotation.Dimension.SP) float);
+    method public static androidx.wear.tiles.DimensionBuilders.WrappedDimensionProp wrap();
+  }
+
+  public static interface DimensionBuilders.ContainerDimension {
+  }
+
+  public static interface DimensionBuilders.ContainerDimension.Builder {
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension build();
+  }
+
+  public static final class DimensionBuilders.DegreesProp {
+    method public float getValue();
+  }
+
+  public static final class DimensionBuilders.DegreesProp.Builder {
+    ctor public DimensionBuilders.DegreesProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.DegreesProp build();
+    method public androidx.wear.tiles.DimensionBuilders.DegreesProp.Builder setValue(float);
+  }
+
+  public static final class DimensionBuilders.DpProp implements androidx.wear.tiles.DimensionBuilders.ContainerDimension androidx.wear.tiles.DimensionBuilders.ImageDimension androidx.wear.tiles.DimensionBuilders.SpacerDimension {
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
+  }
+
+  public static final class DimensionBuilders.DpProp.Builder implements androidx.wear.tiles.DimensionBuilders.ContainerDimension.Builder androidx.wear.tiles.DimensionBuilders.ImageDimension.Builder androidx.wear.tiles.DimensionBuilders.SpacerDimension.Builder {
+    ctor public DimensionBuilders.DpProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp build();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp.Builder setValue(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  public static final class DimensionBuilders.EmProp {
+    method public float getValue();
+  }
+
+  public static final class DimensionBuilders.EmProp.Builder {
+    ctor public DimensionBuilders.EmProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.EmProp build();
+    method public androidx.wear.tiles.DimensionBuilders.EmProp.Builder setValue(float);
+  }
+
+  public static final class DimensionBuilders.ExpandedDimensionProp implements androidx.wear.tiles.DimensionBuilders.ContainerDimension androidx.wear.tiles.DimensionBuilders.ImageDimension {
+  }
+
+  public static final class DimensionBuilders.ExpandedDimensionProp.Builder implements androidx.wear.tiles.DimensionBuilders.ContainerDimension.Builder androidx.wear.tiles.DimensionBuilders.ImageDimension.Builder {
+    ctor public DimensionBuilders.ExpandedDimensionProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.ExpandedDimensionProp build();
+  }
+
+  public static interface DimensionBuilders.ImageDimension {
+  }
+
+  public static interface DimensionBuilders.ImageDimension.Builder {
+    method public androidx.wear.tiles.DimensionBuilders.ImageDimension build();
+  }
+
+  public static final class DimensionBuilders.ProportionalDimensionProp implements androidx.wear.tiles.DimensionBuilders.ImageDimension {
+    method @IntRange(from=0) public int getAspectRatioHeight();
+    method @IntRange(from=0) public int getAspectRatioWidth();
+  }
+
+  public static final class DimensionBuilders.ProportionalDimensionProp.Builder implements androidx.wear.tiles.DimensionBuilders.ImageDimension.Builder {
+    ctor public DimensionBuilders.ProportionalDimensionProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.ProportionalDimensionProp build();
+    method public androidx.wear.tiles.DimensionBuilders.ProportionalDimensionProp.Builder setAspectRatioHeight(@IntRange(from=0) int);
+    method public androidx.wear.tiles.DimensionBuilders.ProportionalDimensionProp.Builder setAspectRatioWidth(@IntRange(from=0) int);
+  }
+
+  public static final class DimensionBuilders.SpProp {
+    method @Dimension(unit=androidx.annotation.Dimension.SP) public float getValue();
+  }
+
+  public static final class DimensionBuilders.SpProp.Builder {
+    ctor public DimensionBuilders.SpProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.SpProp build();
+    method public androidx.wear.tiles.DimensionBuilders.SpProp.Builder setValue(@Dimension(unit=androidx.annotation.Dimension.SP) float);
+  }
+
+  public static interface DimensionBuilders.SpacerDimension {
+  }
+
+  public static interface DimensionBuilders.SpacerDimension.Builder {
+    method public androidx.wear.tiles.DimensionBuilders.SpacerDimension build();
+  }
+
+  public static final class DimensionBuilders.WrappedDimensionProp implements androidx.wear.tiles.DimensionBuilders.ContainerDimension {
+  }
+
+  public static final class DimensionBuilders.WrappedDimensionProp.Builder implements androidx.wear.tiles.DimensionBuilders.ContainerDimension.Builder {
+    ctor public DimensionBuilders.WrappedDimensionProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.WrappedDimensionProp build();
+  }
+
+  public final class EventBuilders {
+  }
+
+  public static final class EventBuilders.TileAddEvent {
+  }
+
+  public static final class EventBuilders.TileAddEvent.Builder {
+    ctor public EventBuilders.TileAddEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileAddEvent build();
+  }
+
+  public static final class EventBuilders.TileEnterEvent {
+  }
+
+  public static final class EventBuilders.TileEnterEvent.Builder {
+    ctor public EventBuilders.TileEnterEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileEnterEvent build();
+  }
+
+  public static final class EventBuilders.TileLeaveEvent {
+  }
+
+  public static final class EventBuilders.TileLeaveEvent.Builder {
+    ctor public EventBuilders.TileLeaveEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileLeaveEvent build();
+  }
+
+  public static final class EventBuilders.TileRemoveEvent {
+  }
+
+  public static final class EventBuilders.TileRemoveEvent.Builder {
+    ctor public EventBuilders.TileRemoveEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileRemoveEvent build();
+  }
+
+  public final class LayoutElementBuilders {
+    field public static final int ARC_ANCHOR_CENTER = 2; // 0x2
+    field public static final int ARC_ANCHOR_END = 3; // 0x3
+    field public static final int ARC_ANCHOR_START = 1; // 0x1
+    field public static final int ARC_ANCHOR_UNDEFINED = 0; // 0x0
+    field public static final int CONTENT_SCALE_MODE_CROP = 2; // 0x2
+    field public static final int CONTENT_SCALE_MODE_FILL_BOUNDS = 3; // 0x3
+    field public static final int CONTENT_SCALE_MODE_FIT = 1; // 0x1
+    field public static final int CONTENT_SCALE_MODE_UNDEFINED = 0; // 0x0
+    field public static final int FONT_VARIANT_BODY = 2; // 0x2
+    field public static final int FONT_VARIANT_TITLE = 1; // 0x1
+    field public static final int FONT_VARIANT_UNDEFINED = 0; // 0x0
+    field public static final int FONT_WEIGHT_BOLD = 700; // 0x2bc
+    field @androidx.wear.tiles.TilesExperimental public static final int FONT_WEIGHT_MEDIUM = 500; // 0x1f4
+    field public static final int FONT_WEIGHT_NORMAL = 400; // 0x190
+    field public static final int FONT_WEIGHT_UNDEFINED = 0; // 0x0
+    field public static final int HORIZONTAL_ALIGN_CENTER = 2; // 0x2
+    field public static final int HORIZONTAL_ALIGN_END = 5; // 0x5
+    field public static final int HORIZONTAL_ALIGN_LEFT = 1; // 0x1
+    field public static final int HORIZONTAL_ALIGN_RIGHT = 3; // 0x3
+    field public static final int HORIZONTAL_ALIGN_START = 4; // 0x4
+    field public static final int HORIZONTAL_ALIGN_UNDEFINED = 0; // 0x0
+    field public static final int SPAN_VERTICAL_ALIGN_BOTTOM = 1; // 0x1
+    field public static final int SPAN_VERTICAL_ALIGN_TEXT_BASELINE = 2; // 0x2
+    field public static final int SPAN_VERTICAL_ALIGN_UNDEFINED = 0; // 0x0
+    field public static final int TEXT_ALIGN_CENTER = 2; // 0x2
+    field public static final int TEXT_ALIGN_END = 3; // 0x3
+    field public static final int TEXT_ALIGN_START = 1; // 0x1
+    field public static final int TEXT_ALIGN_UNDEFINED = 0; // 0x0
+    field public static final int TEXT_OVERFLOW_ELLIPSIZE_END = 2; // 0x2
+    field public static final int TEXT_OVERFLOW_TRUNCATE = 1; // 0x1
+    field public static final int TEXT_OVERFLOW_UNDEFINED = 0; // 0x0
+    field public static final int VERTICAL_ALIGN_BOTTOM = 3; // 0x3
+    field public static final int VERTICAL_ALIGN_CENTER = 2; // 0x2
+    field public static final int VERTICAL_ALIGN_TOP = 1; // 0x1
+    field public static final int VERTICAL_ALIGN_UNDEFINED = 0; // 0x0
+  }
+
+  public static final class LayoutElementBuilders.Arc implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.tiles.DimensionBuilders.DegreesProp? getAnchorAngle();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp? getAnchorType();
+    method public java.util.List<androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement!> getContents();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlign();
+  }
+
+  public static final class LayoutElementBuilders.Arc.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Arc.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setAnchorAngle(androidx.wear.tiles.DimensionBuilders.DegreesProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setAnchorType(androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setAnchorType(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setVerticalAlign(androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setVerticalAlign(int);
+  }
+
+  public static final class LayoutElementBuilders.ArcAdapter implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getContent();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp? getRotateContents();
+  }
+
+  public static final class LayoutElementBuilders.ArcAdapter.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor public LayoutElementBuilders.ArcAdapter.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter.Builder setContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter.Builder setRotateContents(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter.Builder setRotateContents(boolean);
+  }
+
+  public static final class LayoutElementBuilders.ArcAnchorTypeProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.ArcAnchorTypeProp.Builder {
+    ctor public LayoutElementBuilders.ArcAnchorTypeProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp.Builder setValue(int);
+  }
+
+  public static interface LayoutElementBuilders.ArcLayoutElement {
+  }
+
+  public static interface LayoutElementBuilders.ArcLayoutElement.Builder {
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement build();
+  }
+
+  public static final class LayoutElementBuilders.ArcLine implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.tiles.DimensionBuilders.DegreesProp? getLength();
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getThickness();
+  }
+
+  public static final class LayoutElementBuilders.ArcLine.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor public LayoutElementBuilders.ArcLine.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLine build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setLength(androidx.wear.tiles.DimensionBuilders.DegreesProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.ArcModifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setThickness(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class LayoutElementBuilders.ArcSpacer implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.tiles.DimensionBuilders.DegreesProp? getLength();
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getThickness();
+  }
+
+  public static final class LayoutElementBuilders.ArcSpacer.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor public LayoutElementBuilders.ArcSpacer.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer.Builder setLength(androidx.wear.tiles.DimensionBuilders.DegreesProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.ArcModifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer.Builder setThickness(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class LayoutElementBuilders.ArcText implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.tiles.TypeBuilders.StringProp? getText();
+  }
+
+  public static final class LayoutElementBuilders.ArcText.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor public LayoutElementBuilders.ArcText.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcText build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setFontStyle(androidx.wear.tiles.LayoutElementBuilders.FontStyle);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.ArcModifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setText(androidx.wear.tiles.TypeBuilders.StringProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setText(String);
+  }
+
+  public static final class LayoutElementBuilders.Box implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Box.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Box.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setHorizontalAlignment(androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setHorizontalAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setVerticalAlignment(androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setVerticalAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+  }
+
+  public static final class LayoutElementBuilders.ColorFilter {
+    method public androidx.wear.tiles.ColorBuilders.ColorProp? getTint();
+  }
+
+  public static final class LayoutElementBuilders.ColorFilter.Builder {
+    ctor public LayoutElementBuilders.ColorFilter.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ColorFilter build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ColorFilter.Builder setTint(androidx.wear.tiles.ColorBuilders.ColorProp);
+  }
+
+  public static final class LayoutElementBuilders.Column implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Column.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Column.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.tiles.LayoutElementBuilders.Column build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setHorizontalAlignment(androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setHorizontalAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+  }
+
+  public static final class LayoutElementBuilders.ContentScaleModeProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.ContentScaleModeProp.Builder {
+    ctor public LayoutElementBuilders.ContentScaleModeProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.FontStyle {
+    method public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp? getItalic();
+    method public androidx.wear.tiles.DimensionBuilders.EmProp? getLetterSpacing();
+    method public androidx.wear.tiles.DimensionBuilders.SpProp? getSize();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp? getUnderline();
+    method @androidx.wear.tiles.TilesExperimental public androidx.wear.tiles.LayoutElementBuilders.FontVariantProp? getVariant();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontWeightProp? getWeight();
+  }
+
+  public static final class LayoutElementBuilders.FontStyle.Builder {
+    ctor public LayoutElementBuilders.FontStyle.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle build();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setItalic(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setItalic(boolean);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setLetterSpacing(androidx.wear.tiles.DimensionBuilders.EmProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setSize(androidx.wear.tiles.DimensionBuilders.SpProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setUnderline(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setUnderline(boolean);
+    method @androidx.wear.tiles.TilesExperimental public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setVariant(androidx.wear.tiles.LayoutElementBuilders.FontVariantProp);
+    method @androidx.wear.tiles.TilesExperimental public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setVariant(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setWeight(androidx.wear.tiles.LayoutElementBuilders.FontWeightProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setWeight(int);
+  }
+
+  public static class LayoutElementBuilders.FontStyles {
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder body1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder body2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder button(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder caption1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder caption2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder display1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder display2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder display3(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder title1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder title2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder title3(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+  }
+
+  @androidx.wear.tiles.TilesExperimental public static final class LayoutElementBuilders.FontVariantProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.FontVariantProp.Builder {
+    ctor public LayoutElementBuilders.FontVariantProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontVariantProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontVariantProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.FontWeightProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.FontWeightProp.Builder {
+    ctor public LayoutElementBuilders.FontWeightProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontWeightProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontWeightProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.HorizontalAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.HorizontalAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.HorizontalAlignmentProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.Image implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp? getContentScaleMode();
+    method @androidx.wear.tiles.TilesExperimental public androidx.wear.tiles.LayoutElementBuilders.ColorFilter? getFilter();
+    method public androidx.wear.tiles.DimensionBuilders.ImageDimension? getHeight();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.TypeBuilders.StringProp? getResourceId();
+    method public androidx.wear.tiles.DimensionBuilders.ImageDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Image.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Image.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Image build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setContentScaleMode(androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setContentScaleMode(int);
+    method @androidx.wear.tiles.TilesExperimental public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setFilter(androidx.wear.tiles.LayoutElementBuilders.ColorFilter);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ImageDimension);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setResourceId(androidx.wear.tiles.TypeBuilders.StringProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setResourceId(String);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ImageDimension);
+  }
+
+  public static final class LayoutElementBuilders.Layout {
+    method public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getRoot();
+  }
+
+  public static final class LayoutElementBuilders.Layout.Builder {
+    ctor public LayoutElementBuilders.Layout.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Layout build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Layout.Builder setRoot(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+  }
+
+  public static interface LayoutElementBuilders.LayoutElement {
+  }
+
+  public static interface LayoutElementBuilders.LayoutElement.Builder {
+    method public androidx.wear.tiles.LayoutElementBuilders.LayoutElement build();
+  }
+
+  public static final class LayoutElementBuilders.Row implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Row.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Row.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.tiles.LayoutElementBuilders.Row build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setVerticalAlignment(androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setVerticalAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+  }
+
+  public static final class LayoutElementBuilders.Spacer implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.tiles.DimensionBuilders.SpacerDimension? getHeight();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.DimensionBuilders.SpacerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Spacer.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Spacer.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Spacer build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Spacer.Builder setHeight(androidx.wear.tiles.DimensionBuilders.SpacerDimension);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spacer.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spacer.Builder setWidth(androidx.wear.tiles.DimensionBuilders.SpacerDimension);
+  }
+
+  public static interface LayoutElementBuilders.Span {
+  }
+
+  public static interface LayoutElementBuilders.Span.Builder {
+    method public androidx.wear.tiles.LayoutElementBuilders.Span build();
+  }
+
+  public static final class LayoutElementBuilders.SpanImage implements androidx.wear.tiles.LayoutElementBuilders.Span {
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp? getAlignment();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getHeight();
+    method public androidx.wear.tiles.ModifiersBuilders.SpanModifiers? getModifiers();
+    method public androidx.wear.tiles.TypeBuilders.StringProp? getResourceId();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.SpanImage.Builder implements androidx.wear.tiles.LayoutElementBuilders.Span.Builder {
+    ctor public LayoutElementBuilders.SpanImage.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage build();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setAlignment(androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setHeight(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.SpanModifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setResourceId(androidx.wear.tiles.TypeBuilders.StringProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setResourceId(String);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setWidth(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class LayoutElementBuilders.SpanText implements androidx.wear.tiles.LayoutElementBuilders.Span {
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.tiles.ModifiersBuilders.SpanModifiers? getModifiers();
+    method public androidx.wear.tiles.TypeBuilders.StringProp? getText();
+  }
+
+  public static final class LayoutElementBuilders.SpanText.Builder implements androidx.wear.tiles.LayoutElementBuilders.Span.Builder {
+    ctor public LayoutElementBuilders.SpanText.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanText build();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setFontStyle(androidx.wear.tiles.LayoutElementBuilders.FontStyle);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.SpanModifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setText(androidx.wear.tiles.TypeBuilders.StringProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setText(String);
+  }
+
+  public static final class LayoutElementBuilders.SpanVerticalAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.SpanVerticalAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.SpanVerticalAlignmentProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.Spannable implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.tiles.DimensionBuilders.SpProp? getLineHeight();
+    method public androidx.wear.tiles.TypeBuilders.Int32Prop? getMaxLines();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp? getMultilineAlignment();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method public java.util.List<androidx.wear.tiles.LayoutElementBuilders.Span!> getSpans();
+  }
+
+  public static final class LayoutElementBuilders.Spannable.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Spannable.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder addSpan(androidx.wear.tiles.LayoutElementBuilders.Span);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setLineHeight(androidx.wear.tiles.DimensionBuilders.SpProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMaxLines(androidx.wear.tiles.TypeBuilders.Int32Prop);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMaxLines(@IntRange(from=1) int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMultilineAlignment(androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMultilineAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setOverflow(androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setOverflow(int);
+  }
+
+  public static final class LayoutElementBuilders.Text implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.tiles.DimensionBuilders.SpProp? getLineHeight();
+    method public androidx.wear.tiles.TypeBuilders.Int32Prop? getMaxLines();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp? getMultilineAlignment();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method public androidx.wear.tiles.TypeBuilders.StringProp? getText();
+  }
+
+  public static final class LayoutElementBuilders.Text.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Text.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Text build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setFontStyle(androidx.wear.tiles.LayoutElementBuilders.FontStyle);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setLineHeight(androidx.wear.tiles.DimensionBuilders.SpProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMaxLines(androidx.wear.tiles.TypeBuilders.Int32Prop);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMaxLines(@IntRange(from=1) int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMultilineAlignment(androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMultilineAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setOverflow(androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setOverflow(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setText(androidx.wear.tiles.TypeBuilders.StringProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setText(String);
+  }
+
+  public static final class LayoutElementBuilders.TextAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.TextAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.TextAlignmentProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.TextOverflowProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.TextOverflowProp.Builder {
+    ctor public LayoutElementBuilders.TextOverflowProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.VerticalAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.VerticalAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.VerticalAlignmentProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp.Builder setValue(int);
+  }
+
+  public final class ModifiersBuilders {
+  }
+
+  public static final class ModifiersBuilders.ArcModifiers {
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable? getClickable();
+    method public androidx.wear.tiles.ModifiersBuilders.Semantics? getSemantics();
+  }
+
+  public static final class ModifiersBuilders.ArcModifiers.Builder {
+    ctor public ModifiersBuilders.ArcModifiers.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers build();
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers.Builder setClickable(androidx.wear.tiles.ModifiersBuilders.Clickable);
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers.Builder setSemantics(androidx.wear.tiles.ModifiersBuilders.Semantics);
+  }
+
+  public static final class ModifiersBuilders.Background {
+    method public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.tiles.ModifiersBuilders.Corner? getCorner();
+  }
+
+  public static final class ModifiersBuilders.Background.Builder {
+    ctor public ModifiersBuilders.Background.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Background build();
+    method public androidx.wear.tiles.ModifiersBuilders.Background.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Background.Builder setCorner(androidx.wear.tiles.ModifiersBuilders.Corner);
+  }
+
+  public static final class ModifiersBuilders.Border {
+    method public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getWidth();
+  }
+
+  public static final class ModifiersBuilders.Border.Builder {
+    ctor public ModifiersBuilders.Border.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Border build();
+    method public androidx.wear.tiles.ModifiersBuilders.Border.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Border.Builder setWidth(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class ModifiersBuilders.Clickable {
+    method public String getId();
+    method public androidx.wear.tiles.ActionBuilders.Action? getOnClick();
+  }
+
+  public static final class ModifiersBuilders.Clickable.Builder {
+    ctor public ModifiersBuilders.Clickable.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable build();
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable.Builder setId(String);
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable.Builder setOnClick(androidx.wear.tiles.ActionBuilders.Action);
+  }
+
+  public static final class ModifiersBuilders.Corner {
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getRadius();
+  }
+
+  public static final class ModifiersBuilders.Corner.Builder {
+    ctor public ModifiersBuilders.Corner.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Corner build();
+    method public androidx.wear.tiles.ModifiersBuilders.Corner.Builder setRadius(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class ModifiersBuilders.Modifiers {
+    method public androidx.wear.tiles.ModifiersBuilders.Background? getBackground();
+    method public androidx.wear.tiles.ModifiersBuilders.Border? getBorder();
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable? getClickable();
+    method public androidx.wear.tiles.ModifiersBuilders.Padding? getPadding();
+    method public androidx.wear.tiles.ModifiersBuilders.Semantics? getSemantics();
+  }
+
+  public static final class ModifiersBuilders.Modifiers.Builder {
+    ctor public ModifiersBuilders.Modifiers.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers build();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setBackground(androidx.wear.tiles.ModifiersBuilders.Background);
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setBorder(androidx.wear.tiles.ModifiersBuilders.Border);
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setClickable(androidx.wear.tiles.ModifiersBuilders.Clickable);
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setPadding(androidx.wear.tiles.ModifiersBuilders.Padding);
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setSemantics(androidx.wear.tiles.ModifiersBuilders.Semantics);
+  }
+
+  public static final class ModifiersBuilders.Padding {
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getBottom();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getEnd();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp? getRtlAware();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getStart();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getTop();
+  }
+
+  public static final class ModifiersBuilders.Padding.Builder {
+    ctor public ModifiersBuilders.Padding.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Padding build();
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setAll(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setBottom(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setEnd(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setRtlAware(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setRtlAware(boolean);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setStart(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setTop(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class ModifiersBuilders.Semantics {
+    method public String getContentDescription();
+  }
+
+  public static final class ModifiersBuilders.Semantics.Builder {
+    ctor public ModifiersBuilders.Semantics.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Semantics build();
+    method public androidx.wear.tiles.ModifiersBuilders.Semantics.Builder setContentDescription(String);
+  }
+
+  public static final class ModifiersBuilders.SpanModifiers {
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable? getClickable();
+  }
+
+  public static final class ModifiersBuilders.SpanModifiers.Builder {
+    ctor public ModifiersBuilders.SpanModifiers.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.SpanModifiers build();
+    method public androidx.wear.tiles.ModifiersBuilders.SpanModifiers.Builder setClickable(androidx.wear.tiles.ModifiersBuilders.Clickable);
+  }
+
+  public final class RequestBuilders {
+  }
+
+  public static final class RequestBuilders.ResourcesRequest {
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters? getDeviceParameters();
+    method public java.util.List<java.lang.String!> getResourceIds();
+    method public String getVersion();
+  }
+
+  public static final class RequestBuilders.ResourcesRequest.Builder {
+    ctor public RequestBuilders.ResourcesRequest.Builder();
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder addResourceId(String);
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest build();
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setDeviceParameters(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setVersion(String);
+  }
+
+  public static final class RequestBuilders.TileRequest {
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters? getDeviceParameters();
+    method public androidx.wear.tiles.StateBuilders.State? getState();
+  }
+
+  public static final class RequestBuilders.TileRequest.Builder {
+    ctor public RequestBuilders.TileRequest.Builder();
+    method public androidx.wear.tiles.RequestBuilders.TileRequest build();
+    method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setDeviceParameters(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setState(androidx.wear.tiles.StateBuilders.State);
+  }
+
+  public final class ResourceBuilders {
+    field public static final int IMAGE_FORMAT_RGB_565 = 1; // 0x1
+    field public static final int IMAGE_FORMAT_UNDEFINED = 0; // 0x0
+  }
+
+  public static final class ResourceBuilders.AndroidImageResourceByResId {
+    method @DrawableRes public int getResourceId();
+  }
+
+  public static final class ResourceBuilders.AndroidImageResourceByResId.Builder {
+    ctor public ResourceBuilders.AndroidImageResourceByResId.Builder();
+    method public androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId build();
+    method public androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId.Builder setResourceId(@DrawableRes int);
+  }
+
+  public static final class ResourceBuilders.ImageResource {
+    method public androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId? getAndroidResourceByResId();
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource? getInlineResource();
+  }
+
+  public static final class ResourceBuilders.ImageResource.Builder {
+    ctor public ResourceBuilders.ImageResource.Builder();
+    method public androidx.wear.tiles.ResourceBuilders.ImageResource build();
+    method public androidx.wear.tiles.ResourceBuilders.ImageResource.Builder setAndroidResourceByResId(androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId);
+    method public androidx.wear.tiles.ResourceBuilders.ImageResource.Builder setInlineResource(androidx.wear.tiles.ResourceBuilders.InlineImageResource);
+  }
+
+  public static final class ResourceBuilders.InlineImageResource {
+    method public byte[] getData();
+    method public int getFormat();
+    method @Dimension(unit=androidx.annotation.Dimension.PX) public int getHeightPx();
+    method @Dimension(unit=androidx.annotation.Dimension.PX) public int getWidthPx();
+  }
+
+  public static final class ResourceBuilders.InlineImageResource.Builder {
+    ctor public ResourceBuilders.InlineImageResource.Builder();
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource build();
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setData(byte[]);
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setFormat(int);
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setHeightPx(@Dimension(unit=androidx.annotation.Dimension.PX) int);
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setWidthPx(@Dimension(unit=androidx.annotation.Dimension.PX) int);
+  }
+
+  public static final class ResourceBuilders.Resources {
+    method public java.util.Map<java.lang.String!,androidx.wear.tiles.ResourceBuilders.ImageResource!> getIdToImageMapping();
+    method public String getVersion();
+  }
+
+  public static final class ResourceBuilders.Resources.Builder {
+    ctor public ResourceBuilders.Resources.Builder();
+    method public androidx.wear.tiles.ResourceBuilders.Resources.Builder addIdToImageMapping(String, androidx.wear.tiles.ResourceBuilders.ImageResource);
+    method public androidx.wear.tiles.ResourceBuilders.Resources build();
+    method public androidx.wear.tiles.ResourceBuilders.Resources.Builder setVersion(String);
+  }
+
+  public final class StateBuilders {
+  }
+
+  public static final class StateBuilders.State {
+    method public String getLastClickableId();
+  }
+
+  public static final class StateBuilders.State.Builder {
+    ctor public StateBuilders.State.Builder();
+    method public androidx.wear.tiles.StateBuilders.State build();
+  }
+
+  public final class TileBuilders {
+  }
+
+  public static final class TileBuilders.Tile {
+    method public long getFreshnessIntervalMillis();
+    method public String getResourcesVersion();
+    method public androidx.wear.tiles.TimelineBuilders.Timeline? getTimeline();
+  }
+
+  public static final class TileBuilders.Tile.Builder {
+    ctor public TileBuilders.Tile.Builder();
+    method public androidx.wear.tiles.TileBuilders.Tile build();
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setFreshnessIntervalMillis(long);
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setResourcesVersion(String);
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setTimeline(androidx.wear.tiles.TimelineBuilders.Timeline);
+  }
+
+  public abstract class TileService extends android.app.Service {
+    ctor public TileService();
+    method public static androidx.wear.tiles.TileUpdateRequester getUpdater(android.content.Context);
+    method public android.os.IBinder? onBind(android.content.Intent);
+    method @MainThread protected abstract com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources!> onResourcesRequest(androidx.wear.tiles.RequestBuilders.ResourcesRequest);
+    method @MainThread protected void onTileAddEvent(androidx.wear.tiles.EventBuilders.TileAddEvent);
+    method @MainThread protected void onTileEnterEvent(androidx.wear.tiles.EventBuilders.TileEnterEvent);
+    method @MainThread protected void onTileLeaveEvent(androidx.wear.tiles.EventBuilders.TileLeaveEvent);
+    method @MainThread protected void onTileRemoveEvent(androidx.wear.tiles.EventBuilders.TileRemoveEvent);
+    method @MainThread protected abstract com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile!> onTileRequest(androidx.wear.tiles.RequestBuilders.TileRequest);
+    field public static final String ACTION_BIND_TILE_PROVIDER = "androidx.wear.tiles.action.BIND_TILE_PROVIDER";
+    field public static final String EXTRA_CLICKABLE_ID = "androidx.wear.tiles.extra.CLICKABLE_ID";
+    field public static final String METADATA_PREVIEW_KEY = "androidx.wear.tiles.PREVIEW";
+  }
+
+  public interface TileUpdateRequester {
+    method public void requestUpdate(Class<? extends androidx.wear.tiles.TileService>);
+  }
+
+  @RequiresOptIn(level=androidx.annotation.RequiresOptIn.Level.ERROR) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) public @interface TilesExperimental {
+  }
+
+  public final class TimelineBuilders {
+  }
+
+  public static final class TimelineBuilders.TimeInterval {
+    method public long getEndMillis();
+    method public long getStartMillis();
+  }
+
+  public static final class TimelineBuilders.TimeInterval.Builder {
+    ctor public TimelineBuilders.TimeInterval.Builder();
+    method public androidx.wear.tiles.TimelineBuilders.TimeInterval build();
+    method public androidx.wear.tiles.TimelineBuilders.TimeInterval.Builder setEndMillis(long);
+    method public androidx.wear.tiles.TimelineBuilders.TimeInterval.Builder setStartMillis(long);
+  }
+
+  public static final class TimelineBuilders.Timeline {
+    method public java.util.List<androidx.wear.tiles.TimelineBuilders.TimelineEntry!> getTimelineEntries();
+  }
+
+  public static final class TimelineBuilders.Timeline.Builder {
+    ctor public TimelineBuilders.Timeline.Builder();
+    method public androidx.wear.tiles.TimelineBuilders.Timeline.Builder addTimelineEntry(androidx.wear.tiles.TimelineBuilders.TimelineEntry);
+    method public androidx.wear.tiles.TimelineBuilders.Timeline build();
+  }
+
+  public static final class TimelineBuilders.TimelineEntry {
+    method public androidx.wear.tiles.LayoutElementBuilders.Layout? getLayout();
+    method public androidx.wear.tiles.TimelineBuilders.TimeInterval? getValidity();
+  }
+
+  public static final class TimelineBuilders.TimelineEntry.Builder {
+    ctor public TimelineBuilders.TimelineEntry.Builder();
+    method public androidx.wear.tiles.TimelineBuilders.TimelineEntry build();
+    method public androidx.wear.tiles.TimelineBuilders.TimelineEntry.Builder setLayout(androidx.wear.tiles.LayoutElementBuilders.Layout);
+    method public androidx.wear.tiles.TimelineBuilders.TimelineEntry.Builder setValidity(androidx.wear.tiles.TimelineBuilders.TimeInterval);
+  }
+
+  public final class TypeBuilders {
+  }
+
+  public static final class TypeBuilders.BoolProp {
+    method public boolean getValue();
+  }
+
+  public static final class TypeBuilders.BoolProp.Builder {
+    ctor public TypeBuilders.BoolProp.Builder();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp build();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp.Builder setValue(boolean);
+  }
+
+  public static final class TypeBuilders.FloatProp {
+    method public float getValue();
+  }
+
+  public static final class TypeBuilders.FloatProp.Builder {
+    ctor public TypeBuilders.FloatProp.Builder();
+    method public androidx.wear.tiles.TypeBuilders.FloatProp build();
+    method public androidx.wear.tiles.TypeBuilders.FloatProp.Builder setValue(float);
+  }
+
+  public static final class TypeBuilders.Int32Prop {
+    method public int getValue();
+  }
+
+  public static final class TypeBuilders.Int32Prop.Builder {
+    ctor public TypeBuilders.Int32Prop.Builder();
+    method public androidx.wear.tiles.TypeBuilders.Int32Prop build();
+    method public androidx.wear.tiles.TypeBuilders.Int32Prop.Builder setValue(int);
+  }
+
+  public static final class TypeBuilders.StringProp {
+    method public String getValue();
+  }
+
+  public static final class TypeBuilders.StringProp.Builder {
+    ctor public TypeBuilders.StringProp.Builder();
+    method public androidx.wear.tiles.TypeBuilders.StringProp build();
+    method public androidx.wear.tiles.TypeBuilders.StringProp.Builder setValue(String);
+  }
+
+}
+
diff --git a/wear/tiles/tiles/api/res-1.0.0-beta01.txt b/wear/tiles/tiles/api/res-1.0.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/wear/tiles/tiles/api/res-1.0.0-beta01.txt
diff --git a/wear/tiles/tiles/api/restricted_1.0.0-beta01.txt b/wear/tiles/tiles/api/restricted_1.0.0-beta01.txt
new file mode 100644
index 0000000..6c21e92
--- /dev/null
+++ b/wear/tiles/tiles/api/restricted_1.0.0-beta01.txt
@@ -0,0 +1,1066 @@
+// Signature format: 4.0
+package androidx.wear.tiles {
+
+  public final class ActionBuilders {
+    method public static androidx.wear.tiles.ActionBuilders.AndroidBooleanExtra booleanExtra(boolean);
+    method public static androidx.wear.tiles.ActionBuilders.AndroidDoubleExtra doubleExtra(double);
+    method public static androidx.wear.tiles.ActionBuilders.AndroidIntExtra intExtra(int);
+    method public static androidx.wear.tiles.ActionBuilders.AndroidLongExtra longExtra(long);
+    method public static androidx.wear.tiles.ActionBuilders.AndroidStringExtra stringExtra(String);
+  }
+
+  public static interface ActionBuilders.Action {
+  }
+
+  public static interface ActionBuilders.Action.Builder {
+    method public androidx.wear.tiles.ActionBuilders.Action build();
+  }
+
+  public static final class ActionBuilders.AndroidActivity {
+    method public String getClassName();
+    method public java.util.Map<java.lang.String!,androidx.wear.tiles.ActionBuilders.AndroidExtra!> getKeyToExtraMapping();
+    method public String getPackageName();
+  }
+
+  public static final class ActionBuilders.AndroidActivity.Builder {
+    ctor public ActionBuilders.AndroidActivity.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidActivity.Builder addKeyToExtraMapping(String, androidx.wear.tiles.ActionBuilders.AndroidExtra);
+    method public androidx.wear.tiles.ActionBuilders.AndroidActivity build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidActivity.Builder setClassName(String);
+    method public androidx.wear.tiles.ActionBuilders.AndroidActivity.Builder setPackageName(String);
+  }
+
+  public static final class ActionBuilders.AndroidBooleanExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method public boolean getValue();
+  }
+
+  public static final class ActionBuilders.AndroidBooleanExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor public ActionBuilders.AndroidBooleanExtra.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidBooleanExtra build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidBooleanExtra.Builder setValue(boolean);
+  }
+
+  public static final class ActionBuilders.AndroidDoubleExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method public double getValue();
+  }
+
+  public static final class ActionBuilders.AndroidDoubleExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor public ActionBuilders.AndroidDoubleExtra.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidDoubleExtra build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidDoubleExtra.Builder setValue(double);
+  }
+
+  public static interface ActionBuilders.AndroidExtra {
+  }
+
+  public static interface ActionBuilders.AndroidExtra.Builder {
+    method public androidx.wear.tiles.ActionBuilders.AndroidExtra build();
+  }
+
+  public static final class ActionBuilders.AndroidIntExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method public int getValue();
+  }
+
+  public static final class ActionBuilders.AndroidIntExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor public ActionBuilders.AndroidIntExtra.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidIntExtra build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidIntExtra.Builder setValue(int);
+  }
+
+  public static final class ActionBuilders.AndroidLongExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method public long getValue();
+  }
+
+  public static final class ActionBuilders.AndroidLongExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor public ActionBuilders.AndroidLongExtra.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidLongExtra build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidLongExtra.Builder setValue(long);
+  }
+
+  public static final class ActionBuilders.AndroidStringExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method public String getValue();
+  }
+
+  public static final class ActionBuilders.AndroidStringExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor public ActionBuilders.AndroidStringExtra.Builder();
+    method public androidx.wear.tiles.ActionBuilders.AndroidStringExtra build();
+    method public androidx.wear.tiles.ActionBuilders.AndroidStringExtra.Builder setValue(String);
+  }
+
+  public static final class ActionBuilders.LaunchAction implements androidx.wear.tiles.ActionBuilders.Action {
+    method public androidx.wear.tiles.ActionBuilders.AndroidActivity? getAndroidActivity();
+  }
+
+  public static final class ActionBuilders.LaunchAction.Builder implements androidx.wear.tiles.ActionBuilders.Action.Builder {
+    ctor public ActionBuilders.LaunchAction.Builder();
+    method public androidx.wear.tiles.ActionBuilders.LaunchAction build();
+    method public androidx.wear.tiles.ActionBuilders.LaunchAction.Builder setAndroidActivity(androidx.wear.tiles.ActionBuilders.AndroidActivity);
+  }
+
+  public static final class ActionBuilders.LoadAction implements androidx.wear.tiles.ActionBuilders.Action {
+    method public androidx.wear.tiles.StateBuilders.State? getRequestState();
+  }
+
+  public static final class ActionBuilders.LoadAction.Builder implements androidx.wear.tiles.ActionBuilders.Action.Builder {
+    ctor public ActionBuilders.LoadAction.Builder();
+    method public androidx.wear.tiles.ActionBuilders.LoadAction build();
+    method public androidx.wear.tiles.ActionBuilders.LoadAction.Builder setRequestState(androidx.wear.tiles.StateBuilders.State);
+  }
+
+  public final class ColorBuilders {
+    method public static androidx.wear.tiles.ColorBuilders.ColorProp argb(@ColorInt int);
+  }
+
+  public static final class ColorBuilders.ColorProp {
+    method @ColorInt public int getArgb();
+  }
+
+  public static final class ColorBuilders.ColorProp.Builder {
+    ctor public ColorBuilders.ColorProp.Builder();
+    method public androidx.wear.tiles.ColorBuilders.ColorProp build();
+    method public androidx.wear.tiles.ColorBuilders.ColorProp.Builder setArgb(@ColorInt int);
+  }
+
+  public final class DeviceParametersBuilders {
+    field public static final int DEVICE_PLATFORM_UNDEFINED = 0; // 0x0
+    field public static final int DEVICE_PLATFORM_WEAR_OS = 1; // 0x1
+    field public static final int SCREEN_SHAPE_RECT = 2; // 0x2
+    field public static final int SCREEN_SHAPE_ROUND = 1; // 0x1
+    field public static final int SCREEN_SHAPE_UNDEFINED = 0; // 0x0
+  }
+
+  public static final class DeviceParametersBuilders.DeviceParameters {
+    method public int getDevicePlatform();
+    method @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) public float getScreenDensity();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenHeightDp();
+    method public int getScreenShape();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenWidthDp();
+  }
+
+  public static final class DeviceParametersBuilders.DeviceParameters.Builder {
+    ctor public DeviceParametersBuilders.DeviceParameters.Builder();
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters build();
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setDevicePlatform(int);
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenDensity(@FloatRange(from=0.0, fromInclusive=false, toInclusive=false) float);
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenHeightDp(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenShape(int);
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenWidthDp(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+  }
+
+  public final class DimensionBuilders {
+    method public static androidx.wear.tiles.DimensionBuilders.DegreesProp degrees(float);
+    method public static androidx.wear.tiles.DimensionBuilders.DpProp dp(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method public static androidx.wear.tiles.DimensionBuilders.EmProp em(int);
+    method public static androidx.wear.tiles.DimensionBuilders.ExpandedDimensionProp expand();
+    method public static androidx.wear.tiles.DimensionBuilders.SpProp sp(@Dimension(unit=androidx.annotation.Dimension.SP) float);
+    method public static androidx.wear.tiles.DimensionBuilders.WrappedDimensionProp wrap();
+  }
+
+  public static interface DimensionBuilders.ContainerDimension {
+  }
+
+  public static interface DimensionBuilders.ContainerDimension.Builder {
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension build();
+  }
+
+  public static final class DimensionBuilders.DegreesProp {
+    method public float getValue();
+  }
+
+  public static final class DimensionBuilders.DegreesProp.Builder {
+    ctor public DimensionBuilders.DegreesProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.DegreesProp build();
+    method public androidx.wear.tiles.DimensionBuilders.DegreesProp.Builder setValue(float);
+  }
+
+  public static final class DimensionBuilders.DpProp implements androidx.wear.tiles.DimensionBuilders.ContainerDimension androidx.wear.tiles.DimensionBuilders.ImageDimension androidx.wear.tiles.DimensionBuilders.SpacerDimension {
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
+  }
+
+  public static final class DimensionBuilders.DpProp.Builder implements androidx.wear.tiles.DimensionBuilders.ContainerDimension.Builder androidx.wear.tiles.DimensionBuilders.ImageDimension.Builder androidx.wear.tiles.DimensionBuilders.SpacerDimension.Builder {
+    ctor public DimensionBuilders.DpProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp build();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp.Builder setValue(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  public static final class DimensionBuilders.EmProp {
+    method public float getValue();
+  }
+
+  public static final class DimensionBuilders.EmProp.Builder {
+    ctor public DimensionBuilders.EmProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.EmProp build();
+    method public androidx.wear.tiles.DimensionBuilders.EmProp.Builder setValue(float);
+  }
+
+  public static final class DimensionBuilders.ExpandedDimensionProp implements androidx.wear.tiles.DimensionBuilders.ContainerDimension androidx.wear.tiles.DimensionBuilders.ImageDimension {
+  }
+
+  public static final class DimensionBuilders.ExpandedDimensionProp.Builder implements androidx.wear.tiles.DimensionBuilders.ContainerDimension.Builder androidx.wear.tiles.DimensionBuilders.ImageDimension.Builder {
+    ctor public DimensionBuilders.ExpandedDimensionProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.ExpandedDimensionProp build();
+  }
+
+  public static interface DimensionBuilders.ImageDimension {
+  }
+
+  public static interface DimensionBuilders.ImageDimension.Builder {
+    method public androidx.wear.tiles.DimensionBuilders.ImageDimension build();
+  }
+
+  public static final class DimensionBuilders.ProportionalDimensionProp implements androidx.wear.tiles.DimensionBuilders.ImageDimension {
+    method @IntRange(from=0) public int getAspectRatioHeight();
+    method @IntRange(from=0) public int getAspectRatioWidth();
+  }
+
+  public static final class DimensionBuilders.ProportionalDimensionProp.Builder implements androidx.wear.tiles.DimensionBuilders.ImageDimension.Builder {
+    ctor public DimensionBuilders.ProportionalDimensionProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.ProportionalDimensionProp build();
+    method public androidx.wear.tiles.DimensionBuilders.ProportionalDimensionProp.Builder setAspectRatioHeight(@IntRange(from=0) int);
+    method public androidx.wear.tiles.DimensionBuilders.ProportionalDimensionProp.Builder setAspectRatioWidth(@IntRange(from=0) int);
+  }
+
+  public static final class DimensionBuilders.SpProp {
+    method @Dimension(unit=androidx.annotation.Dimension.SP) public float getValue();
+  }
+
+  public static final class DimensionBuilders.SpProp.Builder {
+    ctor public DimensionBuilders.SpProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.SpProp build();
+    method public androidx.wear.tiles.DimensionBuilders.SpProp.Builder setValue(@Dimension(unit=androidx.annotation.Dimension.SP) float);
+  }
+
+  public static interface DimensionBuilders.SpacerDimension {
+  }
+
+  public static interface DimensionBuilders.SpacerDimension.Builder {
+    method public androidx.wear.tiles.DimensionBuilders.SpacerDimension build();
+  }
+
+  public static final class DimensionBuilders.WrappedDimensionProp implements androidx.wear.tiles.DimensionBuilders.ContainerDimension {
+  }
+
+  public static final class DimensionBuilders.WrappedDimensionProp.Builder implements androidx.wear.tiles.DimensionBuilders.ContainerDimension.Builder {
+    ctor public DimensionBuilders.WrappedDimensionProp.Builder();
+    method public androidx.wear.tiles.DimensionBuilders.WrappedDimensionProp build();
+  }
+
+  public final class EventBuilders {
+  }
+
+  public static final class EventBuilders.TileAddEvent {
+  }
+
+  public static final class EventBuilders.TileAddEvent.Builder {
+    ctor public EventBuilders.TileAddEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileAddEvent build();
+  }
+
+  public static final class EventBuilders.TileEnterEvent {
+  }
+
+  public static final class EventBuilders.TileEnterEvent.Builder {
+    ctor public EventBuilders.TileEnterEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileEnterEvent build();
+  }
+
+  public static final class EventBuilders.TileLeaveEvent {
+  }
+
+  public static final class EventBuilders.TileLeaveEvent.Builder {
+    ctor public EventBuilders.TileLeaveEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileLeaveEvent build();
+  }
+
+  public static final class EventBuilders.TileRemoveEvent {
+  }
+
+  public static final class EventBuilders.TileRemoveEvent.Builder {
+    ctor public EventBuilders.TileRemoveEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileRemoveEvent build();
+  }
+
+  public final class LayoutElementBuilders {
+    field public static final int ARC_ANCHOR_CENTER = 2; // 0x2
+    field public static final int ARC_ANCHOR_END = 3; // 0x3
+    field public static final int ARC_ANCHOR_START = 1; // 0x1
+    field public static final int ARC_ANCHOR_UNDEFINED = 0; // 0x0
+    field public static final int CONTENT_SCALE_MODE_CROP = 2; // 0x2
+    field public static final int CONTENT_SCALE_MODE_FILL_BOUNDS = 3; // 0x3
+    field public static final int CONTENT_SCALE_MODE_FIT = 1; // 0x1
+    field public static final int CONTENT_SCALE_MODE_UNDEFINED = 0; // 0x0
+    field public static final int FONT_VARIANT_BODY = 2; // 0x2
+    field public static final int FONT_VARIANT_TITLE = 1; // 0x1
+    field public static final int FONT_VARIANT_UNDEFINED = 0; // 0x0
+    field public static final int FONT_WEIGHT_BOLD = 700; // 0x2bc
+    field public static final int FONT_WEIGHT_NORMAL = 400; // 0x190
+    field public static final int FONT_WEIGHT_UNDEFINED = 0; // 0x0
+    field public static final int HORIZONTAL_ALIGN_CENTER = 2; // 0x2
+    field public static final int HORIZONTAL_ALIGN_END = 5; // 0x5
+    field public static final int HORIZONTAL_ALIGN_LEFT = 1; // 0x1
+    field public static final int HORIZONTAL_ALIGN_RIGHT = 3; // 0x3
+    field public static final int HORIZONTAL_ALIGN_START = 4; // 0x4
+    field public static final int HORIZONTAL_ALIGN_UNDEFINED = 0; // 0x0
+    field public static final int SPAN_VERTICAL_ALIGN_BOTTOM = 1; // 0x1
+    field public static final int SPAN_VERTICAL_ALIGN_TEXT_BASELINE = 2; // 0x2
+    field public static final int SPAN_VERTICAL_ALIGN_UNDEFINED = 0; // 0x0
+    field public static final int TEXT_ALIGN_CENTER = 2; // 0x2
+    field public static final int TEXT_ALIGN_END = 3; // 0x3
+    field public static final int TEXT_ALIGN_START = 1; // 0x1
+    field public static final int TEXT_ALIGN_UNDEFINED = 0; // 0x0
+    field public static final int TEXT_OVERFLOW_ELLIPSIZE_END = 2; // 0x2
+    field public static final int TEXT_OVERFLOW_TRUNCATE = 1; // 0x1
+    field public static final int TEXT_OVERFLOW_UNDEFINED = 0; // 0x0
+    field public static final int VERTICAL_ALIGN_BOTTOM = 3; // 0x3
+    field public static final int VERTICAL_ALIGN_CENTER = 2; // 0x2
+    field public static final int VERTICAL_ALIGN_TOP = 1; // 0x1
+    field public static final int VERTICAL_ALIGN_UNDEFINED = 0; // 0x0
+  }
+
+  public static final class LayoutElementBuilders.Arc implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.tiles.DimensionBuilders.DegreesProp? getAnchorAngle();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp? getAnchorType();
+    method public java.util.List<androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement!> getContents();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlign();
+  }
+
+  public static final class LayoutElementBuilders.Arc.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Arc.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setAnchorAngle(androidx.wear.tiles.DimensionBuilders.DegreesProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setAnchorType(androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setAnchorType(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setVerticalAlign(androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setVerticalAlign(int);
+  }
+
+  public static final class LayoutElementBuilders.ArcAdapter implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getContent();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp? getRotateContents();
+  }
+
+  public static final class LayoutElementBuilders.ArcAdapter.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor public LayoutElementBuilders.ArcAdapter.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter.Builder setContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter.Builder setRotateContents(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter.Builder setRotateContents(boolean);
+  }
+
+  public static final class LayoutElementBuilders.ArcAnchorTypeProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.ArcAnchorTypeProp.Builder {
+    ctor public LayoutElementBuilders.ArcAnchorTypeProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp.Builder setValue(int);
+  }
+
+  public static interface LayoutElementBuilders.ArcLayoutElement {
+  }
+
+  public static interface LayoutElementBuilders.ArcLayoutElement.Builder {
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement build();
+  }
+
+  public static final class LayoutElementBuilders.ArcLine implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.tiles.DimensionBuilders.DegreesProp? getLength();
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getThickness();
+  }
+
+  public static final class LayoutElementBuilders.ArcLine.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor public LayoutElementBuilders.ArcLine.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLine build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setLength(androidx.wear.tiles.DimensionBuilders.DegreesProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.ArcModifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setThickness(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class LayoutElementBuilders.ArcSpacer implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.tiles.DimensionBuilders.DegreesProp? getLength();
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getThickness();
+  }
+
+  public static final class LayoutElementBuilders.ArcSpacer.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor public LayoutElementBuilders.ArcSpacer.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer.Builder setLength(androidx.wear.tiles.DimensionBuilders.DegreesProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.ArcModifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer.Builder setThickness(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class LayoutElementBuilders.ArcText implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.tiles.TypeBuilders.StringProp? getText();
+  }
+
+  public static final class LayoutElementBuilders.ArcText.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor public LayoutElementBuilders.ArcText.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcText build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setFontStyle(androidx.wear.tiles.LayoutElementBuilders.FontStyle);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.ArcModifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setText(androidx.wear.tiles.TypeBuilders.StringProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setText(String);
+  }
+
+  public static final class LayoutElementBuilders.Box implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Box.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Box.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setHorizontalAlignment(androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setHorizontalAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setVerticalAlignment(androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setVerticalAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+  }
+
+  public static final class LayoutElementBuilders.ColorFilter {
+    method public androidx.wear.tiles.ColorBuilders.ColorProp? getTint();
+  }
+
+  public static final class LayoutElementBuilders.ColorFilter.Builder {
+    ctor public LayoutElementBuilders.ColorFilter.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ColorFilter build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ColorFilter.Builder setTint(androidx.wear.tiles.ColorBuilders.ColorProp);
+  }
+
+  public static final class LayoutElementBuilders.Column implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Column.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Column.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.tiles.LayoutElementBuilders.Column build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setHorizontalAlignment(androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setHorizontalAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+  }
+
+  public static final class LayoutElementBuilders.ContentScaleModeProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.ContentScaleModeProp.Builder {
+    ctor public LayoutElementBuilders.ContentScaleModeProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.FontStyle {
+    method public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp? getItalic();
+    method public androidx.wear.tiles.DimensionBuilders.EmProp? getLetterSpacing();
+    method public androidx.wear.tiles.DimensionBuilders.SpProp? getSize();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp? getUnderline();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontWeightProp? getWeight();
+  }
+
+  public static final class LayoutElementBuilders.FontStyle.Builder {
+    ctor public LayoutElementBuilders.FontStyle.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle build();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setItalic(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setItalic(boolean);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setLetterSpacing(androidx.wear.tiles.DimensionBuilders.EmProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setSize(androidx.wear.tiles.DimensionBuilders.SpProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setUnderline(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setUnderline(boolean);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setWeight(androidx.wear.tiles.LayoutElementBuilders.FontWeightProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setWeight(int);
+  }
+
+  public static class LayoutElementBuilders.FontStyles {
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder body1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder body2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder button(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder caption1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder caption2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder display1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder display2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder display3(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder title1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder title2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder title3(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+  }
+
+  public static final class LayoutElementBuilders.FontWeightProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.FontWeightProp.Builder {
+    ctor public LayoutElementBuilders.FontWeightProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontWeightProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.FontWeightProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.HorizontalAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.HorizontalAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.HorizontalAlignmentProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.Image implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp? getContentScaleMode();
+    method public androidx.wear.tiles.DimensionBuilders.ImageDimension? getHeight();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.TypeBuilders.StringProp? getResourceId();
+    method public androidx.wear.tiles.DimensionBuilders.ImageDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Image.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Image.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Image build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setContentScaleMode(androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setContentScaleMode(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ImageDimension);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setResourceId(androidx.wear.tiles.TypeBuilders.StringProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setResourceId(String);
+    method public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ImageDimension);
+  }
+
+  public static final class LayoutElementBuilders.Layout {
+    method public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getRoot();
+  }
+
+  public static final class LayoutElementBuilders.Layout.Builder {
+    ctor public LayoutElementBuilders.Layout.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Layout build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Layout.Builder setRoot(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+  }
+
+  public static interface LayoutElementBuilders.LayoutElement {
+  }
+
+  public static interface LayoutElementBuilders.LayoutElement.Builder {
+    method public androidx.wear.tiles.LayoutElementBuilders.LayoutElement build();
+  }
+
+  public static final class LayoutElementBuilders.Row implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Row.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Row.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.tiles.LayoutElementBuilders.Row build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setVerticalAlignment(androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setVerticalAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+  }
+
+  public static final class LayoutElementBuilders.Spacer implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.tiles.DimensionBuilders.SpacerDimension? getHeight();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.DimensionBuilders.SpacerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Spacer.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Spacer.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Spacer build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Spacer.Builder setHeight(androidx.wear.tiles.DimensionBuilders.SpacerDimension);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spacer.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spacer.Builder setWidth(androidx.wear.tiles.DimensionBuilders.SpacerDimension);
+  }
+
+  public static interface LayoutElementBuilders.Span {
+  }
+
+  public static interface LayoutElementBuilders.Span.Builder {
+    method public androidx.wear.tiles.LayoutElementBuilders.Span build();
+  }
+
+  public static final class LayoutElementBuilders.SpanImage implements androidx.wear.tiles.LayoutElementBuilders.Span {
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp? getAlignment();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getHeight();
+    method public androidx.wear.tiles.ModifiersBuilders.SpanModifiers? getModifiers();
+    method public androidx.wear.tiles.TypeBuilders.StringProp? getResourceId();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.SpanImage.Builder implements androidx.wear.tiles.LayoutElementBuilders.Span.Builder {
+    ctor public LayoutElementBuilders.SpanImage.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage build();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setAlignment(androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setHeight(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.SpanModifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setResourceId(androidx.wear.tiles.TypeBuilders.StringProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setResourceId(String);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setWidth(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class LayoutElementBuilders.SpanText implements androidx.wear.tiles.LayoutElementBuilders.Span {
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.tiles.ModifiersBuilders.SpanModifiers? getModifiers();
+    method public androidx.wear.tiles.TypeBuilders.StringProp? getText();
+  }
+
+  public static final class LayoutElementBuilders.SpanText.Builder implements androidx.wear.tiles.LayoutElementBuilders.Span.Builder {
+    ctor public LayoutElementBuilders.SpanText.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanText build();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setFontStyle(androidx.wear.tiles.LayoutElementBuilders.FontStyle);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.SpanModifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setText(androidx.wear.tiles.TypeBuilders.StringProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setText(String);
+  }
+
+  public static final class LayoutElementBuilders.SpanVerticalAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.SpanVerticalAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.SpanVerticalAlignmentProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.Spannable implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.tiles.DimensionBuilders.SpProp? getLineHeight();
+    method public androidx.wear.tiles.TypeBuilders.Int32Prop? getMaxLines();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp? getMultilineAlignment();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method public java.util.List<androidx.wear.tiles.LayoutElementBuilders.Span!> getSpans();
+  }
+
+  public static final class LayoutElementBuilders.Spannable.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Spannable.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder addSpan(androidx.wear.tiles.LayoutElementBuilders.Span);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setLineHeight(androidx.wear.tiles.DimensionBuilders.SpProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMaxLines(androidx.wear.tiles.TypeBuilders.Int32Prop);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMaxLines(@IntRange(from=1) int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMultilineAlignment(androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMultilineAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setOverflow(androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setOverflow(int);
+  }
+
+  public static final class LayoutElementBuilders.Text implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.tiles.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.tiles.DimensionBuilders.SpProp? getLineHeight();
+    method public androidx.wear.tiles.TypeBuilders.Int32Prop? getMaxLines();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp? getMultilineAlignment();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method public androidx.wear.tiles.TypeBuilders.StringProp? getText();
+  }
+
+  public static final class LayoutElementBuilders.Text.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor public LayoutElementBuilders.Text.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.Text build();
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setFontStyle(androidx.wear.tiles.LayoutElementBuilders.FontStyle);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setLineHeight(androidx.wear.tiles.DimensionBuilders.SpProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMaxLines(androidx.wear.tiles.TypeBuilders.Int32Prop);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMaxLines(@IntRange(from=1) int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMultilineAlignment(androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMultilineAlignment(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setOverflow(androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setOverflow(int);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setText(androidx.wear.tiles.TypeBuilders.StringProp);
+    method public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setText(String);
+  }
+
+  public static final class LayoutElementBuilders.TextAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.TextAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.TextAlignmentProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.TextOverflowProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.TextOverflowProp.Builder {
+    ctor public LayoutElementBuilders.TextOverflowProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.VerticalAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.VerticalAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.VerticalAlignmentProp.Builder();
+    method public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp build();
+    method public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp.Builder setValue(int);
+  }
+
+  public final class ModifiersBuilders {
+  }
+
+  public static final class ModifiersBuilders.ArcModifiers {
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable? getClickable();
+    method public androidx.wear.tiles.ModifiersBuilders.Semantics? getSemantics();
+  }
+
+  public static final class ModifiersBuilders.ArcModifiers.Builder {
+    ctor public ModifiersBuilders.ArcModifiers.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers build();
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers.Builder setClickable(androidx.wear.tiles.ModifiersBuilders.Clickable);
+    method public androidx.wear.tiles.ModifiersBuilders.ArcModifiers.Builder setSemantics(androidx.wear.tiles.ModifiersBuilders.Semantics);
+  }
+
+  public static final class ModifiersBuilders.Background {
+    method public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.tiles.ModifiersBuilders.Corner? getCorner();
+  }
+
+  public static final class ModifiersBuilders.Background.Builder {
+    ctor public ModifiersBuilders.Background.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Background build();
+    method public androidx.wear.tiles.ModifiersBuilders.Background.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Background.Builder setCorner(androidx.wear.tiles.ModifiersBuilders.Corner);
+  }
+
+  public static final class ModifiersBuilders.Border {
+    method public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getWidth();
+  }
+
+  public static final class ModifiersBuilders.Border.Builder {
+    ctor public ModifiersBuilders.Border.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Border build();
+    method public androidx.wear.tiles.ModifiersBuilders.Border.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Border.Builder setWidth(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class ModifiersBuilders.Clickable {
+    method public String getId();
+    method public androidx.wear.tiles.ActionBuilders.Action? getOnClick();
+  }
+
+  public static final class ModifiersBuilders.Clickable.Builder {
+    ctor public ModifiersBuilders.Clickable.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable build();
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable.Builder setId(String);
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable.Builder setOnClick(androidx.wear.tiles.ActionBuilders.Action);
+  }
+
+  public static final class ModifiersBuilders.Corner {
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getRadius();
+  }
+
+  public static final class ModifiersBuilders.Corner.Builder {
+    ctor public ModifiersBuilders.Corner.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Corner build();
+    method public androidx.wear.tiles.ModifiersBuilders.Corner.Builder setRadius(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class ModifiersBuilders.Modifiers {
+    method public androidx.wear.tiles.ModifiersBuilders.Background? getBackground();
+    method public androidx.wear.tiles.ModifiersBuilders.Border? getBorder();
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable? getClickable();
+    method public androidx.wear.tiles.ModifiersBuilders.Padding? getPadding();
+    method public androidx.wear.tiles.ModifiersBuilders.Semantics? getSemantics();
+  }
+
+  public static final class ModifiersBuilders.Modifiers.Builder {
+    ctor public ModifiersBuilders.Modifiers.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers build();
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setBackground(androidx.wear.tiles.ModifiersBuilders.Background);
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setBorder(androidx.wear.tiles.ModifiersBuilders.Border);
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setClickable(androidx.wear.tiles.ModifiersBuilders.Clickable);
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setPadding(androidx.wear.tiles.ModifiersBuilders.Padding);
+    method public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setSemantics(androidx.wear.tiles.ModifiersBuilders.Semantics);
+  }
+
+  public static final class ModifiersBuilders.Padding {
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getBottom();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getEnd();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp? getRtlAware();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getStart();
+    method public androidx.wear.tiles.DimensionBuilders.DpProp? getTop();
+  }
+
+  public static final class ModifiersBuilders.Padding.Builder {
+    ctor public ModifiersBuilders.Padding.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Padding build();
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setAll(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setBottom(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setEnd(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setRtlAware(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setRtlAware(boolean);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setStart(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setTop(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  public static final class ModifiersBuilders.Semantics {
+    method public String getContentDescription();
+  }
+
+  public static final class ModifiersBuilders.Semantics.Builder {
+    ctor public ModifiersBuilders.Semantics.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.Semantics build();
+    method public androidx.wear.tiles.ModifiersBuilders.Semantics.Builder setContentDescription(String);
+  }
+
+  public static final class ModifiersBuilders.SpanModifiers {
+    method public androidx.wear.tiles.ModifiersBuilders.Clickable? getClickable();
+  }
+
+  public static final class ModifiersBuilders.SpanModifiers.Builder {
+    ctor public ModifiersBuilders.SpanModifiers.Builder();
+    method public androidx.wear.tiles.ModifiersBuilders.SpanModifiers build();
+    method public androidx.wear.tiles.ModifiersBuilders.SpanModifiers.Builder setClickable(androidx.wear.tiles.ModifiersBuilders.Clickable);
+  }
+
+  public final class RequestBuilders {
+  }
+
+  public static final class RequestBuilders.ResourcesRequest {
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters? getDeviceParameters();
+    method public java.util.List<java.lang.String!> getResourceIds();
+    method public String getVersion();
+  }
+
+  public static final class RequestBuilders.ResourcesRequest.Builder {
+    ctor public RequestBuilders.ResourcesRequest.Builder();
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder addResourceId(String);
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest build();
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setDeviceParameters(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setVersion(String);
+  }
+
+  public static final class RequestBuilders.TileRequest {
+    method public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters? getDeviceParameters();
+    method public androidx.wear.tiles.StateBuilders.State? getState();
+  }
+
+  public static final class RequestBuilders.TileRequest.Builder {
+    ctor public RequestBuilders.TileRequest.Builder();
+    method public androidx.wear.tiles.RequestBuilders.TileRequest build();
+    method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setDeviceParameters(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setState(androidx.wear.tiles.StateBuilders.State);
+  }
+
+  public final class ResourceBuilders {
+    field public static final int IMAGE_FORMAT_RGB_565 = 1; // 0x1
+    field public static final int IMAGE_FORMAT_UNDEFINED = 0; // 0x0
+  }
+
+  public static final class ResourceBuilders.AndroidImageResourceByResId {
+    method @DrawableRes public int getResourceId();
+  }
+
+  public static final class ResourceBuilders.AndroidImageResourceByResId.Builder {
+    ctor public ResourceBuilders.AndroidImageResourceByResId.Builder();
+    method public androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId build();
+    method public androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId.Builder setResourceId(@DrawableRes int);
+  }
+
+  public static final class ResourceBuilders.ImageResource {
+    method public androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId? getAndroidResourceByResId();
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource? getInlineResource();
+  }
+
+  public static final class ResourceBuilders.ImageResource.Builder {
+    ctor public ResourceBuilders.ImageResource.Builder();
+    method public androidx.wear.tiles.ResourceBuilders.ImageResource build();
+    method public androidx.wear.tiles.ResourceBuilders.ImageResource.Builder setAndroidResourceByResId(androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId);
+    method public androidx.wear.tiles.ResourceBuilders.ImageResource.Builder setInlineResource(androidx.wear.tiles.ResourceBuilders.InlineImageResource);
+  }
+
+  public static final class ResourceBuilders.InlineImageResource {
+    method public byte[] getData();
+    method public int getFormat();
+    method @Dimension(unit=androidx.annotation.Dimension.PX) public int getHeightPx();
+    method @Dimension(unit=androidx.annotation.Dimension.PX) public int getWidthPx();
+  }
+
+  public static final class ResourceBuilders.InlineImageResource.Builder {
+    ctor public ResourceBuilders.InlineImageResource.Builder();
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource build();
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setData(byte[]);
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setFormat(int);
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setHeightPx(@Dimension(unit=androidx.annotation.Dimension.PX) int);
+    method public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setWidthPx(@Dimension(unit=androidx.annotation.Dimension.PX) int);
+  }
+
+  public static final class ResourceBuilders.Resources {
+    method public java.util.Map<java.lang.String!,androidx.wear.tiles.ResourceBuilders.ImageResource!> getIdToImageMapping();
+    method public String getVersion();
+  }
+
+  public static final class ResourceBuilders.Resources.Builder {
+    ctor public ResourceBuilders.Resources.Builder();
+    method public androidx.wear.tiles.ResourceBuilders.Resources.Builder addIdToImageMapping(String, androidx.wear.tiles.ResourceBuilders.ImageResource);
+    method public androidx.wear.tiles.ResourceBuilders.Resources build();
+    method public androidx.wear.tiles.ResourceBuilders.Resources.Builder setVersion(String);
+  }
+
+  public final class StateBuilders {
+  }
+
+  public static final class StateBuilders.State {
+    method public String getLastClickableId();
+  }
+
+  public static final class StateBuilders.State.Builder {
+    ctor public StateBuilders.State.Builder();
+    method public androidx.wear.tiles.StateBuilders.State build();
+  }
+
+  public final class TileBuilders {
+  }
+
+  public static final class TileBuilders.Tile {
+    method public long getFreshnessIntervalMillis();
+    method public String getResourcesVersion();
+    method public androidx.wear.tiles.TimelineBuilders.Timeline? getTimeline();
+  }
+
+  public static final class TileBuilders.Tile.Builder {
+    ctor public TileBuilders.Tile.Builder();
+    method public androidx.wear.tiles.TileBuilders.Tile build();
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setFreshnessIntervalMillis(long);
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setResourcesVersion(String);
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setTimeline(androidx.wear.tiles.TimelineBuilders.Timeline);
+  }
+
+  public abstract class TileService extends android.app.Service {
+    ctor public TileService();
+    method public static androidx.wear.tiles.TileUpdateRequester getUpdater(android.content.Context);
+    method public android.os.IBinder? onBind(android.content.Intent);
+    method @MainThread protected abstract com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources!> onResourcesRequest(androidx.wear.tiles.RequestBuilders.ResourcesRequest);
+    method @MainThread protected void onTileAddEvent(androidx.wear.tiles.EventBuilders.TileAddEvent);
+    method @MainThread protected void onTileEnterEvent(androidx.wear.tiles.EventBuilders.TileEnterEvent);
+    method @MainThread protected void onTileLeaveEvent(androidx.wear.tiles.EventBuilders.TileLeaveEvent);
+    method @MainThread protected void onTileRemoveEvent(androidx.wear.tiles.EventBuilders.TileRemoveEvent);
+    method @MainThread protected abstract com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile!> onTileRequest(androidx.wear.tiles.RequestBuilders.TileRequest);
+    field public static final String ACTION_BIND_TILE_PROVIDER = "androidx.wear.tiles.action.BIND_TILE_PROVIDER";
+    field public static final String EXTRA_CLICKABLE_ID = "androidx.wear.tiles.extra.CLICKABLE_ID";
+    field public static final String METADATA_PREVIEW_KEY = "androidx.wear.tiles.PREVIEW";
+  }
+
+  public interface TileUpdateRequester {
+    method public void requestUpdate(Class<? extends androidx.wear.tiles.TileService>);
+  }
+
+  public final class TimelineBuilders {
+  }
+
+  public static final class TimelineBuilders.TimeInterval {
+    method public long getEndMillis();
+    method public long getStartMillis();
+  }
+
+  public static final class TimelineBuilders.TimeInterval.Builder {
+    ctor public TimelineBuilders.TimeInterval.Builder();
+    method public androidx.wear.tiles.TimelineBuilders.TimeInterval build();
+    method public androidx.wear.tiles.TimelineBuilders.TimeInterval.Builder setEndMillis(long);
+    method public androidx.wear.tiles.TimelineBuilders.TimeInterval.Builder setStartMillis(long);
+  }
+
+  public static final class TimelineBuilders.Timeline {
+    method public java.util.List<androidx.wear.tiles.TimelineBuilders.TimelineEntry!> getTimelineEntries();
+  }
+
+  public static final class TimelineBuilders.Timeline.Builder {
+    ctor public TimelineBuilders.Timeline.Builder();
+    method public androidx.wear.tiles.TimelineBuilders.Timeline.Builder addTimelineEntry(androidx.wear.tiles.TimelineBuilders.TimelineEntry);
+    method public androidx.wear.tiles.TimelineBuilders.Timeline build();
+  }
+
+  public static final class TimelineBuilders.TimelineEntry {
+    method public androidx.wear.tiles.LayoutElementBuilders.Layout? getLayout();
+    method public androidx.wear.tiles.TimelineBuilders.TimeInterval? getValidity();
+  }
+
+  public static final class TimelineBuilders.TimelineEntry.Builder {
+    ctor public TimelineBuilders.TimelineEntry.Builder();
+    method public androidx.wear.tiles.TimelineBuilders.TimelineEntry build();
+    method public androidx.wear.tiles.TimelineBuilders.TimelineEntry.Builder setLayout(androidx.wear.tiles.LayoutElementBuilders.Layout);
+    method public androidx.wear.tiles.TimelineBuilders.TimelineEntry.Builder setValidity(androidx.wear.tiles.TimelineBuilders.TimeInterval);
+  }
+
+  public final class TypeBuilders {
+  }
+
+  public static final class TypeBuilders.BoolProp {
+    method public boolean getValue();
+  }
+
+  public static final class TypeBuilders.BoolProp.Builder {
+    ctor public TypeBuilders.BoolProp.Builder();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp build();
+    method public androidx.wear.tiles.TypeBuilders.BoolProp.Builder setValue(boolean);
+  }
+
+  public static final class TypeBuilders.FloatProp {
+    method public float getValue();
+  }
+
+  public static final class TypeBuilders.FloatProp.Builder {
+    ctor public TypeBuilders.FloatProp.Builder();
+    method public androidx.wear.tiles.TypeBuilders.FloatProp build();
+    method public androidx.wear.tiles.TypeBuilders.FloatProp.Builder setValue(float);
+  }
+
+  public static final class TypeBuilders.Int32Prop {
+    method public int getValue();
+  }
+
+  public static final class TypeBuilders.Int32Prop.Builder {
+    ctor public TypeBuilders.Int32Prop.Builder();
+    method public androidx.wear.tiles.TypeBuilders.Int32Prop build();
+    method public androidx.wear.tiles.TypeBuilders.Int32Prop.Builder setValue(int);
+  }
+
+  public static final class TypeBuilders.StringProp {
+    method public String getValue();
+  }
+
+  public static final class TypeBuilders.StringProp.Builder {
+    ctor public TypeBuilders.StringProp.Builder();
+    method public androidx.wear.tiles.TypeBuilders.StringProp build();
+    method public androidx.wear.tiles.TypeBuilders.StringProp.Builder setValue(String);
+  }
+
+}
+
diff --git a/wear/wear/src/androidTest/AndroidManifest.xml b/wear/wear/src/androidTest/AndroidManifest.xml
index f6f09b4..44a598f2 100644
--- a/wear/wear/src/androidTest/AndroidManifest.xml
+++ b/wear/wear/src/androidTest/AndroidManifest.xml
@@ -31,7 +31,7 @@
         <activity
             android:name="androidx.wear.widget.DismissibleFrameLayoutTestActivity"
             android:exported="false"
-            android:theme="@style/AppThemeNoSwipe">
+            android:theme="@android:style/Theme.DeviceDefault.Light">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
diff --git a/wear/wear/src/androidTest/res/values/styles.xml b/wear/wear/src/androidTest/res/values/styles.xml
index 302db80..f659efa3 100644
--- a/wear/wear/src/androidTest/res/values/styles.xml
+++ b/wear/wear/src/androidTest/res/values/styles.xml
@@ -16,9 +16,6 @@
   -->
 
 <resources>
-    <style name="AppThemeNoSwipe" parent="@android:style/Theme.DeviceDefault.Light">
-        <item name="android:windowSwipeToDismiss">false</item>
-    </style>
     <style name="DrawerLayoutStyle" parent="@android:style/Theme.DeviceDefault">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">match_parent</item>