Merge "PAGING = "3.3.0-beta01" Test: ./gradlew buildOnServer" into androidx-main
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
index dea0fb1..effbaf6 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
@@ -70,6 +70,7 @@
 import javax.inject.Inject
 import org.gradle.api.DefaultTask
 import org.gradle.api.GradleException
+import org.gradle.api.JavaVersion
 import org.gradle.api.JavaVersion.VERSION_11
 import org.gradle.api.JavaVersion.VERSION_17
 import org.gradle.api.JavaVersion.VERSION_1_8
@@ -97,13 +98,13 @@
 import org.gradle.build.event.BuildEventsListenerRegistry
 import org.gradle.jvm.tasks.Jar
 import org.gradle.kotlin.dsl.KotlinClosure1
-import org.gradle.kotlin.dsl.configure
 import org.gradle.kotlin.dsl.create
 import org.gradle.kotlin.dsl.dependencies
 import org.gradle.kotlin.dsl.extra
 import org.gradle.kotlin.dsl.findByType
 import org.gradle.kotlin.dsl.getByType
 import org.gradle.kotlin.dsl.withModule
+import org.gradle.kotlin.dsl.withType
 import org.gradle.plugin.devel.plugins.JavaGradlePluginPlugin
 import org.gradle.plugin.devel.tasks.ValidatePlugins
 import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
@@ -112,8 +113,11 @@
 import org.jetbrains.kotlin.gradle.plugin.KotlinBasePluginWrapper
 import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginWrapper
 import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
+import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
 
 /**
  * A plugin which enables all of the Gradle customizations for AndroidX. This plugin reacts to other
@@ -443,18 +447,57 @@
         project.configureKtfmt()
 
         project.afterEvaluate {
-            project.tasks.withType(KotlinCompile::class.java).configureEach { task ->
-                if (androidXExtension.type == LibraryType.COMPILER_PLUGIN) {
-                    task.kotlinOptions.jvmTarget = "11"
-                } else if (
-                    androidXExtension.type.compilationTarget == CompilationTarget.HOST &&
-                    androidXExtension.type != LibraryType.ANNOTATION_PROCESSOR_UTILS
-                ) {
-                    task.kotlinOptions.jvmTarget = "17"
-                } else {
-                    task.kotlinOptions.jvmTarget = "1.8"
+            val targetsAndroid =
+                project.plugins.hasPlugin(LibraryPlugin::class.java) ||
+                    project.plugins.hasPlugin(AppPlugin::class.java) ||
+                    project.plugins.hasPlugin(TestPlugin::class.java) ||
+                    @Suppress("UnstableApiUsage")
+                    project.plugins.hasPlugin(KotlinMultiplatformAndroidPlugin::class.java)
+            val defaultJavaTargetVersion =
+                getDefaultTargetJavaVersion(androidXExtension.type).toString()
+            if (plugin is KotlinMultiplatformPluginWrapper) {
+                project.extensions.getByType<KotlinMultiplatformExtension>().apply {
+                    targets.withType<KotlinAndroidTarget> {
+                        compilations.configureEach {
+                            it.kotlinOptions.jvmTarget = defaultJavaTargetVersion
+                        }
+                    }
+                    targets.withType<KotlinJvmTarget> {
+                        val defaultJavaTargetVersionForNonAndroidTargets =
+                            getDefaultTargetJavaVersion(
+                                libraryType = androidXExtension.type,
+                                projectName = project.name,
+                                targetName = name
+                            ).toString()
+                        compilations.configureEach {
+                            it.compileJavaTaskProvider?.configure { javaCompile ->
+                                javaCompile.targetCompatibility =
+                                    defaultJavaTargetVersionForNonAndroidTargets
+                                javaCompile.sourceCompatibility =
+                                    defaultJavaTargetVersionForNonAndroidTargets
+                            }
+                            it.kotlinOptions {
+                                jvmTarget = defaultJavaTargetVersionForNonAndroidTargets
+                                // Set jdk-release version for non-Android KMP targets
+                                freeCompilerArgs += listOf(
+                                    "-Xjdk-release=$defaultJavaTargetVersionForNonAndroidTargets",
+                                )
+                            }
+                        }
+                    }
                 }
-
+            } else {
+                project.tasks.withType(KotlinJvmCompile::class.java).configureEach { task ->
+                    task.kotlinOptions.jvmTarget = defaultJavaTargetVersion
+                    if (!targetsAndroid) {
+                        // Set jdk-release version for non-Android JVM projects
+                        task.kotlinOptions.freeCompilerArgs += listOf(
+                            "-Xjdk-release=$defaultJavaTargetVersion",
+                        )
+                    }
+                }
+            }
+            project.tasks.withType(KotlinCompile::class.java).configureEach { task ->
                 val kotlinCompilerArgs =
                     mutableListOf(
                         "-Xskip-metadata-version-check",
@@ -483,13 +526,9 @@
                 logScriptSources(task, project)
             }
 
-            val isAndroidProject =
-                project.plugins.hasPlugin(LibraryPlugin::class.java) ||
-                    project.plugins.hasPlugin(AppPlugin::class.java) ||
-                    project.plugins.hasPlugin(KotlinMultiplatformAndroidPlugin::class.java)
             // Explicit API mode is broken for Android projects
             // https://youtrack.jetbrains.com/issue/KT-37652
-            if (androidXExtension.shouldEnforceKotlinStrictApiMode() && !isAndroidProject) {
+            if (androidXExtension.shouldEnforceKotlinStrictApiMode() && !targetsAndroid) {
                 project.tasks.withType(KotlinCompile::class.java).configureEach { task ->
                     // Workaround for https://youtrack.jetbrains.com/issue/KT-37652
                     if (task.name.endsWith("TestKotlin")) return@configureEach
@@ -853,30 +892,30 @@
         SdkResourceGenerator.generateForHostTest(project)
     }
 
+    private fun getDefaultTargetJavaVersion(
+        libraryType: LibraryType,
+        projectName: String? = null,
+        targetName: String? = null
+    ): JavaVersion {
+        return when {
+            projectName != null && projectName.contains("desktop") -> VERSION_17
+            targetName != null && targetName == "desktop" -> VERSION_17
+            libraryType == LibraryType.COMPILER_PLUGIN -> VERSION_11
+            libraryType.compilationTarget == CompilationTarget.HOST -> VERSION_17
+            else -> VERSION_1_8
+        }
+    }
+
     private fun configureWithJavaPlugin(project: Project, androidXExtension: AndroidXExtension) {
         project.configureErrorProneForJava()
 
         // Force Java 1.8 source- and target-compatibility for all Java libraries.
         val javaExtension = project.extensions.getByType<JavaPluginExtension>()
         project.afterEvaluate {
-            if (androidXExtension.type == LibraryType.COMPILER_PLUGIN) {
-                javaExtension.apply {
-                    sourceCompatibility = VERSION_11
-                    targetCompatibility = VERSION_11
-                }
-            } else if (
-                androidXExtension.type.compilationTarget == CompilationTarget.HOST &&
-                androidXExtension.type != LibraryType.ANNOTATION_PROCESSOR_UTILS
-            ) {
-                javaExtension.apply {
-                    sourceCompatibility = VERSION_17
-                    targetCompatibility = VERSION_17
-                }
-            } else {
-                javaExtension.apply {
-                    sourceCompatibility = VERSION_1_8
-                    targetCompatibility = VERSION_1_8
-                }
+            javaExtension.apply {
+                val defaultTargetJavaVersion = getDefaultTargetJavaVersion(androidXExtension.type)
+                sourceCompatibility = defaultTargetJavaVersion
+                targetCompatibility = defaultTargetJavaVersion
             }
             if (!project.plugins.hasPlugin(KotlinBasePluginWrapper::class.java)) {
                 project.configureSourceJarForJava()
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXRootImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXRootImplPlugin.kt
index 2f91d77..1e8f047 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXRootImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXRootImplPlugin.kt
@@ -27,6 +27,7 @@
 import androidx.build.playground.VerifyPlaygroundGradleConfigurationTask
 import androidx.build.studio.StudioTask.Companion.registerStudioTask
 import androidx.build.testConfiguration.registerOwnersServiceTasks
+import androidx.build.uptodatedness.TaskUpToDateValidator
 import androidx.build.uptodatedness.cacheEvenIfNoOutputs
 import com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
 import java.io.File
@@ -40,9 +41,11 @@
 import org.gradle.api.tasks.Copy
 import org.gradle.api.tasks.bundling.Zip
 import org.gradle.api.tasks.bundling.ZipEntryCompression
+import org.gradle.build.event.BuildEventsListenerRegistry
 import org.gradle.kotlin.dsl.extra
 
 abstract class AndroidXRootImplPlugin : Plugin<Project> {
+    @get:javax.inject.Inject abstract val registry: BuildEventsListenerRegistry
     override fun apply(project: Project) {
         if (!project.isRoot) {
             throw Exception("This plugin should only be applied to root project")
@@ -173,6 +176,8 @@
 
         project.zipComposeCompilerMetrics()
         project.zipComposeCompilerReports()
+
+        TaskUpToDateValidator.setup(project, registry)
     }
 
     private fun Project.setDependencyVersions() {
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/java/JavaCompileInputs.kt b/buildSrc/private/src/main/kotlin/androidx/build/java/JavaCompileInputs.kt
index fb1f4d0..3cb7bbf 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/java/JavaCompileInputs.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/java/JavaCompileInputs.kt
@@ -19,9 +19,10 @@
 import androidx.build.getAndroidJar
 import androidx.build.multiplatformExtension
 import com.android.build.api.dsl.KotlinMultiplatformAndroidTarget
-import java.io.File
 import org.gradle.api.Project
+import org.gradle.api.file.ConfigurableFileCollection
 import org.gradle.api.file.FileCollection
+import org.gradle.api.provider.Provider
 import org.gradle.api.tasks.SourceSet
 import org.gradle.kotlin.dsl.get
 import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
@@ -34,7 +35,10 @@
     // Source files to process
     val sourcePaths: FileCollection,
 
-    // Dependencies of [sourcePaths].
+    // Source files from the KMP common module of this project
+    val commonModuleSourcePaths: FileCollection,
+
+    // Dependencies (compiled classes) of [sourcePaths].
     val dependencyClasspath: FileCollection,
 
     // Android's boot classpath.
@@ -49,10 +53,16 @@
             bootClasspath: FileCollection
         ): JavaCompileInputs {
             val sourceCollection = getSourceCollection(variant, project)
+            val commonModuleSourceCollection = getCommonModuleSourceCollection(variant, project)
 
             val dependencyClasspath = variant.getCompileClasspath(null).filter { it.exists() }
 
-            return JavaCompileInputs(sourceCollection, dependencyClasspath, bootClasspath)
+            return JavaCompileInputs(
+                sourcePaths = sourceCollection,
+                commonModuleSourcePaths = commonModuleSourceCollection,
+                dependencyClasspath = dependencyClasspath,
+                bootClasspath = bootClasspath
+            )
         }
 
         /**
@@ -70,17 +80,17 @@
                         .trimIndent()
                 }
             val jvmTarget = kmpExtension.targets.requirePlatform(KotlinPlatformType.jvm)
-            val sourceCollection =
-                project.files(
-                    project.provider {
-                        jvmTarget.sourceFiles(
-                            compilationName = KotlinCompilation.MAIN_COMPILATION_NAME
-                        )
-                    }
-                )
+            val jvmCompilation = jvmTarget.findCompilation(
+                compilationName = KotlinCompilation.MAIN_COMPILATION_NAME
+            )
+
+            val sourceCollection = project.sourceFiles(jvmCompilation)
+
+            val commonModuleSourcePaths = project.commonModuleSourcePaths(jvmCompilation)
 
             return JavaCompileInputs(
                 sourcePaths = sourceCollection,
+                commonModuleSourcePaths = commonModuleSourcePaths,
                 dependencyClasspath =
                     jvmTarget.compilations[KotlinCompilation.MAIN_COMPILATION_NAME]
                         .compileDependencyFiles,
@@ -105,17 +115,14 @@
             val target = kmpExtension.targets.withType(
                 KotlinMultiplatformAndroidTarget::class.java
             ).single()
-            val sourceCollection =
-                project.files(
-                    project.provider {
-                        target.sourceFiles(
-                            compilationName = KotlinCompilation.MAIN_COMPILATION_NAME
-                        )
-                    }
-                )
+            val compilation = target.findCompilation(KotlinCompilation.MAIN_COMPILATION_NAME)
+            val sourceCollection = project.sourceFiles(compilation)
+
+            val commonModuleSourcePaths = project.commonModuleSourcePaths(compilation)
 
             return JavaCompileInputs(
                 sourcePaths = sourceCollection,
+                commonModuleSourcePaths = commonModuleSourcePaths,
                 dependencyClasspath =
                 target.compilations[KotlinCompilation.MAIN_COMPILATION_NAME]
                     .compileDependencyFiles,
@@ -128,7 +135,12 @@
             val sourcePaths: FileCollection =
                 project.files(project.provider { sourceSet.allSource.srcDirs })
             val dependencyClasspath = sourceSet.compileClasspath
-            return JavaCompileInputs(sourcePaths, dependencyClasspath, project.getAndroidJar())
+            return JavaCompileInputs(
+                sourcePaths = sourcePaths,
+                commonModuleSourcePaths = project.files(),
+                dependencyClasspath = dependencyClasspath,
+                bootClasspath = project.getAndroidJar()
+            )
         }
 
         @Suppress("DEPRECATION") // BaseVariant, SourceKind
@@ -137,30 +149,57 @@
             project: Project
         ): FileCollection {
             // If the project has the kotlin-multiplatform plugin, we want to return a combined
+            // collection of all the source files inside '*main' source sets. i.e., given a module
+            // with a common and Android source set, this will look inside commonMain and
+            // androidMain.
+            val taskDependencies = mutableListOf<Any>(variant.javaCompileProvider)
+            val sourceCollection: ConfigurableFileCollection =
+                project.multiplatformExtension?.let { kmpExtension ->
+                    project.sourceFiles(
+                        kmpExtension.targets
+                            .requirePlatform(KotlinPlatformType.androidJvm)
+                            .findCompilation(compilationName = variant.name)
+                    )
+                }
+                    ?: project.files(
+                           project.provider {
+                               variant
+                                   .getSourceFolders(com.android.build.gradle.api.SourceKind.JAVA)
+                                   .map { folder ->
+                                       for (builtBy in folder.builtBy) {
+                                           taskDependencies.add(builtBy)
+                                       }
+                                       folder.dir
+                                   }
+                           }
+                       )
+
+            for (dep in taskDependencies) {
+                sourceCollection.builtBy(dep)
+            }
+            return sourceCollection
+        }
+
+        @Suppress("DEPRECATION") // BaseVariant, SourceKind
+        private fun getCommonModuleSourceCollection(
+            variant: com.android.build.gradle.api.BaseVariant,
+            project: Project
+        ): FileCollection {
+            // If the project has the kotlin-multiplatform plugin, we want to return a combined
             // collection of all the source files inside '*main' source sets. I.e, given a module
             // with a common and Android source set, this will look inside commonMain and
             // androidMain.
             val taskDependencies = mutableListOf<Any>(variant.javaCompileProvider)
-            val sourceFiles =
+            val sourceCollection: ConfigurableFileCollection =
                 project.multiplatformExtension?.let { kmpExtension ->
-                    project.provider {
+                    project.commonModuleSourcePaths(
                         kmpExtension.targets
                             .requirePlatform(KotlinPlatformType.androidJvm)
-                            .sourceFiles(compilationName = variant.name)
-                    }
+                            .findCompilation(compilationName = variant.name)
+                    )
                 }
-                    ?: project.provider {
-                        variant
-                            .getSourceFolders(com.android.build.gradle.api.SourceKind.JAVA)
-                            .map { folder ->
-                                for (builtBy in folder.builtBy) {
-                                    taskDependencies.add(builtBy)
-                                }
-                                folder.dir
-                            }
-                    }
+                    ?: project.files()
 
-            val sourceCollection = project.files(sourceFiles)
             for (dep in taskDependencies) {
                 sourceCollection.builtBy(dep)
             }
@@ -174,26 +213,58 @@
          * @param compilationName The name of the compilation. A target might have separate
          *   compilations (e.g. main vs test for jvm or debug vs release for Android)
          */
-        private fun KotlinTarget.sourceFiles(compilationName: String): List<File> {
-            val selectedCompilation =
-                checkNotNull(compilations.findByName(compilationName)) {
+        private fun KotlinTarget.findCompilation(
+            compilationName: String
+        ): Provider<KotlinCompilation<*>> {
+            return project.provider {
+                val selectedCompilation =
+                    checkNotNull(compilations.findByName(compilationName)) {
+                        """
+                    Cannot find $compilationName compilation configuration of $name in
+                    ${project.parent}.
+                    Available compilations: ${compilations.joinToString(", ") { it.name }}
                     """
-                Cannot find $compilationName compilation configuration of $name in
-                ${project.parent}.
-                Available compilations: ${compilations.joinToString(", ") { it.name }}
-                """
-                        .trimIndent()
-                }
-            return selectedCompilation.allKotlinSourceSets
-                .flatMap { it.kotlin.sourceDirectories }
-                .also {
-                    require(it.isNotEmpty()) {
-                        """
-                        Didn't find any source sets for $selectedCompilation in ${project.path}.
-                        """
                             .trimIndent()
                     }
+                selectedCompilation
+            }
+        }
+
+        private fun Project.sourceFiles(
+            kotlinCompilation: Provider<KotlinCompilation<*>>
+        ): ConfigurableFileCollection {
+            return project.files(
+                    project.provider {
+                        kotlinCompilation.get().allKotlinSourceSets
+                            .flatMap {
+                                it.kotlin.sourceDirectories
+                            }
+                            .also {
+                                require(it.isNotEmpty()) {
+                                    """
+                                    Didn't find any source sets for $kotlinCompilation in ${project.path}.
+                                    """
+                                        .trimIndent()
+                                }
+                            }
+                    }
+                )
+        }
+
+        private fun Project.commonModuleSourcePaths(
+            kotlinCompilation: Provider<KotlinCompilation<*>>
+        ): ConfigurableFileCollection {
+            return project.files(
+                project.provider {
+                    kotlinCompilation.get().allKotlinSourceSets
+                        .filter {
+                            it.dependsOn.isEmpty()
+                        }
+                        .flatMap {
+                            it.kotlin.sourceDirectories.files
+                        }
                 }
+            )
         }
 
         /**
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/GenerateApiTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/GenerateApiTask.kt
index f432494..7c59f11 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/GenerateApiTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/GenerateApiTask.kt
@@ -92,7 +92,12 @@
         check(bootClasspath.files.isNotEmpty()) { "Android boot classpath not set." }
         check(sourcePaths.files.isNotEmpty()) { "Source paths not set." }
 
-        val inputs = JavaCompileInputs(sourcePaths, dependencyClasspath, bootClasspath)
+        val inputs = JavaCompileInputs(
+            sourcePaths = sourcePaths,
+            commonModuleSourcePaths = commonModuleSourcePaths,
+            dependencyClasspath = dependencyClasspath,
+            bootClasspath = bootClasspath
+        )
 
         val levelsArgs =
             getGenerateApiLevelsArgs(
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt
index 3f18ee4..1bd89e1 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt
@@ -250,9 +250,7 @@
     generateApiConfigs.forEach { (generateApiMode, apiLintMode) ->
         generateApi(
             metalavaClasspath,
-            files.bootClasspath,
-            files.dependencyClasspath,
-            files.sourcePaths.files,
+            files,
             apiLocation,
             generateApiMode,
             apiLintMode,
@@ -271,9 +269,7 @@
  */
 private fun generateApi(
     metalavaClasspath: FileCollection,
-    bootClasspath: FileCollection,
-    dependencyClasspath: FileCollection,
-    sourcePaths: Collection<File>,
+    files: JavaCompileInputs,
     outputLocation: ApiLocation,
     generateApiMode: GenerateApiMode,
     apiLintMode: ApiLintMode,
@@ -285,9 +281,10 @@
 ) {
     val args =
         getGenerateApiArgs(
-            bootClasspath,
-            dependencyClasspath,
-            sourcePaths,
+            files.bootClasspath,
+            files.dependencyClasspath,
+            files.sourcePaths.files,
+            files.commonModuleSourcePaths.files,
             outputLocation,
             generateApiMode,
             apiLintMode,
@@ -305,6 +302,7 @@
     bootClasspath: FileCollection,
     dependencyClasspath: FileCollection,
     sourcePaths: Collection<File>,
+    commonModuleSourcePaths: Collection<File>,
     outputLocation: ApiLocation?,
     generateApiMode: GenerateApiMode,
     apiLintMode: ApiLintMode,
@@ -318,10 +316,17 @@
             (bootClasspath.files + dependencyClasspath.files).joinToString(File.pathSeparator),
             "--source-path",
             sourcePaths.filter { it.exists() }.joinToString(File.pathSeparator),
-            "--format=v4",
-            "--warnings-as-errors"
         )
 
+    val existentCommonModuleSourcePaths = commonModuleSourcePaths.filter { it.exists() }
+    if (existentCommonModuleSourcePaths.isNotEmpty()) {
+        args += listOf("--common-source-path", existentCommonModuleSourcePaths.joinToString(":"))
+    }
+    args += listOf(
+        "--format=v4",
+        "--warnings-as-errors"
+    )
+
     pathToManifest?.let { args += listOf("--manifest", pathToManifest) }
 
     if (outputLocation != null) {
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaTask.kt
index 66e7772..17e6ba4 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaTask.kt
@@ -45,13 +45,17 @@
     /** Android's boot classpath */
     @get:Classpath lateinit var bootClasspath: FileCollection
 
-    /** Dependencies of [sourcePaths]. */
+    /** Dependencies (compiled classes) of [sourcePaths]. */
     @get:Classpath lateinit var dependencyClasspath: FileCollection
 
     /** Source files against which API signatures will be validated. */
     @get:[InputFiles PathSensitive(PathSensitivity.RELATIVE)]
     var sourcePaths: FileCollection = project.files()
 
+    /** Multiplatform source files from the module's common sourceset */
+    @get:[InputFiles PathSensitive(PathSensitivity.RELATIVE)]
+    var commonModuleSourcePaths: FileCollection = project.files()
+
     @get:[Optional InputFile PathSensitive(PathSensitivity.NONE)]
     abstract val manifestPath: RegularFileProperty
 
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaTasks.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaTasks.kt
index 38f7732..9902dd5 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaTasks.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaTasks.kt
@@ -210,6 +210,7 @@
 
     private fun applyInputs(inputs: JavaCompileInputs, task: MetalavaTask) {
         task.sourcePaths = inputs.sourcePaths
+        task.commonModuleSourcePaths = inputs.commonModuleSourcePaths
         task.dependsOn(inputs.sourcePaths)
         task.dependencyClasspath = inputs.dependencyClasspath
         task.bootClasspath = inputs.bootClasspath
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/RegenerateOldApisTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/RegenerateOldApisTask.kt
index 1dcc6f9..739fe9a 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/RegenerateOldApisTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/RegenerateOldApisTask.kt
@@ -110,7 +110,14 @@
         val jars = getJars(runnerProject, mavenId)
         val sources = getSources(runnerProject, mavenId + ":sources")
 
-        return JavaCompileInputs(sources, jars, project.getAndroidJar())
+        return JavaCompileInputs(
+            sourcePaths = sources,
+            // TODO(b/330721660) parse META-INF/kotlin-project-structure-metadata.json for
+            // common sources
+            commonModuleSourcePaths = project.files(),
+            dependencyClasspath = jars,
+            bootClasspath = project.getAndroidJar()
+        )
     }
 
     fun getJars(runnerProject: Project, mavenId: String): FileCollection {
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/UpdateBaselineTasks.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/UpdateBaselineTasks.kt
index 29bb09f..47998b0 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/UpdateBaselineTasks.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/UpdateBaselineTasks.kt
@@ -61,6 +61,7 @@
                 bootClasspath,
                 dependencyClasspath,
                 sourcePaths.files.filter { it.exists() },
+                commonModuleSourcePaths.files.filter { it.exists() },
                 null,
                 GenerateApiMode.PublicApi,
                 ApiLintMode.CheckBaseline(baselineFile, targetsJavaConsumers.get()),
diff --git a/buildSrc/shared.gradle b/buildSrc/shared.gradle
index b135cf6..3923507 100644
--- a/buildSrc/shared.gradle
+++ b/buildSrc/shared.gradle
@@ -37,7 +37,8 @@
         jvmTarget = "17"
         freeCompilerArgs += [
                 "-Werror",
-                "-Xskip-metadata-version-check"
+                "-Xskip-metadata-version-check",
+                "-Xjdk-release=17",
         ]
         languageVersion = "1.8"
         apiVersion = "1.8"
diff --git a/camera/camera-camera2/api/1.4.0-beta01.txt b/camera/camera-camera2/api/1.4.0-beta01.txt
new file mode 100644
index 0000000..1f2bf8d
--- /dev/null
+++ b/camera/camera-camera2/api/1.4.0-beta01.txt
@@ -0,0 +1,54 @@
+// Signature format: 4.0
+package androidx.camera.camera2 {
+
+  @RequiresApi(21) public final class Camera2Config {
+    method public static androidx.camera.core.CameraXConfig defaultConfig();
+  }
+
+}
+
+package androidx.camera.camera2.interop {
+
+  @SuppressCompatibility @RequiresApi(21) @androidx.camera.camera2.interop.ExperimentalCamera2Interop public final class Camera2CameraControl {
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> addCaptureRequestOptions(androidx.camera.camera2.interop.CaptureRequestOptions);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> clearCaptureRequestOptions();
+    method public static androidx.camera.camera2.interop.Camera2CameraControl from(androidx.camera.core.CameraControl);
+    method public androidx.camera.camera2.interop.CaptureRequestOptions getCaptureRequestOptions();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setCaptureRequestOptions(androidx.camera.camera2.interop.CaptureRequestOptions);
+  }
+
+  @SuppressCompatibility @RequiresApi(21) @androidx.camera.camera2.interop.ExperimentalCamera2Interop public final class Camera2CameraInfo {
+    method public static androidx.camera.camera2.interop.Camera2CameraInfo from(androidx.camera.core.CameraInfo);
+    method public <T> T? getCameraCharacteristic(android.hardware.camera2.CameraCharacteristics.Key<T!>);
+    method public String getCameraId();
+  }
+
+  @SuppressCompatibility @RequiresApi(21) @androidx.camera.camera2.interop.ExperimentalCamera2Interop public final class Camera2Interop {
+  }
+
+  @RequiresApi(21) public static final class Camera2Interop.Extender<T> {
+    ctor public Camera2Interop.Extender(androidx.camera.core.ExtendableBuilder<T!>);
+    method public <ValueT> androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT!>, ValueT);
+    method public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setDeviceStateCallback(android.hardware.camera2.CameraDevice.StateCallback);
+    method @RequiresApi(28) public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setPhysicalCameraId(String);
+    method public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setSessionCaptureCallback(android.hardware.camera2.CameraCaptureSession.CaptureCallback);
+    method public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setSessionStateCallback(android.hardware.camera2.CameraCaptureSession.StateCallback);
+    method @RequiresApi(33) public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setStreamUseCase(long);
+  }
+
+  @SuppressCompatibility @RequiresApi(21) @androidx.camera.camera2.interop.ExperimentalCamera2Interop public class CaptureRequestOptions {
+    method public <ValueT> ValueT? getCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT!>);
+  }
+
+  @RequiresApi(21) public static final class CaptureRequestOptions.Builder implements androidx.camera.core.ExtendableBuilder<androidx.camera.camera2.interop.CaptureRequestOptions!> {
+    ctor public CaptureRequestOptions.Builder();
+    method public androidx.camera.camera2.interop.CaptureRequestOptions build();
+    method public <ValueT> androidx.camera.camera2.interop.CaptureRequestOptions.Builder clearCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT!>);
+    method public <ValueT> androidx.camera.camera2.interop.CaptureRequestOptions.Builder setCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT!>, ValueT);
+  }
+
+  @SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalCamera2Interop {
+  }
+
+}
+
diff --git a/camera/camera-camera2/api/res-1.4.0-beta01.txt b/camera/camera-camera2/api/res-1.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/camera/camera-camera2/api/res-1.4.0-beta01.txt
diff --git a/camera/camera-camera2/api/restricted_1.4.0-beta01.txt b/camera/camera-camera2/api/restricted_1.4.0-beta01.txt
new file mode 100644
index 0000000..1f2bf8d
--- /dev/null
+++ b/camera/camera-camera2/api/restricted_1.4.0-beta01.txt
@@ -0,0 +1,54 @@
+// Signature format: 4.0
+package androidx.camera.camera2 {
+
+  @RequiresApi(21) public final class Camera2Config {
+    method public static androidx.camera.core.CameraXConfig defaultConfig();
+  }
+
+}
+
+package androidx.camera.camera2.interop {
+
+  @SuppressCompatibility @RequiresApi(21) @androidx.camera.camera2.interop.ExperimentalCamera2Interop public final class Camera2CameraControl {
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> addCaptureRequestOptions(androidx.camera.camera2.interop.CaptureRequestOptions);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> clearCaptureRequestOptions();
+    method public static androidx.camera.camera2.interop.Camera2CameraControl from(androidx.camera.core.CameraControl);
+    method public androidx.camera.camera2.interop.CaptureRequestOptions getCaptureRequestOptions();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setCaptureRequestOptions(androidx.camera.camera2.interop.CaptureRequestOptions);
+  }
+
+  @SuppressCompatibility @RequiresApi(21) @androidx.camera.camera2.interop.ExperimentalCamera2Interop public final class Camera2CameraInfo {
+    method public static androidx.camera.camera2.interop.Camera2CameraInfo from(androidx.camera.core.CameraInfo);
+    method public <T> T? getCameraCharacteristic(android.hardware.camera2.CameraCharacteristics.Key<T!>);
+    method public String getCameraId();
+  }
+
+  @SuppressCompatibility @RequiresApi(21) @androidx.camera.camera2.interop.ExperimentalCamera2Interop public final class Camera2Interop {
+  }
+
+  @RequiresApi(21) public static final class Camera2Interop.Extender<T> {
+    ctor public Camera2Interop.Extender(androidx.camera.core.ExtendableBuilder<T!>);
+    method public <ValueT> androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT!>, ValueT);
+    method public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setDeviceStateCallback(android.hardware.camera2.CameraDevice.StateCallback);
+    method @RequiresApi(28) public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setPhysicalCameraId(String);
+    method public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setSessionCaptureCallback(android.hardware.camera2.CameraCaptureSession.CaptureCallback);
+    method public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setSessionStateCallback(android.hardware.camera2.CameraCaptureSession.StateCallback);
+    method @RequiresApi(33) public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setStreamUseCase(long);
+  }
+
+  @SuppressCompatibility @RequiresApi(21) @androidx.camera.camera2.interop.ExperimentalCamera2Interop public class CaptureRequestOptions {
+    method public <ValueT> ValueT? getCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT!>);
+  }
+
+  @RequiresApi(21) public static final class CaptureRequestOptions.Builder implements androidx.camera.core.ExtendableBuilder<androidx.camera.camera2.interop.CaptureRequestOptions!> {
+    ctor public CaptureRequestOptions.Builder();
+    method public androidx.camera.camera2.interop.CaptureRequestOptions build();
+    method public <ValueT> androidx.camera.camera2.interop.CaptureRequestOptions.Builder clearCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT!>);
+    method public <ValueT> androidx.camera.camera2.interop.CaptureRequestOptions.Builder setCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT!>, ValueT);
+  }
+
+  @SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalCamera2Interop {
+  }
+
+}
+
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraInfoImpl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraInfoImpl.java
index d524379..d86a586 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraInfoImpl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraInfoImpl.java
@@ -19,6 +19,7 @@
 import static android.hardware.camera2.CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES;
 import static android.hardware.camera2.CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_ON;
 import static android.hardware.camera2.CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION;
+import static android.hardware.camera2.CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA;
 import static android.hardware.camera2.CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING;
 import static android.hardware.camera2.CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME;
 import static android.hardware.camera2.CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
@@ -409,6 +410,12 @@
                 REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING);
     }
 
+    @Override
+    public boolean isLogicalMultiCameraSupported() {
+        return isCapabilitySupported(mCameraCharacteristicsCompat,
+                REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA);
+    }
+
     /** {@inheritDoc} */
     @NonNull
     @Override
diff --git a/camera/camera-core/api/1.4.0-beta01.txt b/camera/camera-core/api/1.4.0-beta01.txt
new file mode 100644
index 0000000..abd42142
--- /dev/null
+++ b/camera/camera-core/api/1.4.0-beta01.txt
@@ -0,0 +1,716 @@
+// Signature format: 4.0
+package androidx.camera.core {
+
+  @RequiresApi(21) public class AspectRatio {
+    field public static final int RATIO_16_9 = 1; // 0x1
+    field public static final int RATIO_4_3 = 0; // 0x0
+    field public static final int RATIO_DEFAULT = -1; // 0xffffffff
+  }
+
+  @RequiresApi(21) public interface Camera {
+    method public androidx.camera.core.CameraControl getCameraControl();
+    method public androidx.camera.core.CameraInfo getCameraInfo();
+  }
+
+  @RequiresApi(21) public interface CameraControl {
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> cancelFocusAndMetering();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> enableTorch(boolean);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> setExposureCompensationIndex(int);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setLinearZoom(@FloatRange(from=0.0f, to=1.0f) float);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setZoomRatio(float);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.camera.core.FocusMeteringResult!> startFocusAndMetering(androidx.camera.core.FocusMeteringAction);
+  }
+
+  public static final class CameraControl.OperationCanceledException extends java.lang.Exception {
+  }
+
+  @RequiresApi(21) public abstract class CameraEffect {
+    ctor protected CameraEffect(int, java.util.concurrent.Executor, androidx.camera.core.ImageProcessor, androidx.core.util.Consumer<java.lang.Throwable!>);
+    ctor protected CameraEffect(int, java.util.concurrent.Executor, androidx.camera.core.SurfaceProcessor, androidx.core.util.Consumer<java.lang.Throwable!>);
+    method public androidx.core.util.Consumer<java.lang.Throwable!> getErrorListener();
+    method public java.util.concurrent.Executor getExecutor();
+    method public androidx.camera.core.SurfaceProcessor? getSurfaceProcessor();
+    method public int getTargets();
+    field public static final int IMAGE_CAPTURE = 4; // 0x4
+    field public static final int PREVIEW = 1; // 0x1
+    field public static final int VIDEO_CAPTURE = 2; // 0x2
+  }
+
+  @RequiresApi(21) public interface CameraFilter {
+    method public java.util.List<androidx.camera.core.CameraInfo!> filter(java.util.List<androidx.camera.core.CameraInfo!>);
+  }
+
+  @RequiresApi(21) public interface CameraInfo {
+    method public androidx.camera.core.CameraSelector getCameraSelector();
+    method public androidx.lifecycle.LiveData<androidx.camera.core.CameraState!> getCameraState();
+    method public androidx.camera.core.ExposureState getExposureState();
+    method @FloatRange(from=0, fromInclusive=false) public default float getIntrinsicZoomRatio();
+    method public default int getLensFacing();
+    method public int getSensorRotationDegrees();
+    method public int getSensorRotationDegrees(int);
+    method public default java.util.Set<android.util.Range<java.lang.Integer!>!> getSupportedFrameRateRanges();
+    method public androidx.lifecycle.LiveData<java.lang.Integer!> getTorchState();
+    method public androidx.lifecycle.LiveData<androidx.camera.core.ZoomState!> getZoomState();
+    method public boolean hasFlashUnit();
+    method public default boolean isFocusMeteringSupported(androidx.camera.core.FocusMeteringAction);
+    method @SuppressCompatibility @androidx.camera.core.ExperimentalZeroShutterLag public default boolean isZslSupported();
+    method public static boolean mustPlayShutterSound();
+    method public default java.util.Set<androidx.camera.core.DynamicRange!> querySupportedDynamicRanges(java.util.Set<androidx.camera.core.DynamicRange!>);
+  }
+
+  @RequiresApi(21) public final class CameraInfoUnavailableException extends java.lang.Exception {
+  }
+
+  @RequiresApi(21) public interface CameraProvider {
+    method public java.util.List<androidx.camera.core.CameraInfo!> getAvailableCameraInfos();
+    method public boolean hasCamera(androidx.camera.core.CameraSelector) throws androidx.camera.core.CameraInfoUnavailableException;
+  }
+
+  @RequiresApi(21) public final class CameraSelector {
+    method public java.util.List<androidx.camera.core.CameraInfo!> filter(java.util.List<androidx.camera.core.CameraInfo!>);
+    field public static final androidx.camera.core.CameraSelector DEFAULT_BACK_CAMERA;
+    field public static final androidx.camera.core.CameraSelector DEFAULT_FRONT_CAMERA;
+    field public static final int LENS_FACING_BACK = 1; // 0x1
+    field @SuppressCompatibility @androidx.camera.core.ExperimentalLensFacing public static final int LENS_FACING_EXTERNAL = 2; // 0x2
+    field public static final int LENS_FACING_FRONT = 0; // 0x0
+    field public static final int LENS_FACING_UNKNOWN = -1; // 0xffffffff
+  }
+
+  public static final class CameraSelector.Builder {
+    ctor public CameraSelector.Builder();
+    method public androidx.camera.core.CameraSelector.Builder addCameraFilter(androidx.camera.core.CameraFilter);
+    method public androidx.camera.core.CameraSelector build();
+    method public androidx.camera.core.CameraSelector.Builder requireLensFacing(int);
+  }
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class CameraState {
+    ctor public CameraState();
+    method public static androidx.camera.core.CameraState create(androidx.camera.core.CameraState.Type);
+    method public static androidx.camera.core.CameraState create(androidx.camera.core.CameraState.Type, androidx.camera.core.CameraState.StateError?);
+    method public abstract androidx.camera.core.CameraState.StateError? getError();
+    method public abstract androidx.camera.core.CameraState.Type getType();
+    field public static final int ERROR_CAMERA_DISABLED = 5; // 0x5
+    field public static final int ERROR_CAMERA_FATAL_ERROR = 6; // 0x6
+    field public static final int ERROR_CAMERA_IN_USE = 2; // 0x2
+    field public static final int ERROR_DO_NOT_DISTURB_MODE_ENABLED = 7; // 0x7
+    field public static final int ERROR_MAX_CAMERAS_IN_USE = 1; // 0x1
+    field public static final int ERROR_OTHER_RECOVERABLE_ERROR = 3; // 0x3
+    field public static final int ERROR_STREAM_CONFIG = 4; // 0x4
+  }
+
+  public enum CameraState.ErrorType {
+    enum_constant public static final androidx.camera.core.CameraState.ErrorType CRITICAL;
+    enum_constant public static final androidx.camera.core.CameraState.ErrorType RECOVERABLE;
+  }
+
+  @com.google.auto.value.AutoValue public abstract static class CameraState.StateError {
+    ctor public CameraState.StateError();
+    method public static androidx.camera.core.CameraState.StateError create(int);
+    method public static androidx.camera.core.CameraState.StateError create(int, Throwable?);
+    method public abstract Throwable? getCause();
+    method public abstract int getCode();
+    method public androidx.camera.core.CameraState.ErrorType getType();
+  }
+
+  public enum CameraState.Type {
+    enum_constant public static final androidx.camera.core.CameraState.Type CLOSED;
+    enum_constant public static final androidx.camera.core.CameraState.Type CLOSING;
+    enum_constant public static final androidx.camera.core.CameraState.Type OPEN;
+    enum_constant public static final androidx.camera.core.CameraState.Type OPENING;
+    enum_constant public static final androidx.camera.core.CameraState.Type PENDING_OPEN;
+  }
+
+  @RequiresApi(21) public class CameraUnavailableException extends java.lang.Exception {
+    ctor public CameraUnavailableException(int);
+    ctor public CameraUnavailableException(int, String?);
+    ctor public CameraUnavailableException(int, String?, Throwable?);
+    ctor public CameraUnavailableException(int, Throwable?);
+    method public int getReason();
+    field public static final int CAMERA_DISABLED = 1; // 0x1
+    field public static final int CAMERA_DISCONNECTED = 2; // 0x2
+    field public static final int CAMERA_ERROR = 3; // 0x3
+    field public static final int CAMERA_IN_USE = 4; // 0x4
+    field public static final int CAMERA_MAX_IN_USE = 5; // 0x5
+    field public static final int CAMERA_UNAVAILABLE_DO_NOT_DISTURB = 6; // 0x6
+    field public static final int CAMERA_UNKNOWN_ERROR = 0; // 0x0
+  }
+
+  @RequiresApi(21) public final class CameraXConfig {
+    method public androidx.camera.core.CameraSelector? getAvailableCamerasLimiter(androidx.camera.core.CameraSelector?);
+    method public java.util.concurrent.Executor? getCameraExecutor(java.util.concurrent.Executor?);
+    method public long getCameraOpenRetryMaxTimeoutInMillisWhileResuming();
+    method @SuppressCompatibility @androidx.camera.core.ExperimentalRetryPolicy public androidx.camera.core.RetryPolicy getCameraProviderInitRetryPolicy();
+    method public int getMinimumLoggingLevel();
+    method public android.os.Handler? getSchedulerHandler(android.os.Handler?);
+  }
+
+  public static final class CameraXConfig.Builder {
+    method public androidx.camera.core.CameraXConfig build();
+    method public static androidx.camera.core.CameraXConfig.Builder fromConfig(androidx.camera.core.CameraXConfig);
+    method public androidx.camera.core.CameraXConfig.Builder setAvailableCamerasLimiter(androidx.camera.core.CameraSelector);
+    method public androidx.camera.core.CameraXConfig.Builder setCameraExecutor(java.util.concurrent.Executor);
+    method public androidx.camera.core.CameraXConfig.Builder setCameraOpenRetryMaxTimeoutInMillisWhileResuming(long);
+    method @SuppressCompatibility @androidx.camera.core.ExperimentalRetryPolicy public androidx.camera.core.CameraXConfig.Builder setCameraProviderInitRetryPolicy(androidx.camera.core.RetryPolicy);
+    method public androidx.camera.core.CameraXConfig.Builder setMinimumLoggingLevel(@IntRange(from=android.util.Log.DEBUG, to=android.util.Log.ERROR) int);
+    method public androidx.camera.core.CameraXConfig.Builder setSchedulerHandler(android.os.Handler);
+  }
+
+  public static interface CameraXConfig.Provider {
+    method public androidx.camera.core.CameraXConfig getCameraXConfig();
+  }
+
+  @RequiresApi(21) public class ConcurrentCamera {
+    ctor public ConcurrentCamera(java.util.List<androidx.camera.core.Camera!>);
+    method public java.util.List<androidx.camera.core.Camera!> getCameras();
+  }
+
+  public static final class ConcurrentCamera.SingleCameraConfig {
+    ctor public ConcurrentCamera.SingleCameraConfig(androidx.camera.core.CameraSelector, androidx.camera.core.UseCaseGroup, androidx.lifecycle.LifecycleOwner);
+    method public androidx.camera.core.CameraSelector getCameraSelector();
+    method public androidx.lifecycle.LifecycleOwner getLifecycleOwner();
+    method public androidx.camera.core.UseCaseGroup getUseCaseGroup();
+  }
+
+  @RequiresApi(21) public final class DisplayOrientedMeteringPointFactory extends androidx.camera.core.MeteringPointFactory {
+    ctor public DisplayOrientedMeteringPointFactory(android.view.Display, androidx.camera.core.CameraInfo, float, float);
+  }
+
+  @RequiresApi(21) public final class DynamicRange {
+    ctor public DynamicRange(int, int);
+    method public int getBitDepth();
+    method public int getEncoding();
+    field public static final int BIT_DEPTH_10_BIT = 10; // 0xa
+    field public static final int BIT_DEPTH_8_BIT = 8; // 0x8
+    field public static final int BIT_DEPTH_UNSPECIFIED = 0; // 0x0
+    field public static final androidx.camera.core.DynamicRange DOLBY_VISION_10_BIT;
+    field public static final androidx.camera.core.DynamicRange DOLBY_VISION_8_BIT;
+    field public static final int ENCODING_DOLBY_VISION = 6; // 0x6
+    field public static final int ENCODING_HDR10 = 4; // 0x4
+    field public static final int ENCODING_HDR10_PLUS = 5; // 0x5
+    field public static final int ENCODING_HDR_UNSPECIFIED = 2; // 0x2
+    field public static final int ENCODING_HLG = 3; // 0x3
+    field public static final int ENCODING_SDR = 1; // 0x1
+    field public static final int ENCODING_UNSPECIFIED = 0; // 0x0
+    field public static final androidx.camera.core.DynamicRange HDR10_10_BIT;
+    field public static final androidx.camera.core.DynamicRange HDR10_PLUS_10_BIT;
+    field public static final androidx.camera.core.DynamicRange HDR_UNSPECIFIED_10_BIT;
+    field public static final androidx.camera.core.DynamicRange HLG_10_BIT;
+    field public static final androidx.camera.core.DynamicRange SDR;
+    field public static final androidx.camera.core.DynamicRange UNSPECIFIED;
+  }
+
+  @SuppressCompatibility @RequiresApi(21) @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalGetImage {
+  }
+
+  @SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalLensFacing {
+  }
+
+  @SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalRetryPolicy {
+  }
+
+  @SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalUseCaseApi {
+  }
+
+  @SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalZeroShutterLag {
+  }
+
+  @RequiresApi(21) public interface ExposureState {
+    method public int getExposureCompensationIndex();
+    method public android.util.Range<java.lang.Integer!> getExposureCompensationRange();
+    method public android.util.Rational getExposureCompensationStep();
+    method public boolean isExposureCompensationSupported();
+  }
+
+  @RequiresApi(21) public interface ExtendableBuilder<T> {
+    method public T build();
+  }
+
+  @RequiresApi(21) public final class FocusMeteringAction {
+    method public long getAutoCancelDurationInMillis();
+    method public java.util.List<androidx.camera.core.MeteringPoint!> getMeteringPointsAe();
+    method public java.util.List<androidx.camera.core.MeteringPoint!> getMeteringPointsAf();
+    method public java.util.List<androidx.camera.core.MeteringPoint!> getMeteringPointsAwb();
+    method public boolean isAutoCancelEnabled();
+    field public static final int FLAG_AE = 2; // 0x2
+    field public static final int FLAG_AF = 1; // 0x1
+    field public static final int FLAG_AWB = 4; // 0x4
+  }
+
+  public static class FocusMeteringAction.Builder {
+    ctor public FocusMeteringAction.Builder(androidx.camera.core.MeteringPoint);
+    ctor public FocusMeteringAction.Builder(androidx.camera.core.MeteringPoint, int);
+    method public androidx.camera.core.FocusMeteringAction.Builder addPoint(androidx.camera.core.MeteringPoint);
+    method public androidx.camera.core.FocusMeteringAction.Builder addPoint(androidx.camera.core.MeteringPoint, int);
+    method public androidx.camera.core.FocusMeteringAction build();
+    method public androidx.camera.core.FocusMeteringAction.Builder disableAutoCancel();
+    method public androidx.camera.core.FocusMeteringAction.Builder setAutoCancelDuration(@IntRange(from=1) long, java.util.concurrent.TimeUnit);
+  }
+
+  @RequiresApi(21) public final class FocusMeteringResult {
+    method public boolean isFocusSuccessful();
+  }
+
+  @RequiresApi(21) public final class ImageAnalysis extends androidx.camera.core.UseCase {
+    method public void clearAnalyzer();
+    method @SuppressCompatibility @androidx.camera.core.ExperimentalUseCaseApi public java.util.concurrent.Executor? getBackgroundExecutor();
+    method public int getBackpressureStrategy();
+    method public int getImageQueueDepth();
+    method public int getOutputImageFormat();
+    method public androidx.camera.core.ResolutionInfo? getResolutionInfo();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector? getResolutionSelector();
+    method public int getTargetRotation();
+    method public boolean isOutputImageRotationEnabled();
+    method public void setAnalyzer(java.util.concurrent.Executor, androidx.camera.core.ImageAnalysis.Analyzer);
+    method public void setTargetRotation(int);
+    field public static final int COORDINATE_SYSTEM_ORIGINAL = 0; // 0x0
+    field public static final int COORDINATE_SYSTEM_SENSOR = 2; // 0x2
+    field public static final int OUTPUT_IMAGE_FORMAT_RGBA_8888 = 2; // 0x2
+    field public static final int OUTPUT_IMAGE_FORMAT_YUV_420_888 = 1; // 0x1
+    field public static final int STRATEGY_BLOCK_PRODUCER = 1; // 0x1
+    field public static final int STRATEGY_KEEP_ONLY_LATEST = 0; // 0x0
+  }
+
+  public static interface ImageAnalysis.Analyzer {
+    method public void analyze(androidx.camera.core.ImageProxy);
+    method public default android.util.Size? getDefaultTargetResolution();
+    method public default int getTargetCoordinateSystem();
+    method public default void updateTransform(android.graphics.Matrix?);
+  }
+
+  public static final class ImageAnalysis.Builder implements androidx.camera.core.ExtendableBuilder<androidx.camera.core.ImageAnalysis!> {
+    ctor public ImageAnalysis.Builder();
+    method public androidx.camera.core.ImageAnalysis build();
+    method public androidx.camera.core.ImageAnalysis.Builder setBackgroundExecutor(java.util.concurrent.Executor);
+    method public androidx.camera.core.ImageAnalysis.Builder setBackpressureStrategy(int);
+    method public androidx.camera.core.ImageAnalysis.Builder setImageQueueDepth(int);
+    method public androidx.camera.core.ImageAnalysis.Builder setOutputImageFormat(int);
+    method @RequiresApi(23) public androidx.camera.core.ImageAnalysis.Builder setOutputImageRotationEnabled(boolean);
+    method public androidx.camera.core.ImageAnalysis.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
+    method @Deprecated public androidx.camera.core.ImageAnalysis.Builder setTargetAspectRatio(int);
+    method public androidx.camera.core.ImageAnalysis.Builder setTargetName(String);
+    method @Deprecated public androidx.camera.core.ImageAnalysis.Builder setTargetResolution(android.util.Size);
+    method public androidx.camera.core.ImageAnalysis.Builder setTargetRotation(int);
+  }
+
+  @RequiresApi(21) public final class ImageCapture extends androidx.camera.core.UseCase {
+    method public int getCaptureMode();
+    method public int getFlashMode();
+    method public static androidx.camera.core.ImageCaptureCapabilities getImageCaptureCapabilities(androidx.camera.core.CameraInfo);
+    method @IntRange(from=1, to=100) public int getJpegQuality();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector? getPostviewResolutionSelector();
+    method public androidx.camera.core.ImageCaptureLatencyEstimate getRealtimeCaptureLatencyEstimate();
+    method public androidx.camera.core.ResolutionInfo? getResolutionInfo();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector? getResolutionSelector();
+    method public androidx.camera.core.ImageCapture.ScreenFlash? getScreenFlash();
+    method public int getTargetRotation();
+    method public boolean isPostviewEnabled();
+    method public void setCropAspectRatio(android.util.Rational);
+    method public void setFlashMode(int);
+    method public void setScreenFlash(androidx.camera.core.ImageCapture.ScreenFlash?);
+    method public void setTargetRotation(int);
+    method public void takePicture(androidx.camera.core.ImageCapture.OutputFileOptions, java.util.concurrent.Executor, androidx.camera.core.ImageCapture.OnImageSavedCallback);
+    method public void takePicture(java.util.concurrent.Executor, androidx.camera.core.ImageCapture.OnImageCapturedCallback);
+    field public static final int CAPTURE_MODE_MAXIMIZE_QUALITY = 0; // 0x0
+    field public static final int CAPTURE_MODE_MINIMIZE_LATENCY = 1; // 0x1
+    field @SuppressCompatibility @androidx.camera.core.ExperimentalZeroShutterLag public static final int CAPTURE_MODE_ZERO_SHUTTER_LAG = 2; // 0x2
+    field public static final int ERROR_CAMERA_CLOSED = 3; // 0x3
+    field public static final int ERROR_CAPTURE_FAILED = 2; // 0x2
+    field public static final int ERROR_FILE_IO = 1; // 0x1
+    field public static final int ERROR_INVALID_CAMERA = 4; // 0x4
+    field public static final int ERROR_UNKNOWN = 0; // 0x0
+    field public static final int FLASH_MODE_AUTO = 0; // 0x0
+    field public static final int FLASH_MODE_OFF = 2; // 0x2
+    field public static final int FLASH_MODE_ON = 1; // 0x1
+    field public static final int FLASH_MODE_SCREEN = 3; // 0x3
+  }
+
+  public static final class ImageCapture.Builder implements androidx.camera.core.ExtendableBuilder<androidx.camera.core.ImageCapture!> {
+    ctor public ImageCapture.Builder();
+    method public androidx.camera.core.ImageCapture build();
+    method public androidx.camera.core.ImageCapture.Builder setCaptureMode(int);
+    method public androidx.camera.core.ImageCapture.Builder setFlashMode(int);
+    method public androidx.camera.core.ImageCapture.Builder setIoExecutor(java.util.concurrent.Executor);
+    method public androidx.camera.core.ImageCapture.Builder setJpegQuality(@IntRange(from=1, to=100) int);
+    method public androidx.camera.core.ImageCapture.Builder setPostviewEnabled(boolean);
+    method public androidx.camera.core.ImageCapture.Builder setPostviewResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
+    method public androidx.camera.core.ImageCapture.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
+    method public androidx.camera.core.ImageCapture.Builder setScreenFlash(androidx.camera.core.ImageCapture.ScreenFlash);
+    method @Deprecated public androidx.camera.core.ImageCapture.Builder setTargetAspectRatio(int);
+    method public androidx.camera.core.ImageCapture.Builder setTargetName(String);
+    method @Deprecated public androidx.camera.core.ImageCapture.Builder setTargetResolution(android.util.Size);
+    method public androidx.camera.core.ImageCapture.Builder setTargetRotation(int);
+  }
+
+  public static final class ImageCapture.Metadata {
+    ctor public ImageCapture.Metadata();
+    method public android.location.Location? getLocation();
+    method public boolean isReversedHorizontal();
+    method public boolean isReversedVertical();
+    method public void setLocation(android.location.Location?);
+    method public void setReversedHorizontal(boolean);
+    method public void setReversedVertical(boolean);
+  }
+
+  public abstract static class ImageCapture.OnImageCapturedCallback {
+    ctor public ImageCapture.OnImageCapturedCallback();
+    method public void onCaptureProcessProgressed(int);
+    method public void onCaptureStarted();
+    method public void onCaptureSuccess(androidx.camera.core.ImageProxy);
+    method public void onError(androidx.camera.core.ImageCaptureException);
+    method public void onPostviewBitmapAvailable(android.graphics.Bitmap);
+  }
+
+  public static interface ImageCapture.OnImageSavedCallback {
+    method public default void onCaptureProcessProgressed(int);
+    method public default void onCaptureStarted();
+    method public void onError(androidx.camera.core.ImageCaptureException);
+    method public void onImageSaved(androidx.camera.core.ImageCapture.OutputFileResults);
+    method public default void onPostviewBitmapAvailable(android.graphics.Bitmap);
+  }
+
+  public static final class ImageCapture.OutputFileOptions {
+  }
+
+  public static final class ImageCapture.OutputFileOptions.Builder {
+    ctor public ImageCapture.OutputFileOptions.Builder(android.content.ContentResolver, android.net.Uri, android.content.ContentValues);
+    ctor public ImageCapture.OutputFileOptions.Builder(java.io.File);
+    ctor public ImageCapture.OutputFileOptions.Builder(java.io.OutputStream);
+    method public androidx.camera.core.ImageCapture.OutputFileOptions build();
+    method public androidx.camera.core.ImageCapture.OutputFileOptions.Builder setMetadata(androidx.camera.core.ImageCapture.Metadata);
+  }
+
+  public static class ImageCapture.OutputFileResults {
+    method public android.net.Uri? getSavedUri();
+  }
+
+  public static interface ImageCapture.ScreenFlash {
+    method @UiThread public void apply(long, androidx.camera.core.ImageCapture.ScreenFlashListener);
+    method @UiThread public void clear();
+  }
+
+  public static interface ImageCapture.ScreenFlashListener {
+    method public void onCompleted();
+  }
+
+  public interface ImageCaptureCapabilities {
+    method public boolean isCaptureProcessProgressSupported();
+    method public boolean isPostviewSupported();
+  }
+
+  @RequiresApi(21) public class ImageCaptureException extends java.lang.Exception {
+    ctor public ImageCaptureException(int, String, Throwable?);
+    method public int getImageCaptureError();
+  }
+
+  @RequiresApi(21) public class ImageCaptureLatencyEstimate {
+    ctor public ImageCaptureLatencyEstimate(long, long);
+    method public long getCaptureLatencyMillis();
+    method public long getProcessingLatencyMillis();
+    method public long getTotalCaptureLatencyMillis();
+    field public static final long UNDEFINED_CAPTURE_LATENCY = -1L; // 0xffffffffffffffffL
+    field public static final androidx.camera.core.ImageCaptureLatencyEstimate UNDEFINED_IMAGE_CAPTURE_LATENCY;
+    field public static final long UNDEFINED_PROCESSING_LATENCY = -1L; // 0xffffffffffffffffL
+  }
+
+  @RequiresApi(21) public interface ImageInfo {
+    method public int getRotationDegrees();
+    method public default android.graphics.Matrix getSensorToBufferTransformMatrix();
+    method public long getTimestamp();
+  }
+
+  public interface ImageProcessor {
+    method public androidx.camera.core.ImageProcessor.Response process(androidx.camera.core.ImageProcessor.Request) throws androidx.camera.core.ProcessingException;
+  }
+
+  public static interface ImageProcessor.Request {
+    method public androidx.camera.core.ImageProxy getInputImage();
+    method public int getOutputFormat();
+  }
+
+  public static interface ImageProcessor.Response {
+    method public androidx.camera.core.ImageProxy getOutputImage();
+  }
+
+  @RequiresApi(21) public interface ImageProxy extends java.lang.AutoCloseable {
+    method public void close();
+    method public android.graphics.Rect getCropRect();
+    method public int getFormat();
+    method public int getHeight();
+    method @SuppressCompatibility @androidx.camera.core.ExperimentalGetImage public android.media.Image? getImage();
+    method public androidx.camera.core.ImageInfo getImageInfo();
+    method public androidx.camera.core.ImageProxy.PlaneProxy![] getPlanes();
+    method public int getWidth();
+    method public void setCropRect(android.graphics.Rect?);
+    method public default android.graphics.Bitmap toBitmap();
+  }
+
+  public static interface ImageProxy.PlaneProxy {
+    method public java.nio.ByteBuffer getBuffer();
+    method public int getPixelStride();
+    method public int getRowStride();
+  }
+
+  @RequiresApi(21) public class InitializationException extends java.lang.Exception {
+    ctor public InitializationException(String?);
+    ctor public InitializationException(String?, Throwable?);
+    ctor public InitializationException(Throwable?);
+  }
+
+  @RequiresApi(21) public class MeteringPoint {
+    method public float getSize();
+  }
+
+  @RequiresApi(21) public abstract class MeteringPointFactory {
+    method public final androidx.camera.core.MeteringPoint createPoint(float, float);
+    method public final androidx.camera.core.MeteringPoint createPoint(float, float, float);
+    method public static float getDefaultPointSize();
+  }
+
+  @RequiresApi(21) public class MirrorMode {
+    field public static final int MIRROR_MODE_OFF = 0; // 0x0
+    field public static final int MIRROR_MODE_ON = 1; // 0x1
+    field public static final int MIRROR_MODE_ON_FRONT_ONLY = 2; // 0x2
+  }
+
+  @RequiresApi(21) public final class Preview extends androidx.camera.core.UseCase {
+    method public androidx.camera.core.DynamicRange getDynamicRange();
+    method public static androidx.camera.core.PreviewCapabilities getPreviewCapabilities(androidx.camera.core.CameraInfo);
+    method public androidx.camera.core.ResolutionInfo? getResolutionInfo();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector? getResolutionSelector();
+    method public android.util.Range<java.lang.Integer!> getTargetFrameRate();
+    method public int getTargetRotation();
+    method public boolean isPreviewStabilizationEnabled();
+    method @UiThread public void setSurfaceProvider(androidx.camera.core.Preview.SurfaceProvider?);
+    method @UiThread public void setSurfaceProvider(java.util.concurrent.Executor, androidx.camera.core.Preview.SurfaceProvider?);
+    method public void setTargetRotation(int);
+  }
+
+  public static final class Preview.Builder implements androidx.camera.core.ExtendableBuilder<androidx.camera.core.Preview!> {
+    ctor public Preview.Builder();
+    method public androidx.camera.core.Preview build();
+    method public androidx.camera.core.Preview.Builder setDynamicRange(androidx.camera.core.DynamicRange);
+    method public androidx.camera.core.Preview.Builder setPreviewStabilizationEnabled(boolean);
+    method public androidx.camera.core.Preview.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
+    method @Deprecated public androidx.camera.core.Preview.Builder setTargetAspectRatio(int);
+    method public androidx.camera.core.Preview.Builder setTargetFrameRate(android.util.Range<java.lang.Integer!>);
+    method public androidx.camera.core.Preview.Builder setTargetName(String);
+    method @Deprecated public androidx.camera.core.Preview.Builder setTargetResolution(android.util.Size);
+    method public androidx.camera.core.Preview.Builder setTargetRotation(int);
+  }
+
+  public static interface Preview.SurfaceProvider {
+    method public void onSurfaceRequested(androidx.camera.core.SurfaceRequest);
+  }
+
+  @RequiresApi(21) public interface PreviewCapabilities {
+    method public boolean isStabilizationSupported();
+  }
+
+  public class ProcessingException extends java.lang.Exception {
+    ctor public ProcessingException();
+  }
+
+  @RequiresApi(21) public class ResolutionInfo {
+    ctor public ResolutionInfo(android.util.Size, android.graphics.Rect, int);
+    method public android.graphics.Rect getCropRect();
+    method public android.util.Size getResolution();
+    method public int getRotationDegrees();
+  }
+
+  @SuppressCompatibility @RequiresApi(21) @androidx.camera.core.ExperimentalRetryPolicy public interface RetryPolicy {
+    method public static long getDefaultRetryTimeoutInMillis();
+    method public default long getTimeoutInMillis();
+    method public androidx.camera.core.RetryPolicy.RetryConfig onRetryDecisionRequested(androidx.camera.core.RetryPolicy.ExecutionState);
+    field public static final androidx.camera.core.RetryPolicy DEFAULT;
+    field public static final androidx.camera.core.RetryPolicy NEVER;
+    field public static final androidx.camera.core.RetryPolicy RETRY_UNAVAILABLE_CAMERA;
+  }
+
+  @SuppressCompatibility @androidx.camera.core.ExperimentalRetryPolicy public static final class RetryPolicy.Builder {
+    ctor public RetryPolicy.Builder(androidx.camera.core.RetryPolicy);
+    method public androidx.camera.core.RetryPolicy build();
+    method public androidx.camera.core.RetryPolicy.Builder setTimeoutInMillis(long);
+  }
+
+  @SuppressCompatibility @androidx.camera.core.ExperimentalRetryPolicy public static interface RetryPolicy.ExecutionState {
+    method public Throwable? getCause();
+    method public long getExecutedTimeInMillis();
+    method public int getNumOfAttempts();
+    method public int getStatus();
+    field public static final int STATUS_CAMERA_UNAVAILABLE = 2; // 0x2
+    field public static final int STATUS_CONFIGURATION_FAIL = 1; // 0x1
+    field public static final int STATUS_UNKNOWN_ERROR = 0; // 0x0
+  }
+
+  @SuppressCompatibility @androidx.camera.core.ExperimentalRetryPolicy public static final class RetryPolicy.RetryConfig {
+    method public static long getDefaultRetryDelayInMillis();
+    method public long getRetryDelayInMillis();
+    method public boolean shouldRetry();
+    field public static final androidx.camera.core.RetryPolicy.RetryConfig DEFAULT_DELAY_RETRY;
+    field public static final androidx.camera.core.RetryPolicy.RetryConfig MINI_DELAY_RETRY;
+    field public static final androidx.camera.core.RetryPolicy.RetryConfig NOT_RETRY;
+  }
+
+  @SuppressCompatibility @androidx.camera.core.ExperimentalRetryPolicy public static final class RetryPolicy.RetryConfig.Builder {
+    ctor public RetryPolicy.RetryConfig.Builder();
+    method public androidx.camera.core.RetryPolicy.RetryConfig build();
+    method public androidx.camera.core.RetryPolicy.RetryConfig.Builder setRetryDelayInMillis(@IntRange(from=100, to=2000) long);
+    method public androidx.camera.core.RetryPolicy.RetryConfig.Builder setShouldRetry(boolean);
+  }
+
+  @RequiresApi(21) public class SurfaceOrientedMeteringPointFactory extends androidx.camera.core.MeteringPointFactory {
+    ctor public SurfaceOrientedMeteringPointFactory(float, float);
+    ctor public SurfaceOrientedMeteringPointFactory(float, float, androidx.camera.core.UseCase);
+  }
+
+  public interface SurfaceOutput extends java.io.Closeable {
+    method public void close();
+    method public default android.graphics.Matrix getSensorToBufferTransform();
+    method public android.util.Size getSize();
+    method public android.view.Surface getSurface(java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.core.SurfaceOutput.Event!>);
+    method public int getTargets();
+    method public void updateTransformMatrix(float[], float[]);
+  }
+
+  @com.google.auto.value.AutoValue public abstract static class SurfaceOutput.Event {
+    method public abstract int getEventCode();
+    method public abstract androidx.camera.core.SurfaceOutput getSurfaceOutput();
+    field public static final int EVENT_REQUEST_CLOSE = 0; // 0x0
+  }
+
+  public interface SurfaceProcessor {
+    method public void onInputSurface(androidx.camera.core.SurfaceRequest) throws androidx.camera.core.ProcessingException;
+    method public void onOutputSurface(androidx.camera.core.SurfaceOutput) throws androidx.camera.core.ProcessingException;
+  }
+
+  @RequiresApi(21) public final class SurfaceRequest {
+    method public void addRequestCancellationListener(java.util.concurrent.Executor, Runnable);
+    method public void clearTransformationInfoListener();
+    method public androidx.camera.core.DynamicRange getDynamicRange();
+    method public android.util.Size getResolution();
+    method public boolean invalidate();
+    method public void provideSurface(android.view.Surface, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.core.SurfaceRequest.Result!>);
+    method public void setTransformationInfoListener(java.util.concurrent.Executor, androidx.camera.core.SurfaceRequest.TransformationInfoListener);
+    method public boolean willNotProvideSurface();
+  }
+
+  @com.google.auto.value.AutoValue public abstract static class SurfaceRequest.Result {
+    method public abstract int getResultCode();
+    method public abstract android.view.Surface getSurface();
+    field public static final int RESULT_INVALID_SURFACE = 2; // 0x2
+    field public static final int RESULT_REQUEST_CANCELLED = 1; // 0x1
+    field public static final int RESULT_SURFACE_ALREADY_PROVIDED = 3; // 0x3
+    field public static final int RESULT_SURFACE_USED_SUCCESSFULLY = 0; // 0x0
+    field public static final int RESULT_WILL_NOT_PROVIDE_SURFACE = 4; // 0x4
+  }
+
+  @com.google.auto.value.AutoValue public abstract static class SurfaceRequest.TransformationInfo {
+    method public abstract android.graphics.Rect getCropRect();
+    method public abstract int getRotationDegrees();
+    method public abstract android.graphics.Matrix getSensorToBufferTransform();
+    method public abstract boolean hasCameraTransform();
+    method public abstract boolean isMirroring();
+  }
+
+  public static interface SurfaceRequest.TransformationInfoListener {
+    method public void onTransformationInfoUpdate(androidx.camera.core.SurfaceRequest.TransformationInfo);
+  }
+
+  @RequiresApi(21) public class TorchState {
+    field public static final int OFF = 0; // 0x0
+    field public static final int ON = 1; // 0x1
+  }
+
+  @RequiresApi(21) public abstract class UseCase {
+    method public static int snapToSurfaceRotation(@IntRange(from=0, to=359) int);
+  }
+
+  @RequiresApi(21) public final class UseCaseGroup {
+    method public java.util.List<androidx.camera.core.CameraEffect!> getEffects();
+    method public java.util.List<androidx.camera.core.UseCase!> getUseCases();
+    method public androidx.camera.core.ViewPort? getViewPort();
+  }
+
+  public static final class UseCaseGroup.Builder {
+    ctor public UseCaseGroup.Builder();
+    method public androidx.camera.core.UseCaseGroup.Builder addEffect(androidx.camera.core.CameraEffect);
+    method public androidx.camera.core.UseCaseGroup.Builder addUseCase(androidx.camera.core.UseCase);
+    method public androidx.camera.core.UseCaseGroup build();
+    method public androidx.camera.core.UseCaseGroup.Builder setViewPort(androidx.camera.core.ViewPort);
+  }
+
+  @RequiresApi(21) public final class ViewPort {
+    method public android.util.Rational getAspectRatio();
+    method public int getLayoutDirection();
+    method public int getRotation();
+    method public int getScaleType();
+    field public static final int FILL_CENTER = 1; // 0x1
+    field public static final int FILL_END = 2; // 0x2
+    field public static final int FILL_START = 0; // 0x0
+    field public static final int FIT = 3; // 0x3
+  }
+
+  public static final class ViewPort.Builder {
+    ctor public ViewPort.Builder(android.util.Rational, int);
+    method public androidx.camera.core.ViewPort build();
+    method public androidx.camera.core.ViewPort.Builder setLayoutDirection(int);
+    method public androidx.camera.core.ViewPort.Builder setScaleType(int);
+  }
+
+  @RequiresApi(21) public interface ZoomState {
+    method public float getLinearZoom();
+    method public float getMaxZoomRatio();
+    method public float getMinZoomRatio();
+    method public float getZoomRatio();
+  }
+
+}
+
+package androidx.camera.core.resolutionselector {
+
+  @RequiresApi(21) public final class AspectRatioStrategy {
+    ctor public AspectRatioStrategy(int, int);
+    method public int getFallbackRule();
+    method public int getPreferredAspectRatio();
+    field public static final int FALLBACK_RULE_AUTO = 1; // 0x1
+    field public static final int FALLBACK_RULE_NONE = 0; // 0x0
+    field public static final androidx.camera.core.resolutionselector.AspectRatioStrategy RATIO_16_9_FALLBACK_AUTO_STRATEGY;
+    field public static final androidx.camera.core.resolutionselector.AspectRatioStrategy RATIO_4_3_FALLBACK_AUTO_STRATEGY;
+  }
+
+  @RequiresApi(21) public interface ResolutionFilter {
+    method public java.util.List<android.util.Size!> filter(java.util.List<android.util.Size!>, int);
+  }
+
+  @RequiresApi(21) public final class ResolutionSelector {
+    method public int getAllowedResolutionMode();
+    method public androidx.camera.core.resolutionselector.AspectRatioStrategy getAspectRatioStrategy();
+    method public androidx.camera.core.resolutionselector.ResolutionFilter? getResolutionFilter();
+    method public androidx.camera.core.resolutionselector.ResolutionStrategy? getResolutionStrategy();
+    field public static final int PREFER_CAPTURE_RATE_OVER_HIGHER_RESOLUTION = 0; // 0x0
+    field public static final int PREFER_HIGHER_RESOLUTION_OVER_CAPTURE_RATE = 1; // 0x1
+  }
+
+  public static final class ResolutionSelector.Builder {
+    ctor public ResolutionSelector.Builder();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector build();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector.Builder setAllowedResolutionMode(int);
+    method public androidx.camera.core.resolutionselector.ResolutionSelector.Builder setAspectRatioStrategy(androidx.camera.core.resolutionselector.AspectRatioStrategy);
+    method public androidx.camera.core.resolutionselector.ResolutionSelector.Builder setResolutionFilter(androidx.camera.core.resolutionselector.ResolutionFilter);
+    method public androidx.camera.core.resolutionselector.ResolutionSelector.Builder setResolutionStrategy(androidx.camera.core.resolutionselector.ResolutionStrategy);
+  }
+
+  @RequiresApi(21) public final class ResolutionStrategy {
+    ctor public ResolutionStrategy(android.util.Size, int);
+    method public android.util.Size? getBoundSize();
+    method public int getFallbackRule();
+    field public static final int FALLBACK_RULE_CLOSEST_HIGHER = 2; // 0x2
+    field public static final int FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER = 1; // 0x1
+    field public static final int FALLBACK_RULE_CLOSEST_LOWER = 4; // 0x4
+    field public static final int FALLBACK_RULE_CLOSEST_LOWER_THEN_HIGHER = 3; // 0x3
+    field public static final int FALLBACK_RULE_NONE = 0; // 0x0
+    field public static final androidx.camera.core.resolutionselector.ResolutionStrategy HIGHEST_AVAILABLE_STRATEGY;
+  }
+
+}
+
diff --git a/camera/camera-core/api/res-1.4.0-beta01.txt b/camera/camera-core/api/res-1.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/camera/camera-core/api/res-1.4.0-beta01.txt
diff --git a/camera/camera-core/api/restricted_1.4.0-beta01.txt b/camera/camera-core/api/restricted_1.4.0-beta01.txt
new file mode 100644
index 0000000..abd42142
--- /dev/null
+++ b/camera/camera-core/api/restricted_1.4.0-beta01.txt
@@ -0,0 +1,716 @@
+// Signature format: 4.0
+package androidx.camera.core {
+
+  @RequiresApi(21) public class AspectRatio {
+    field public static final int RATIO_16_9 = 1; // 0x1
+    field public static final int RATIO_4_3 = 0; // 0x0
+    field public static final int RATIO_DEFAULT = -1; // 0xffffffff
+  }
+
+  @RequiresApi(21) public interface Camera {
+    method public androidx.camera.core.CameraControl getCameraControl();
+    method public androidx.camera.core.CameraInfo getCameraInfo();
+  }
+
+  @RequiresApi(21) public interface CameraControl {
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> cancelFocusAndMetering();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> enableTorch(boolean);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> setExposureCompensationIndex(int);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setLinearZoom(@FloatRange(from=0.0f, to=1.0f) float);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setZoomRatio(float);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.camera.core.FocusMeteringResult!> startFocusAndMetering(androidx.camera.core.FocusMeteringAction);
+  }
+
+  public static final class CameraControl.OperationCanceledException extends java.lang.Exception {
+  }
+
+  @RequiresApi(21) public abstract class CameraEffect {
+    ctor protected CameraEffect(int, java.util.concurrent.Executor, androidx.camera.core.ImageProcessor, androidx.core.util.Consumer<java.lang.Throwable!>);
+    ctor protected CameraEffect(int, java.util.concurrent.Executor, androidx.camera.core.SurfaceProcessor, androidx.core.util.Consumer<java.lang.Throwable!>);
+    method public androidx.core.util.Consumer<java.lang.Throwable!> getErrorListener();
+    method public java.util.concurrent.Executor getExecutor();
+    method public androidx.camera.core.SurfaceProcessor? getSurfaceProcessor();
+    method public int getTargets();
+    field public static final int IMAGE_CAPTURE = 4; // 0x4
+    field public static final int PREVIEW = 1; // 0x1
+    field public static final int VIDEO_CAPTURE = 2; // 0x2
+  }
+
+  @RequiresApi(21) public interface CameraFilter {
+    method public java.util.List<androidx.camera.core.CameraInfo!> filter(java.util.List<androidx.camera.core.CameraInfo!>);
+  }
+
+  @RequiresApi(21) public interface CameraInfo {
+    method public androidx.camera.core.CameraSelector getCameraSelector();
+    method public androidx.lifecycle.LiveData<androidx.camera.core.CameraState!> getCameraState();
+    method public androidx.camera.core.ExposureState getExposureState();
+    method @FloatRange(from=0, fromInclusive=false) public default float getIntrinsicZoomRatio();
+    method public default int getLensFacing();
+    method public int getSensorRotationDegrees();
+    method public int getSensorRotationDegrees(int);
+    method public default java.util.Set<android.util.Range<java.lang.Integer!>!> getSupportedFrameRateRanges();
+    method public androidx.lifecycle.LiveData<java.lang.Integer!> getTorchState();
+    method public androidx.lifecycle.LiveData<androidx.camera.core.ZoomState!> getZoomState();
+    method public boolean hasFlashUnit();
+    method public default boolean isFocusMeteringSupported(androidx.camera.core.FocusMeteringAction);
+    method @SuppressCompatibility @androidx.camera.core.ExperimentalZeroShutterLag public default boolean isZslSupported();
+    method public static boolean mustPlayShutterSound();
+    method public default java.util.Set<androidx.camera.core.DynamicRange!> querySupportedDynamicRanges(java.util.Set<androidx.camera.core.DynamicRange!>);
+  }
+
+  @RequiresApi(21) public final class CameraInfoUnavailableException extends java.lang.Exception {
+  }
+
+  @RequiresApi(21) public interface CameraProvider {
+    method public java.util.List<androidx.camera.core.CameraInfo!> getAvailableCameraInfos();
+    method public boolean hasCamera(androidx.camera.core.CameraSelector) throws androidx.camera.core.CameraInfoUnavailableException;
+  }
+
+  @RequiresApi(21) public final class CameraSelector {
+    method public java.util.List<androidx.camera.core.CameraInfo!> filter(java.util.List<androidx.camera.core.CameraInfo!>);
+    field public static final androidx.camera.core.CameraSelector DEFAULT_BACK_CAMERA;
+    field public static final androidx.camera.core.CameraSelector DEFAULT_FRONT_CAMERA;
+    field public static final int LENS_FACING_BACK = 1; // 0x1
+    field @SuppressCompatibility @androidx.camera.core.ExperimentalLensFacing public static final int LENS_FACING_EXTERNAL = 2; // 0x2
+    field public static final int LENS_FACING_FRONT = 0; // 0x0
+    field public static final int LENS_FACING_UNKNOWN = -1; // 0xffffffff
+  }
+
+  public static final class CameraSelector.Builder {
+    ctor public CameraSelector.Builder();
+    method public androidx.camera.core.CameraSelector.Builder addCameraFilter(androidx.camera.core.CameraFilter);
+    method public androidx.camera.core.CameraSelector build();
+    method public androidx.camera.core.CameraSelector.Builder requireLensFacing(int);
+  }
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class CameraState {
+    ctor public CameraState();
+    method public static androidx.camera.core.CameraState create(androidx.camera.core.CameraState.Type);
+    method public static androidx.camera.core.CameraState create(androidx.camera.core.CameraState.Type, androidx.camera.core.CameraState.StateError?);
+    method public abstract androidx.camera.core.CameraState.StateError? getError();
+    method public abstract androidx.camera.core.CameraState.Type getType();
+    field public static final int ERROR_CAMERA_DISABLED = 5; // 0x5
+    field public static final int ERROR_CAMERA_FATAL_ERROR = 6; // 0x6
+    field public static final int ERROR_CAMERA_IN_USE = 2; // 0x2
+    field public static final int ERROR_DO_NOT_DISTURB_MODE_ENABLED = 7; // 0x7
+    field public static final int ERROR_MAX_CAMERAS_IN_USE = 1; // 0x1
+    field public static final int ERROR_OTHER_RECOVERABLE_ERROR = 3; // 0x3
+    field public static final int ERROR_STREAM_CONFIG = 4; // 0x4
+  }
+
+  public enum CameraState.ErrorType {
+    enum_constant public static final androidx.camera.core.CameraState.ErrorType CRITICAL;
+    enum_constant public static final androidx.camera.core.CameraState.ErrorType RECOVERABLE;
+  }
+
+  @com.google.auto.value.AutoValue public abstract static class CameraState.StateError {
+    ctor public CameraState.StateError();
+    method public static androidx.camera.core.CameraState.StateError create(int);
+    method public static androidx.camera.core.CameraState.StateError create(int, Throwable?);
+    method public abstract Throwable? getCause();
+    method public abstract int getCode();
+    method public androidx.camera.core.CameraState.ErrorType getType();
+  }
+
+  public enum CameraState.Type {
+    enum_constant public static final androidx.camera.core.CameraState.Type CLOSED;
+    enum_constant public static final androidx.camera.core.CameraState.Type CLOSING;
+    enum_constant public static final androidx.camera.core.CameraState.Type OPEN;
+    enum_constant public static final androidx.camera.core.CameraState.Type OPENING;
+    enum_constant public static final androidx.camera.core.CameraState.Type PENDING_OPEN;
+  }
+
+  @RequiresApi(21) public class CameraUnavailableException extends java.lang.Exception {
+    ctor public CameraUnavailableException(int);
+    ctor public CameraUnavailableException(int, String?);
+    ctor public CameraUnavailableException(int, String?, Throwable?);
+    ctor public CameraUnavailableException(int, Throwable?);
+    method public int getReason();
+    field public static final int CAMERA_DISABLED = 1; // 0x1
+    field public static final int CAMERA_DISCONNECTED = 2; // 0x2
+    field public static final int CAMERA_ERROR = 3; // 0x3
+    field public static final int CAMERA_IN_USE = 4; // 0x4
+    field public static final int CAMERA_MAX_IN_USE = 5; // 0x5
+    field public static final int CAMERA_UNAVAILABLE_DO_NOT_DISTURB = 6; // 0x6
+    field public static final int CAMERA_UNKNOWN_ERROR = 0; // 0x0
+  }
+
+  @RequiresApi(21) public final class CameraXConfig {
+    method public androidx.camera.core.CameraSelector? getAvailableCamerasLimiter(androidx.camera.core.CameraSelector?);
+    method public java.util.concurrent.Executor? getCameraExecutor(java.util.concurrent.Executor?);
+    method public long getCameraOpenRetryMaxTimeoutInMillisWhileResuming();
+    method @SuppressCompatibility @androidx.camera.core.ExperimentalRetryPolicy public androidx.camera.core.RetryPolicy getCameraProviderInitRetryPolicy();
+    method public int getMinimumLoggingLevel();
+    method public android.os.Handler? getSchedulerHandler(android.os.Handler?);
+  }
+
+  public static final class CameraXConfig.Builder {
+    method public androidx.camera.core.CameraXConfig build();
+    method public static androidx.camera.core.CameraXConfig.Builder fromConfig(androidx.camera.core.CameraXConfig);
+    method public androidx.camera.core.CameraXConfig.Builder setAvailableCamerasLimiter(androidx.camera.core.CameraSelector);
+    method public androidx.camera.core.CameraXConfig.Builder setCameraExecutor(java.util.concurrent.Executor);
+    method public androidx.camera.core.CameraXConfig.Builder setCameraOpenRetryMaxTimeoutInMillisWhileResuming(long);
+    method @SuppressCompatibility @androidx.camera.core.ExperimentalRetryPolicy public androidx.camera.core.CameraXConfig.Builder setCameraProviderInitRetryPolicy(androidx.camera.core.RetryPolicy);
+    method public androidx.camera.core.CameraXConfig.Builder setMinimumLoggingLevel(@IntRange(from=android.util.Log.DEBUG, to=android.util.Log.ERROR) int);
+    method public androidx.camera.core.CameraXConfig.Builder setSchedulerHandler(android.os.Handler);
+  }
+
+  public static interface CameraXConfig.Provider {
+    method public androidx.camera.core.CameraXConfig getCameraXConfig();
+  }
+
+  @RequiresApi(21) public class ConcurrentCamera {
+    ctor public ConcurrentCamera(java.util.List<androidx.camera.core.Camera!>);
+    method public java.util.List<androidx.camera.core.Camera!> getCameras();
+  }
+
+  public static final class ConcurrentCamera.SingleCameraConfig {
+    ctor public ConcurrentCamera.SingleCameraConfig(androidx.camera.core.CameraSelector, androidx.camera.core.UseCaseGroup, androidx.lifecycle.LifecycleOwner);
+    method public androidx.camera.core.CameraSelector getCameraSelector();
+    method public androidx.lifecycle.LifecycleOwner getLifecycleOwner();
+    method public androidx.camera.core.UseCaseGroup getUseCaseGroup();
+  }
+
+  @RequiresApi(21) public final class DisplayOrientedMeteringPointFactory extends androidx.camera.core.MeteringPointFactory {
+    ctor public DisplayOrientedMeteringPointFactory(android.view.Display, androidx.camera.core.CameraInfo, float, float);
+  }
+
+  @RequiresApi(21) public final class DynamicRange {
+    ctor public DynamicRange(int, int);
+    method public int getBitDepth();
+    method public int getEncoding();
+    field public static final int BIT_DEPTH_10_BIT = 10; // 0xa
+    field public static final int BIT_DEPTH_8_BIT = 8; // 0x8
+    field public static final int BIT_DEPTH_UNSPECIFIED = 0; // 0x0
+    field public static final androidx.camera.core.DynamicRange DOLBY_VISION_10_BIT;
+    field public static final androidx.camera.core.DynamicRange DOLBY_VISION_8_BIT;
+    field public static final int ENCODING_DOLBY_VISION = 6; // 0x6
+    field public static final int ENCODING_HDR10 = 4; // 0x4
+    field public static final int ENCODING_HDR10_PLUS = 5; // 0x5
+    field public static final int ENCODING_HDR_UNSPECIFIED = 2; // 0x2
+    field public static final int ENCODING_HLG = 3; // 0x3
+    field public static final int ENCODING_SDR = 1; // 0x1
+    field public static final int ENCODING_UNSPECIFIED = 0; // 0x0
+    field public static final androidx.camera.core.DynamicRange HDR10_10_BIT;
+    field public static final androidx.camera.core.DynamicRange HDR10_PLUS_10_BIT;
+    field public static final androidx.camera.core.DynamicRange HDR_UNSPECIFIED_10_BIT;
+    field public static final androidx.camera.core.DynamicRange HLG_10_BIT;
+    field public static final androidx.camera.core.DynamicRange SDR;
+    field public static final androidx.camera.core.DynamicRange UNSPECIFIED;
+  }
+
+  @SuppressCompatibility @RequiresApi(21) @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalGetImage {
+  }
+
+  @SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalLensFacing {
+  }
+
+  @SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalRetryPolicy {
+  }
+
+  @SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalUseCaseApi {
+  }
+
+  @SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalZeroShutterLag {
+  }
+
+  @RequiresApi(21) public interface ExposureState {
+    method public int getExposureCompensationIndex();
+    method public android.util.Range<java.lang.Integer!> getExposureCompensationRange();
+    method public android.util.Rational getExposureCompensationStep();
+    method public boolean isExposureCompensationSupported();
+  }
+
+  @RequiresApi(21) public interface ExtendableBuilder<T> {
+    method public T build();
+  }
+
+  @RequiresApi(21) public final class FocusMeteringAction {
+    method public long getAutoCancelDurationInMillis();
+    method public java.util.List<androidx.camera.core.MeteringPoint!> getMeteringPointsAe();
+    method public java.util.List<androidx.camera.core.MeteringPoint!> getMeteringPointsAf();
+    method public java.util.List<androidx.camera.core.MeteringPoint!> getMeteringPointsAwb();
+    method public boolean isAutoCancelEnabled();
+    field public static final int FLAG_AE = 2; // 0x2
+    field public static final int FLAG_AF = 1; // 0x1
+    field public static final int FLAG_AWB = 4; // 0x4
+  }
+
+  public static class FocusMeteringAction.Builder {
+    ctor public FocusMeteringAction.Builder(androidx.camera.core.MeteringPoint);
+    ctor public FocusMeteringAction.Builder(androidx.camera.core.MeteringPoint, int);
+    method public androidx.camera.core.FocusMeteringAction.Builder addPoint(androidx.camera.core.MeteringPoint);
+    method public androidx.camera.core.FocusMeteringAction.Builder addPoint(androidx.camera.core.MeteringPoint, int);
+    method public androidx.camera.core.FocusMeteringAction build();
+    method public androidx.camera.core.FocusMeteringAction.Builder disableAutoCancel();
+    method public androidx.camera.core.FocusMeteringAction.Builder setAutoCancelDuration(@IntRange(from=1) long, java.util.concurrent.TimeUnit);
+  }
+
+  @RequiresApi(21) public final class FocusMeteringResult {
+    method public boolean isFocusSuccessful();
+  }
+
+  @RequiresApi(21) public final class ImageAnalysis extends androidx.camera.core.UseCase {
+    method public void clearAnalyzer();
+    method @SuppressCompatibility @androidx.camera.core.ExperimentalUseCaseApi public java.util.concurrent.Executor? getBackgroundExecutor();
+    method public int getBackpressureStrategy();
+    method public int getImageQueueDepth();
+    method public int getOutputImageFormat();
+    method public androidx.camera.core.ResolutionInfo? getResolutionInfo();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector? getResolutionSelector();
+    method public int getTargetRotation();
+    method public boolean isOutputImageRotationEnabled();
+    method public void setAnalyzer(java.util.concurrent.Executor, androidx.camera.core.ImageAnalysis.Analyzer);
+    method public void setTargetRotation(int);
+    field public static final int COORDINATE_SYSTEM_ORIGINAL = 0; // 0x0
+    field public static final int COORDINATE_SYSTEM_SENSOR = 2; // 0x2
+    field public static final int OUTPUT_IMAGE_FORMAT_RGBA_8888 = 2; // 0x2
+    field public static final int OUTPUT_IMAGE_FORMAT_YUV_420_888 = 1; // 0x1
+    field public static final int STRATEGY_BLOCK_PRODUCER = 1; // 0x1
+    field public static final int STRATEGY_KEEP_ONLY_LATEST = 0; // 0x0
+  }
+
+  public static interface ImageAnalysis.Analyzer {
+    method public void analyze(androidx.camera.core.ImageProxy);
+    method public default android.util.Size? getDefaultTargetResolution();
+    method public default int getTargetCoordinateSystem();
+    method public default void updateTransform(android.graphics.Matrix?);
+  }
+
+  public static final class ImageAnalysis.Builder implements androidx.camera.core.ExtendableBuilder<androidx.camera.core.ImageAnalysis!> {
+    ctor public ImageAnalysis.Builder();
+    method public androidx.camera.core.ImageAnalysis build();
+    method public androidx.camera.core.ImageAnalysis.Builder setBackgroundExecutor(java.util.concurrent.Executor);
+    method public androidx.camera.core.ImageAnalysis.Builder setBackpressureStrategy(int);
+    method public androidx.camera.core.ImageAnalysis.Builder setImageQueueDepth(int);
+    method public androidx.camera.core.ImageAnalysis.Builder setOutputImageFormat(int);
+    method @RequiresApi(23) public androidx.camera.core.ImageAnalysis.Builder setOutputImageRotationEnabled(boolean);
+    method public androidx.camera.core.ImageAnalysis.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
+    method @Deprecated public androidx.camera.core.ImageAnalysis.Builder setTargetAspectRatio(int);
+    method public androidx.camera.core.ImageAnalysis.Builder setTargetName(String);
+    method @Deprecated public androidx.camera.core.ImageAnalysis.Builder setTargetResolution(android.util.Size);
+    method public androidx.camera.core.ImageAnalysis.Builder setTargetRotation(int);
+  }
+
+  @RequiresApi(21) public final class ImageCapture extends androidx.camera.core.UseCase {
+    method public int getCaptureMode();
+    method public int getFlashMode();
+    method public static androidx.camera.core.ImageCaptureCapabilities getImageCaptureCapabilities(androidx.camera.core.CameraInfo);
+    method @IntRange(from=1, to=100) public int getJpegQuality();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector? getPostviewResolutionSelector();
+    method public androidx.camera.core.ImageCaptureLatencyEstimate getRealtimeCaptureLatencyEstimate();
+    method public androidx.camera.core.ResolutionInfo? getResolutionInfo();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector? getResolutionSelector();
+    method public androidx.camera.core.ImageCapture.ScreenFlash? getScreenFlash();
+    method public int getTargetRotation();
+    method public boolean isPostviewEnabled();
+    method public void setCropAspectRatio(android.util.Rational);
+    method public void setFlashMode(int);
+    method public void setScreenFlash(androidx.camera.core.ImageCapture.ScreenFlash?);
+    method public void setTargetRotation(int);
+    method public void takePicture(androidx.camera.core.ImageCapture.OutputFileOptions, java.util.concurrent.Executor, androidx.camera.core.ImageCapture.OnImageSavedCallback);
+    method public void takePicture(java.util.concurrent.Executor, androidx.camera.core.ImageCapture.OnImageCapturedCallback);
+    field public static final int CAPTURE_MODE_MAXIMIZE_QUALITY = 0; // 0x0
+    field public static final int CAPTURE_MODE_MINIMIZE_LATENCY = 1; // 0x1
+    field @SuppressCompatibility @androidx.camera.core.ExperimentalZeroShutterLag public static final int CAPTURE_MODE_ZERO_SHUTTER_LAG = 2; // 0x2
+    field public static final int ERROR_CAMERA_CLOSED = 3; // 0x3
+    field public static final int ERROR_CAPTURE_FAILED = 2; // 0x2
+    field public static final int ERROR_FILE_IO = 1; // 0x1
+    field public static final int ERROR_INVALID_CAMERA = 4; // 0x4
+    field public static final int ERROR_UNKNOWN = 0; // 0x0
+    field public static final int FLASH_MODE_AUTO = 0; // 0x0
+    field public static final int FLASH_MODE_OFF = 2; // 0x2
+    field public static final int FLASH_MODE_ON = 1; // 0x1
+    field public static final int FLASH_MODE_SCREEN = 3; // 0x3
+  }
+
+  public static final class ImageCapture.Builder implements androidx.camera.core.ExtendableBuilder<androidx.camera.core.ImageCapture!> {
+    ctor public ImageCapture.Builder();
+    method public androidx.camera.core.ImageCapture build();
+    method public androidx.camera.core.ImageCapture.Builder setCaptureMode(int);
+    method public androidx.camera.core.ImageCapture.Builder setFlashMode(int);
+    method public androidx.camera.core.ImageCapture.Builder setIoExecutor(java.util.concurrent.Executor);
+    method public androidx.camera.core.ImageCapture.Builder setJpegQuality(@IntRange(from=1, to=100) int);
+    method public androidx.camera.core.ImageCapture.Builder setPostviewEnabled(boolean);
+    method public androidx.camera.core.ImageCapture.Builder setPostviewResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
+    method public androidx.camera.core.ImageCapture.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
+    method public androidx.camera.core.ImageCapture.Builder setScreenFlash(androidx.camera.core.ImageCapture.ScreenFlash);
+    method @Deprecated public androidx.camera.core.ImageCapture.Builder setTargetAspectRatio(int);
+    method public androidx.camera.core.ImageCapture.Builder setTargetName(String);
+    method @Deprecated public androidx.camera.core.ImageCapture.Builder setTargetResolution(android.util.Size);
+    method public androidx.camera.core.ImageCapture.Builder setTargetRotation(int);
+  }
+
+  public static final class ImageCapture.Metadata {
+    ctor public ImageCapture.Metadata();
+    method public android.location.Location? getLocation();
+    method public boolean isReversedHorizontal();
+    method public boolean isReversedVertical();
+    method public void setLocation(android.location.Location?);
+    method public void setReversedHorizontal(boolean);
+    method public void setReversedVertical(boolean);
+  }
+
+  public abstract static class ImageCapture.OnImageCapturedCallback {
+    ctor public ImageCapture.OnImageCapturedCallback();
+    method public void onCaptureProcessProgressed(int);
+    method public void onCaptureStarted();
+    method public void onCaptureSuccess(androidx.camera.core.ImageProxy);
+    method public void onError(androidx.camera.core.ImageCaptureException);
+    method public void onPostviewBitmapAvailable(android.graphics.Bitmap);
+  }
+
+  public static interface ImageCapture.OnImageSavedCallback {
+    method public default void onCaptureProcessProgressed(int);
+    method public default void onCaptureStarted();
+    method public void onError(androidx.camera.core.ImageCaptureException);
+    method public void onImageSaved(androidx.camera.core.ImageCapture.OutputFileResults);
+    method public default void onPostviewBitmapAvailable(android.graphics.Bitmap);
+  }
+
+  public static final class ImageCapture.OutputFileOptions {
+  }
+
+  public static final class ImageCapture.OutputFileOptions.Builder {
+    ctor public ImageCapture.OutputFileOptions.Builder(android.content.ContentResolver, android.net.Uri, android.content.ContentValues);
+    ctor public ImageCapture.OutputFileOptions.Builder(java.io.File);
+    ctor public ImageCapture.OutputFileOptions.Builder(java.io.OutputStream);
+    method public androidx.camera.core.ImageCapture.OutputFileOptions build();
+    method public androidx.camera.core.ImageCapture.OutputFileOptions.Builder setMetadata(androidx.camera.core.ImageCapture.Metadata);
+  }
+
+  public static class ImageCapture.OutputFileResults {
+    method public android.net.Uri? getSavedUri();
+  }
+
+  public static interface ImageCapture.ScreenFlash {
+    method @UiThread public void apply(long, androidx.camera.core.ImageCapture.ScreenFlashListener);
+    method @UiThread public void clear();
+  }
+
+  public static interface ImageCapture.ScreenFlashListener {
+    method public void onCompleted();
+  }
+
+  public interface ImageCaptureCapabilities {
+    method public boolean isCaptureProcessProgressSupported();
+    method public boolean isPostviewSupported();
+  }
+
+  @RequiresApi(21) public class ImageCaptureException extends java.lang.Exception {
+    ctor public ImageCaptureException(int, String, Throwable?);
+    method public int getImageCaptureError();
+  }
+
+  @RequiresApi(21) public class ImageCaptureLatencyEstimate {
+    ctor public ImageCaptureLatencyEstimate(long, long);
+    method public long getCaptureLatencyMillis();
+    method public long getProcessingLatencyMillis();
+    method public long getTotalCaptureLatencyMillis();
+    field public static final long UNDEFINED_CAPTURE_LATENCY = -1L; // 0xffffffffffffffffL
+    field public static final androidx.camera.core.ImageCaptureLatencyEstimate UNDEFINED_IMAGE_CAPTURE_LATENCY;
+    field public static final long UNDEFINED_PROCESSING_LATENCY = -1L; // 0xffffffffffffffffL
+  }
+
+  @RequiresApi(21) public interface ImageInfo {
+    method public int getRotationDegrees();
+    method public default android.graphics.Matrix getSensorToBufferTransformMatrix();
+    method public long getTimestamp();
+  }
+
+  public interface ImageProcessor {
+    method public androidx.camera.core.ImageProcessor.Response process(androidx.camera.core.ImageProcessor.Request) throws androidx.camera.core.ProcessingException;
+  }
+
+  public static interface ImageProcessor.Request {
+    method public androidx.camera.core.ImageProxy getInputImage();
+    method public int getOutputFormat();
+  }
+
+  public static interface ImageProcessor.Response {
+    method public androidx.camera.core.ImageProxy getOutputImage();
+  }
+
+  @RequiresApi(21) public interface ImageProxy extends java.lang.AutoCloseable {
+    method public void close();
+    method public android.graphics.Rect getCropRect();
+    method public int getFormat();
+    method public int getHeight();
+    method @SuppressCompatibility @androidx.camera.core.ExperimentalGetImage public android.media.Image? getImage();
+    method public androidx.camera.core.ImageInfo getImageInfo();
+    method public androidx.camera.core.ImageProxy.PlaneProxy![] getPlanes();
+    method public int getWidth();
+    method public void setCropRect(android.graphics.Rect?);
+    method public default android.graphics.Bitmap toBitmap();
+  }
+
+  public static interface ImageProxy.PlaneProxy {
+    method public java.nio.ByteBuffer getBuffer();
+    method public int getPixelStride();
+    method public int getRowStride();
+  }
+
+  @RequiresApi(21) public class InitializationException extends java.lang.Exception {
+    ctor public InitializationException(String?);
+    ctor public InitializationException(String?, Throwable?);
+    ctor public InitializationException(Throwable?);
+  }
+
+  @RequiresApi(21) public class MeteringPoint {
+    method public float getSize();
+  }
+
+  @RequiresApi(21) public abstract class MeteringPointFactory {
+    method public final androidx.camera.core.MeteringPoint createPoint(float, float);
+    method public final androidx.camera.core.MeteringPoint createPoint(float, float, float);
+    method public static float getDefaultPointSize();
+  }
+
+  @RequiresApi(21) public class MirrorMode {
+    field public static final int MIRROR_MODE_OFF = 0; // 0x0
+    field public static final int MIRROR_MODE_ON = 1; // 0x1
+    field public static final int MIRROR_MODE_ON_FRONT_ONLY = 2; // 0x2
+  }
+
+  @RequiresApi(21) public final class Preview extends androidx.camera.core.UseCase {
+    method public androidx.camera.core.DynamicRange getDynamicRange();
+    method public static androidx.camera.core.PreviewCapabilities getPreviewCapabilities(androidx.camera.core.CameraInfo);
+    method public androidx.camera.core.ResolutionInfo? getResolutionInfo();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector? getResolutionSelector();
+    method public android.util.Range<java.lang.Integer!> getTargetFrameRate();
+    method public int getTargetRotation();
+    method public boolean isPreviewStabilizationEnabled();
+    method @UiThread public void setSurfaceProvider(androidx.camera.core.Preview.SurfaceProvider?);
+    method @UiThread public void setSurfaceProvider(java.util.concurrent.Executor, androidx.camera.core.Preview.SurfaceProvider?);
+    method public void setTargetRotation(int);
+  }
+
+  public static final class Preview.Builder implements androidx.camera.core.ExtendableBuilder<androidx.camera.core.Preview!> {
+    ctor public Preview.Builder();
+    method public androidx.camera.core.Preview build();
+    method public androidx.camera.core.Preview.Builder setDynamicRange(androidx.camera.core.DynamicRange);
+    method public androidx.camera.core.Preview.Builder setPreviewStabilizationEnabled(boolean);
+    method public androidx.camera.core.Preview.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
+    method @Deprecated public androidx.camera.core.Preview.Builder setTargetAspectRatio(int);
+    method public androidx.camera.core.Preview.Builder setTargetFrameRate(android.util.Range<java.lang.Integer!>);
+    method public androidx.camera.core.Preview.Builder setTargetName(String);
+    method @Deprecated public androidx.camera.core.Preview.Builder setTargetResolution(android.util.Size);
+    method public androidx.camera.core.Preview.Builder setTargetRotation(int);
+  }
+
+  public static interface Preview.SurfaceProvider {
+    method public void onSurfaceRequested(androidx.camera.core.SurfaceRequest);
+  }
+
+  @RequiresApi(21) public interface PreviewCapabilities {
+    method public boolean isStabilizationSupported();
+  }
+
+  public class ProcessingException extends java.lang.Exception {
+    ctor public ProcessingException();
+  }
+
+  @RequiresApi(21) public class ResolutionInfo {
+    ctor public ResolutionInfo(android.util.Size, android.graphics.Rect, int);
+    method public android.graphics.Rect getCropRect();
+    method public android.util.Size getResolution();
+    method public int getRotationDegrees();
+  }
+
+  @SuppressCompatibility @RequiresApi(21) @androidx.camera.core.ExperimentalRetryPolicy public interface RetryPolicy {
+    method public static long getDefaultRetryTimeoutInMillis();
+    method public default long getTimeoutInMillis();
+    method public androidx.camera.core.RetryPolicy.RetryConfig onRetryDecisionRequested(androidx.camera.core.RetryPolicy.ExecutionState);
+    field public static final androidx.camera.core.RetryPolicy DEFAULT;
+    field public static final androidx.camera.core.RetryPolicy NEVER;
+    field public static final androidx.camera.core.RetryPolicy RETRY_UNAVAILABLE_CAMERA;
+  }
+
+  @SuppressCompatibility @androidx.camera.core.ExperimentalRetryPolicy public static final class RetryPolicy.Builder {
+    ctor public RetryPolicy.Builder(androidx.camera.core.RetryPolicy);
+    method public androidx.camera.core.RetryPolicy build();
+    method public androidx.camera.core.RetryPolicy.Builder setTimeoutInMillis(long);
+  }
+
+  @SuppressCompatibility @androidx.camera.core.ExperimentalRetryPolicy public static interface RetryPolicy.ExecutionState {
+    method public Throwable? getCause();
+    method public long getExecutedTimeInMillis();
+    method public int getNumOfAttempts();
+    method public int getStatus();
+    field public static final int STATUS_CAMERA_UNAVAILABLE = 2; // 0x2
+    field public static final int STATUS_CONFIGURATION_FAIL = 1; // 0x1
+    field public static final int STATUS_UNKNOWN_ERROR = 0; // 0x0
+  }
+
+  @SuppressCompatibility @androidx.camera.core.ExperimentalRetryPolicy public static final class RetryPolicy.RetryConfig {
+    method public static long getDefaultRetryDelayInMillis();
+    method public long getRetryDelayInMillis();
+    method public boolean shouldRetry();
+    field public static final androidx.camera.core.RetryPolicy.RetryConfig DEFAULT_DELAY_RETRY;
+    field public static final androidx.camera.core.RetryPolicy.RetryConfig MINI_DELAY_RETRY;
+    field public static final androidx.camera.core.RetryPolicy.RetryConfig NOT_RETRY;
+  }
+
+  @SuppressCompatibility @androidx.camera.core.ExperimentalRetryPolicy public static final class RetryPolicy.RetryConfig.Builder {
+    ctor public RetryPolicy.RetryConfig.Builder();
+    method public androidx.camera.core.RetryPolicy.RetryConfig build();
+    method public androidx.camera.core.RetryPolicy.RetryConfig.Builder setRetryDelayInMillis(@IntRange(from=100, to=2000) long);
+    method public androidx.camera.core.RetryPolicy.RetryConfig.Builder setShouldRetry(boolean);
+  }
+
+  @RequiresApi(21) public class SurfaceOrientedMeteringPointFactory extends androidx.camera.core.MeteringPointFactory {
+    ctor public SurfaceOrientedMeteringPointFactory(float, float);
+    ctor public SurfaceOrientedMeteringPointFactory(float, float, androidx.camera.core.UseCase);
+  }
+
+  public interface SurfaceOutput extends java.io.Closeable {
+    method public void close();
+    method public default android.graphics.Matrix getSensorToBufferTransform();
+    method public android.util.Size getSize();
+    method public android.view.Surface getSurface(java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.core.SurfaceOutput.Event!>);
+    method public int getTargets();
+    method public void updateTransformMatrix(float[], float[]);
+  }
+
+  @com.google.auto.value.AutoValue public abstract static class SurfaceOutput.Event {
+    method public abstract int getEventCode();
+    method public abstract androidx.camera.core.SurfaceOutput getSurfaceOutput();
+    field public static final int EVENT_REQUEST_CLOSE = 0; // 0x0
+  }
+
+  public interface SurfaceProcessor {
+    method public void onInputSurface(androidx.camera.core.SurfaceRequest) throws androidx.camera.core.ProcessingException;
+    method public void onOutputSurface(androidx.camera.core.SurfaceOutput) throws androidx.camera.core.ProcessingException;
+  }
+
+  @RequiresApi(21) public final class SurfaceRequest {
+    method public void addRequestCancellationListener(java.util.concurrent.Executor, Runnable);
+    method public void clearTransformationInfoListener();
+    method public androidx.camera.core.DynamicRange getDynamicRange();
+    method public android.util.Size getResolution();
+    method public boolean invalidate();
+    method public void provideSurface(android.view.Surface, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.core.SurfaceRequest.Result!>);
+    method public void setTransformationInfoListener(java.util.concurrent.Executor, androidx.camera.core.SurfaceRequest.TransformationInfoListener);
+    method public boolean willNotProvideSurface();
+  }
+
+  @com.google.auto.value.AutoValue public abstract static class SurfaceRequest.Result {
+    method public abstract int getResultCode();
+    method public abstract android.view.Surface getSurface();
+    field public static final int RESULT_INVALID_SURFACE = 2; // 0x2
+    field public static final int RESULT_REQUEST_CANCELLED = 1; // 0x1
+    field public static final int RESULT_SURFACE_ALREADY_PROVIDED = 3; // 0x3
+    field public static final int RESULT_SURFACE_USED_SUCCESSFULLY = 0; // 0x0
+    field public static final int RESULT_WILL_NOT_PROVIDE_SURFACE = 4; // 0x4
+  }
+
+  @com.google.auto.value.AutoValue public abstract static class SurfaceRequest.TransformationInfo {
+    method public abstract android.graphics.Rect getCropRect();
+    method public abstract int getRotationDegrees();
+    method public abstract android.graphics.Matrix getSensorToBufferTransform();
+    method public abstract boolean hasCameraTransform();
+    method public abstract boolean isMirroring();
+  }
+
+  public static interface SurfaceRequest.TransformationInfoListener {
+    method public void onTransformationInfoUpdate(androidx.camera.core.SurfaceRequest.TransformationInfo);
+  }
+
+  @RequiresApi(21) public class TorchState {
+    field public static final int OFF = 0; // 0x0
+    field public static final int ON = 1; // 0x1
+  }
+
+  @RequiresApi(21) public abstract class UseCase {
+    method public static int snapToSurfaceRotation(@IntRange(from=0, to=359) int);
+  }
+
+  @RequiresApi(21) public final class UseCaseGroup {
+    method public java.util.List<androidx.camera.core.CameraEffect!> getEffects();
+    method public java.util.List<androidx.camera.core.UseCase!> getUseCases();
+    method public androidx.camera.core.ViewPort? getViewPort();
+  }
+
+  public static final class UseCaseGroup.Builder {
+    ctor public UseCaseGroup.Builder();
+    method public androidx.camera.core.UseCaseGroup.Builder addEffect(androidx.camera.core.CameraEffect);
+    method public androidx.camera.core.UseCaseGroup.Builder addUseCase(androidx.camera.core.UseCase);
+    method public androidx.camera.core.UseCaseGroup build();
+    method public androidx.camera.core.UseCaseGroup.Builder setViewPort(androidx.camera.core.ViewPort);
+  }
+
+  @RequiresApi(21) public final class ViewPort {
+    method public android.util.Rational getAspectRatio();
+    method public int getLayoutDirection();
+    method public int getRotation();
+    method public int getScaleType();
+    field public static final int FILL_CENTER = 1; // 0x1
+    field public static final int FILL_END = 2; // 0x2
+    field public static final int FILL_START = 0; // 0x0
+    field public static final int FIT = 3; // 0x3
+  }
+
+  public static final class ViewPort.Builder {
+    ctor public ViewPort.Builder(android.util.Rational, int);
+    method public androidx.camera.core.ViewPort build();
+    method public androidx.camera.core.ViewPort.Builder setLayoutDirection(int);
+    method public androidx.camera.core.ViewPort.Builder setScaleType(int);
+  }
+
+  @RequiresApi(21) public interface ZoomState {
+    method public float getLinearZoom();
+    method public float getMaxZoomRatio();
+    method public float getMinZoomRatio();
+    method public float getZoomRatio();
+  }
+
+}
+
+package androidx.camera.core.resolutionselector {
+
+  @RequiresApi(21) public final class AspectRatioStrategy {
+    ctor public AspectRatioStrategy(int, int);
+    method public int getFallbackRule();
+    method public int getPreferredAspectRatio();
+    field public static final int FALLBACK_RULE_AUTO = 1; // 0x1
+    field public static final int FALLBACK_RULE_NONE = 0; // 0x0
+    field public static final androidx.camera.core.resolutionselector.AspectRatioStrategy RATIO_16_9_FALLBACK_AUTO_STRATEGY;
+    field public static final androidx.camera.core.resolutionselector.AspectRatioStrategy RATIO_4_3_FALLBACK_AUTO_STRATEGY;
+  }
+
+  @RequiresApi(21) public interface ResolutionFilter {
+    method public java.util.List<android.util.Size!> filter(java.util.List<android.util.Size!>, int);
+  }
+
+  @RequiresApi(21) public final class ResolutionSelector {
+    method public int getAllowedResolutionMode();
+    method public androidx.camera.core.resolutionselector.AspectRatioStrategy getAspectRatioStrategy();
+    method public androidx.camera.core.resolutionselector.ResolutionFilter? getResolutionFilter();
+    method public androidx.camera.core.resolutionselector.ResolutionStrategy? getResolutionStrategy();
+    field public static final int PREFER_CAPTURE_RATE_OVER_HIGHER_RESOLUTION = 0; // 0x0
+    field public static final int PREFER_HIGHER_RESOLUTION_OVER_CAPTURE_RATE = 1; // 0x1
+  }
+
+  public static final class ResolutionSelector.Builder {
+    ctor public ResolutionSelector.Builder();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector build();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector.Builder setAllowedResolutionMode(int);
+    method public androidx.camera.core.resolutionselector.ResolutionSelector.Builder setAspectRatioStrategy(androidx.camera.core.resolutionselector.AspectRatioStrategy);
+    method public androidx.camera.core.resolutionselector.ResolutionSelector.Builder setResolutionFilter(androidx.camera.core.resolutionselector.ResolutionFilter);
+    method public androidx.camera.core.resolutionselector.ResolutionSelector.Builder setResolutionStrategy(androidx.camera.core.resolutionselector.ResolutionStrategy);
+  }
+
+  @RequiresApi(21) public final class ResolutionStrategy {
+    ctor public ResolutionStrategy(android.util.Size, int);
+    method public android.util.Size? getBoundSize();
+    method public int getFallbackRule();
+    field public static final int FALLBACK_RULE_CLOSEST_HIGHER = 2; // 0x2
+    field public static final int FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER = 1; // 0x1
+    field public static final int FALLBACK_RULE_CLOSEST_LOWER = 4; // 0x4
+    field public static final int FALLBACK_RULE_CLOSEST_LOWER_THEN_HIGHER = 3; // 0x3
+    field public static final int FALLBACK_RULE_NONE = 0; // 0x0
+    field public static final androidx.camera.core.resolutionselector.ResolutionStrategy HIGHEST_AVAILABLE_STRATEGY;
+  }
+
+}
+
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraInfo.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraInfo.java
index 1ae1ec4..846b3a8 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraInfo.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraInfo.java
@@ -330,6 +330,18 @@
     }
 
     /**
+     * Returns if logical multi camera is supported on the device.
+     *
+     * @return true if supported, otherwise false.
+     * @see android.hardware.camera2.CameraMetadata
+     * #REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    default boolean isLogicalMultiCameraSupported() {
+        return false;
+    }
+
+    /**
      * Returns if {@link ImageFormat#PRIVATE} reprocessing is supported on the device.
      *
      * @return true if supported, otherwise false.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/ForwardingCameraInfo.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/ForwardingCameraInfo.java
index 1cd1453..cbdfa54 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/ForwardingCameraInfo.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/ForwardingCameraInfo.java
@@ -130,6 +130,11 @@
         return mCameraInfoInternal.isPrivateReprocessingSupported();
     }
 
+    @Override
+    public boolean isLogicalMultiCameraSupported() {
+        return mCameraInfoInternal.isLogicalMultiCameraSupported();
+    }
+
     @NonNull
     @Override
     public String getCameraId() {
diff --git a/camera/camera-effects-still-portrait/api/1.4.0-beta01.txt b/camera/camera-effects-still-portrait/api/1.4.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/camera/camera-effects-still-portrait/api/1.4.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/camera/camera-effects-still-portrait/api/res-1.4.0-beta01.txt b/camera/camera-effects-still-portrait/api/res-1.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/camera/camera-effects-still-portrait/api/res-1.4.0-beta01.txt
diff --git a/camera/camera-effects-still-portrait/api/restricted_1.4.0-beta01.txt b/camera/camera-effects-still-portrait/api/restricted_1.4.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/camera/camera-effects-still-portrait/api/restricted_1.4.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/camera/camera-effects/api/1.4.0-beta01.txt b/camera/camera-effects/api/1.4.0-beta01.txt
new file mode 100644
index 0000000..e47a913
--- /dev/null
+++ b/camera/camera-effects/api/1.4.0-beta01.txt
@@ -0,0 +1,30 @@
+// Signature format: 4.0
+package androidx.camera.effects {
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class Frame {
+    ctor public Frame();
+    method public abstract android.graphics.Rect getCropRect();
+    method public android.graphics.Canvas getOverlayCanvas();
+    method @IntRange(from=0, to=359) public abstract int getRotationDegrees();
+    method public abstract android.graphics.Matrix getSensorToBufferTransform();
+    method public abstract android.util.Size getSize();
+    method public abstract long getTimestampNanos();
+    method public abstract boolean isMirroring();
+  }
+
+  @RequiresApi(21) public class OverlayEffect extends androidx.camera.core.CameraEffect implements java.lang.AutoCloseable {
+    ctor public OverlayEffect(int, int, android.os.Handler, androidx.core.util.Consumer<java.lang.Throwable!>);
+    method public void clearOnDrawListener();
+    method public void close();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> drawFrameAsync(long);
+    method public android.os.Handler getHandler();
+    method public int getQueueDepth();
+    method public void setOnDrawListener(androidx.arch.core.util.Function<androidx.camera.effects.Frame!,java.lang.Boolean!>);
+    field public static final int RESULT_CANCELLED_BY_CALLER = 4; // 0x4
+    field public static final int RESULT_FRAME_NOT_FOUND = 2; // 0x2
+    field public static final int RESULT_INVALID_SURFACE = 3; // 0x3
+    field public static final int RESULT_SUCCESS = 1; // 0x1
+  }
+
+}
+
diff --git a/camera/camera-effects/api/res-1.4.0-beta01.txt b/camera/camera-effects/api/res-1.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/camera/camera-effects/api/res-1.4.0-beta01.txt
diff --git a/camera/camera-effects/api/restricted_1.4.0-beta01.txt b/camera/camera-effects/api/restricted_1.4.0-beta01.txt
new file mode 100644
index 0000000..e47a913
--- /dev/null
+++ b/camera/camera-effects/api/restricted_1.4.0-beta01.txt
@@ -0,0 +1,30 @@
+// Signature format: 4.0
+package androidx.camera.effects {
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class Frame {
+    ctor public Frame();
+    method public abstract android.graphics.Rect getCropRect();
+    method public android.graphics.Canvas getOverlayCanvas();
+    method @IntRange(from=0, to=359) public abstract int getRotationDegrees();
+    method public abstract android.graphics.Matrix getSensorToBufferTransform();
+    method public abstract android.util.Size getSize();
+    method public abstract long getTimestampNanos();
+    method public abstract boolean isMirroring();
+  }
+
+  @RequiresApi(21) public class OverlayEffect extends androidx.camera.core.CameraEffect implements java.lang.AutoCloseable {
+    ctor public OverlayEffect(int, int, android.os.Handler, androidx.core.util.Consumer<java.lang.Throwable!>);
+    method public void clearOnDrawListener();
+    method public void close();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> drawFrameAsync(long);
+    method public android.os.Handler getHandler();
+    method public int getQueueDepth();
+    method public void setOnDrawListener(androidx.arch.core.util.Function<androidx.camera.effects.Frame!,java.lang.Boolean!>);
+    field public static final int RESULT_CANCELLED_BY_CALLER = 4; // 0x4
+    field public static final int RESULT_FRAME_NOT_FOUND = 2; // 0x2
+    field public static final int RESULT_INVALID_SURFACE = 3; // 0x3
+    field public static final int RESULT_SUCCESS = 1; // 0x1
+  }
+
+}
+
diff --git a/camera/camera-extensions/api/1.4.0-beta01.txt b/camera/camera-extensions/api/1.4.0-beta01.txt
new file mode 100644
index 0000000..f365e3d
--- /dev/null
+++ b/camera/camera-extensions/api/1.4.0-beta01.txt
@@ -0,0 +1,35 @@
+// Signature format: 4.0
+package androidx.camera.extensions {
+
+  public interface CameraExtensionsControl {
+    method public default void setExtensionStrength(@IntRange(from=0, to=100) int);
+  }
+
+  public interface CameraExtensionsInfo {
+    method public default androidx.lifecycle.LiveData<java.lang.Integer!>? getCurrentExtensionMode();
+    method public default androidx.lifecycle.LiveData<java.lang.Integer!>? getExtensionStrength();
+    method public default boolean isCurrentExtensionModeAvailable();
+    method public default boolean isExtensionStrengthAvailable();
+  }
+
+  @RequiresApi(21) public final class ExtensionMode {
+    field public static final int AUTO = 5; // 0x5
+    field public static final int BOKEH = 1; // 0x1
+    field public static final int FACE_RETOUCH = 4; // 0x4
+    field public static final int HDR = 2; // 0x2
+    field public static final int NIGHT = 3; // 0x3
+    field public static final int NONE = 0; // 0x0
+  }
+
+  @RequiresApi(21) public final class ExtensionsManager {
+    method public androidx.camera.extensions.CameraExtensionsControl? getCameraExtensionsControl(androidx.camera.core.CameraControl);
+    method public androidx.camera.extensions.CameraExtensionsInfo getCameraExtensionsInfo(androidx.camera.core.CameraInfo);
+    method public android.util.Range<java.lang.Long!>? getEstimatedCaptureLatencyRange(androidx.camera.core.CameraSelector, int);
+    method public androidx.camera.core.CameraSelector getExtensionEnabledCameraSelector(androidx.camera.core.CameraSelector, int);
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.camera.extensions.ExtensionsManager!> getInstanceAsync(android.content.Context, androidx.camera.core.CameraProvider);
+    method public boolean isExtensionAvailable(androidx.camera.core.CameraSelector, int);
+    method public boolean isImageAnalysisSupported(androidx.camera.core.CameraSelector, int);
+  }
+
+}
+
diff --git a/camera/camera-extensions/api/res-1.4.0-beta01.txt b/camera/camera-extensions/api/res-1.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/camera/camera-extensions/api/res-1.4.0-beta01.txt
diff --git a/camera/camera-extensions/api/restricted_1.4.0-beta01.txt b/camera/camera-extensions/api/restricted_1.4.0-beta01.txt
new file mode 100644
index 0000000..f365e3d
--- /dev/null
+++ b/camera/camera-extensions/api/restricted_1.4.0-beta01.txt
@@ -0,0 +1,35 @@
+// Signature format: 4.0
+package androidx.camera.extensions {
+
+  public interface CameraExtensionsControl {
+    method public default void setExtensionStrength(@IntRange(from=0, to=100) int);
+  }
+
+  public interface CameraExtensionsInfo {
+    method public default androidx.lifecycle.LiveData<java.lang.Integer!>? getCurrentExtensionMode();
+    method public default androidx.lifecycle.LiveData<java.lang.Integer!>? getExtensionStrength();
+    method public default boolean isCurrentExtensionModeAvailable();
+    method public default boolean isExtensionStrengthAvailable();
+  }
+
+  @RequiresApi(21) public final class ExtensionMode {
+    field public static final int AUTO = 5; // 0x5
+    field public static final int BOKEH = 1; // 0x1
+    field public static final int FACE_RETOUCH = 4; // 0x4
+    field public static final int HDR = 2; // 0x2
+    field public static final int NIGHT = 3; // 0x3
+    field public static final int NONE = 0; // 0x0
+  }
+
+  @RequiresApi(21) public final class ExtensionsManager {
+    method public androidx.camera.extensions.CameraExtensionsControl? getCameraExtensionsControl(androidx.camera.core.CameraControl);
+    method public androidx.camera.extensions.CameraExtensionsInfo getCameraExtensionsInfo(androidx.camera.core.CameraInfo);
+    method public android.util.Range<java.lang.Long!>? getEstimatedCaptureLatencyRange(androidx.camera.core.CameraSelector, int);
+    method public androidx.camera.core.CameraSelector getExtensionEnabledCameraSelector(androidx.camera.core.CameraSelector, int);
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.camera.extensions.ExtensionsManager!> getInstanceAsync(android.content.Context, androidx.camera.core.CameraProvider);
+    method public boolean isExtensionAvailable(androidx.camera.core.CameraSelector, int);
+    method public boolean isImageAnalysisSupported(androidx.camera.core.CameraSelector, int);
+  }
+
+}
+
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessor.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessor.java
index edcf69a..9c5d04ae 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessor.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessor.java
@@ -290,6 +290,7 @@
         }
 
         if (mPreviewProcessor != null) {
+            mPreviewProcessor.resume();
             setImageProcessor(mPreviewOutputConfig.getId(),
                     new ImageProcessor() {
                         @Override
@@ -357,6 +358,9 @@
     @Override
     public void onCaptureSessionEnd() {
         mOnEnableDisableSessionDurationCheck.onDisableSessionInvoked();
+        if (mPreviewProcessor != null) {
+            mPreviewProcessor.pause();
+        }
         List<CaptureStageImpl> captureStages = new ArrayList<>();
         CaptureStageImpl captureStage1 = mPreviewExtenderImpl.onDisableSession();
         Logger.d(TAG, "preview onDisableSession: " + captureStage1);
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/PreviewProcessor.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/PreviewProcessor.java
index bf0f327..337a01e 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/PreviewProcessor.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/PreviewProcessor.java
@@ -52,12 +52,15 @@
 class PreviewProcessor {
     private static final String TAG = "PreviewProcessor";
     @NonNull
-    final PreviewImageProcessorImpl mPreviewImageProcessor;
+    private final PreviewImageProcessorImpl mPreviewImageProcessor;
     @NonNull
-    final CaptureResultImageMatcher mCaptureResultImageMatcher = new CaptureResultImageMatcher();
-    final Object mLock = new Object();
+    private final CaptureResultImageMatcher mCaptureResultImageMatcher =
+            new CaptureResultImageMatcher();
+    private final Object mLock = new Object();
     @GuardedBy("mLock")
-    boolean mIsClosed = false;
+    private boolean mIsClosed = false;
+    @GuardedBy("mLock")
+    private boolean mIsPaused = false;
 
     PreviewProcessor(@NonNull PreviewImageProcessorImpl previewImageProcessor,
             @NonNull Surface previewOutputSurface, @NonNull Size surfaceSize) {
@@ -72,13 +75,25 @@
                 @NonNull List<Pair<CaptureResult.Key, Object>> result);
     }
 
+    void pause() {
+        synchronized (mLock) {
+            mIsPaused = true;
+        }
+    }
+
+    void resume() {
+        synchronized (mLock) {
+            mIsPaused = false;
+        }
+    }
+
     void start(@NonNull OnCaptureResultCallback onResultCallback) {
         mCaptureResultImageMatcher.setImageReferenceListener(
                 (imageReference, totalCaptureResult, captureStageId) -> {
                     synchronized (mLock) {
-                        if (mIsClosed) {
+                        if (mIsClosed || mIsPaused) {
                             imageReference.decrement();
-                            Logger.d(TAG, "Ignore image in closed state");
+                            Logger.d(TAG, "Ignore image in closed or paused state");
                             return;
                         }
                         if (ClientVersion.isMinimumCompatibleVersion(Version.VERSION_1_3)
diff --git a/camera/camera-lifecycle/api/1.4.0-beta01.txt b/camera/camera-lifecycle/api/1.4.0-beta01.txt
new file mode 100644
index 0000000..5dd135e
--- /dev/null
+++ b/camera/camera-lifecycle/api/1.4.0-beta01.txt
@@ -0,0 +1,24 @@
+// Signature format: 4.0
+package androidx.camera.lifecycle {
+
+  @SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalCameraProviderConfiguration {
+  }
+
+  @RequiresApi(21) public final class ProcessCameraProvider implements androidx.camera.core.CameraProvider {
+    method @MainThread public androidx.camera.core.Camera bindToLifecycle(androidx.lifecycle.LifecycleOwner, androidx.camera.core.CameraSelector, androidx.camera.core.UseCase!...);
+    method @MainThread public androidx.camera.core.Camera bindToLifecycle(androidx.lifecycle.LifecycleOwner, androidx.camera.core.CameraSelector, androidx.camera.core.UseCaseGroup);
+    method @MainThread public androidx.camera.core.ConcurrentCamera bindToLifecycle(java.util.List<androidx.camera.core.ConcurrentCamera.SingleCameraConfig!>);
+    method @SuppressCompatibility @androidx.camera.lifecycle.ExperimentalCameraProviderConfiguration public static void configureInstance(androidx.camera.core.CameraXConfig);
+    method public java.util.List<androidx.camera.core.CameraInfo!> getAvailableCameraInfos();
+    method public java.util.List<java.util.List<androidx.camera.core.CameraInfo!>!> getAvailableConcurrentCameraInfos();
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.camera.lifecycle.ProcessCameraProvider!> getInstance(android.content.Context);
+    method public boolean hasCamera(androidx.camera.core.CameraSelector) throws androidx.camera.core.CameraInfoUnavailableException;
+    method public boolean isBound(androidx.camera.core.UseCase);
+    method @MainThread public boolean isConcurrentCameraModeOn();
+    method @VisibleForTesting public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> shutdownAsync();
+    method @MainThread public void unbind(androidx.camera.core.UseCase!...);
+    method @MainThread public void unbindAll();
+  }
+
+}
+
diff --git a/camera/camera-lifecycle/api/res-1.4.0-beta01.txt b/camera/camera-lifecycle/api/res-1.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/camera/camera-lifecycle/api/res-1.4.0-beta01.txt
diff --git a/camera/camera-lifecycle/api/restricted_1.4.0-beta01.txt b/camera/camera-lifecycle/api/restricted_1.4.0-beta01.txt
new file mode 100644
index 0000000..5dd135e
--- /dev/null
+++ b/camera/camera-lifecycle/api/restricted_1.4.0-beta01.txt
@@ -0,0 +1,24 @@
+// Signature format: 4.0
+package androidx.camera.lifecycle {
+
+  @SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalCameraProviderConfiguration {
+  }
+
+  @RequiresApi(21) public final class ProcessCameraProvider implements androidx.camera.core.CameraProvider {
+    method @MainThread public androidx.camera.core.Camera bindToLifecycle(androidx.lifecycle.LifecycleOwner, androidx.camera.core.CameraSelector, androidx.camera.core.UseCase!...);
+    method @MainThread public androidx.camera.core.Camera bindToLifecycle(androidx.lifecycle.LifecycleOwner, androidx.camera.core.CameraSelector, androidx.camera.core.UseCaseGroup);
+    method @MainThread public androidx.camera.core.ConcurrentCamera bindToLifecycle(java.util.List<androidx.camera.core.ConcurrentCamera.SingleCameraConfig!>);
+    method @SuppressCompatibility @androidx.camera.lifecycle.ExperimentalCameraProviderConfiguration public static void configureInstance(androidx.camera.core.CameraXConfig);
+    method public java.util.List<androidx.camera.core.CameraInfo!> getAvailableCameraInfos();
+    method public java.util.List<java.util.List<androidx.camera.core.CameraInfo!>!> getAvailableConcurrentCameraInfos();
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.camera.lifecycle.ProcessCameraProvider!> getInstance(android.content.Context);
+    method public boolean hasCamera(androidx.camera.core.CameraSelector) throws androidx.camera.core.CameraInfoUnavailableException;
+    method public boolean isBound(androidx.camera.core.UseCase);
+    method @MainThread public boolean isConcurrentCameraModeOn();
+    method @VisibleForTesting public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> shutdownAsync();
+    method @MainThread public void unbind(androidx.camera.core.UseCase!...);
+    method @MainThread public void unbindAll();
+  }
+
+}
+
diff --git a/camera/camera-lifecycle/src/androidTest/java/androidx/camera/lifecycle/ProcessCameraProviderTest.kt b/camera/camera-lifecycle/src/androidTest/java/androidx/camera/lifecycle/ProcessCameraProviderTest.kt
index b39c18a..2c0a5a4 100644
--- a/camera/camera-lifecycle/src/androidTest/java/androidx/camera/lifecycle/ProcessCameraProviderTest.kt
+++ b/camera/camera-lifecycle/src/androidTest/java/androidx/camera/lifecycle/ProcessCameraProviderTest.kt
@@ -806,6 +806,43 @@
     }
 
     @Test
+    fun bindConcurrentPhysicalCamera_isBound() {
+        ProcessCameraProvider.configureInstance(createConcurrentCameraAppConfig())
+
+        runBlocking(MainScope().coroutineContext) {
+            provider = ProcessCameraProvider.getInstance(context).await()
+            val useCase0 = Preview.Builder().setSessionOptionUnpacker { _, _, _ -> }.build()
+            val useCase1 = Preview.Builder().setSessionOptionUnpacker { _, _, _ -> }.build()
+
+            val singleCameraConfig0 = SingleCameraConfig(
+                CameraSelector.Builder()
+                    .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
+                    .build(),
+                UseCaseGroup.Builder()
+                    .addUseCase(useCase0)
+                    .build(),
+                lifecycleOwner0)
+            val singleCameraConfig1 = SingleCameraConfig(
+                CameraSelector.Builder()
+                    .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
+                    .build(),
+                UseCaseGroup.Builder()
+                    .addUseCase(useCase1)
+                    .build(),
+                lifecycleOwner0)
+
+            val concurrentCamera = provider.bindToLifecycle(
+                listOf(singleCameraConfig0, singleCameraConfig1))
+
+            assertThat(concurrentCamera).isNotNull()
+            assertThat(concurrentCamera.cameras.size).isEqualTo(1)
+            assertThat(provider.isBound(useCase0)).isTrue()
+            assertThat(provider.isBound(useCase1)).isTrue()
+            assertThat(provider.isConcurrentCameraModeOn).isFalse()
+        }
+    }
+
+    @Test
     fun bindConcurrentCameraTwice_isBound() {
         ProcessCameraProvider.configureInstance(createConcurrentCameraAppConfig())
 
@@ -882,15 +919,8 @@
                     .build(),
                 lifecycleOwner0)
 
-            if (context.packageManager.hasSystemFeature(FEATURE_CAMERA_CONCURRENT)) {
-                assertThrows<IllegalArgumentException> {
-                    provider.bindToLifecycle(listOf(singleCameraConfig0))
-                }
-                assertThat(provider.isConcurrentCameraModeOn).isFalse()
-            } else {
-                assertThrows<UnsupportedOperationException> {
-                    provider.bindToLifecycle(listOf(singleCameraConfig0))
-                }
+            assertThrows<IllegalArgumentException> {
+                provider.bindToLifecycle(listOf(singleCameraConfig0))
             }
         }
     }
@@ -923,17 +953,9 @@
                     .build(),
                 lifecycleOwner1)
 
-            if (context.packageManager.hasSystemFeature(FEATURE_CAMERA_CONCURRENT)) {
-                assertThrows<IllegalArgumentException> {
-                    provider.bindToLifecycle(
-                        listOf(singleCameraConfig0, singleCameraConfig1, singleCameraConfig2))
-                }
-                assertThat(provider.isConcurrentCameraModeOn).isFalse()
-            } else {
-                assertThrows<java.lang.UnsupportedOperationException> {
-                    provider.bindToLifecycle(
-                        listOf(singleCameraConfig0, singleCameraConfig1, singleCameraConfig2))
-                }
+            assertThrows<java.lang.IllegalArgumentException> {
+                provider.bindToLifecycle(
+                    listOf(singleCameraConfig0, singleCameraConfig1, singleCameraConfig2))
             }
         }
     }
diff --git a/camera/camera-lifecycle/src/main/java/androidx/camera/lifecycle/ProcessCameraProvider.java b/camera/camera-lifecycle/src/main/java/androidx/camera/lifecycle/ProcessCameraProvider.java
index 536684e..11038bb 100644
--- a/camera/camera-lifecycle/src/main/java/androidx/camera/lifecycle/ProcessCameraProvider.java
+++ b/camera/camera-lifecycle/src/main/java/androidx/camera/lifecycle/ProcessCameraProvider.java
@@ -82,6 +82,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.Executor;
 
@@ -453,16 +454,6 @@
     @MainThread
     @NonNull
     public ConcurrentCamera bindToLifecycle(@NonNull List<SingleCameraConfig> singleCameraConfigs) {
-        if (!mContext.getPackageManager().hasSystemFeature(FEATURE_CAMERA_CONCURRENT)) {
-            throw new UnsupportedOperationException("Concurrent camera is not supported on the "
-                    + "device");
-        }
-
-        if (getCameraOperatingMode() == CAMERA_OPERATING_MODE_SINGLE) {
-            throw new UnsupportedOperationException("Camera is already running, call "
-                    + "unbindAll() before binding more cameras");
-        }
-
         if (singleCameraConfigs.size() < 2) {
             throw new IllegalArgumentException("Concurrent camera needs two camera configs");
         }
@@ -472,37 +463,81 @@
                     + "cameras at maximum.");
         }
 
-        List<CameraInfo> cameraInfosToBind = new ArrayList<>();
-        CameraInfo firstCameraInfo;
-        CameraInfo secondCameraInfo;
-        try {
-            firstCameraInfo = getCameraInfo(
-                    singleCameraConfigs.get(0).getCameraSelector());
-            secondCameraInfo = getCameraInfo(
-                    singleCameraConfigs.get(1).getCameraSelector());
-        } catch (IllegalArgumentException e) {
-            throw new IllegalArgumentException("Invalid camera selectors in camera configs");
-        }
-        cameraInfosToBind.add(firstCameraInfo);
-        cameraInfosToBind.add(secondCameraInfo);
-        if (!getActiveConcurrentCameraInfos().isEmpty()
-                && !cameraInfosToBind.equals(getActiveConcurrentCameraInfos())) {
-            throw new UnsupportedOperationException("Cameras are already running, call "
-                    + "unbindAll() before binding more cameras");
-        }
-
-        setCameraOperatingMode(CAMERA_OPERATING_MODE_CONCURRENT);
         List<Camera> cameras = new ArrayList<>();
-        for (SingleCameraConfig config : singleCameraConfigs) {
-            Camera camera = bindToLifecycle(
-                    config.getLifecycleOwner(),
-                    config.getCameraSelector(),
-                    config.getUseCaseGroup().getViewPort(),
-                    config.getUseCaseGroup().getEffects(),
-                    config.getUseCaseGroup().getUseCases().toArray(new UseCase[0]));
+        if (Objects.equals(singleCameraConfigs.get(0).getCameraSelector().getLensFacing(),
+                singleCameraConfigs.get(1).getCameraSelector().getLensFacing())) {
+            if (getCameraOperatingMode() == CAMERA_OPERATING_MODE_CONCURRENT) {
+                throw new UnsupportedOperationException("Camera is already running, call "
+                        + "unbindAll() before binding more cameras");
+            }
+            if (!Objects.equals(singleCameraConfigs.get(0).getLifecycleOwner(),
+                    singleCameraConfigs.get(1).getLifecycleOwner())
+                    || !Objects.equals(singleCameraConfigs.get(0).getUseCaseGroup().getViewPort(),
+                    singleCameraConfigs.get(1).getUseCaseGroup().getViewPort())
+                    || !Objects.equals(singleCameraConfigs.get(0).getUseCaseGroup().getEffects(),
+                    singleCameraConfigs.get(1).getUseCaseGroup().getEffects())) {
+                throw new IllegalArgumentException("Two camera configs need to have the same "
+                        + "lifecycle owner, view port and effects");
+            }
+            LifecycleOwner lifecycleOwner = singleCameraConfigs.get(0).getLifecycleOwner();
+            CameraSelector cameraSelector = singleCameraConfigs.get(0).getCameraSelector();
+            ViewPort viewPort = singleCameraConfigs.get(0).getUseCaseGroup().getViewPort();
+            List<CameraEffect> effects = singleCameraConfigs.get(0).getUseCaseGroup().getEffects();
+            List<UseCase> useCases = new ArrayList<>();
+            for (SingleCameraConfig config : singleCameraConfigs) {
+                // Connect physical camera id with use case
+                for (UseCase useCase : config.getUseCaseGroup().getUseCases()) {
+                    useCase.setPhysicalCameraId(config.getCameraSelector().getPhysicalCameraId());
+                }
+                useCases.addAll(config.getUseCaseGroup().getUseCases());
+            }
+
+            setCameraOperatingMode(CAMERA_OPERATING_MODE_SINGLE);
+            Camera camera = bindToLifecycle(lifecycleOwner, cameraSelector, viewPort,
+                    effects, useCases.toArray(new UseCase[0]));
             cameras.add(camera);
+        } else {
+            if (!mContext.getPackageManager().hasSystemFeature(FEATURE_CAMERA_CONCURRENT)) {
+                throw new UnsupportedOperationException("Concurrent camera is not supported on the "
+                        + "device");
+            }
+
+            if (getCameraOperatingMode() == CAMERA_OPERATING_MODE_SINGLE) {
+                throw new UnsupportedOperationException("Camera is already running, call "
+                        + "unbindAll() before binding more cameras");
+            }
+
+            List<CameraInfo> cameraInfosToBind = new ArrayList<>();
+            CameraInfo firstCameraInfo;
+            CameraInfo secondCameraInfo;
+            try {
+                firstCameraInfo = getCameraInfo(
+                        singleCameraConfigs.get(0).getCameraSelector());
+                secondCameraInfo = getCameraInfo(
+                        singleCameraConfigs.get(1).getCameraSelector());
+            } catch (IllegalArgumentException e) {
+                throw new IllegalArgumentException("Invalid camera selectors in camera configs");
+            }
+            cameraInfosToBind.add(firstCameraInfo);
+            cameraInfosToBind.add(secondCameraInfo);
+            if (!getActiveConcurrentCameraInfos().isEmpty()
+                    && !cameraInfosToBind.equals(getActiveConcurrentCameraInfos())) {
+                throw new UnsupportedOperationException("Cameras are already running, call "
+                        + "unbindAll() before binding more cameras");
+            }
+
+            setCameraOperatingMode(CAMERA_OPERATING_MODE_CONCURRENT);
+            for (SingleCameraConfig config : singleCameraConfigs) {
+                Camera camera = bindToLifecycle(
+                        config.getLifecycleOwner(),
+                        config.getCameraSelector(),
+                        config.getUseCaseGroup().getViewPort(),
+                        config.getUseCaseGroup().getEffects(),
+                        config.getUseCaseGroup().getUseCases().toArray(new UseCase[0]));
+                cameras.add(camera);
+            }
+            setActiveConcurrentCameraInfos(cameraInfosToBind);
         }
-        setActiveConcurrentCameraInfos(cameraInfosToBind);
         return new ConcurrentCamera(cameras);
     }
 
diff --git a/camera/camera-mlkit-vision/api/1.4.0-beta01.txt b/camera/camera-mlkit-vision/api/1.4.0-beta01.txt
new file mode 100644
index 0000000..0599c25
--- /dev/null
+++ b/camera/camera-mlkit-vision/api/1.4.0-beta01.txt
@@ -0,0 +1,20 @@
+// Signature format: 4.0
+package androidx.camera.mlkit.vision {
+
+  @RequiresApi(21) public class MlKitAnalyzer implements androidx.camera.core.ImageAnalysis.Analyzer {
+    ctor public MlKitAnalyzer(java.util.List<com.google.mlkit.vision.interfaces.Detector<?>!>, int, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.mlkit.vision.MlKitAnalyzer.Result!>);
+    method public final void analyze(androidx.camera.core.ImageProxy);
+    method public final android.util.Size getDefaultTargetResolution();
+    method public final int getTargetCoordinateSystem();
+    method public final void updateTransform(android.graphics.Matrix?);
+  }
+
+  public static final class MlKitAnalyzer.Result {
+    ctor public MlKitAnalyzer.Result(java.util.Map<com.google.mlkit.vision.interfaces.Detector<?>!,java.lang.Object!>, long, java.util.Map<com.google.mlkit.vision.interfaces.Detector<?>!,java.lang.Throwable!>);
+    method public Throwable? getThrowable(com.google.mlkit.vision.interfaces.Detector<?>);
+    method public long getTimestamp();
+    method public <T> T? getValue(com.google.mlkit.vision.interfaces.Detector<T!>);
+  }
+
+}
+
diff --git a/camera/camera-mlkit-vision/api/res-1.4.0-beta01.txt b/camera/camera-mlkit-vision/api/res-1.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/camera/camera-mlkit-vision/api/res-1.4.0-beta01.txt
diff --git a/camera/camera-mlkit-vision/api/restricted_1.4.0-beta01.txt b/camera/camera-mlkit-vision/api/restricted_1.4.0-beta01.txt
new file mode 100644
index 0000000..0599c25
--- /dev/null
+++ b/camera/camera-mlkit-vision/api/restricted_1.4.0-beta01.txt
@@ -0,0 +1,20 @@
+// Signature format: 4.0
+package androidx.camera.mlkit.vision {
+
+  @RequiresApi(21) public class MlKitAnalyzer implements androidx.camera.core.ImageAnalysis.Analyzer {
+    ctor public MlKitAnalyzer(java.util.List<com.google.mlkit.vision.interfaces.Detector<?>!>, int, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.mlkit.vision.MlKitAnalyzer.Result!>);
+    method public final void analyze(androidx.camera.core.ImageProxy);
+    method public final android.util.Size getDefaultTargetResolution();
+    method public final int getTargetCoordinateSystem();
+    method public final void updateTransform(android.graphics.Matrix?);
+  }
+
+  public static final class MlKitAnalyzer.Result {
+    ctor public MlKitAnalyzer.Result(java.util.Map<com.google.mlkit.vision.interfaces.Detector<?>!,java.lang.Object!>, long, java.util.Map<com.google.mlkit.vision.interfaces.Detector<?>!,java.lang.Throwable!>);
+    method public Throwable? getThrowable(com.google.mlkit.vision.interfaces.Detector<?>);
+    method public long getTimestamp();
+    method public <T> T? getValue(com.google.mlkit.vision.interfaces.Detector<T!>);
+  }
+
+}
+
diff --git a/camera/camera-video/api/1.4.0-beta01.txt b/camera/camera-video/api/1.4.0-beta01.txt
new file mode 100644
index 0000000..405c299
--- /dev/null
+++ b/camera/camera-video/api/1.4.0-beta01.txt
@@ -0,0 +1,220 @@
+// Signature format: 4.0
+package androidx.camera.video {
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class AudioStats {
+    method public double getAudioAmplitude();
+    method public abstract int getAudioState();
+    method public abstract Throwable? getErrorCause();
+    method public boolean hasAudio();
+    method public boolean hasError();
+    field public static final double AUDIO_AMPLITUDE_NONE = 0.0;
+    field public static final int AUDIO_STATE_ACTIVE = 0; // 0x0
+    field public static final int AUDIO_STATE_DISABLED = 1; // 0x1
+    field public static final int AUDIO_STATE_ENCODER_ERROR = 3; // 0x3
+    field public static final int AUDIO_STATE_MUTED = 5; // 0x5
+    field public static final int AUDIO_STATE_SOURCE_ERROR = 4; // 0x4
+    field public static final int AUDIO_STATE_SOURCE_SILENCED = 2; // 0x2
+  }
+
+  @SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalAudioApi {
+  }
+
+  @SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalPersistentRecording {
+  }
+
+  @RequiresApi(21) public class FallbackStrategy {
+    method public static androidx.camera.video.FallbackStrategy higherQualityOrLowerThan(androidx.camera.video.Quality);
+    method public static androidx.camera.video.FallbackStrategy higherQualityThan(androidx.camera.video.Quality);
+    method public static androidx.camera.video.FallbackStrategy lowerQualityOrHigherThan(androidx.camera.video.Quality);
+    method public static androidx.camera.video.FallbackStrategy lowerQualityThan(androidx.camera.video.Quality);
+  }
+
+  @RequiresApi(21) public final class FileDescriptorOutputOptions extends androidx.camera.video.OutputOptions {
+    method public android.os.ParcelFileDescriptor getParcelFileDescriptor();
+  }
+
+  @RequiresApi(21) public static final class FileDescriptorOutputOptions.Builder {
+    ctor public FileDescriptorOutputOptions.Builder(android.os.ParcelFileDescriptor);
+    method public androidx.camera.video.FileDescriptorOutputOptions build();
+    method public androidx.camera.video.FileDescriptorOutputOptions.Builder setDurationLimitMillis(@IntRange(from=0) long);
+    method public androidx.camera.video.FileDescriptorOutputOptions.Builder setFileSizeLimit(@IntRange(from=0) long);
+    method public androidx.camera.video.FileDescriptorOutputOptions.Builder setLocation(android.location.Location?);
+  }
+
+  @RequiresApi(21) public final class FileOutputOptions extends androidx.camera.video.OutputOptions {
+    method public java.io.File getFile();
+  }
+
+  @RequiresApi(21) public static final class FileOutputOptions.Builder {
+    ctor public FileOutputOptions.Builder(java.io.File);
+    method public androidx.camera.video.FileOutputOptions build();
+    method public androidx.camera.video.FileOutputOptions.Builder setDurationLimitMillis(@IntRange(from=0) long);
+    method public androidx.camera.video.FileOutputOptions.Builder setFileSizeLimit(@IntRange(from=0) long);
+    method public androidx.camera.video.FileOutputOptions.Builder setLocation(android.location.Location?);
+  }
+
+  @RequiresApi(21) public final class MediaStoreOutputOptions extends androidx.camera.video.OutputOptions {
+    method public android.net.Uri getCollectionUri();
+    method public android.content.ContentResolver getContentResolver();
+    method public android.content.ContentValues getContentValues();
+    field public static final android.content.ContentValues EMPTY_CONTENT_VALUES;
+  }
+
+  public static final class MediaStoreOutputOptions.Builder {
+    ctor public MediaStoreOutputOptions.Builder(android.content.ContentResolver, android.net.Uri);
+    method public androidx.camera.video.MediaStoreOutputOptions build();
+    method public androidx.camera.video.MediaStoreOutputOptions.Builder setContentValues(android.content.ContentValues);
+    method public androidx.camera.video.MediaStoreOutputOptions.Builder setDurationLimitMillis(@IntRange(from=0) long);
+    method public androidx.camera.video.MediaStoreOutputOptions.Builder setFileSizeLimit(@IntRange(from=0) long);
+    method public androidx.camera.video.MediaStoreOutputOptions.Builder setLocation(android.location.Location?);
+  }
+
+  @RequiresApi(21) public abstract class OutputOptions {
+    method @IntRange(from=0) public long getDurationLimitMillis();
+    method @IntRange(from=0) public long getFileSizeLimit();
+    method public android.location.Location? getLocation();
+    field public static final int DURATION_UNLIMITED = 0; // 0x0
+    field public static final int FILE_SIZE_UNLIMITED = 0; // 0x0
+  }
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class OutputResults {
+    ctor public OutputResults();
+    method public abstract android.net.Uri getOutputUri();
+  }
+
+  @RequiresApi(21) public final class PendingRecording {
+    method @SuppressCompatibility @androidx.camera.video.ExperimentalPersistentRecording public androidx.camera.video.PendingRecording asPersistentRecording();
+    method @CheckResult public androidx.camera.video.Recording start(java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.video.VideoRecordEvent!>);
+    method @RequiresPermission(android.Manifest.permission.RECORD_AUDIO) public androidx.camera.video.PendingRecording withAudioEnabled();
+  }
+
+  @RequiresApi(21) public class Quality {
+    field public static final androidx.camera.video.Quality FHD;
+    field public static final androidx.camera.video.Quality HD;
+    field public static final androidx.camera.video.Quality HIGHEST;
+    field public static final androidx.camera.video.Quality LOWEST;
+    field public static final androidx.camera.video.Quality SD;
+    field public static final androidx.camera.video.Quality UHD;
+  }
+
+  @RequiresApi(21) public final class QualitySelector {
+    method public static androidx.camera.video.QualitySelector from(androidx.camera.video.Quality);
+    method public static androidx.camera.video.QualitySelector from(androidx.camera.video.Quality, androidx.camera.video.FallbackStrategy);
+    method public static androidx.camera.video.QualitySelector fromOrderedList(java.util.List<androidx.camera.video.Quality!>);
+    method public static androidx.camera.video.QualitySelector fromOrderedList(java.util.List<androidx.camera.video.Quality!>, androidx.camera.video.FallbackStrategy);
+    method public static android.util.Size? getResolution(androidx.camera.core.CameraInfo, androidx.camera.video.Quality);
+    method @Deprecated public static java.util.List<androidx.camera.video.Quality!> getSupportedQualities(androidx.camera.core.CameraInfo);
+    method @Deprecated public static boolean isQualitySupported(androidx.camera.core.CameraInfo, androidx.camera.video.Quality);
+  }
+
+  @RequiresApi(21) public final class Recorder implements androidx.camera.video.VideoOutput {
+    method public int getAspectRatio();
+    method public java.util.concurrent.Executor? getExecutor();
+    method public androidx.camera.video.QualitySelector getQualitySelector();
+    method public int getTargetVideoEncodingBitRate();
+    method public static androidx.camera.video.VideoCapabilities getVideoCapabilities(androidx.camera.core.CameraInfo);
+    method public static androidx.camera.video.VideoCapabilities getVideoCapabilities(androidx.camera.core.CameraInfo, int);
+    method public int getVideoCapabilitiesSource();
+    method public void onSurfaceRequested(androidx.camera.core.SurfaceRequest);
+    method @RequiresApi(26) public androidx.camera.video.PendingRecording prepareRecording(android.content.Context, androidx.camera.video.FileDescriptorOutputOptions);
+    method public androidx.camera.video.PendingRecording prepareRecording(android.content.Context, androidx.camera.video.FileOutputOptions);
+    method public androidx.camera.video.PendingRecording prepareRecording(android.content.Context, androidx.camera.video.MediaStoreOutputOptions);
+    field public static final androidx.camera.video.QualitySelector DEFAULT_QUALITY_SELECTOR;
+    field public static final int VIDEO_CAPABILITIES_SOURCE_CAMCORDER_PROFILE = 0; // 0x0
+    field public static final int VIDEO_CAPABILITIES_SOURCE_CODEC_CAPABILITIES = 1; // 0x1
+  }
+
+  @RequiresApi(21) public static final class Recorder.Builder {
+    ctor public Recorder.Builder();
+    method public androidx.camera.video.Recorder build();
+    method public androidx.camera.video.Recorder.Builder setAspectRatio(int);
+    method public androidx.camera.video.Recorder.Builder setExecutor(java.util.concurrent.Executor);
+    method public androidx.camera.video.Recorder.Builder setQualitySelector(androidx.camera.video.QualitySelector);
+    method public androidx.camera.video.Recorder.Builder setTargetVideoEncodingBitRate(@IntRange(from=1) int);
+    method public androidx.camera.video.Recorder.Builder setVideoCapabilitiesSource(int);
+  }
+
+  @RequiresApi(21) public final class Recording implements java.lang.AutoCloseable {
+    method public void close();
+    method @SuppressCompatibility @androidx.camera.video.ExperimentalPersistentRecording public boolean isPersistent();
+    method public void mute(boolean);
+    method public void pause();
+    method public void resume();
+    method public void stop();
+  }
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class RecordingStats {
+    method public abstract androidx.camera.video.AudioStats getAudioStats();
+    method public abstract long getNumBytesRecorded();
+    method public abstract long getRecordedDurationNanos();
+  }
+
+  @RequiresApi(21) public interface VideoCapabilities {
+    method public java.util.Set<androidx.camera.core.DynamicRange!> getSupportedDynamicRanges();
+    method public java.util.List<androidx.camera.video.Quality!> getSupportedQualities(androidx.camera.core.DynamicRange);
+    method public boolean isQualitySupported(androidx.camera.video.Quality, androidx.camera.core.DynamicRange);
+    method public default boolean isStabilizationSupported();
+  }
+
+  @RequiresApi(21) public final class VideoCapture<T extends androidx.camera.video.VideoOutput> extends androidx.camera.core.UseCase {
+    method public androidx.camera.core.DynamicRange getDynamicRange();
+    method public int getMirrorMode();
+    method public T getOutput();
+    method public android.util.Range<java.lang.Integer!> getTargetFrameRate();
+    method public int getTargetRotation();
+    method public boolean isVideoStabilizationEnabled();
+    method public void setTargetRotation(int);
+    method public static <T extends androidx.camera.video.VideoOutput> androidx.camera.video.VideoCapture<T!> withOutput(T);
+  }
+
+  @RequiresApi(21) public static final class VideoCapture.Builder<T extends androidx.camera.video.VideoOutput> implements androidx.camera.core.ExtendableBuilder<androidx.camera.video.VideoCapture!> {
+    ctor public VideoCapture.Builder(T);
+    method public androidx.camera.video.VideoCapture<T!> build();
+    method public androidx.camera.video.VideoCapture.Builder<T!> setDynamicRange(androidx.camera.core.DynamicRange);
+    method public androidx.camera.video.VideoCapture.Builder<T!> setMirrorMode(int);
+    method public androidx.camera.video.VideoCapture.Builder<T!> setTargetFrameRate(android.util.Range<java.lang.Integer!>);
+    method public androidx.camera.video.VideoCapture.Builder<T!> setTargetRotation(int);
+    method public androidx.camera.video.VideoCapture.Builder<T!> setVideoStabilizationEnabled(boolean);
+  }
+
+  @RequiresApi(21) public interface VideoOutput {
+    method public void onSurfaceRequested(androidx.camera.core.SurfaceRequest);
+  }
+
+  @RequiresApi(21) public abstract class VideoRecordEvent {
+    method public androidx.camera.video.OutputOptions getOutputOptions();
+    method public androidx.camera.video.RecordingStats getRecordingStats();
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Finalize extends androidx.camera.video.VideoRecordEvent {
+    method public Throwable? getCause();
+    method public int getError();
+    method public androidx.camera.video.OutputResults getOutputResults();
+    method public boolean hasError();
+    field public static final int ERROR_DURATION_LIMIT_REACHED = 9; // 0x9
+    field public static final int ERROR_ENCODING_FAILED = 6; // 0x6
+    field public static final int ERROR_FILE_SIZE_LIMIT_REACHED = 2; // 0x2
+    field public static final int ERROR_INSUFFICIENT_STORAGE = 3; // 0x3
+    field public static final int ERROR_INVALID_OUTPUT_OPTIONS = 5; // 0x5
+    field public static final int ERROR_NONE = 0; // 0x0
+    field public static final int ERROR_NO_VALID_DATA = 8; // 0x8
+    field public static final int ERROR_RECORDER_ERROR = 7; // 0x7
+    field public static final int ERROR_RECORDING_GARBAGE_COLLECTED = 10; // 0xa
+    field public static final int ERROR_SOURCE_INACTIVE = 4; // 0x4
+    field public static final int ERROR_UNKNOWN = 1; // 0x1
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Pause extends androidx.camera.video.VideoRecordEvent {
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Resume extends androidx.camera.video.VideoRecordEvent {
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Start extends androidx.camera.video.VideoRecordEvent {
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Status extends androidx.camera.video.VideoRecordEvent {
+  }
+
+}
+
diff --git a/camera/camera-video/api/res-1.4.0-beta01.txt b/camera/camera-video/api/res-1.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/camera/camera-video/api/res-1.4.0-beta01.txt
diff --git a/camera/camera-video/api/restricted_1.4.0-beta01.txt b/camera/camera-video/api/restricted_1.4.0-beta01.txt
new file mode 100644
index 0000000..405c299
--- /dev/null
+++ b/camera/camera-video/api/restricted_1.4.0-beta01.txt
@@ -0,0 +1,220 @@
+// Signature format: 4.0
+package androidx.camera.video {
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class AudioStats {
+    method public double getAudioAmplitude();
+    method public abstract int getAudioState();
+    method public abstract Throwable? getErrorCause();
+    method public boolean hasAudio();
+    method public boolean hasError();
+    field public static final double AUDIO_AMPLITUDE_NONE = 0.0;
+    field public static final int AUDIO_STATE_ACTIVE = 0; // 0x0
+    field public static final int AUDIO_STATE_DISABLED = 1; // 0x1
+    field public static final int AUDIO_STATE_ENCODER_ERROR = 3; // 0x3
+    field public static final int AUDIO_STATE_MUTED = 5; // 0x5
+    field public static final int AUDIO_STATE_SOURCE_ERROR = 4; // 0x4
+    field public static final int AUDIO_STATE_SOURCE_SILENCED = 2; // 0x2
+  }
+
+  @SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalAudioApi {
+  }
+
+  @SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalPersistentRecording {
+  }
+
+  @RequiresApi(21) public class FallbackStrategy {
+    method public static androidx.camera.video.FallbackStrategy higherQualityOrLowerThan(androidx.camera.video.Quality);
+    method public static androidx.camera.video.FallbackStrategy higherQualityThan(androidx.camera.video.Quality);
+    method public static androidx.camera.video.FallbackStrategy lowerQualityOrHigherThan(androidx.camera.video.Quality);
+    method public static androidx.camera.video.FallbackStrategy lowerQualityThan(androidx.camera.video.Quality);
+  }
+
+  @RequiresApi(21) public final class FileDescriptorOutputOptions extends androidx.camera.video.OutputOptions {
+    method public android.os.ParcelFileDescriptor getParcelFileDescriptor();
+  }
+
+  @RequiresApi(21) public static final class FileDescriptorOutputOptions.Builder {
+    ctor public FileDescriptorOutputOptions.Builder(android.os.ParcelFileDescriptor);
+    method public androidx.camera.video.FileDescriptorOutputOptions build();
+    method public androidx.camera.video.FileDescriptorOutputOptions.Builder setDurationLimitMillis(@IntRange(from=0) long);
+    method public androidx.camera.video.FileDescriptorOutputOptions.Builder setFileSizeLimit(@IntRange(from=0) long);
+    method public androidx.camera.video.FileDescriptorOutputOptions.Builder setLocation(android.location.Location?);
+  }
+
+  @RequiresApi(21) public final class FileOutputOptions extends androidx.camera.video.OutputOptions {
+    method public java.io.File getFile();
+  }
+
+  @RequiresApi(21) public static final class FileOutputOptions.Builder {
+    ctor public FileOutputOptions.Builder(java.io.File);
+    method public androidx.camera.video.FileOutputOptions build();
+    method public androidx.camera.video.FileOutputOptions.Builder setDurationLimitMillis(@IntRange(from=0) long);
+    method public androidx.camera.video.FileOutputOptions.Builder setFileSizeLimit(@IntRange(from=0) long);
+    method public androidx.camera.video.FileOutputOptions.Builder setLocation(android.location.Location?);
+  }
+
+  @RequiresApi(21) public final class MediaStoreOutputOptions extends androidx.camera.video.OutputOptions {
+    method public android.net.Uri getCollectionUri();
+    method public android.content.ContentResolver getContentResolver();
+    method public android.content.ContentValues getContentValues();
+    field public static final android.content.ContentValues EMPTY_CONTENT_VALUES;
+  }
+
+  public static final class MediaStoreOutputOptions.Builder {
+    ctor public MediaStoreOutputOptions.Builder(android.content.ContentResolver, android.net.Uri);
+    method public androidx.camera.video.MediaStoreOutputOptions build();
+    method public androidx.camera.video.MediaStoreOutputOptions.Builder setContentValues(android.content.ContentValues);
+    method public androidx.camera.video.MediaStoreOutputOptions.Builder setDurationLimitMillis(@IntRange(from=0) long);
+    method public androidx.camera.video.MediaStoreOutputOptions.Builder setFileSizeLimit(@IntRange(from=0) long);
+    method public androidx.camera.video.MediaStoreOutputOptions.Builder setLocation(android.location.Location?);
+  }
+
+  @RequiresApi(21) public abstract class OutputOptions {
+    method @IntRange(from=0) public long getDurationLimitMillis();
+    method @IntRange(from=0) public long getFileSizeLimit();
+    method public android.location.Location? getLocation();
+    field public static final int DURATION_UNLIMITED = 0; // 0x0
+    field public static final int FILE_SIZE_UNLIMITED = 0; // 0x0
+  }
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class OutputResults {
+    ctor public OutputResults();
+    method public abstract android.net.Uri getOutputUri();
+  }
+
+  @RequiresApi(21) public final class PendingRecording {
+    method @SuppressCompatibility @androidx.camera.video.ExperimentalPersistentRecording public androidx.camera.video.PendingRecording asPersistentRecording();
+    method @CheckResult public androidx.camera.video.Recording start(java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.video.VideoRecordEvent!>);
+    method @RequiresPermission(android.Manifest.permission.RECORD_AUDIO) public androidx.camera.video.PendingRecording withAudioEnabled();
+  }
+
+  @RequiresApi(21) public class Quality {
+    field public static final androidx.camera.video.Quality FHD;
+    field public static final androidx.camera.video.Quality HD;
+    field public static final androidx.camera.video.Quality HIGHEST;
+    field public static final androidx.camera.video.Quality LOWEST;
+    field public static final androidx.camera.video.Quality SD;
+    field public static final androidx.camera.video.Quality UHD;
+  }
+
+  @RequiresApi(21) public final class QualitySelector {
+    method public static androidx.camera.video.QualitySelector from(androidx.camera.video.Quality);
+    method public static androidx.camera.video.QualitySelector from(androidx.camera.video.Quality, androidx.camera.video.FallbackStrategy);
+    method public static androidx.camera.video.QualitySelector fromOrderedList(java.util.List<androidx.camera.video.Quality!>);
+    method public static androidx.camera.video.QualitySelector fromOrderedList(java.util.List<androidx.camera.video.Quality!>, androidx.camera.video.FallbackStrategy);
+    method public static android.util.Size? getResolution(androidx.camera.core.CameraInfo, androidx.camera.video.Quality);
+    method @Deprecated public static java.util.List<androidx.camera.video.Quality!> getSupportedQualities(androidx.camera.core.CameraInfo);
+    method @Deprecated public static boolean isQualitySupported(androidx.camera.core.CameraInfo, androidx.camera.video.Quality);
+  }
+
+  @RequiresApi(21) public final class Recorder implements androidx.camera.video.VideoOutput {
+    method public int getAspectRatio();
+    method public java.util.concurrent.Executor? getExecutor();
+    method public androidx.camera.video.QualitySelector getQualitySelector();
+    method public int getTargetVideoEncodingBitRate();
+    method public static androidx.camera.video.VideoCapabilities getVideoCapabilities(androidx.camera.core.CameraInfo);
+    method public static androidx.camera.video.VideoCapabilities getVideoCapabilities(androidx.camera.core.CameraInfo, int);
+    method public int getVideoCapabilitiesSource();
+    method public void onSurfaceRequested(androidx.camera.core.SurfaceRequest);
+    method @RequiresApi(26) public androidx.camera.video.PendingRecording prepareRecording(android.content.Context, androidx.camera.video.FileDescriptorOutputOptions);
+    method public androidx.camera.video.PendingRecording prepareRecording(android.content.Context, androidx.camera.video.FileOutputOptions);
+    method public androidx.camera.video.PendingRecording prepareRecording(android.content.Context, androidx.camera.video.MediaStoreOutputOptions);
+    field public static final androidx.camera.video.QualitySelector DEFAULT_QUALITY_SELECTOR;
+    field public static final int VIDEO_CAPABILITIES_SOURCE_CAMCORDER_PROFILE = 0; // 0x0
+    field public static final int VIDEO_CAPABILITIES_SOURCE_CODEC_CAPABILITIES = 1; // 0x1
+  }
+
+  @RequiresApi(21) public static final class Recorder.Builder {
+    ctor public Recorder.Builder();
+    method public androidx.camera.video.Recorder build();
+    method public androidx.camera.video.Recorder.Builder setAspectRatio(int);
+    method public androidx.camera.video.Recorder.Builder setExecutor(java.util.concurrent.Executor);
+    method public androidx.camera.video.Recorder.Builder setQualitySelector(androidx.camera.video.QualitySelector);
+    method public androidx.camera.video.Recorder.Builder setTargetVideoEncodingBitRate(@IntRange(from=1) int);
+    method public androidx.camera.video.Recorder.Builder setVideoCapabilitiesSource(int);
+  }
+
+  @RequiresApi(21) public final class Recording implements java.lang.AutoCloseable {
+    method public void close();
+    method @SuppressCompatibility @androidx.camera.video.ExperimentalPersistentRecording public boolean isPersistent();
+    method public void mute(boolean);
+    method public void pause();
+    method public void resume();
+    method public void stop();
+  }
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class RecordingStats {
+    method public abstract androidx.camera.video.AudioStats getAudioStats();
+    method public abstract long getNumBytesRecorded();
+    method public abstract long getRecordedDurationNanos();
+  }
+
+  @RequiresApi(21) public interface VideoCapabilities {
+    method public java.util.Set<androidx.camera.core.DynamicRange!> getSupportedDynamicRanges();
+    method public java.util.List<androidx.camera.video.Quality!> getSupportedQualities(androidx.camera.core.DynamicRange);
+    method public boolean isQualitySupported(androidx.camera.video.Quality, androidx.camera.core.DynamicRange);
+    method public default boolean isStabilizationSupported();
+  }
+
+  @RequiresApi(21) public final class VideoCapture<T extends androidx.camera.video.VideoOutput> extends androidx.camera.core.UseCase {
+    method public androidx.camera.core.DynamicRange getDynamicRange();
+    method public int getMirrorMode();
+    method public T getOutput();
+    method public android.util.Range<java.lang.Integer!> getTargetFrameRate();
+    method public int getTargetRotation();
+    method public boolean isVideoStabilizationEnabled();
+    method public void setTargetRotation(int);
+    method public static <T extends androidx.camera.video.VideoOutput> androidx.camera.video.VideoCapture<T!> withOutput(T);
+  }
+
+  @RequiresApi(21) public static final class VideoCapture.Builder<T extends androidx.camera.video.VideoOutput> implements androidx.camera.core.ExtendableBuilder<androidx.camera.video.VideoCapture!> {
+    ctor public VideoCapture.Builder(T);
+    method public androidx.camera.video.VideoCapture<T!> build();
+    method public androidx.camera.video.VideoCapture.Builder<T!> setDynamicRange(androidx.camera.core.DynamicRange);
+    method public androidx.camera.video.VideoCapture.Builder<T!> setMirrorMode(int);
+    method public androidx.camera.video.VideoCapture.Builder<T!> setTargetFrameRate(android.util.Range<java.lang.Integer!>);
+    method public androidx.camera.video.VideoCapture.Builder<T!> setTargetRotation(int);
+    method public androidx.camera.video.VideoCapture.Builder<T!> setVideoStabilizationEnabled(boolean);
+  }
+
+  @RequiresApi(21) public interface VideoOutput {
+    method public void onSurfaceRequested(androidx.camera.core.SurfaceRequest);
+  }
+
+  @RequiresApi(21) public abstract class VideoRecordEvent {
+    method public androidx.camera.video.OutputOptions getOutputOptions();
+    method public androidx.camera.video.RecordingStats getRecordingStats();
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Finalize extends androidx.camera.video.VideoRecordEvent {
+    method public Throwable? getCause();
+    method public int getError();
+    method public androidx.camera.video.OutputResults getOutputResults();
+    method public boolean hasError();
+    field public static final int ERROR_DURATION_LIMIT_REACHED = 9; // 0x9
+    field public static final int ERROR_ENCODING_FAILED = 6; // 0x6
+    field public static final int ERROR_FILE_SIZE_LIMIT_REACHED = 2; // 0x2
+    field public static final int ERROR_INSUFFICIENT_STORAGE = 3; // 0x3
+    field public static final int ERROR_INVALID_OUTPUT_OPTIONS = 5; // 0x5
+    field public static final int ERROR_NONE = 0; // 0x0
+    field public static final int ERROR_NO_VALID_DATA = 8; // 0x8
+    field public static final int ERROR_RECORDER_ERROR = 7; // 0x7
+    field public static final int ERROR_RECORDING_GARBAGE_COLLECTED = 10; // 0xa
+    field public static final int ERROR_SOURCE_INACTIVE = 4; // 0x4
+    field public static final int ERROR_UNKNOWN = 1; // 0x1
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Pause extends androidx.camera.video.VideoRecordEvent {
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Resume extends androidx.camera.video.VideoRecordEvent {
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Start extends androidx.camera.video.VideoRecordEvent {
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Status extends androidx.camera.video.VideoRecordEvent {
+  }
+
+}
+
diff --git a/camera/camera-view/api/1.4.0-beta01.txt b/camera/camera-view/api/1.4.0-beta01.txt
new file mode 100644
index 0000000..ea8f480
--- /dev/null
+++ b/camera/camera-view/api/1.4.0-beta01.txt
@@ -0,0 +1,199 @@
+// Signature format: 4.0
+package androidx.camera.view {
+
+  @RequiresApi(21) public abstract class CameraController {
+    method @MainThread public void clearEffects();
+    method @MainThread public void clearImageAnalysisAnalyzer();
+    method @MainThread public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> enableTorch(boolean);
+    method @MainThread public androidx.camera.core.CameraControl? getCameraControl();
+    method @MainThread public androidx.camera.core.CameraInfo? getCameraInfo();
+    method @MainThread public androidx.camera.core.CameraSelector getCameraSelector();
+    method @MainThread public java.util.concurrent.Executor? getImageAnalysisBackgroundExecutor();
+    method @MainThread public int getImageAnalysisBackpressureStrategy();
+    method @MainThread public int getImageAnalysisImageQueueDepth();
+    method @MainThread public int getImageAnalysisOutputImageFormat();
+    method @MainThread public androidx.camera.core.resolutionselector.ResolutionSelector? getImageAnalysisResolutionSelector();
+    method @Deprecated @MainThread public androidx.camera.view.CameraController.OutputSize? getImageAnalysisTargetSize();
+    method @MainThread public int getImageCaptureFlashMode();
+    method @MainThread public java.util.concurrent.Executor? getImageCaptureIoExecutor();
+    method @MainThread public int getImageCaptureMode();
+    method @MainThread public androidx.camera.core.resolutionselector.ResolutionSelector? getImageCaptureResolutionSelector();
+    method @Deprecated @MainThread public androidx.camera.view.CameraController.OutputSize? getImageCaptureTargetSize();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> getInitializationFuture();
+    method @MainThread public androidx.camera.core.resolutionselector.ResolutionSelector? getPreviewResolutionSelector();
+    method @Deprecated @MainThread public androidx.camera.view.CameraController.OutputSize? getPreviewTargetSize();
+    method @MainThread public androidx.lifecycle.LiveData<java.lang.Integer!> getTapToFocusState();
+    method @MainThread public androidx.lifecycle.LiveData<java.lang.Integer!> getTorchState();
+    method @MainThread public androidx.camera.core.DynamicRange getVideoCaptureDynamicRange();
+    method @MainThread public int getVideoCaptureMirrorMode();
+    method @MainThread public androidx.camera.video.QualitySelector getVideoCaptureQualitySelector();
+    method @MainThread public android.util.Range<java.lang.Integer!> getVideoCaptureTargetFrameRate();
+    method @MainThread public androidx.lifecycle.LiveData<androidx.camera.core.ZoomState!> getZoomState();
+    method @MainThread public boolean hasCamera(androidx.camera.core.CameraSelector);
+    method @MainThread public boolean isImageAnalysisEnabled();
+    method @MainThread public boolean isImageCaptureEnabled();
+    method @MainThread public boolean isPinchToZoomEnabled();
+    method @MainThread public boolean isRecording();
+    method @MainThread public boolean isTapToFocusEnabled();
+    method @MainThread public boolean isVideoCaptureEnabled();
+    method @MainThread public void setCameraSelector(androidx.camera.core.CameraSelector);
+    method @MainThread public void setEffects(java.util.Set<androidx.camera.core.CameraEffect!>);
+    method @MainThread public void setEnabledUseCases(int);
+    method @MainThread public void setImageAnalysisAnalyzer(java.util.concurrent.Executor, androidx.camera.core.ImageAnalysis.Analyzer);
+    method @MainThread public void setImageAnalysisBackgroundExecutor(java.util.concurrent.Executor?);
+    method @MainThread public void setImageAnalysisBackpressureStrategy(int);
+    method @MainThread public void setImageAnalysisImageQueueDepth(int);
+    method @MainThread public void setImageAnalysisOutputImageFormat(int);
+    method @MainThread public void setImageAnalysisResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector?);
+    method @Deprecated @MainThread public void setImageAnalysisTargetSize(androidx.camera.view.CameraController.OutputSize?);
+    method @MainThread public void setImageCaptureFlashMode(int);
+    method @MainThread public void setImageCaptureIoExecutor(java.util.concurrent.Executor?);
+    method @MainThread public void setImageCaptureMode(int);
+    method @MainThread public void setImageCaptureResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector?);
+    method @Deprecated @MainThread public void setImageCaptureTargetSize(androidx.camera.view.CameraController.OutputSize?);
+    method @MainThread public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setLinearZoom(@FloatRange(from=0.0f, to=1.0f) float);
+    method @MainThread public void setPinchToZoomEnabled(boolean);
+    method @MainThread public void setPreviewResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector?);
+    method @Deprecated @MainThread public void setPreviewTargetSize(androidx.camera.view.CameraController.OutputSize?);
+    method @MainThread public void setTapToFocusEnabled(boolean);
+    method @MainThread public void setVideoCaptureDynamicRange(androidx.camera.core.DynamicRange);
+    method @MainThread public void setVideoCaptureMirrorMode(int);
+    method @MainThread public void setVideoCaptureQualitySelector(androidx.camera.video.QualitySelector);
+    method @MainThread public void setVideoCaptureTargetFrameRate(android.util.Range<java.lang.Integer!>);
+    method @MainThread public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setZoomRatio(float);
+    method @MainThread @RequiresApi(26) public androidx.camera.video.Recording startRecording(androidx.camera.video.FileDescriptorOutputOptions, androidx.camera.view.video.AudioConfig, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.video.VideoRecordEvent!>);
+    method @MainThread public androidx.camera.video.Recording startRecording(androidx.camera.video.FileOutputOptions, androidx.camera.view.video.AudioConfig, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.video.VideoRecordEvent!>);
+    method @MainThread public androidx.camera.video.Recording startRecording(androidx.camera.video.MediaStoreOutputOptions, androidx.camera.view.video.AudioConfig, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.video.VideoRecordEvent!>);
+    method @MainThread public void takePicture(androidx.camera.core.ImageCapture.OutputFileOptions, java.util.concurrent.Executor, androidx.camera.core.ImageCapture.OnImageSavedCallback);
+    method @MainThread public void takePicture(java.util.concurrent.Executor, androidx.camera.core.ImageCapture.OnImageCapturedCallback);
+    field public static final int COORDINATE_SYSTEM_VIEW_REFERENCED = 1; // 0x1
+    field public static final int IMAGE_ANALYSIS = 2; // 0x2
+    field public static final int IMAGE_CAPTURE = 1; // 0x1
+    field public static final int TAP_TO_FOCUS_FAILED = 4; // 0x4
+    field public static final int TAP_TO_FOCUS_FOCUSED = 2; // 0x2
+    field public static final int TAP_TO_FOCUS_NOT_FOCUSED = 3; // 0x3
+    field public static final int TAP_TO_FOCUS_NOT_STARTED = 0; // 0x0
+    field public static final int TAP_TO_FOCUS_STARTED = 1; // 0x1
+    field public static final int VIDEO_CAPTURE = 4; // 0x4
+  }
+
+  @Deprecated @RequiresApi(21) public static final class CameraController.OutputSize {
+    ctor @Deprecated public CameraController.OutputSize(android.util.Size);
+    ctor @Deprecated public CameraController.OutputSize(int);
+    method @Deprecated public int getAspectRatio();
+    method @Deprecated public android.util.Size? getResolution();
+    field @Deprecated public static final int UNASSIGNED_ASPECT_RATIO = -1; // 0xffffffff
+  }
+
+  @RequiresApi(21) public final class LifecycleCameraController extends androidx.camera.view.CameraController {
+    ctor public LifecycleCameraController(android.content.Context);
+    method @MainThread public void bindToLifecycle(androidx.lifecycle.LifecycleOwner);
+    method @MainThread public void unbind();
+  }
+
+  @RequiresApi(21) public final class PreviewView extends android.widget.FrameLayout {
+    ctor @UiThread public PreviewView(android.content.Context);
+    ctor @UiThread public PreviewView(android.content.Context, android.util.AttributeSet?);
+    ctor @UiThread public PreviewView(android.content.Context, android.util.AttributeSet?, int);
+    ctor @UiThread public PreviewView(android.content.Context, android.util.AttributeSet?, int, int);
+    method @UiThread public android.graphics.Bitmap? getBitmap();
+    method @UiThread public androidx.camera.view.CameraController? getController();
+    method @UiThread public androidx.camera.view.PreviewView.ImplementationMode getImplementationMode();
+    method @UiThread public androidx.camera.core.MeteringPointFactory getMeteringPointFactory();
+    method @SuppressCompatibility public androidx.camera.view.transform.OutputTransform? getOutputTransform();
+    method public androidx.lifecycle.LiveData<androidx.camera.view.PreviewView.StreamState!> getPreviewStreamState();
+    method @UiThread public androidx.camera.view.PreviewView.ScaleType getScaleType();
+    method @UiThread public android.graphics.Matrix? getSensorToViewTransform();
+    method @UiThread public androidx.camera.core.Preview.SurfaceProvider getSurfaceProvider();
+    method @UiThread public androidx.camera.core.ViewPort? getViewPort();
+    method @UiThread public androidx.camera.core.ViewPort? getViewPort(int);
+    method @UiThread public void setController(androidx.camera.view.CameraController?);
+    method @UiThread public void setImplementationMode(androidx.camera.view.PreviewView.ImplementationMode);
+    method @UiThread public void setScaleType(androidx.camera.view.PreviewView.ScaleType);
+    method @UiThread public void setScreenFlashWindow(android.view.Window?);
+  }
+
+  @RequiresApi(21) public enum PreviewView.ImplementationMode {
+    enum_constant public static final androidx.camera.view.PreviewView.ImplementationMode COMPATIBLE;
+    enum_constant public static final androidx.camera.view.PreviewView.ImplementationMode PERFORMANCE;
+  }
+
+  @RequiresApi(21) public enum PreviewView.ScaleType {
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FILL_CENTER;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FILL_END;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FILL_START;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FIT_CENTER;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FIT_END;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FIT_START;
+  }
+
+  public enum PreviewView.StreamState {
+    enum_constant public static final androidx.camera.view.PreviewView.StreamState IDLE;
+    enum_constant public static final androidx.camera.view.PreviewView.StreamState STREAMING;
+  }
+
+  @RequiresApi(21) public final class RotationProvider {
+    ctor public RotationProvider(android.content.Context);
+    method @CheckResult public boolean addListener(java.util.concurrent.Executor, androidx.camera.view.RotationProvider.Listener);
+    method public void removeListener(androidx.camera.view.RotationProvider.Listener);
+  }
+
+  public static interface RotationProvider.Listener {
+    method public void onRotationChanged(int);
+  }
+
+  @RequiresApi(21) public final class ScreenFlashView extends android.view.View {
+    ctor @UiThread public ScreenFlashView(android.content.Context);
+    ctor @UiThread public ScreenFlashView(android.content.Context, android.util.AttributeSet?);
+    ctor @UiThread public ScreenFlashView(android.content.Context, android.util.AttributeSet?, int);
+    ctor @UiThread public ScreenFlashView(android.content.Context, android.util.AttributeSet?, int, int);
+    method @UiThread public androidx.camera.core.ImageCapture.ScreenFlash? getScreenFlash();
+    method @UiThread public void setController(androidx.camera.view.CameraController?);
+    method @UiThread public void setScreenFlashWindow(android.view.Window?);
+  }
+
+}
+
+package androidx.camera.view.transform {
+
+  @SuppressCompatibility @RequiresApi(21) public final class CoordinateTransform {
+    ctor public CoordinateTransform(androidx.camera.view.transform.OutputTransform, androidx.camera.view.transform.OutputTransform);
+    method public void mapPoint(android.graphics.PointF);
+    method public void mapPoints(float[]);
+    method public void mapRect(android.graphics.RectF);
+    method public void transform(android.graphics.Matrix);
+  }
+
+  @SuppressCompatibility @RequiresApi(21) public final class FileTransformFactory {
+    ctor public FileTransformFactory();
+    method public androidx.camera.view.transform.OutputTransform getOutputTransform(android.content.ContentResolver, android.net.Uri) throws java.io.IOException;
+    method public androidx.camera.view.transform.OutputTransform getOutputTransform(java.io.File) throws java.io.IOException;
+    method public androidx.camera.view.transform.OutputTransform getOutputTransform(java.io.InputStream) throws java.io.IOException;
+    method public boolean isUsingExifOrientation();
+    method public void setUsingExifOrientation(boolean);
+  }
+
+  @SuppressCompatibility @RequiresApi(21) public final class ImageProxyTransformFactory {
+    ctor public ImageProxyTransformFactory();
+    method public androidx.camera.view.transform.OutputTransform getOutputTransform(androidx.camera.core.ImageProxy);
+    method public boolean isUsingCropRect();
+    method public boolean isUsingRotationDegrees();
+    method public void setUsingCropRect(boolean);
+    method public void setUsingRotationDegrees(boolean);
+  }
+
+  @SuppressCompatibility @RequiresApi(21) public final class OutputTransform {
+  }
+
+}
+
+package androidx.camera.view.video {
+
+  @RequiresApi(21) public class AudioConfig {
+    method @RequiresPermission(android.Manifest.permission.RECORD_AUDIO) public static androidx.camera.view.video.AudioConfig create(boolean);
+    method public boolean getAudioEnabled();
+    field public static final androidx.camera.view.video.AudioConfig AUDIO_DISABLED;
+  }
+
+}
+
diff --git a/camera/camera-view/api/res-1.4.0-beta01.txt b/camera/camera-view/api/res-1.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/camera/camera-view/api/res-1.4.0-beta01.txt
diff --git a/camera/camera-view/api/restricted_1.4.0-beta01.txt b/camera/camera-view/api/restricted_1.4.0-beta01.txt
new file mode 100644
index 0000000..ea8f480
--- /dev/null
+++ b/camera/camera-view/api/restricted_1.4.0-beta01.txt
@@ -0,0 +1,199 @@
+// Signature format: 4.0
+package androidx.camera.view {
+
+  @RequiresApi(21) public abstract class CameraController {
+    method @MainThread public void clearEffects();
+    method @MainThread public void clearImageAnalysisAnalyzer();
+    method @MainThread public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> enableTorch(boolean);
+    method @MainThread public androidx.camera.core.CameraControl? getCameraControl();
+    method @MainThread public androidx.camera.core.CameraInfo? getCameraInfo();
+    method @MainThread public androidx.camera.core.CameraSelector getCameraSelector();
+    method @MainThread public java.util.concurrent.Executor? getImageAnalysisBackgroundExecutor();
+    method @MainThread public int getImageAnalysisBackpressureStrategy();
+    method @MainThread public int getImageAnalysisImageQueueDepth();
+    method @MainThread public int getImageAnalysisOutputImageFormat();
+    method @MainThread public androidx.camera.core.resolutionselector.ResolutionSelector? getImageAnalysisResolutionSelector();
+    method @Deprecated @MainThread public androidx.camera.view.CameraController.OutputSize? getImageAnalysisTargetSize();
+    method @MainThread public int getImageCaptureFlashMode();
+    method @MainThread public java.util.concurrent.Executor? getImageCaptureIoExecutor();
+    method @MainThread public int getImageCaptureMode();
+    method @MainThread public androidx.camera.core.resolutionselector.ResolutionSelector? getImageCaptureResolutionSelector();
+    method @Deprecated @MainThread public androidx.camera.view.CameraController.OutputSize? getImageCaptureTargetSize();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> getInitializationFuture();
+    method @MainThread public androidx.camera.core.resolutionselector.ResolutionSelector? getPreviewResolutionSelector();
+    method @Deprecated @MainThread public androidx.camera.view.CameraController.OutputSize? getPreviewTargetSize();
+    method @MainThread public androidx.lifecycle.LiveData<java.lang.Integer!> getTapToFocusState();
+    method @MainThread public androidx.lifecycle.LiveData<java.lang.Integer!> getTorchState();
+    method @MainThread public androidx.camera.core.DynamicRange getVideoCaptureDynamicRange();
+    method @MainThread public int getVideoCaptureMirrorMode();
+    method @MainThread public androidx.camera.video.QualitySelector getVideoCaptureQualitySelector();
+    method @MainThread public android.util.Range<java.lang.Integer!> getVideoCaptureTargetFrameRate();
+    method @MainThread public androidx.lifecycle.LiveData<androidx.camera.core.ZoomState!> getZoomState();
+    method @MainThread public boolean hasCamera(androidx.camera.core.CameraSelector);
+    method @MainThread public boolean isImageAnalysisEnabled();
+    method @MainThread public boolean isImageCaptureEnabled();
+    method @MainThread public boolean isPinchToZoomEnabled();
+    method @MainThread public boolean isRecording();
+    method @MainThread public boolean isTapToFocusEnabled();
+    method @MainThread public boolean isVideoCaptureEnabled();
+    method @MainThread public void setCameraSelector(androidx.camera.core.CameraSelector);
+    method @MainThread public void setEffects(java.util.Set<androidx.camera.core.CameraEffect!>);
+    method @MainThread public void setEnabledUseCases(int);
+    method @MainThread public void setImageAnalysisAnalyzer(java.util.concurrent.Executor, androidx.camera.core.ImageAnalysis.Analyzer);
+    method @MainThread public void setImageAnalysisBackgroundExecutor(java.util.concurrent.Executor?);
+    method @MainThread public void setImageAnalysisBackpressureStrategy(int);
+    method @MainThread public void setImageAnalysisImageQueueDepth(int);
+    method @MainThread public void setImageAnalysisOutputImageFormat(int);
+    method @MainThread public void setImageAnalysisResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector?);
+    method @Deprecated @MainThread public void setImageAnalysisTargetSize(androidx.camera.view.CameraController.OutputSize?);
+    method @MainThread public void setImageCaptureFlashMode(int);
+    method @MainThread public void setImageCaptureIoExecutor(java.util.concurrent.Executor?);
+    method @MainThread public void setImageCaptureMode(int);
+    method @MainThread public void setImageCaptureResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector?);
+    method @Deprecated @MainThread public void setImageCaptureTargetSize(androidx.camera.view.CameraController.OutputSize?);
+    method @MainThread public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setLinearZoom(@FloatRange(from=0.0f, to=1.0f) float);
+    method @MainThread public void setPinchToZoomEnabled(boolean);
+    method @MainThread public void setPreviewResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector?);
+    method @Deprecated @MainThread public void setPreviewTargetSize(androidx.camera.view.CameraController.OutputSize?);
+    method @MainThread public void setTapToFocusEnabled(boolean);
+    method @MainThread public void setVideoCaptureDynamicRange(androidx.camera.core.DynamicRange);
+    method @MainThread public void setVideoCaptureMirrorMode(int);
+    method @MainThread public void setVideoCaptureQualitySelector(androidx.camera.video.QualitySelector);
+    method @MainThread public void setVideoCaptureTargetFrameRate(android.util.Range<java.lang.Integer!>);
+    method @MainThread public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setZoomRatio(float);
+    method @MainThread @RequiresApi(26) public androidx.camera.video.Recording startRecording(androidx.camera.video.FileDescriptorOutputOptions, androidx.camera.view.video.AudioConfig, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.video.VideoRecordEvent!>);
+    method @MainThread public androidx.camera.video.Recording startRecording(androidx.camera.video.FileOutputOptions, androidx.camera.view.video.AudioConfig, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.video.VideoRecordEvent!>);
+    method @MainThread public androidx.camera.video.Recording startRecording(androidx.camera.video.MediaStoreOutputOptions, androidx.camera.view.video.AudioConfig, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.video.VideoRecordEvent!>);
+    method @MainThread public void takePicture(androidx.camera.core.ImageCapture.OutputFileOptions, java.util.concurrent.Executor, androidx.camera.core.ImageCapture.OnImageSavedCallback);
+    method @MainThread public void takePicture(java.util.concurrent.Executor, androidx.camera.core.ImageCapture.OnImageCapturedCallback);
+    field public static final int COORDINATE_SYSTEM_VIEW_REFERENCED = 1; // 0x1
+    field public static final int IMAGE_ANALYSIS = 2; // 0x2
+    field public static final int IMAGE_CAPTURE = 1; // 0x1
+    field public static final int TAP_TO_FOCUS_FAILED = 4; // 0x4
+    field public static final int TAP_TO_FOCUS_FOCUSED = 2; // 0x2
+    field public static final int TAP_TO_FOCUS_NOT_FOCUSED = 3; // 0x3
+    field public static final int TAP_TO_FOCUS_NOT_STARTED = 0; // 0x0
+    field public static final int TAP_TO_FOCUS_STARTED = 1; // 0x1
+    field public static final int VIDEO_CAPTURE = 4; // 0x4
+  }
+
+  @Deprecated @RequiresApi(21) public static final class CameraController.OutputSize {
+    ctor @Deprecated public CameraController.OutputSize(android.util.Size);
+    ctor @Deprecated public CameraController.OutputSize(int);
+    method @Deprecated public int getAspectRatio();
+    method @Deprecated public android.util.Size? getResolution();
+    field @Deprecated public static final int UNASSIGNED_ASPECT_RATIO = -1; // 0xffffffff
+  }
+
+  @RequiresApi(21) public final class LifecycleCameraController extends androidx.camera.view.CameraController {
+    ctor public LifecycleCameraController(android.content.Context);
+    method @MainThread public void bindToLifecycle(androidx.lifecycle.LifecycleOwner);
+    method @MainThread public void unbind();
+  }
+
+  @RequiresApi(21) public final class PreviewView extends android.widget.FrameLayout {
+    ctor @UiThread public PreviewView(android.content.Context);
+    ctor @UiThread public PreviewView(android.content.Context, android.util.AttributeSet?);
+    ctor @UiThread public PreviewView(android.content.Context, android.util.AttributeSet?, int);
+    ctor @UiThread public PreviewView(android.content.Context, android.util.AttributeSet?, int, int);
+    method @UiThread public android.graphics.Bitmap? getBitmap();
+    method @UiThread public androidx.camera.view.CameraController? getController();
+    method @UiThread public androidx.camera.view.PreviewView.ImplementationMode getImplementationMode();
+    method @UiThread public androidx.camera.core.MeteringPointFactory getMeteringPointFactory();
+    method @SuppressCompatibility public androidx.camera.view.transform.OutputTransform? getOutputTransform();
+    method public androidx.lifecycle.LiveData<androidx.camera.view.PreviewView.StreamState!> getPreviewStreamState();
+    method @UiThread public androidx.camera.view.PreviewView.ScaleType getScaleType();
+    method @UiThread public android.graphics.Matrix? getSensorToViewTransform();
+    method @UiThread public androidx.camera.core.Preview.SurfaceProvider getSurfaceProvider();
+    method @UiThread public androidx.camera.core.ViewPort? getViewPort();
+    method @UiThread public androidx.camera.core.ViewPort? getViewPort(int);
+    method @UiThread public void setController(androidx.camera.view.CameraController?);
+    method @UiThread public void setImplementationMode(androidx.camera.view.PreviewView.ImplementationMode);
+    method @UiThread public void setScaleType(androidx.camera.view.PreviewView.ScaleType);
+    method @UiThread public void setScreenFlashWindow(android.view.Window?);
+  }
+
+  @RequiresApi(21) public enum PreviewView.ImplementationMode {
+    enum_constant public static final androidx.camera.view.PreviewView.ImplementationMode COMPATIBLE;
+    enum_constant public static final androidx.camera.view.PreviewView.ImplementationMode PERFORMANCE;
+  }
+
+  @RequiresApi(21) public enum PreviewView.ScaleType {
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FILL_CENTER;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FILL_END;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FILL_START;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FIT_CENTER;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FIT_END;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FIT_START;
+  }
+
+  public enum PreviewView.StreamState {
+    enum_constant public static final androidx.camera.view.PreviewView.StreamState IDLE;
+    enum_constant public static final androidx.camera.view.PreviewView.StreamState STREAMING;
+  }
+
+  @RequiresApi(21) public final class RotationProvider {
+    ctor public RotationProvider(android.content.Context);
+    method @CheckResult public boolean addListener(java.util.concurrent.Executor, androidx.camera.view.RotationProvider.Listener);
+    method public void removeListener(androidx.camera.view.RotationProvider.Listener);
+  }
+
+  public static interface RotationProvider.Listener {
+    method public void onRotationChanged(int);
+  }
+
+  @RequiresApi(21) public final class ScreenFlashView extends android.view.View {
+    ctor @UiThread public ScreenFlashView(android.content.Context);
+    ctor @UiThread public ScreenFlashView(android.content.Context, android.util.AttributeSet?);
+    ctor @UiThread public ScreenFlashView(android.content.Context, android.util.AttributeSet?, int);
+    ctor @UiThread public ScreenFlashView(android.content.Context, android.util.AttributeSet?, int, int);
+    method @UiThread public androidx.camera.core.ImageCapture.ScreenFlash? getScreenFlash();
+    method @UiThread public void setController(androidx.camera.view.CameraController?);
+    method @UiThread public void setScreenFlashWindow(android.view.Window?);
+  }
+
+}
+
+package androidx.camera.view.transform {
+
+  @SuppressCompatibility @RequiresApi(21) public final class CoordinateTransform {
+    ctor public CoordinateTransform(androidx.camera.view.transform.OutputTransform, androidx.camera.view.transform.OutputTransform);
+    method public void mapPoint(android.graphics.PointF);
+    method public void mapPoints(float[]);
+    method public void mapRect(android.graphics.RectF);
+    method public void transform(android.graphics.Matrix);
+  }
+
+  @SuppressCompatibility @RequiresApi(21) public final class FileTransformFactory {
+    ctor public FileTransformFactory();
+    method public androidx.camera.view.transform.OutputTransform getOutputTransform(android.content.ContentResolver, android.net.Uri) throws java.io.IOException;
+    method public androidx.camera.view.transform.OutputTransform getOutputTransform(java.io.File) throws java.io.IOException;
+    method public androidx.camera.view.transform.OutputTransform getOutputTransform(java.io.InputStream) throws java.io.IOException;
+    method public boolean isUsingExifOrientation();
+    method public void setUsingExifOrientation(boolean);
+  }
+
+  @SuppressCompatibility @RequiresApi(21) public final class ImageProxyTransformFactory {
+    ctor public ImageProxyTransformFactory();
+    method public androidx.camera.view.transform.OutputTransform getOutputTransform(androidx.camera.core.ImageProxy);
+    method public boolean isUsingCropRect();
+    method public boolean isUsingRotationDegrees();
+    method public void setUsingCropRect(boolean);
+    method public void setUsingRotationDegrees(boolean);
+  }
+
+  @SuppressCompatibility @RequiresApi(21) public final class OutputTransform {
+  }
+
+}
+
+package androidx.camera.view.video {
+
+  @RequiresApi(21) public class AudioConfig {
+    method @RequiresPermission(android.Manifest.permission.RECORD_AUDIO) public static androidx.camera.view.video.AudioConfig create(boolean);
+    method public boolean getAudioEnabled();
+    field public static final androidx.camera.view.video.AudioConfig AUDIO_DISABLED;
+  }
+
+}
+
diff --git a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/ConcurrentCameraActivity.java b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/ConcurrentCameraActivity.java
index 4c33201..441d427 100644
--- a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/ConcurrentCameraActivity.java
+++ b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/ConcurrentCameraActivity.java
@@ -19,7 +19,10 @@
 import static android.view.View.GONE;
 import static android.view.View.VISIBLE;
 
+import android.annotation.SuppressLint;
 import android.content.pm.PackageManager;
+import android.hardware.camera2.CameraCharacteristics;
+import android.os.Build;
 import android.os.Bundle;
 import android.view.MotionEvent;
 import android.view.ScaleGestureDetector;
@@ -41,6 +44,7 @@
 import androidx.camera.core.ConcurrentCamera.SingleCameraConfig;
 import androidx.camera.core.FocusMeteringAction;
 import androidx.camera.core.MeteringPoint;
+import androidx.camera.core.PhysicalCameraInfo;
 import androidx.camera.core.Preview;
 import androidx.camera.core.UseCaseGroup;
 import androidx.camera.lifecycle.ProcessCameraProvider;
@@ -50,6 +54,7 @@
 import androidx.core.math.MathUtils;
 import androidx.lifecycle.LifecycleOwner;
 
+import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.ListenableFuture;
 
@@ -75,6 +80,7 @@
     @NonNull private ToggleButton mModeButton;
     @NonNull private ToggleButton mLayoutButton;
     @NonNull private ToggleButton mToggleButton;
+    @NonNull private ToggleButton mDualSelfieButton;
     @NonNull private LinearLayout mSideBySideLayout;
     @NonNull private FrameLayout mPiPLayout;
     @Nullable private ProcessCameraProvider mCameraProvider;
@@ -82,6 +88,8 @@
     private boolean mIsLayoutPiP = true;
     private boolean mIsFrontPrimary = true;
 
+    private boolean mIsDualSelfieEnabled = false;
+
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -96,6 +104,7 @@
         mModeButton = findViewById(R.id.mode_button);
         mLayoutButton = findViewById(R.id.layout_button);
         mToggleButton = findViewById(R.id.toggle_button);
+        mDualSelfieButton = findViewById(R.id.dual_selfie);
 
         boolean isConcurrentCameraSupported =
                 getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_CONCURRENT);
@@ -144,6 +153,10 @@
                 bindPreviewForSingle(mCameraProvider);
             }
         });
+        mDualSelfieButton.setOnClickListener(view -> {
+            mIsDualSelfieEnabled = mDualSelfieButton.isChecked();
+            mDualSelfieButton.setChecked(mIsDualSelfieEnabled);
+        });
         if (allPermissionsGranted()) {
             if (mCameraProvider != null) {
                 mCameraProvider.unbindAll();
@@ -167,6 +180,8 @@
             }
         }, ContextCompat.getMainExecutor(this));
     }
+
+    @SuppressLint("RestrictedApiAndroidX")
     void bindPreviewForSingle(@NonNull ProcessCameraProvider cameraProvider) {
         cameraProvider.unbindAll();
         mSideBySideLayout.setVisibility(GONE);
@@ -186,13 +201,18 @@
         previewFront.setSurfaceProvider(mSinglePreviewView.getSurfaceProvider());
         Camera camera = cameraProvider.bindToLifecycle(
                 this, cameraSelectorFront, previewFront);
+        mDualSelfieButton.setVisibility(camera.getCameraInfo().isLogicalMultiCameraSupported()
+                ? VISIBLE : GONE);
+        mIsDualSelfieEnabled = false;
         setupZoomAndTapToFocus(camera, mSinglePreviewView);
     }
+
     void bindPreviewForPiP(@NonNull ProcessCameraProvider cameraProvider) {
         mSideBySideLayout.setVisibility(GONE);
         mFrontPreviewViewForPip.setVisibility(VISIBLE);
         mBackPreviewViewForPip.setVisibility(VISIBLE);
         mPiPLayout.setVisibility(VISIBLE);
+        mDualSelfieButton.setVisibility(GONE);
         if (mFrontPreviewView == null && mBackPreviewView == null) {
             // Front
             mFrontPreviewView = new PreviewView(this);
@@ -223,9 +243,11 @@
                     mBackPreviewView);
         }
     }
+
     void bindPreviewForSideBySide() {
         mSideBySideLayout.setVisibility(VISIBLE);
         mPiPLayout.setVisibility(GONE);
+        mDualSelfieButton.setVisibility(GONE);
         if (mFrontPreviewView == null && mBackPreviewView == null) {
             mFrontPreviewView = new PreviewView(this);
             mFrontPreviewView.setImplementationMode(PreviewView.ImplementationMode.COMPATIBLE);
@@ -239,62 +261,121 @@
                 mFrontPreviewView,
                 mBackPreviewView);
     }
+
+    @SuppressLint("RestrictedApiAndroidX")
     private void bindToLifecycleForConcurrentCamera(
             @NonNull ProcessCameraProvider cameraProvider,
             @NonNull LifecycleOwner lifecycleOwner,
             @NonNull PreviewView frontPreviewView,
             @NonNull PreviewView backPreviewView) {
-        Preview previewFront = new Preview.Builder()
-                .build();
-        CameraSelector cameraSelectorPrimary = null;
-        CameraSelector cameraSelectorSecondary = null;
-        for (List<CameraInfo> cameraInfoList : cameraProvider.getAvailableConcurrentCameraInfos()) {
-            for (CameraInfo cameraInfo : cameraInfoList) {
+        if (mIsDualSelfieEnabled) {
+            CameraInfo cameraInfoPrimary = null;
+            for (CameraInfo cameraInfo : cameraProvider.getAvailableCameraInfos()) {
                 if (cameraInfo.getLensFacing() == CameraSelector.LENS_FACING_FRONT) {
-                    cameraSelectorPrimary = cameraInfo.getCameraSelector();
-                } else if (cameraInfo.getLensFacing() == CameraSelector.LENS_FACING_BACK) {
-                    cameraSelectorSecondary = cameraInfo.getCameraSelector();
+                    cameraInfoPrimary = cameraInfo;
+                    break;
+                }
+            }
+            if (cameraInfoPrimary == null
+                    || cameraInfoPrimary.getPhysicalCameraInfos().size() != 2) {
+                return;
+            }
+
+            String innerPhysicalCameraId = null;
+            String outerPhysicalCameraId = null;
+            for (PhysicalCameraInfo info : cameraInfoPrimary.getPhysicalCameraInfos()) {
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+                    if (info.getLensPoseReference()
+                            == CameraCharacteristics.LENS_POSE_REFERENCE_PRIMARY_CAMERA) {
+                        innerPhysicalCameraId = info.getPhysicalCameraId();
+                    } else {
+                        outerPhysicalCameraId = info.getPhysicalCameraId();
+                    }
                 }
             }
 
-            if (cameraSelectorPrimary == null || cameraSelectorSecondary == null) {
-                // If either a primary or secondary selector wasn't found, reset both
-                // to move on to the next list of CameraInfos.
-                cameraSelectorPrimary = null;
-                cameraSelectorSecondary = null;
-            } else {
-                // If both primary and secondary camera selectors were found, we can
-                // conclude the search.
-                break;
+            if (Objects.equal(innerPhysicalCameraId, outerPhysicalCameraId)) {
+                return;
             }
-        }
-        if (cameraSelectorPrimary == null || cameraSelectorSecondary == null) {
-            return;
-        }
-        previewFront.setSurfaceProvider(frontPreviewView.getSurfaceProvider());
-        SingleCameraConfig primary = new SingleCameraConfig(
-                cameraSelectorPrimary,
-                new UseCaseGroup.Builder()
-                        .addUseCase(previewFront)
-                        .build(),
-                lifecycleOwner);
-        Preview previewBack = new Preview.Builder()
-                .build();
-        previewBack.setSurfaceProvider(backPreviewView.getSurfaceProvider());
-        SingleCameraConfig secondary = new SingleCameraConfig(
-                cameraSelectorSecondary,
-                new UseCaseGroup.Builder()
-                        .addUseCase(previewBack)
-                        .build(),
-                lifecycleOwner);
-        ConcurrentCamera concurrentCamera =
-                cameraProvider.bindToLifecycle(ImmutableList.of(primary, secondary));
 
-        setupZoomAndTapToFocus(concurrentCamera.getCameras().get(0), frontPreviewView);
-        setupZoomAndTapToFocus(concurrentCamera.getCameras().get(1), backPreviewView);
+            Preview previewFront = new Preview.Builder()
+                    .build();
+            previewFront.setSurfaceProvider(frontPreviewView.getSurfaceProvider());
+            SingleCameraConfig primary = new SingleCameraConfig(
+                    new CameraSelector.Builder()
+                            .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
+                            .setPhysicalCameraId(innerPhysicalCameraId)
+                            .build(),
+                    new UseCaseGroup.Builder()
+                            .addUseCase(previewFront)
+                            .build(),
+                    lifecycleOwner);
+            Preview previewBack = new Preview.Builder()
+                    .build();
+            previewBack.setSurfaceProvider(backPreviewView.getSurfaceProvider());
+            SingleCameraConfig secondary = new SingleCameraConfig(
+                    new CameraSelector.Builder()
+                            .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
+                            .setPhysicalCameraId(outerPhysicalCameraId)
+                            .build(),
+                    new UseCaseGroup.Builder()
+                            .addUseCase(previewBack)
+                            .build(),
+                    lifecycleOwner);
+            cameraProvider.bindToLifecycle(ImmutableList.of(primary, secondary));
+        } else {
+            CameraSelector cameraSelectorPrimary = null;
+            CameraSelector cameraSelectorSecondary = null;
+            for (List<CameraInfo> cameraInfoList : cameraProvider
+                    .getAvailableConcurrentCameraInfos()) {
+                for (CameraInfo cameraInfo : cameraInfoList) {
+                    if (cameraInfo.getLensFacing() == CameraSelector.LENS_FACING_FRONT) {
+                        cameraSelectorPrimary = cameraInfo.getCameraSelector();
+                    } else if (cameraInfo.getLensFacing() == CameraSelector.LENS_FACING_BACK) {
+                        cameraSelectorSecondary = cameraInfo.getCameraSelector();
+                    }
+                }
+
+                if (cameraSelectorPrimary == null || cameraSelectorSecondary == null) {
+                    // If either a primary or secondary selector wasn't found, reset both
+                    // to move on to the next list of CameraInfos.
+                    cameraSelectorPrimary = null;
+                    cameraSelectorSecondary = null;
+                } else {
+                    // If both primary and secondary camera selectors were found, we can
+                    // conclude the search.
+                    break;
+                }
+            }
+            if (cameraSelectorPrimary == null || cameraSelectorSecondary == null) {
+                return;
+            }
+            Preview previewFront = new Preview.Builder()
+                    .build();
+            previewFront.setSurfaceProvider(frontPreviewView.getSurfaceProvider());
+            SingleCameraConfig primary = new SingleCameraConfig(
+                    cameraSelectorPrimary,
+                    new UseCaseGroup.Builder()
+                            .addUseCase(previewFront)
+                            .build(),
+                    lifecycleOwner);
+            Preview previewBack = new Preview.Builder()
+                    .build();
+            previewBack.setSurfaceProvider(backPreviewView.getSurfaceProvider());
+            SingleCameraConfig secondary = new SingleCameraConfig(
+                    cameraSelectorSecondary,
+                    new UseCaseGroup.Builder()
+                            .addUseCase(previewBack)
+                            .build(),
+                    lifecycleOwner);
+            ConcurrentCamera concurrentCamera =
+                    cameraProvider.bindToLifecycle(ImmutableList.of(primary, secondary));
+
+            setupZoomAndTapToFocus(concurrentCamera.getCameras().get(0), frontPreviewView);
+            setupZoomAndTapToFocus(concurrentCamera.getCameras().get(1), backPreviewView);
+        }
     }
 
-
     private void setupZoomAndTapToFocus(Camera camera, PreviewView previewView) {
         ScaleGestureDetector scaleDetector = new ScaleGestureDetector(this,
                 new ScaleGestureDetector.SimpleOnScaleGestureListener() {
@@ -330,6 +411,7 @@
             return true;
         });
     }
+
     private static void updateFrontAndBackView(
             boolean isFrontPrimary,
             @NonNull ViewGroup frontParent,
@@ -360,6 +442,7 @@
                             ViewGroup.LayoutParams.MATCH_PARENT));
         }
     }
+
     private boolean allPermissionsGranted() {
         for (String permission : REQUIRED_PERMISSIONS) {
             if (ContextCompat.checkSelfPermission(this, permission)
@@ -369,6 +452,7 @@
         }
         return true;
     }
+
     @Override
     public void onRequestPermissionsResult(int requestCode,
             @NonNull String[] permissions,
diff --git a/camera/integration-tests/coretestapp/src/main/res/layout/activity_concurrent_camera.xml b/camera/integration-tests/coretestapp/src/main/res/layout/activity_concurrent_camera.xml
index 45e472a..9c75f56 100644
--- a/camera/integration-tests/coretestapp/src/main/res/layout/activity_concurrent_camera.xml
+++ b/camera/integration-tests/coretestapp/src/main/res/layout/activity_concurrent_camera.xml
@@ -122,6 +122,22 @@
                 android:layout_gravity="top|right"
                 android:layout_marginRight="15dp"
                 android:layout_marginTop="15dp" />
+
+            <ToggleButton
+                android:id="@+id/dual_selfie"
+                android:textOn="@string/dual_selfie_on"
+                android:textOff="@string/dual_selfie_off"
+                android:layout_width="46dp"
+                android:layout_height="wrap_content"
+                android:scaleType="fitXY"
+                android:textColor="#EEEEEE"
+                android:textSize="10dp"
+                android:checked="false"
+                android:background="@drawable/round_toggle_button"
+                android:visibility="gone"
+                android:layout_gravity="top|right"
+                android:layout_marginRight="15dp"
+                android:layout_marginTop="15dp" />
         </LinearLayout>
     </FrameLayout>
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/camera/integration-tests/coretestapp/src/main/res/values/strings.xml b/camera/integration-tests/coretestapp/src/main/res/values/strings.xml
index b4fd308..2a8d205 100644
--- a/camera/integration-tests/coretestapp/src/main/res/values/strings.xml
+++ b/camera/integration-tests/coretestapp/src/main/res/values/strings.xml
@@ -20,6 +20,8 @@
     <string name="switch_mode">Switch Mode</string>
     <string name="change_layout">Change Layout</string>
     <string name="toggle_camera">Toggle Camera</string>
+    <string name="dual_selfie_on">Dual Selfie On</string>
+    <string name="dual_selfie_off">Dual Selfie Off</string>
     <string name="toggle">Toggle</string>
     <string name="finish">Finish</string>
     <string name="is_front_primary">IsFrontPrimary</string>
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/androidUnitTest/kotlin/androidx/compose/compiler/plugins/kotlin/ComposerParamSignatureTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/androidUnitTest/kotlin/androidx/compose/compiler/plugins/kotlin/ComposerParamSignatureTests.kt
index 00830a4..e00da50 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/androidUnitTest/kotlin/androidx/compose/compiler/plugins/kotlin/ComposerParamSignatureTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/androidUnitTest/kotlin/androidx/compose/compiler/plugins/kotlin/ComposerParamSignatureTests.kt
@@ -1046,6 +1046,7 @@
         """,
         """
             public abstract class CompositionLocal2 {
+              PERMITTEDSUBCLASS ProvidableCompositionLocal2
               private <init>()V
               public final getCurrent(Landroidx/compose/runtime/Composer;I)Ljava/lang/Object;
               public final foo(Landroidx/compose/runtime/Composer;I)V
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/facade/KotlinCompilerFacade.kt b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/facade/KotlinCompilerFacade.kt
index 8498808..d3c67fb 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/facade/KotlinCompilerFacade.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/facade/KotlinCompilerFacade.kt
@@ -114,7 +114,7 @@
                 put(CommonConfigurationKeys.MODULE_NAME, TEST_MODULE_NAME)
                 put(JVMConfigurationKeys.IR, true)
                 put(JVMConfigurationKeys.VALIDATE_IR, true)
-                put(JVMConfigurationKeys.JVM_TARGET, JvmTarget.JVM_1_8)
+                put(JVMConfigurationKeys.JVM_TARGET, JvmTarget.JVM_17)
                 put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, TestMessageCollector)
                 put(IrMessageLogger.IR_MESSAGE_LOGGER, IrMessageCollector(TestMessageCollector))
                 updateConfiguration()
diff --git a/compose/compiler/compiler-hosted/runtime-tests/build.gradle b/compose/compiler/compiler-hosted/runtime-tests/build.gradle
index cb9c454..095b280 100644
--- a/compose/compiler/compiler-hosted/runtime-tests/build.gradle
+++ b/compose/compiler/compiler-hosted/runtime-tests/build.gradle
@@ -22,7 +22,7 @@
 }
 
 androidXMultiplatform {
-    jvm()
+    desktop()
 
     sourceSets {
         commonMain {
@@ -39,13 +39,13 @@
             }
         }
 
-        jvmMain {
+        desktopMain {
             dependsOn(commonMain)
             dependencies {
             }
         }
 
-        jvmTest {
+        desktopTest {
             dependsOn(commonTest)
             dependencies {
             }
diff --git a/compose/compiler/compiler-hosted/runtime-tests/src/jvmTest/kotlin/androidx/compose/compiler/test/JvmCompositionTests.kt b/compose/compiler/compiler-hosted/runtime-tests/src/desktopTest/kotlin/androidx/compose/compiler/test/JvmCompositionTests.kt
similarity index 100%
rename from compose/compiler/compiler-hosted/runtime-tests/src/jvmTest/kotlin/androidx/compose/compiler/test/JvmCompositionTests.kt
rename to compose/compiler/compiler-hosted/runtime-tests/src/desktopTest/kotlin/androidx/compose/compiler/test/JvmCompositionTests.kt
diff --git a/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/ContextualFlowRowColumnTest.kt b/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/ContextualFlowRowColumnTest.kt
index bc6097c..db46f25 100644
--- a/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/ContextualFlowRowColumnTest.kt
+++ b/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/ContextualFlowRowColumnTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.compose.foundation.layout
 
+import androidx.compose.foundation.background
 import androidx.compose.foundation.clickable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
@@ -25,6 +26,7 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.layout.onGloballyPositioned
@@ -39,6 +41,7 @@
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performTouchInput
 import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -421,6 +424,156 @@
     }
 
     @Test
+    fun testContextualFlowRow_horizontalArrangementStart_SeeMoreFullWidth() {
+        val eachSize = 50
+
+        val totalCount = 20
+        val positions: MutableList<Offset> = mutableListOf()
+        var seeMorePosition: Offset? = null
+        var seeMoreSize: IntSize? = null
+        var mainAxisSpacing = 10
+        var crossAxisSpacing = 20
+        rule.setContent {
+            CompositionLocalProvider(
+                LocalDensity provides NoOpDensity
+            ) {
+                var maxLines by remember {
+                    mutableStateOf(2)
+                }
+                Box(modifier = Modifier.width(320.dp).wrapContentHeight()) {
+                    ContextualFlowRow(
+                        itemCount = totalCount,
+                        Modifier
+                            .fillMaxWidth(1f)
+                            .wrapContentHeight(align = Alignment.Top),
+                        horizontalArrangement = Arrangement.spacedBy(mainAxisSpacing.dp),
+                        verticalArrangement = Arrangement.spacedBy(crossAxisSpacing.dp),
+                        maxLines = maxLines,
+                        overflow = ContextualFlowRowOverflow.expandIndicator {
+                            Box(modifier = Modifier
+                                .fillMaxWidth(1f)
+                                .height(eachSize.dp)
+                                .background(Color.Green)
+                                .clickable {
+                                    maxLines += 2
+                                }.onPlaced {
+                                    seeMorePosition = it.positionInParent()
+                                    seeMoreSize = it.size
+                                }
+                            ) {}
+                        },
+                    ) { index ->
+                        Box(
+                            Modifier
+                                .width(eachSize.dp)
+                                .height(50.dp)
+                                .background(Color.Green)
+                                .onPlaced {
+                                    val positionInParent = it.positionInParent()
+                                    positions.add(index, positionInParent)
+                                }
+                        ) {}
+                    }
+                }
+            }
+        }
+
+        rule.waitForIdle()
+        var expectedXPosition = 0
+        var expectedYPosition = 0
+        Truth.assertThat(positions.size).isEqualTo(5)
+        positions.forEach { position ->
+            Truth
+                .assertThat(position.x)
+                .isEqualTo(expectedXPosition)
+
+            Truth
+                .assertThat(position.y)
+                .isEqualTo(expectedYPosition)
+            expectedXPosition += eachSize + mainAxisSpacing
+        }
+        expectedYPosition += eachSize + crossAxisSpacing
+        Truth.assertThat(seeMorePosition?.x).isEqualTo(0)
+        Truth.assertThat(seeMorePosition?.y).isEqualTo(expectedYPosition)
+        Truth.assertThat(seeMoreSize?.width).isEqualTo(320)
+        Truth.assertThat(seeMoreSize?.height).isEqualTo(eachSize)
+    }
+
+    @Test
+    fun testContextualFlowColumn_verticalArrangementTop_SeeMoreFullHeight() {
+        val eachSize = 50
+
+        val totalCount = 20
+        val positions: MutableList<Offset> = mutableListOf()
+        var seeMorePosition: Offset? = null
+        var seeMoreSize: IntSize? = null
+        var mainAxisSpacing = 10
+        var crossAxisSpacing = 20
+        rule.setContent {
+            CompositionLocalProvider(
+                LocalDensity provides NoOpDensity
+            ) {
+                var maxLines by remember {
+                    mutableStateOf(2)
+                }
+                Box(modifier = Modifier.height(320.dp).wrapContentWidth()) {
+                    ContextualFlowColumn(
+                        itemCount = totalCount,
+                        Modifier
+                            .fillMaxHeight(1f)
+                            .wrapContentWidth(align = Alignment.Start),
+                        verticalArrangement = Arrangement.spacedBy(mainAxisSpacing.dp),
+                        horizontalArrangement = Arrangement.spacedBy(crossAxisSpacing.dp),
+                        maxLines = maxLines,
+                        overflow = ContextualFlowColumnOverflow.expandIndicator {
+                            Box(modifier = Modifier
+                                .fillMaxHeight(1f)
+                                .width(eachSize.dp)
+                                .clickable {
+                                    maxLines += 2
+                                }.onPlaced {
+                                    seeMorePosition = it.positionInParent()
+                                    seeMoreSize = it.size
+                                }
+                            ) {}
+                        }
+                    ) { index ->
+                        Box(
+                            Modifier
+                                .width(eachSize.dp)
+                                .height(eachSize.dp)
+                                .onPlaced {
+                                    val positionInParent = it.positionInParent()
+                                    positions.add(index, positionInParent)
+                                }
+                        ) {}
+                    }
+                }
+            }
+        }
+
+        rule.waitForIdle()
+        var expectedXPosition = 0
+        var expectedYPosition = 0
+        Truth.assertThat(positions.size).isEqualTo(5)
+        positions.forEach { position ->
+            Truth
+                .assertThat(position.x)
+                .isEqualTo(expectedXPosition)
+
+            Truth
+                .assertThat(position.y)
+                .isEqualTo(expectedYPosition)
+            expectedYPosition += eachSize + mainAxisSpacing
+        }
+        expectedXPosition += eachSize + crossAxisSpacing
+        Truth.assertThat(seeMorePosition?.x).isEqualTo(expectedXPosition)
+        Truth.assertThat(seeMorePosition?.y).isEqualTo(0)
+        Truth.assertThat(seeMoreSize?.height).isEqualTo(320)
+        Truth.assertThat(seeMoreSize?.width).isEqualTo(eachSize)
+    }
+
+    @Test
     fun testContextualFlowRow_equalHeight() {
         val listOfHeights = mutableListOf<Int>()
 
diff --git a/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/FlowRowColumnTest.kt b/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/FlowRowColumnTest.kt
index 8a860f4..e6123e22 100644
--- a/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/FlowRowColumnTest.kt
+++ b/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/FlowRowColumnTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.compose.foundation.layout
 
+import androidx.compose.foundation.background
 import androidx.compose.foundation.clickable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
@@ -24,6 +25,7 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.layout.MultiContentMeasurePolicy
@@ -41,6 +43,7 @@
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performTouchInput
 import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -1376,7 +1379,7 @@
                                 }
                                 .size(itemSize.dp)
                                 .testTag(seeMoreTag)
-                                .onPlaced {
+                                .onGloballyPositioned {
                                     seeMoreShown = true
                                 }
                         )
@@ -1455,7 +1458,7 @@
                                 }
                                 .size(itemSize.dp)
                                 .testTag(seeMoreTag)
-                                .onPlaced {
+                                .onGloballyPositioned {
                                     seeMoreShown = true
                                 }
                         )
@@ -2077,7 +2080,7 @@
                                     }
                                     .size(itemSize.dp)
                                     .testTag(seeMoreTag)
-                                    .onPlaced {
+                                    .onGloballyPositioned {
                                         seeMoreShown = true
                                     }
                             )
@@ -2095,7 +2098,7 @@
                                     }
                                     .size(collapseSize.dp)
                                     .testTag(collapseTag)
-                                    .onPlaced {
+                                    .onGloballyPositioned {
                                         collapseShown = true
                                     }
                             )
@@ -2217,7 +2220,7 @@
                                     }
                                     .size(itemSize.dp)
                                     .testTag(seeMoreTag)
-                                    .onPlaced {
+                                    .onGloballyPositioned {
                                         seeMoreShown = true
                                     }
                             )
@@ -2235,7 +2238,7 @@
                                     }
                                     .size(collapseSize.dp)
                                     .testTag(collapseTag)
-                                    .onPlaced {
+                                    .onGloballyPositioned {
                                         collapseShown = true
                                     }
                             )
@@ -2616,6 +2619,158 @@
     }
 
     @Test
+    fun testFlowRow_horizontalArrangementStart_SeeMoreFullWidth() {
+        val eachSize = 50
+
+        val totalCount = 20
+        val positions: MutableList<Offset> = mutableListOf()
+        var seeMorePosition: Offset? = null
+        var seeMoreSize: IntSize? = null
+        var mainAxisSpacing = 10
+        var crossAxisSpacing = 20
+        rule.setContent {
+            CompositionLocalProvider(
+                LocalDensity provides NoOpDensity
+            ) {
+                var maxLines by remember {
+                    mutableStateOf(2)
+                }
+                Box(modifier = Modifier.width(320.dp).wrapContentHeight()) {
+                    FlowRow(
+                        Modifier
+                            .fillMaxWidth(1f)
+                            .wrapContentHeight(align = Alignment.Top),
+                        horizontalArrangement = Arrangement.spacedBy(mainAxisSpacing.dp),
+                        verticalArrangement = Arrangement.spacedBy(crossAxisSpacing.dp),
+                        maxLines = maxLines,
+                        overflow = FlowRowOverflow.expandIndicator {
+                            Box(modifier = Modifier
+                                .fillMaxWidth(1f)
+                                .height(eachSize.dp)
+                                .background(Color.Green)
+                                .clickable {
+                                    maxLines += 2
+                                }.onPlaced {
+                                    seeMorePosition = it.positionInParent()
+                                    seeMoreSize = it.size
+                                }
+                            ) {}
+                        }
+                    ) {
+                        repeat(totalCount) { index ->
+                            Box(
+                                Modifier
+                                    .width(eachSize.dp)
+                                    .height(50.dp)
+                                    .background(Color.Green)
+                                    .onPlaced {
+                                        val positionInParent = it.positionInParent()
+                                        positions.add(index, positionInParent)
+                                    }
+                            ) {}
+                        }
+                    }
+                }
+            }
+        }
+
+        rule.waitForIdle()
+        var expectedXPosition = 0
+        var expectedYPosition = 0
+        Truth.assertThat(positions.size).isEqualTo(5)
+        positions.forEach { position ->
+            Truth
+                .assertThat(position.x)
+                .isEqualTo(expectedXPosition)
+
+            Truth
+                .assertThat(position.y)
+                .isEqualTo(expectedYPosition)
+            expectedXPosition += eachSize + mainAxisSpacing
+        }
+        expectedYPosition += eachSize + crossAxisSpacing
+        Truth.assertThat(seeMorePosition?.x).isEqualTo(0)
+        Truth.assertThat(seeMorePosition?.y).isEqualTo(expectedYPosition)
+        Truth.assertThat(seeMoreSize?.width).isEqualTo(320)
+        Truth.assertThat(seeMoreSize?.height).isEqualTo(eachSize)
+    }
+
+    @Test
+    fun testFlowColumn_verticalArrangementTop_SeeMoreFullHeight() {
+        val eachSize = 50
+
+        val totalCount = 20
+        val positions: MutableList<Offset> = mutableListOf()
+        var seeMorePosition: Offset? = null
+        var seeMoreSize: IntSize? = null
+        var mainAxisSpacing = 10
+        var crossAxisSpacing = 20
+        rule.setContent {
+            CompositionLocalProvider(
+                LocalDensity provides NoOpDensity
+            ) {
+                var maxLines by remember {
+                    mutableStateOf(2)
+                }
+                Box(modifier = Modifier.height(320.dp).wrapContentWidth()) {
+                    FlowColumn(
+                        Modifier
+                            .fillMaxHeight(1f)
+                            .wrapContentWidth(align = Alignment.Start),
+                        verticalArrangement = Arrangement.spacedBy(mainAxisSpacing.dp),
+                        horizontalArrangement = Arrangement.spacedBy(crossAxisSpacing.dp),
+                        maxLines = maxLines,
+                        overflow = FlowColumnOverflow.expandIndicator {
+                            Box(modifier = Modifier
+                                .fillMaxHeight(1f)
+                                .width(eachSize.dp)
+                                .clickable {
+                                    maxLines += 2
+                                }.onPlaced {
+                                    seeMorePosition = it.positionInParent()
+                                    seeMoreSize = it.size
+                                }
+                            ) {}
+                        }
+                    ) {
+                        repeat(totalCount) { index ->
+                            Box(
+                                Modifier
+                                    .width(eachSize.dp)
+                                    .height(eachSize.dp)
+                                    .onPlaced {
+                                        val positionInParent = it.positionInParent()
+                                        positions.add(index, positionInParent)
+                                    }
+                            ) {}
+                        }
+                    }
+                }
+            }
+        }
+
+        rule.waitForIdle()
+        var expectedXPosition = 0
+        var expectedYPosition = 0
+        Truth.assertThat(positions.size).isEqualTo(5)
+        positions.forEach { position ->
+            Truth
+                .assertThat(position.x)
+                .isEqualTo(expectedXPosition)
+
+            Truth
+                .assertThat(position.y)
+                .isEqualTo(expectedYPosition)
+            expectedYPosition += eachSize + mainAxisSpacing
+        }
+        expectedXPosition += eachSize + crossAxisSpacing
+        Truth.assertThat(seeMorePosition?.x).isEqualTo(expectedXPosition)
+        Truth.assertThat(seeMorePosition?.y).isEqualTo(0)
+        Truth.assertThat(seeMoreSize?.height).isEqualTo(320)
+        Truth.assertThat(seeMoreSize?.width).isEqualTo(eachSize)
+    }
+
+    @Test
     fun testFlowRow_horizontalArrangementStart_MaxLines() {
         val eachSize = 20
         val maxItemsInMainAxis = 5
@@ -5679,7 +5834,7 @@
                             Box(
                                 Modifier
                                     .size(20.dp)
-                                    .onPlaced {
+                                    .onGloballyPositioned {
                                         itemShown = index + 1
                                     }
                             )
diff --git a/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/SizeTest.kt b/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/SizeTest.kt
index e0f239b..82927ce 100644
--- a/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/SizeTest.kt
+++ b/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/SizeTest.kt
@@ -19,9 +19,11 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.drawBehind
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.layout.IntrinsicMeasurable
 import androidx.compose.ui.layout.IntrinsicMeasureScope
@@ -60,7 +62,6 @@
 import org.junit.Assert.assertNotEquals
 import org.junit.Assert.assertTrue
 import org.junit.Before
-import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -1839,23 +1840,30 @@
         )
     }
 
-    @Ignore // b/281171119
     @Test
     fun testModifiers_doNotCauseUnnecessaryRemeasure() {
+        var drawLatch = CountDownLatch(1)
         var first by mutableStateOf(true)
         var totalMeasures = 0
         @Composable fun CountMeasures(modifier: Modifier) {
             Layout(
                 content = {},
                 modifier = modifier,
-                measurePolicy = { _, _ ->
-                    ++totalMeasures
-                    layout(0, 0) {}
+                // remember the measurePolicy so it doesn't change and cause a relayout when
+                // recomposed
+                measurePolicy = remember {
+                    { _, _ ->
+                        ++totalMeasures
+                        layout(0, 0) {}
+                    }
                 }
             )
         }
+        val drawLatchModifier = Modifier.drawBehind {
+            drawLatch.countDown()
+        }
         show {
-            Box {
+            Box(drawLatchModifier) {
                 if (first) Box {} else Row {}
                 CountMeasures(Modifier.size(10.dp))
                 CountMeasures(Modifier.requiredSize(10.dp))
@@ -1865,14 +1873,16 @@
             }
         }
 
-        val root = findComposeView()
-        waitForDraw(root)
+        assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
 
         activityTestRule.runOnUiThread {
             assertEquals(5, totalMeasures)
+            drawLatch = CountDownLatch(1)
             first = false
         }
 
+        assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
+
         activityTestRule.runOnUiThread {
             assertEquals(5, totalMeasures)
         }
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ContextualFlowLayout.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ContextualFlowLayout.kt
index 1c194ca..537b801 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ContextualFlowLayout.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/ContextualFlowLayout.kt
@@ -455,7 +455,7 @@
         }
         overflow.itemCount = itemCount
         overflow.setOverflowMeasurables(
-            isHorizontal,
+            this@FlowMeasureLazyPolicy,
             constraints
         ) { canExpand, noOfItemsShown ->
             val composableIndex = if (canExpand) 0 else 1
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt
index c595316..6535884 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt
@@ -660,9 +660,9 @@
         val collapseMeasurable = measurables.getOrNull(2)?.firstOrNull()
         overflow.itemCount = list.size
         overflow.setOverflowMeasurables(
+            this@FlowMeasurePolicy,
             seeMoreMeasurable,
             collapseMeasurable,
-            isHorizontal,
             constraints,
         )
         return breakDownItems(
@@ -1182,7 +1182,7 @@
     val spacing = ceil(mainAxisSpacingDp.toPx()).toInt()
     val crossAxisSpacing = ceil(crossAxisSpacingDp.toPx()).toInt()
     val subsetConstraints = OrientationIndependentConstraints(
-        mainAxisMin,
+        0,
         mainAxisMax,
         0,
         crossAxisMax
@@ -1347,6 +1347,7 @@
 
     ellipsisWrapInfo?.let {
         measurables.add(it.ellipsis)
+        placeables[measurables.size - 1] = it.placeable
         lineIndex = endBreakLineList.lastIndex
         if (it.placeEllipsisOnLastContentLine) {
             val lastIndex = endBreakLineList.size - 1
@@ -1450,7 +1451,7 @@
 // For weighted items, we continue to use their intrinsic widths.
 // This is because their fixed sizes are only determined after we determine
 // the number of items that can fit in the row/column it only lies on.
-private fun Measurable.measureAndCache(
+internal fun Measurable.measureAndCache(
     measurePolicy: FlowLineMeasurePolicy,
     constraints: Constraints,
     storePlaceable: (Placeable?) -> Unit
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayoutBuildingBlocks.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayoutBuildingBlocks.kt
index 3dfa4ecc..d49e626 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayoutBuildingBlocks.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayoutBuildingBlocks.kt
@@ -17,6 +17,7 @@
 
 import androidx.collection.IntIntPair
 import androidx.compose.ui.layout.Measurable
+import androidx.compose.ui.layout.Placeable
 import kotlin.math.max
 
 @OptIn(ExperimentalLayoutApi::class)
@@ -35,8 +36,9 @@
 
     class WrapEllipsisInfo(
         val ellipsis: Measurable,
+        val placeable: Placeable?,
         val ellipsisSize: IntIntPair,
-        val placeEllipsisOnLastContentLine: Boolean,
+        var placeEllipsisOnLastContentLine: Boolean = true,
     )
 
     fun getWrapEllipsisInfo(
@@ -49,29 +51,18 @@
     ): WrapEllipsisInfo? {
         if (!wrapInfo.isLastItemInContainer) return null
 
-        val ellipsis = overflow.ellipsis(
+        val ellipsisInfo = overflow.ellipsisInfo(
             hasNext,
             lastContentLineIndex,
-            getFinalMeasurable = true,
             totalCrossAxisSize
         ) ?: return null
 
-        val ellipsisSize = ellipsis.let {
-            overflow.ellipsisSize(
-                hasNext,
-                lastContentLineIndex,
-                totalCrossAxisSize
-            )
-        } ?: return null
-
         val canFitLine = lastContentLineIndex >= 0 && (nextIndexInLine == 0 ||
-            !(leftOverMainAxis - ellipsisSize.first < 0 || nextIndexInLine >= maxItemsInMainAxis))
+            !(leftOverMainAxis - ellipsisInfo.ellipsisSize.first < 0 ||
+                nextIndexInLine >= maxItemsInMainAxis))
 
-        return WrapEllipsisInfo(
-            ellipsis,
-            ellipsisSize,
-            canFitLine
-        )
+        ellipsisInfo.placeEllipsisOnLastContentLine = canFitLine
+        return ellipsisInfo
     }
 
     fun getWrapInfo(
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayoutOverflow.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayoutOverflow.kt
index ed110b2..8fc7e1b 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayoutOverflow.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayoutOverflow.kt
@@ -30,6 +30,7 @@
 import androidx.compose.runtime.remember
 import androidx.compose.ui.layout.IntrinsicMeasurable
 import androidx.compose.ui.layout.Measurable
+import androidx.compose.ui.layout.Placeable
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Dp
@@ -718,7 +719,9 @@
     internal var itemShown: Int = -1
     internal var itemCount = 0
     private var seeMoreMeasurable: Measurable? = null
+    private var seeMorePlaceable: Placeable? = null
     private var collapseMeasurable: Measurable? = null
+    private var collapsePlaceable: Placeable? = null
     private var seeMoreSize: IntIntPair? = null
     private var collapseSize: IntIntPair? = null
     // for contextual flow row
@@ -750,42 +753,46 @@
         }
     }
 
-    internal fun ellipsis(
+    internal fun ellipsisInfo(
         hasNext: Boolean,
         lineIndex: Int,
-        getFinalMeasurable: Boolean,
         totalCrossAxisSize: Int
-    ): Measurable? {
+    ): FlowLayoutBuildingBlocks.WrapEllipsisInfo? {
         return when (type) {
             FlowLayoutOverflow.OverflowType.Visible -> null
             FlowLayoutOverflow.OverflowType.Clip -> null
             FlowLayoutOverflow.OverflowType.ExpandIndicator,
             FlowLayoutOverflow.OverflowType.ExpandOrCollapseIndicator -> {
+                var measurable: Measurable? = null
+                var placeable: Placeable? = null
+                var ellipsisSize: IntIntPair?
                 if (hasNext) {
-                    if (getFinalMeasurable) {
-                        getOverflowMeasurable?.invoke(
-                            /* isExpandable */ true,
-                            noOfItemsShown
-                        ) ?: seeMoreMeasurable
-                    } else {
-                        seeMoreMeasurable
+                    measurable = getOverflowMeasurable?.invoke(
+                        /* isExpandable */ true, noOfItemsShown
+                    ) ?: seeMoreMeasurable
+                    ellipsisSize = seeMoreSize
+                    if (getOverflowMeasurable == null) {
+                        placeable = seeMorePlaceable
                     }
                 } else {
-                    if (lineIndex < (minLinesToShowCollapse - 1) ||
-                        totalCrossAxisSize < (minCrossAxisSizeToShowCollapse)
-                    ) {
-                        null
-                    } else {
-                        if (getFinalMeasurable) {
-                            getOverflowMeasurable?.invoke(
-                                /* isExpandable */ false,
-                                noOfItemsShown
-                            ) ?: collapseMeasurable
-                        } else {
-                            collapseMeasurable
-                        }
+                    if (lineIndex >= (minLinesToShowCollapse - 1) &&
+                        totalCrossAxisSize >= (minCrossAxisSizeToShowCollapse)
+                     ) {
+                        measurable = getOverflowMeasurable?.invoke(
+                            /* isExpandable */ false, noOfItemsShown
+                        ) ?: collapseMeasurable
+                    }
+                    ellipsisSize = collapseSize
+                    if (getOverflowMeasurable == null) {
+                        placeable = collapsePlaceable
                     }
                 }
+                measurable ?: return null
+                FlowLayoutBuildingBlocks.WrapEllipsisInfo(
+                    measurable,
+                    placeable,
+                    ellipsisSize!!
+                )
             }
         }
     }
@@ -810,6 +817,7 @@
             )
             this.seeMoreSize = IntIntPair(mainAxisSize, crossAxisSize)
             this.seeMoreMeasurable = item as? Measurable
+            this.seeMorePlaceable = null
         }
         collapseMeasurable?.let { item ->
             val mainAxisSize = item.mainAxisMin(
@@ -819,11 +827,63 @@
             val crossAxisSize = item.crossAxisMin(isHorizontal, mainAxisSize)
             this.collapseSize = IntIntPair(mainAxisSize, crossAxisSize)
             this.collapseMeasurable = item as? Measurable
+            this.collapsePlaceable = null
         }
     }
 
     internal fun setOverflowMeasurables(
-        isHorizontal: Boolean,
+        measurePolicy: FlowLineMeasurePolicy,
+        seeMoreMeasurable: Measurable?,
+        collapseMeasurable: Measurable?,
+        constraints: Constraints,
+    ) {
+        val isHorizontal = measurePolicy.isHorizontal
+        val orientation = if (isHorizontal)
+            LayoutOrientation.Horizontal else LayoutOrientation.Vertical
+        val orientationIndependentConstraints =
+            OrientationIndependentConstraints(constraints, orientation)
+                .copy(mainAxisMin = 0, crossAxisMin = 0)
+        val finalConstraints = orientationIndependentConstraints.toBoxConstraints(orientation)
+        seeMoreMeasurable?.let { item ->
+            item.measureAndCache(
+                measurePolicy,
+                finalConstraints
+            ) { placeable ->
+                var mainAxisSize = 0
+                var crossAxisSize = 0
+                placeable?.let {
+                    with(measurePolicy) {
+                        mainAxisSize = placeable.mainAxisSize()
+                        crossAxisSize = placeable.crossAxisSize()
+                    }
+                }
+                seeMoreSize = IntIntPair(mainAxisSize, crossAxisSize)
+                seeMorePlaceable = placeable
+            }
+            this.seeMoreMeasurable = item
+        }
+        collapseMeasurable?.let { item ->
+            item.measureAndCache(
+                measurePolicy,
+                finalConstraints
+            ) { placeable ->
+                var mainAxisSize = 0
+                var crossAxisSize = 0
+                placeable?.let {
+                    with(measurePolicy) {
+                        mainAxisSize = placeable.mainAxisSize()
+                        crossAxisSize = placeable.crossAxisSize()
+                    }
+                }
+                this.collapseSize = IntIntPair(mainAxisSize, crossAxisSize)
+                collapsePlaceable = placeable
+            }
+            this.collapseMeasurable = item
+        }
+    }
+
+    internal fun setOverflowMeasurables(
+        measurePolicy: FlowLineMeasurePolicy,
         constraints: Constraints,
         getOverflowMeasurable: ((isExpandable: Boolean, numberOfItemsShown: Int) -> Measurable?)
     ) {
@@ -836,9 +896,9 @@
             /* isExpandable */ false, /* numberOfItemsShown */ 0
         )
         setOverflowMeasurables(
+            measurePolicy,
             seeMoreMeasurable,
             collapseMeasurable,
-            isHorizontal,
             constraints
         )
     }
diff --git a/compose/foundation/foundation/api/current.txt b/compose/foundation/foundation/api/current.txt
index a94e5bd..5d21cbf 100644
--- a/compose/foundation/foundation/api/current.txt
+++ b/compose/foundation/foundation/api/current.txt
@@ -391,6 +391,7 @@
   public final class AnchoredDraggableKt {
     method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static <T> androidx.compose.foundation.gestures.DraggableAnchors<T> DraggableAnchors(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.gestures.DraggableAnchorsConfig<T>,kotlin.Unit> builder);
     method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static <T> androidx.compose.ui.Modifier anchoredDraggable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.AnchoredDraggableState<T> state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional androidx.compose.foundation.OverscrollEffect? overscrollEffect, optional boolean startDragImmediately);
+    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static <T> androidx.compose.ui.Modifier anchoredDraggable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.AnchoredDraggableState<T> state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional boolean startDragImmediately);
     method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static suspend <T> Object? animateTo(androidx.compose.foundation.gestures.AnchoredDraggableState<T>, T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static suspend <T> Object? animateToWithDecay(androidx.compose.foundation.gestures.AnchoredDraggableState<T>, T targetValue, float velocity, kotlin.coroutines.Continuation<? super java.lang.Float>);
     method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static suspend <T> Object? snapTo(androidx.compose.foundation.gestures.AnchoredDraggableState<T>, T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
diff --git a/compose/foundation/foundation/api/restricted_current.txt b/compose/foundation/foundation/api/restricted_current.txt
index 86fc321..c291ab6 100644
--- a/compose/foundation/foundation/api/restricted_current.txt
+++ b/compose/foundation/foundation/api/restricted_current.txt
@@ -393,6 +393,7 @@
   public final class AnchoredDraggableKt {
     method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static <T> androidx.compose.foundation.gestures.DraggableAnchors<T> DraggableAnchors(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.gestures.DraggableAnchorsConfig<T>,kotlin.Unit> builder);
     method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static <T> androidx.compose.ui.Modifier anchoredDraggable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.AnchoredDraggableState<T> state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional androidx.compose.foundation.OverscrollEffect? overscrollEffect, optional boolean startDragImmediately);
+    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static <T> androidx.compose.ui.Modifier anchoredDraggable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.AnchoredDraggableState<T> state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional boolean startDragImmediately);
     method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static suspend <T> Object? animateTo(androidx.compose.foundation.gestures.AnchoredDraggableState<T>, T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static suspend <T> Object? animateToWithDecay(androidx.compose.foundation.gestures.AnchoredDraggableState<T>, T targetValue, float velocity, kotlin.coroutines.Continuation<? super java.lang.Float>);
     method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static suspend <T> Object? snapTo(androidx.compose.foundation.gestures.AnchoredDraggableState<T>, T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/FoundationDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/FoundationDemos.kt
index ab1b2e3..66b6ccb 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/FoundationDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/FoundationDemos.kt
@@ -16,6 +16,7 @@
 
 package androidx.compose.foundation.demos
 
+import androidx.compose.foundation.demos.contextmenu.ContextMenuDemos
 import androidx.compose.foundation.demos.draganddrop.DragAndDropMultiAppDemo
 import androidx.compose.foundation.demos.draganddrop.DragAndDropNestedDemo
 import androidx.compose.foundation.demos.focus.FocusGroupDemo
@@ -93,5 +94,6 @@
         ComposableDemo("Marquee") { BasicMarqueeDemo() },
         DemoCategory("Pointer Icon", PointerIconDemos),
         DemoCategory("Long screenshots", ScrollingScreenshotsDemos),
+        DemoCategory("Context Menu", ContextMenuDemos),
     )
 )
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/contextmenu/ComposeContextMenu.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/contextmenu/ComposeContextMenu.kt
new file mode 100644
index 0000000..2215255
--- /dev/null
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/contextmenu/ComposeContextMenu.kt
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class)
+
+package androidx.compose.foundation.demos.contextmenu
+
+import android.widget.EditText
+import android.widget.TextView
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.border
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.layout.Arrangement.spacedBy
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.text.BasicSecureTextField
+import androidx.compose.foundation.text.BasicTextField
+import androidx.compose.foundation.text.input.rememberTextFieldState
+import androidx.compose.foundation.text.selection.SelectionContainer
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.integration.demos.common.ComposableDemo
+import androidx.compose.material.ExperimentalMaterialApi
+import androidx.compose.material.LocalContentColor
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Text
+import androidx.compose.material.TextFieldDefaults
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.toArgb
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.input.PasswordVisualTransformation
+import androidx.compose.ui.text.input.TextFieldValue
+import androidx.compose.ui.text.input.VisualTransformation
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.viewinterop.AndroidView
+
+val ContextMenuDemos = listOf(
+    ComposableDemo(title = "Text Context Menus") { TextContextMenusDemo() },
+)
+
+@Composable
+private fun TextContextMenusDemo() {
+    Box(
+        modifier = Modifier
+            .fillMaxSize()
+            .verticalScroll(rememberScrollState())
+    ) {
+        Column(
+            modifier = Modifier
+                .fillMaxSize()
+                .padding(start = 32.dp, end = 32.dp, bottom = 32.dp),
+            verticalArrangement = spacedBy(16.dp),
+            horizontalAlignment = Alignment.CenterHorizontally,
+        ) {
+            Text("Try opening the context menu in any of the components below.")
+
+            LabeledItem("NOT Selectable Text (No Context Menu)") {
+                MyText("This single text is NOT selectable.")
+            }
+
+            LabeledItem("Selectable Text - Single") {
+                SelectionContainer {
+                    MyText("This single text is selectable.")
+                }
+            }
+
+            LabeledItem("Selectable Text - Multiple") {
+                SelectionContainer {
+                    Column(Modifier.outline()) {
+                        MyText("These four texts")
+                        MyText("in a column")
+                        MyText("are all")
+                        MyText("selectable together.")
+                    }
+                }
+            }
+
+            LabeledItem("BTF1 Fully Enabled") {
+                MyTextFieldOne(initialText = "Basic Text Field One")
+            }
+
+            LabeledItem("BTF1 Read-only") {
+                MyTextFieldOne(initialText = "Basic Text Field One", readOnly = true)
+            }
+
+            LabeledItem("BTF1 Disabled (No Context Menu)") {
+                MyTextFieldOne(initialText = "Basic Text Field One", enabled = false)
+            }
+
+            LabeledItem("BTF1 Password") {
+                MyTextFieldOne(
+                    initialText = "Basic Text Field One",
+                    visualTransformation = PasswordVisualTransformation()
+                )
+            }
+
+            LabeledItem("BTF2 Fully Enabled") {
+                MyTextFieldTwo(initialText = "Basic Text Field Two")
+            }
+
+            LabeledItem("BTF2 Read-only") {
+                MyTextFieldTwo(initialText = "Basic Text Field Two", readOnly = true)
+            }
+
+            LabeledItem("BTF2 Disabled (No Context Menu)") {
+                MyTextFieldTwo(initialText = "Basic Text Field Two", enabled = false)
+            }
+
+            LabeledItem("BTF2 Password") {
+                val tfs = rememberTextFieldState("Basic Text Field Two")
+                val interactionSource = remember { MutableInteractionSource() }
+                BasicSecureTextField(
+                    state = tfs,
+                    textStyle = MaterialTheme.typography.body1
+                        .copy(color = LocalContentColor.current),
+                    interactionSource = interactionSource,
+                    decorator = { innerTextField ->
+                        TextFieldDefaults.OutlinedTextFieldDecorationBox(
+                            value = tfs.text.toString(),
+                            innerTextField = innerTextField,
+                            enabled = true,
+                            singleLine = false,
+                            visualTransformation = VisualTransformation.None,
+                            interactionSource = interactionSource
+                        )
+                    },
+                )
+            }
+
+            val textColor = LocalContentColor.current.toArgb()
+            LabeledItem("Platform TextView - NOT Selectable\n(No Context Menu)") {
+                AndroidView(
+                    modifier = Modifier.outline(),
+                    factory = { ctx ->
+                        TextView(ctx).apply {
+                            text = "Platform NON-selectable text."
+                            setTextColor(textColor)
+                        }
+                    },
+                )
+            }
+
+            LabeledItem("Platform TextView - Selectable") {
+                AndroidView(
+                    modifier = Modifier.outline(),
+                    factory = { ctx ->
+                        TextView(ctx).apply {
+                            text = "Platform selectable text."
+                            setTextColor(textColor)
+                            setTextIsSelectable(true)
+                        }
+                    },
+                )
+            }
+
+            LabeledItem("Platform EditText") {
+                AndroidView(
+                    modifier = Modifier.outline(),
+                    factory = { ctx ->
+                        EditText(ctx).apply {
+                            setText("Platform editable text.")
+                            setTextIsSelectable(true)
+                            setTextColor(textColor)
+                        }
+                    },
+                )
+            }
+        }
+    }
+}
+
+@Composable
+private fun MyText(text: String) {
+    Text(text = text, modifier = Modifier.outline())
+}
+
+@Composable
+private fun MyTextFieldOne(
+    initialText: String,
+    modifier: Modifier = Modifier,
+    enabled: Boolean = true,
+    readOnly: Boolean = false,
+    textStyle: TextStyle? = null,
+    visualTransformation: VisualTransformation = VisualTransformation.None,
+) {
+    var tfv by remember { mutableStateOf(TextFieldValue(initialText)) }
+    val interactionSource = remember { MutableInteractionSource() }
+    BasicTextField(
+        value = tfv,
+        onValueChange = { tfv = it },
+        modifier = modifier,
+        enabled = enabled,
+        readOnly = readOnly,
+        textStyle = MaterialTheme.typography.body1
+            .copy(color = LocalContentColor.current)
+            .merge(textStyle),
+        visualTransformation = visualTransformation,
+        interactionSource = interactionSource,
+        decorationBox = { innerTextField ->
+            TextFieldDefaults.OutlinedTextFieldDecorationBox(
+                value = tfv.text,
+                innerTextField = innerTextField,
+                enabled = enabled,
+                singleLine = false,
+                visualTransformation = VisualTransformation.None,
+                interactionSource = interactionSource
+            )
+        },
+    )
+}
+
+@Composable
+private fun MyTextFieldTwo(
+    initialText: String,
+    modifier: Modifier = Modifier,
+    enabled: Boolean = true,
+    readOnly: Boolean = false,
+    textStyle: TextStyle? = null,
+) {
+    val tfs = rememberTextFieldState(initialText)
+    val interactionSource = remember { MutableInteractionSource() }
+    BasicTextField(
+        state = tfs,
+        modifier = modifier,
+        enabled = enabled,
+        readOnly = readOnly,
+        textStyle = MaterialTheme.typography.body1
+            .copy(color = LocalContentColor.current)
+            .merge(textStyle),
+        interactionSource = interactionSource,
+        decorator = { innerTextField ->
+            TextFieldDefaults.OutlinedTextFieldDecorationBox(
+                value = tfs.text.toString(),
+                innerTextField = innerTextField,
+                enabled = enabled,
+                singleLine = false,
+                visualTransformation = VisualTransformation.None,
+                interactionSource = interactionSource
+            )
+        },
+    )
+}
+
+@Composable
+private fun LabeledItem(label: String, content: @Composable () -> Unit) {
+    Column(Modifier.fillMaxSize(), spacedBy(4.dp)) {
+        Text(label, color = LocalContentColor.current.copy(alpha = 0.5f))
+        content()
+    }
+}
+
+private fun Modifier.outline(color: Color = Color.LightGray): Modifier = this
+    .border(1.dp, color, RoundedCornerShape(4.dp))
+    .padding(2.dp)
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/input/internal/selection/TextFieldTextToolbarTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/input/internal/selection/TextFieldTextToolbarTest.kt
index 2577a43..6e374de 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/input/internal/selection/TextFieldTextToolbarTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/input/internal/selection/TextFieldTextToolbarTest.kt
@@ -48,7 +48,6 @@
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.input.key.Key
 import androidx.compose.ui.platform.ClipEntry
-import androidx.compose.ui.platform.ClipMetadata
 import androidx.compose.ui.platform.ClipboardManager
 import androidx.compose.ui.platform.LocalClipboardManager
 import androidx.compose.ui.platform.LocalTextToolbar
@@ -56,7 +55,6 @@
 import androidx.compose.ui.platform.TextToolbarStatus
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.platform.toClipEntry
-import androidx.compose.ui.platform.toClipMetadata
 import androidx.compose.ui.semantics.SemanticsActions
 import androidx.compose.ui.test.ExperimentalTestApi
 import androidx.compose.ui.test.SemanticsNodeInteraction
@@ -970,22 +968,6 @@
         }
     }
 
-    override fun getClipMetadata(): ClipMetadata? {
-        if (supportsClipEntry) {
-            return currentClipEntry?.clipData?.description?.toClipMetadata()
-        } else {
-            throw NotImplementedError("This clipboard does not support clip entries")
-        }
-    }
-
-    override fun hasClip(): Boolean {
-        if (supportsClipEntry) {
-            return currentClipEntry != null
-        } else {
-            throw NotImplementedError("This clipboard does not support clip entries")
-        }
-    }
-
     override fun setClip(clipEntry: ClipEntry?) {
         if (supportsClipEntry) {
             currentClipEntry = clipEntry
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Clickable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Clickable.kt
index 3adfa54..413e5560 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Clickable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Clickable.kt
@@ -29,7 +29,6 @@
 import androidx.compose.ui.composed
 import androidx.compose.ui.focus.FocusEventModifierNode
 import androidx.compose.ui.focus.FocusState
-import androidx.compose.ui.focus.focusTarget
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.input.key.Key
 import androidx.compose.ui.input.key.KeyEvent
@@ -180,7 +179,6 @@
     role: Role? = null,
     onClick: () -> Unit
 ) = clickableWithIndicationIfNeeded(
-    enabled = enabled,
     interactionSource = interactionSource,
     indication = indication
 ) { intSource, indicationNodeFactory ->
@@ -335,7 +333,6 @@
     onDoubleClick: (() -> Unit)? = null,
     onClick: () -> Unit
 ) = clickableWithIndicationIfNeeded(
-    enabled = enabled,
     interactionSource = interactionSource,
     indication = indication
 ) { intSource, indicationNodeFactory ->
@@ -357,11 +354,10 @@
  * [createClickable] is the lambda that creates the actual clickable element, which will be chained
  * with [Modifier.indication] if needed.
  */
-internal fun Modifier.clickableWithIndicationIfNeeded(
-    enabled: Boolean,
+internal inline fun Modifier.clickableWithIndicationIfNeeded(
     interactionSource: MutableInteractionSource?,
     indication: Indication?,
-    createClickable: (MutableInteractionSource?, IndicationNodeFactory?) -> Modifier
+    crossinline createClickable: (MutableInteractionSource?, IndicationNodeFactory?) -> Modifier
 ): Modifier {
     return this.then(when {
         // Fast path - indication is managed internally
@@ -381,7 +377,7 @@
                 .indication(newInteractionSource, indication)
                 .then(createClickable(newInteractionSource, null))
         }
-    }).then(if (enabled) Modifier.focusTarget() else Modifier)
+    })
 }
 
 /**
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Focusable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Focusable.kt
index 5e32fa2..272d758 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Focusable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Focusable.kt
@@ -27,6 +27,7 @@
 import androidx.compose.ui.focus.FocusPropertiesModifierNode
 import androidx.compose.ui.focus.FocusRequesterModifierNode
 import androidx.compose.ui.focus.FocusState
+import androidx.compose.ui.focus.FocusTargetModifierNode
 import androidx.compose.ui.focus.focusProperties
 import androidx.compose.ui.focus.focusTarget
 import androidx.compose.ui.focus.requestFocus
@@ -70,9 +71,7 @@
     interactionSource: MutableInteractionSource? = null,
 ) = this.then(
     if (enabled) {
-        FocusableElement(
-            interactionSource
-        ).focusTarget()
+        FocusableElement(interactionSource)
     } else {
         Modifier
     }
@@ -195,6 +194,10 @@
     private val focusablePinnableContainer = delegate(FocusablePinnableContainerNode())
     private val focusedBoundsNode = delegate(FocusedBoundsNode())
 
+    init {
+        delegate(FocusTargetModifierNode())
+    }
+
     // Focusables have a few different cases where they need to make sure they stay visible:
     //
     // 1. Focusable node newly receives focus – always bring entire node into view. That's what this
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt
index 46c8929..9adcd08 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt
@@ -60,6 +60,401 @@
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.launch
 
+// start Overscroll
+// This file contains both a Modifier.anchoredDraggable overload with overscroll and without
+// Everything below the Overscroll part should be copied to M2/M3 and kept in sync.
+/**
+ * Enable drag gestures between a set of predefined values.
+ *
+ * When a drag is detected, the offset of the [AnchoredDraggableState] will be updated with the drag
+ * delta. You should use this offset to move your content accordingly (see [Modifier.offset]).
+ * When the drag ends, the offset will be animated to one of the anchors and when that anchor is
+ * reached, the value of the [AnchoredDraggableState] will also be updated to the value
+ * corresponding to the new anchor.
+ *
+ * Dragging is constrained between the minimum and maximum anchors.
+ *
+ * @param state The associated [AnchoredDraggableState].
+ * @param orientation The orientation in which the [anchoredDraggable] can be dragged.
+ * @param enabled Whether this [anchoredDraggable] is enabled and should react to the user's input.
+ * @param reverseDirection Whether to reverse the direction of the drag, so a top to bottom
+ * drag will behave like bottom to top, and a left to right drag will behave like right to left.
+ * @param interactionSource Optional [MutableInteractionSource] that will passed on to
+ * the internal [Modifier.draggable].
+ * @param overscrollEffect optional effect to dispatch any excess delta or velocity to. The excess
+ * delta or velocity are a result of dragging/flinging and reaching the bounds. If you provide an
+ * [overscrollEffect], make sure to apply [androidx.compose.foundation.overscroll] to render the
+ * effect as well.
+ * @param startDragImmediately when set to false, [draggable] will start dragging only when the
+ * gesture crosses the touchSlop. This is useful to prevent users from "catching" an animating
+ * widget when pressing on it. See [draggable] to learn more about startDragImmediately.
+ */
+@ExperimentalFoundationApi
+fun <T> Modifier.anchoredDraggable(
+    state: AnchoredDraggableState<T>,
+    orientation: Orientation,
+    enabled: Boolean = true,
+    reverseDirection: Boolean = false,
+    interactionSource: MutableInteractionSource? = null,
+    overscrollEffect: OverscrollEffect? = null,
+    startDragImmediately: Boolean = state.isAnimationRunning
+): Modifier = this then AnchoredDraggableOverscrollElement(
+    state = state,
+    orientation = orientation,
+    enabled = enabled,
+    reverseDirection = reverseDirection,
+    interactionSource = interactionSource,
+    overscrollEffect = overscrollEffect,
+    startDragImmediately = startDragImmediately
+)
+
+@OptIn(ExperimentalFoundationApi::class)
+private class AnchoredDraggableOverscrollElement<T>(
+    private val state: AnchoredDraggableState<T>,
+    private val orientation: Orientation,
+    private val enabled: Boolean,
+    private val reverseDirection: Boolean,
+    private val interactionSource: MutableInteractionSource?,
+    private val startDragImmediately: Boolean,
+    private val overscrollEffect: OverscrollEffect?,
+) : ModifierNodeElement<AnchoredDraggableOverscrollNode<T>>() {
+    override fun create() = AnchoredDraggableOverscrollNode(
+        state,
+        orientation,
+        enabled,
+        reverseDirection,
+        interactionSource,
+        startDragImmediately,
+        overscrollEffect,
+    )
+
+    override fun update(node: AnchoredDraggableOverscrollNode<T>) {
+        node.update(
+            state,
+            orientation,
+            enabled,
+            reverseDirection,
+            interactionSource,
+            overscrollEffect,
+            startDragImmediately
+        )
+    }
+
+    override fun hashCode(): Int {
+        var result = state.hashCode()
+        result = 31 * result + orientation.hashCode()
+        result = 31 * result + enabled.hashCode()
+        result = 31 * result + reverseDirection.hashCode()
+        result = 31 * result + interactionSource.hashCode()
+        result = 31 * result + startDragImmediately.hashCode()
+        result = 31 * result + overscrollEffect.hashCode()
+        return result
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+
+        if (other !is AnchoredDraggableOverscrollElement<*>) return false
+
+        if (state != other.state) return false
+        if (orientation != other.orientation) return false
+        if (enabled != other.enabled) return false
+        if (reverseDirection != other.reverseDirection) return false
+        if (interactionSource != other.interactionSource) return false
+        if (startDragImmediately != other.startDragImmediately) return false
+        if (overscrollEffect != other.overscrollEffect) return false
+
+        return true
+    }
+
+    override fun InspectorInfo.inspectableProperties() {
+        name = "anchoredDraggable"
+        properties["state"] = state
+        properties["orientation"] = orientation
+        properties["enabled"] = enabled
+        properties["reverseDirection"] = reverseDirection
+        properties["interactionSource"] = interactionSource
+        properties["startDragImmediately"] = startDragImmediately
+        properties["overscrollEffect"] = overscrollEffect
+    }
+}
+
+@OptIn(ExperimentalFoundationApi::class)
+private class AnchoredDraggableOverscrollNode<T>(
+    state: AnchoredDraggableState<T>,
+    orientation: Orientation,
+    enabled: Boolean,
+    reverseDirection: Boolean,
+    interactionSource: MutableInteractionSource?,
+    startDragImmediately: Boolean,
+    private var overscrollEffect: OverscrollEffect?,
+) : AnchoredDraggableNode<T>(
+    state = state,
+    orientation = orientation,
+    enabled = enabled,
+    reverseDirection = reverseDirection,
+    interactionSource = interactionSource,
+    startDragImmediately = startDragImmediately
+) {
+    override suspend fun AnchoredDragScope.anchoredDrag(
+        forEachDelta: suspend ((dragDelta: DragEvent.DragDelta) -> Unit) -> Unit
+    ) {
+        forEachDelta { dragDelta ->
+            if (overscrollEffect == null) {
+                dragTo(state.newOffsetForDelta(dragDelta.delta.reverseIfNeeded().toFloat()))
+            } else {
+                overscrollEffect!!.applyToScroll(
+                    delta = dragDelta.delta.reverseIfNeeded(),
+                    source = NestedScrollSource.Drag
+                ) { deltaForDrag ->
+                    val dragOffset = state.newOffsetForDelta(deltaForDrag.toFloat())
+                    val consumedDelta = (dragOffset - state.requireOffset()).toOffset()
+                    dragTo(dragOffset)
+                    consumedDelta
+                }
+            }
+        }
+    }
+
+    override suspend fun CoroutineScope.onDragStopped(velocity: Velocity) {
+        if (overscrollEffect == null) {
+            state.settle(velocity.reverseIfNeeded().toFloat()).toVelocity()
+        } else {
+            overscrollEffect!!.applyToFling(
+                velocity = velocity.reverseIfNeeded()
+            ) { availableVelocity ->
+                val consumed = state.settle(availableVelocity.toFloat()).toVelocity()
+                val currentOffset = state.requireOffset()
+                val minAnchor = state.anchors.minAnchor()
+                val maxAnchor = state.anchors.maxAnchor()
+                // return consumed velocity only if we are reaching the min/max anchors
+                if (currentOffset >= maxAnchor || currentOffset <= minAnchor) {
+                    consumed
+                } else {
+                    availableVelocity
+                }
+            }
+        }
+    }
+
+    fun update(
+        state: AnchoredDraggableState<T>,
+        orientation: Orientation,
+        enabled: Boolean,
+        reverseDirection: Boolean,
+        interactionSource: MutableInteractionSource?,
+        overscrollEffect: OverscrollEffect?,
+        startDragImmediately: Boolean
+    ) {
+        this.overscrollEffect = overscrollEffect
+        update(
+            state = state,
+            orientation = orientation,
+            enabled = enabled,
+            reverseDirection = reverseDirection,
+            interactionSource = interactionSource,
+            startDragImmediately = startDragImmediately
+        )
+    }
+}
+// end Overscroll
+
+/**
+ * Enable drag gestures between a set of predefined values.
+ *
+ * When a drag is detected, the offset of the [AnchoredDraggableState] will be updated with the drag
+ * delta. You should use this offset to move your content accordingly (see [Modifier.offset]).
+ * When the drag ends, the offset will be animated to one of the anchors and when that anchor is
+ * reached, the value of the [AnchoredDraggableState] will also be updated to the value
+ * corresponding to the new anchor.
+ *
+ * Dragging is constrained between the minimum and maximum anchors.
+ *
+ * @param state The associated [AnchoredDraggableState].
+ * @param orientation The orientation in which the [anchoredDraggable] can be dragged.
+ * @param enabled Whether this [anchoredDraggable] is enabled and should react to the user's input.
+ * @param reverseDirection Whether to reverse the direction of the drag, so a top to bottom
+ * drag will behave like bottom to top, and a left to right drag will behave like right to left.
+ * @param interactionSource Optional [MutableInteractionSource] that will passed on to
+ * the internal [Modifier.draggable].
+ * @param startDragImmediately when set to false, [draggable] will start dragging only when the
+ * gesture crosses the touchSlop. This is useful to prevent users from "catching" an animating
+ * widget when pressing on it. See [draggable] to learn more about startDragImmediately.
+ */
+@ExperimentalFoundationApi
+fun <T> Modifier.anchoredDraggable(
+    state: AnchoredDraggableState<T>,
+    orientation: Orientation,
+    enabled: Boolean = true,
+    reverseDirection: Boolean = false,
+    interactionSource: MutableInteractionSource? = null,
+    startDragImmediately: Boolean = state.isAnimationRunning
+): Modifier = this then AnchoredDraggableElement(
+    state = state,
+    orientation = orientation,
+    enabled = enabled,
+    reverseDirection = reverseDirection,
+    interactionSource = interactionSource,
+    startDragImmediately = startDragImmediately
+)
+
+@OptIn(ExperimentalFoundationApi::class)
+private class AnchoredDraggableElement<T>(
+    private val state: AnchoredDraggableState<T>,
+    private val orientation: Orientation,
+    private val enabled: Boolean,
+    private val reverseDirection: Boolean,
+    private val interactionSource: MutableInteractionSource?,
+    private val startDragImmediately: Boolean
+) : ModifierNodeElement<AnchoredDraggableNode<T>>() {
+    override fun create() = AnchoredDraggableNode(
+        state,
+        orientation,
+        enabled,
+        reverseDirection,
+        interactionSource,
+        startDragImmediately
+    )
+
+    override fun update(node: AnchoredDraggableNode<T>) {
+        node.update(
+            state,
+            orientation,
+            enabled,
+            reverseDirection,
+            interactionSource,
+            startDragImmediately
+        )
+    }
+
+    override fun hashCode(): Int {
+        var result = state.hashCode()
+        result = 31 * result + orientation.hashCode()
+        result = 31 * result + enabled.hashCode()
+        result = 31 * result + reverseDirection.hashCode()
+        result = 31 * result + interactionSource.hashCode()
+        result = 31 * result + startDragImmediately.hashCode()
+        return result
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+
+        if (other !is AnchoredDraggableElement<*>) return false
+
+        if (state != other.state) return false
+        if (orientation != other.orientation) return false
+        if (enabled != other.enabled) return false
+        if (reverseDirection != other.reverseDirection) return false
+        if (interactionSource != other.interactionSource) return false
+        if (startDragImmediately != other.startDragImmediately) return false
+
+        return true
+    }
+
+    override fun InspectorInfo.inspectableProperties() {
+        name = "anchoredDraggable"
+        properties["state"] = state
+        properties["orientation"] = orientation
+        properties["enabled"] = enabled
+        properties["reverseDirection"] = reverseDirection
+        properties["interactionSource"] = interactionSource
+        properties["startDragImmediately"] = startDragImmediately
+    }
+}
+
+@OptIn(ExperimentalFoundationApi::class)
+private open class AnchoredDraggableNode<T>(
+    protected var state: AnchoredDraggableState<T>,
+    protected var orientation: Orientation,
+    enabled: Boolean,
+    protected var reverseDirection: Boolean,
+    interactionSource: MutableInteractionSource?,
+    protected var startDragImmediately: Boolean
+) : DragGestureNode(
+    canDrag = AlwaysDrag,
+    enabled = enabled,
+    interactionSource = interactionSource
+) {
+
+    open suspend fun AnchoredDragScope.anchoredDrag(
+        forEachDelta: suspend ((dragDelta: DragDelta) -> Unit) -> Unit
+    ) {
+        forEachDelta { dragDelta ->
+            dragTo(state.newOffsetForDelta(dragDelta.delta.reverseIfNeeded().toFloat()))
+        }
+    }
+
+    override suspend fun drag(forEachDelta: suspend ((dragDelta: DragDelta) -> Unit) -> Unit) {
+        state.anchoredDrag(MutatePriority.Default) { anchoredDrag(forEachDelta) }
+    }
+
+    override val pointerDirectionConfig: PointerDirectionConfig
+        get() = orientation.toPointerDirectionConfig()
+
+    override suspend fun CoroutineScope.onDragStarted(startedPosition: Offset) {}
+
+    override suspend fun CoroutineScope.onDragStopped(velocity: Velocity) {
+        state.settle(velocity.reverseIfNeeded().toFloat()).toVelocity()
+    }
+
+    override fun startDragImmediately(): Boolean = startDragImmediately
+
+    fun update(
+        state: AnchoredDraggableState<T>,
+        orientation: Orientation,
+        enabled: Boolean,
+        reverseDirection: Boolean,
+        interactionSource: MutableInteractionSource?,
+        startDragImmediately: Boolean
+    ) {
+        var resetPointerInputHandling = false
+
+        if (this.state != state) {
+            this.state = state
+            resetPointerInputHandling = true
+        }
+        if (this.orientation != orientation) {
+            this.orientation = orientation
+            resetPointerInputHandling = true
+        }
+
+        if (this.reverseDirection != reverseDirection) {
+            this.reverseDirection = reverseDirection
+            resetPointerInputHandling = true
+        }
+
+        this.startDragImmediately = startDragImmediately
+
+        update(
+            enabled = enabled,
+            interactionSource = interactionSource,
+            isResetPointerInputHandling = resetPointerInputHandling,
+        )
+    }
+
+    protected fun Float.toOffset() = Offset(
+        x = if (orientation == Orientation.Horizontal) this else 0f,
+        y = if (orientation == Orientation.Vertical) this else 0f,
+    )
+
+    protected fun Float.toVelocity() = Velocity(
+        x = if (orientation == Orientation.Horizontal) this else 0f,
+        y = if (orientation == Orientation.Vertical) this else 0f,
+    )
+
+    protected fun Velocity.toFloat() =
+        if (orientation == Orientation.Vertical) this.y else this.x
+
+    protected fun Offset.toFloat() =
+        if (orientation == Orientation.Vertical) this.y else this.x
+
+    protected fun Velocity.reverseIfNeeded() = if (reverseDirection) this * -1f else this * 1f
+    protected fun Offset.reverseIfNeeded() = if (reverseDirection) this * -1f else this * 1f
+}
+
+private val AlwaysDrag: (PointerInputChange) -> Boolean = { true }
+
 /**
  * Structure that represents the anchors of a [AnchoredDraggableState].
  *
@@ -183,244 +578,6 @@
 }
 
 /**
- * Enable drag gestures between a set of predefined values.
- *
- * When a drag is detected, the offset of the [AnchoredDraggableState] will be updated with the drag
- * delta. You should use this offset to move your content accordingly (see [Modifier.offset]).
- * When the drag ends, the offset will be animated to one of the anchors and when that anchor is
- * reached, the value of the [AnchoredDraggableState] will also be updated to the value
- * corresponding to the new anchor.
- *
- * Dragging is constrained between the minimum and maximum anchors.
- *
- * @param state The associated [AnchoredDraggableState].
- * @param orientation The orientation in which the [anchoredDraggable] can be dragged.
- * @param enabled Whether this [anchoredDraggable] is enabled and should react to the user's input.
- * @param reverseDirection Whether to reverse the direction of the drag, so a top to bottom
- * drag will behave like bottom to top, and a left to right drag will behave like right to left.
- * @param interactionSource Optional [MutableInteractionSource] that will passed on to
- * the internal [Modifier.draggable].
- * @param overscrollEffect optional effect to dispatch any excess delta or velocity to. The excess
- * delta or velocity are a result of dragging/flinging and reaching the bounds. If you provide an
- * [overscrollEffect], make sure to apply [androidx.compose.foundation.overscroll] to render the
- * effect as well.
- * @param startDragImmediately when set to false, [draggable] will start dragging only when the
- * gesture crosses the touchSlop. This is useful to prevent users from "catching" an animating
- * widget when pressing on it. See [draggable] to learn more about startDragImmediately.
- */
-@ExperimentalFoundationApi
-fun <T> Modifier.anchoredDraggable(
-    state: AnchoredDraggableState<T>,
-    orientation: Orientation,
-    enabled: Boolean = true,
-    reverseDirection: Boolean = false,
-    interactionSource: MutableInteractionSource? = null,
-    overscrollEffect: OverscrollEffect? = null,
-    startDragImmediately: Boolean = state.isAnimationRunning
-): Modifier = this then AnchoredDraggableElement(
-    state = state,
-    orientation = orientation,
-    enabled = enabled,
-    reverseDirection = reverseDirection,
-    interactionSource = interactionSource,
-    overscrollEffect = overscrollEffect,
-    startDragImmediately = startDragImmediately
-)
-
-@OptIn(ExperimentalFoundationApi::class)
-private class AnchoredDraggableElement<T>(
-    private val state: AnchoredDraggableState<T>,
-    private val orientation: Orientation,
-    private val enabled: Boolean,
-    private val reverseDirection: Boolean,
-    private val interactionSource: MutableInteractionSource?,
-    private val overscrollEffect: OverscrollEffect?,
-    private val startDragImmediately: Boolean
-) : ModifierNodeElement<AnchoredDraggableNode<T>>() {
-    override fun create(): AnchoredDraggableNode<T> {
-        return AnchoredDraggableNode(
-            state,
-            orientation,
-            enabled,
-            reverseDirection,
-            interactionSource,
-            overscrollEffect,
-            { startDragImmediately }
-        )
-    }
-
-    override fun update(node: AnchoredDraggableNode<T>) {
-        node.update(
-            state,
-            orientation,
-            enabled,
-            reverseDirection,
-            interactionSource,
-            overscrollEffect,
-            { startDragImmediately }
-        )
-    }
-
-    override fun hashCode(): Int {
-        var result = state.hashCode()
-        result = 31 * result + orientation.hashCode()
-        result = 31 * result + enabled.hashCode()
-        result = 31 * result + reverseDirection.hashCode()
-        result = 31 * result + interactionSource.hashCode()
-        result = 31 * result + overscrollEffect.hashCode()
-        result = 31 * result + startDragImmediately.hashCode()
-        return result
-    }
-
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-
-        if (other !is AnchoredDraggableElement<*>) return false
-
-        if (state != other.state) return false
-        if (orientation != other.orientation) return false
-        if (enabled != other.enabled) return false
-        if (reverseDirection != other.reverseDirection) return false
-        if (interactionSource != other.interactionSource) return false
-        if (overscrollEffect != other.overscrollEffect) return false
-        if (startDragImmediately != other.startDragImmediately) return false
-
-        return true
-    }
-
-    override fun InspectorInfo.inspectableProperties() {
-        name = "anchoredDraggable"
-        properties["state"] = state
-        properties["orientation"] = orientation
-        properties["enabled"] = enabled
-        properties["reverseDirection"] = reverseDirection
-        properties["interactionSource"] = interactionSource
-        properties["overscrollEffect"] = overscrollEffect
-        properties["startDragImmediately"] = startDragImmediately
-    }
-}
-
-@ExperimentalFoundationApi
-private class AnchoredDraggableNode<T>(
-    private var state: AnchoredDraggableState<T>,
-    private var orientation: Orientation,
-    enabled: Boolean,
-    private var reverseDirection: Boolean,
-    interactionSource: MutableInteractionSource?,
-    private var overscrollEffect: OverscrollEffect?,
-    private var startDragImmediately: () -> Boolean
-) : DragGestureNode(
-    canDrag = AlwaysDrag,
-    enabled = enabled,
-    interactionSource = interactionSource
-) {
-
-    override suspend fun drag(forEachDelta: suspend ((dragDelta: DragDelta) -> Unit) -> Unit) {
-        state.anchoredDrag(MutatePriority.Default) {
-            forEachDelta { dragDelta ->
-                if (overscrollEffect == null) {
-                    dragTo(state.newOffsetForDelta(dragDelta.delta.reverseIfNeeded().toFloat()))
-                } else {
-                    overscrollEffect!!.applyToScroll(
-                        delta = dragDelta.delta.reverseIfNeeded(),
-                        source = NestedScrollSource.Drag
-                    ) { deltaForDrag ->
-                        val dragOffset = state.newOffsetForDelta(deltaForDrag.toFloat())
-                        val consumedDelta = (dragOffset - state.requireOffset()).toOffset()
-                        dragTo(dragOffset)
-                        consumedDelta
-                    }
-                }
-            }
-        }
-    }
-
-    override val pointerDirectionConfig: PointerDirectionConfig
-        get() = orientation.toPointerDirectionConfig()
-
-    override suspend fun CoroutineScope.onDragStarted(startedPosition: Offset) {}
-
-    override suspend fun CoroutineScope.onDragStopped(velocity: Velocity) {
-        if (overscrollEffect == null) {
-            state.settle(velocity.reverseIfNeeded().toFloat()).toVelocity()
-        } else {
-            overscrollEffect!!.applyToFling(
-                velocity = velocity.reverseIfNeeded()
-            ) { availableVelocity ->
-                val consumed = state.settle(availableVelocity.toFloat()).toVelocity()
-                val currentOffset = state.requireOffset()
-                val minAnchor = state.anchors.minAnchor()
-                val maxAnchor = state.anchors.maxAnchor()
-                // return consumed velocity only if we are reaching the min/max anchors
-                if (currentOffset >= maxAnchor || currentOffset <= minAnchor) {
-                    consumed
-                } else {
-                    availableVelocity
-                }
-            }
-        }
-    }
-
-    override fun startDragImmediately(): Boolean = startDragImmediately.invoke()
-
-    fun update(
-        state: AnchoredDraggableState<T>,
-        orientation: Orientation,
-        enabled: Boolean,
-        reverseDirection: Boolean,
-        interactionSource: MutableInteractionSource?,
-        overscrollEffect: OverscrollEffect?,
-        startDragImmediately: () -> Boolean
-    ) {
-        var resetPointerInputHandling = false
-
-        if (this.state != state) {
-            this.state = state
-            resetPointerInputHandling = true
-        }
-        if (this.orientation != orientation) {
-            this.orientation = orientation
-            resetPointerInputHandling = true
-        }
-
-        if (this.reverseDirection != reverseDirection) {
-            this.reverseDirection = reverseDirection
-            resetPointerInputHandling = true
-        }
-
-        this.overscrollEffect = overscrollEffect
-        this.startDragImmediately = startDragImmediately
-
-        update(
-            enabled = enabled,
-            interactionSource = interactionSource,
-            isResetPointerInputHandling = resetPointerInputHandling,
-        )
-    }
-
-    private fun Float.toOffset() = Offset(
-        x = if (orientation == Orientation.Horizontal) this else 0f,
-        y = if (orientation == Orientation.Vertical) this else 0f,
-    )
-
-    fun Float.toVelocity() = Velocity(
-        x = if (orientation == Orientation.Horizontal) this else 0f,
-        y = if (orientation == Orientation.Vertical) this else 0f,
-    )
-
-    private fun Velocity.toFloat() =
-        if (orientation == Orientation.Vertical) this.y else this.x
-
-    private fun Offset.toFloat() =
-        if (orientation == Orientation.Vertical) this.y else this.x
-
-    private fun Velocity.reverseIfNeeded() = if (reverseDirection) this * -1f else this * 1f
-    private fun Offset.reverseIfNeeded() = if (reverseDirection) this * -1f else this * 1f
-}
-
-private val AlwaysDrag: (PointerInputChange) -> Boolean = { true }
-
-/**
  * State of the [anchoredDraggable] modifier.
  * Use the constructor overload with anchors if the anchors are defined in composition, or update
  * the anchors using [updateAnchors].
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Selectable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Selectable.kt
index ed4711b..caa756a 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Selectable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Selectable.kt
@@ -140,7 +140,6 @@
     role: Role? = null,
     onClick: () -> Unit
 ) = clickableWithIndicationIfNeeded(
-    enabled = enabled,
     interactionSource = interactionSource,
     indication = indication
 ) { intSource, indicationNodeFactory ->
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Toggleable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Toggleable.kt
index c98b15a..b75e3c1 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Toggleable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Toggleable.kt
@@ -134,7 +134,6 @@
     role: Role? = null,
     onValueChange: (Boolean) -> Unit
 ) = clickableWithIndicationIfNeeded(
-    enabled = enabled,
     interactionSource = interactionSource,
     indication = indication
 ) { intSource, indicationNodeFactory ->
@@ -370,7 +369,6 @@
     role: Role? = null,
     onClick: () -> Unit
 ) = clickableWithIndicationIfNeeded(
-    enabled = enabled,
     interactionSource = interactionSource,
     indication = indication
 ) { intSource, indicationNodeFactory ->
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/selection/TextFieldSelectionState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/selection/TextFieldSelectionState.kt
index 99014f8..5d422b9 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/selection/TextFieldSelectionState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/selection/TextFieldSelectionState.kt
@@ -1157,8 +1157,8 @@
         val receiveContentConfiguration = receiveContentConfiguration?.invoke()
             ?: return pasteAsPlainText()
 
-        val clipEntry = clipboardManager?.getClip() ?: return
-        val clipMetadata = clipboardManager?.getClipMetadata() ?: return pasteAsPlainText()
+        val clipEntry = clipboardManager?.getClip() ?: return pasteAsPlainText()
+        val clipMetadata = clipEntry.getMetadata()
 
         val remaining = receiveContentConfiguration.receiveContentListener.onReceive(
             TransferableContent(
@@ -1208,7 +1208,7 @@
 
         // if receive content is configured, hasClip should be enough to show the paste option
         val canPasteContent = receiveContentConfiguration?.invoke() != null &&
-            clipboardManager?.hasClip() == true
+            clipboardManager?.getClip() != null
         // if receive content is not configured, we expect at least a text item to be present
         val canPasteText = clipboardManager?.hasText() == true
         val canPaste = editable && (canPasteContent || canPasteText)
diff --git a/compose/material/material/api/current.txt b/compose/material/material/api/current.txt
index def4217..6b52d49 100644
--- a/compose/material/material/api/current.txt
+++ b/compose/material/material/api/current.txt
@@ -374,10 +374,16 @@
   }
 
   public final class DrawerDefaults {
+    method public androidx.compose.animation.core.TweenSpec<java.lang.Float> getAnimationSpec();
+    method @androidx.compose.runtime.Composable public long getBackgroundColor();
     method public float getElevation();
     method @androidx.compose.runtime.Composable public long getScrimColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    property public final androidx.compose.animation.core.TweenSpec<java.lang.Float> AnimationSpec;
     property public final float Elevation;
+    property @androidx.compose.runtime.Composable public final long backgroundColor;
     property @androidx.compose.runtime.Composable public final long scrimColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
     field public static final androidx.compose.material.DrawerDefaults INSTANCE;
     field public static final float ScrimOpacity = 0.32f;
   }
diff --git a/compose/material/material/api/restricted_current.txt b/compose/material/material/api/restricted_current.txt
index def4217..6b52d49 100644
--- a/compose/material/material/api/restricted_current.txt
+++ b/compose/material/material/api/restricted_current.txt
@@ -374,10 +374,16 @@
   }
 
   public final class DrawerDefaults {
+    method public androidx.compose.animation.core.TweenSpec<java.lang.Float> getAnimationSpec();
+    method @androidx.compose.runtime.Composable public long getBackgroundColor();
     method public float getElevation();
     method @androidx.compose.runtime.Composable public long getScrimColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    property public final androidx.compose.animation.core.TweenSpec<java.lang.Float> AnimationSpec;
     property public final float Elevation;
+    property @androidx.compose.runtime.Composable public final long backgroundColor;
     property @androidx.compose.runtime.Composable public final long scrimColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
     field public static final androidx.compose.material.DrawerDefaults INSTANCE;
     field public static final float ScrimOpacity = 0.32f;
   }
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
index 7cd36cd..d2f9de7 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
@@ -257,8 +257,9 @@
  *
  * @param initialValue The initial value of the state.
  * @param density The density that this state can use to convert values to and from dp.
- * @param animationSpec The animation spec to be used for animations.
  * @param confirmStateChange Optional callback invoked to confirm or veto a pending state change.
+ * @param animationSpec The animation spec to be used for open/close animations, as well as
+ * settling when a user lets go.
  */
 @OptIn(ExperimentalMaterialApi::class)
 @Suppress("NotCloseable")
@@ -266,7 +267,7 @@
     initialValue: BottomDrawerValue,
     density: Density,
     confirmStateChange: (BottomDrawerValue) -> Boolean = { true },
-    animationSpec: AnimationSpec<Float> = AnimationSpec
+    animationSpec: AnimationSpec<Float> = DrawerDefaults.AnimationSpec
 ) {
     internal val anchoredDraggableState = AnchoredDraggableState(
         initialValue = initialValue,
@@ -284,7 +285,7 @@
         get() = anchoredDraggableState.targetValue
 
     /**
-     * The current offset, or [Float.NaN] if it has not been initialized yet.
+     * The current offset in pixels, or [Float.NaN] if it has not been initialized yet.
      */
     val offset: Float
         get() = anchoredDraggableState.offset
@@ -435,14 +436,15 @@
  * Create and [remember] a [BottomDrawerState].
  *
  * @param initialValue The initial value of the state.
- * @param animationSpec The animation spec to be used for animations.
  * @param confirmStateChange Optional callback invoked to confirm or veto a pending state change.
+ * @param animationSpec The animation spec to be used for open/close animations, as well as
+ * settling when a user lets go.
  */
 @Composable
 fun rememberBottomDrawerState(
     initialValue: BottomDrawerValue,
     confirmStateChange: (BottomDrawerValue) -> Boolean = { true },
-    animationSpec: AnimationSpec<Float> = AnimationSpec,
+    animationSpec: AnimationSpec<Float> = DrawerDefaults.AnimationSpec,
 ): BottomDrawerState {
     val density = LocalDensity.current
     return rememberSaveable(
@@ -489,9 +491,9 @@
     modifier: Modifier = Modifier,
     drawerState: DrawerState = rememberDrawerState(DrawerValue.Closed),
     gesturesEnabled: Boolean = true,
-    drawerShape: Shape = MaterialTheme.shapes.large,
+    drawerShape: Shape = DrawerDefaults.shape,
     drawerElevation: Dp = DrawerDefaults.Elevation,
-    drawerBackgroundColor: Color = MaterialTheme.colors.surface,
+    drawerBackgroundColor: Color = DrawerDefaults.backgroundColor,
     drawerContentColor: Color = contentColorFor(drawerBackgroundColor),
     scrimColor: Color = DrawerDefaults.scrimColor,
     content: @Composable () -> Unit
@@ -599,13 +601,13 @@
  *
  * @sample androidx.compose.material.samples.BottomDrawerSample
  *
- * @param drawerState state of the drawer
+ * @param drawerContent composable that represents content inside the drawer
  * @param modifier optional [Modifier] for the entire component
+ * @param drawerState state of the drawer
  * @param gesturesEnabled whether or not drawer can be interacted by gestures
  * @param drawerShape shape of the drawer sheet
  * @param drawerElevation drawer sheet elevation. This controls the size of the shadow below the
  * drawer sheet
- * @param drawerContent composable that represents content inside the drawer
  * @param drawerBackgroundColor background color to be used for the drawer sheet
  * @param drawerContentColor color of the content to use inside the drawer sheet. Defaults to
  * either the matching content color for [drawerBackgroundColor], or, if it is not a color from
@@ -614,7 +616,6 @@
  * color passed is [Color.Unspecified], then a scrim will no longer be applied and the bottom
  * drawer will not block interaction with the rest of the screen when visible.
  * @param content content of the rest of the UI
- *
  */
 @OptIn(ExperimentalMaterialApi::class)
 @Composable
@@ -623,9 +624,9 @@
     modifier: Modifier = Modifier,
     drawerState: BottomDrawerState = rememberBottomDrawerState(Closed),
     gesturesEnabled: Boolean = true,
-    drawerShape: Shape = MaterialTheme.shapes.large,
+    drawerShape: Shape = DrawerDefaults.shape,
     drawerElevation: Dp = DrawerDefaults.Elevation,
-    drawerBackgroundColor: Color = MaterialTheme.colors.surface,
+    drawerBackgroundColor: Color = DrawerDefaults.backgroundColor,
     drawerContentColor: Color = contentColorFor(drawerBackgroundColor),
     scrimColor: Color = DrawerDefaults.scrimColor,
     content: @Composable () -> Unit
@@ -744,10 +745,33 @@
 object DrawerDefaults {
 
     /**
-     * Default Elevation for drawer sheet as specified in material specs
+     * Default animation spec used for [ModalDrawer] and [BottomDrawer] open and close animations,
+     * as well as settling when a user lets go.
+     */
+    val AnimationSpec = TweenSpec<Float>(durationMillis = 256)
+
+    /**
+     * Default background color for drawer sheets
+     */
+    val backgroundColor: Color
+        @Composable
+        get() = MaterialTheme.colors.surface
+
+    /**
+     * Default elevation for drawer sheet as specified in material specs
      */
     val Elevation = 16.dp
 
+    /**
+     * Default shape for drawer sheets
+     */
+    val shape: Shape
+        @Composable
+        get() = MaterialTheme.shapes.large
+
+    /**
+     * Default color of the scrim that obscures content when the drawer is open
+     */
     val scrimColor: Color
         @Composable
         get() = MaterialTheme.colors.onSurface.copy(alpha = ScrimOpacity)
diff --git a/compose/material3/adaptive/adaptive-navigation/api/current.txt b/compose/material3/adaptive/adaptive-navigation/api/current.txt
index 0c5fcc1..1a5b767 100644
--- a/compose/material3/adaptive/adaptive-navigation/api/current.txt
+++ b/compose/material3/adaptive/adaptive-navigation/api/current.txt
@@ -24,7 +24,9 @@
   }
 
   public final class ThreePaneScaffoldNavigatorKt {
+    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator rememberListDetailPaneScaffoldNavigator(optional androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, optional boolean isDestinationHistoryAware);
     method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static <T> androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator<T> rememberListDetailPaneScaffoldNavigator(optional androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, optional boolean isDestinationHistoryAware, optional java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends T>> initialDestinationHistory);
+    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator rememberSupportingPaneScaffoldNavigator(optional androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, optional boolean isDestinationHistoryAware);
     method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static <T> androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator<T> rememberSupportingPaneScaffoldNavigator(optional androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, optional boolean isDestinationHistoryAware, optional java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends T>> initialDestinationHistory);
   }
 
diff --git a/compose/material3/adaptive/adaptive-navigation/api/restricted_current.txt b/compose/material3/adaptive/adaptive-navigation/api/restricted_current.txt
index 0c5fcc1..1a5b767 100644
--- a/compose/material3/adaptive/adaptive-navigation/api/restricted_current.txt
+++ b/compose/material3/adaptive/adaptive-navigation/api/restricted_current.txt
@@ -24,7 +24,9 @@
   }
 
   public final class ThreePaneScaffoldNavigatorKt {
+    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator rememberListDetailPaneScaffoldNavigator(optional androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, optional boolean isDestinationHistoryAware);
     method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static <T> androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator<T> rememberListDetailPaneScaffoldNavigator(optional androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, optional boolean isDestinationHistoryAware, optional java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends T>> initialDestinationHistory);
+    method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator rememberSupportingPaneScaffoldNavigator(optional androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, optional boolean isDestinationHistoryAware);
     method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static <T> androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator<T> rememberSupportingPaneScaffoldNavigator(optional androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, optional boolean isDestinationHistoryAware, optional java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<? extends T>> initialDestinationHistory);
   }
 
diff --git a/compose/material3/adaptive/adaptive-navigation/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation/ListDetailPaneScaffoldNavigatorTest.kt b/compose/material3/adaptive/adaptive-navigation/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation/ListDetailPaneScaffoldNavigatorTest.kt
index d665d36..5b6e31c 100644
--- a/compose/material3/adaptive/adaptive-navigation/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation/ListDetailPaneScaffoldNavigatorTest.kt
+++ b/compose/material3/adaptive/adaptive-navigation/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation/ListDetailPaneScaffoldNavigatorTest.kt
@@ -46,7 +46,7 @@
         var canNavigateBack by Delegates.notNull<Boolean>()
 
         composeRule.setContent {
-            scaffoldNavigator = rememberListDetailPaneScaffoldNavigator(
+            scaffoldNavigator = rememberListDetailPaneScaffoldNavigator<Int>(
                 scaffoldDirective = MockSinglePaneScaffoldDirective
             )
             canNavigateBack = scaffoldNavigator.canNavigateBack()
@@ -77,7 +77,7 @@
         var canNavigateBack by Delegates.notNull<Boolean>()
 
         composeRule.setContent {
-            scaffoldNavigator = rememberListDetailPaneScaffoldNavigator(
+            scaffoldNavigator = rememberListDetailPaneScaffoldNavigator<Int>(
                 scaffoldDirective = MockDualPaneScaffoldDirective
             )
             canNavigateBack = scaffoldNavigator.canNavigateBack()
@@ -108,7 +108,7 @@
         var canNavigateBack by Delegates.notNull<Boolean>()
 
         composeRule.setContent {
-            scaffoldNavigator = rememberListDetailPaneScaffoldNavigator(
+            scaffoldNavigator = rememberListDetailPaneScaffoldNavigator<Int>(
                 scaffoldDirective = MockDualPaneScaffoldDirective,
                 isDestinationHistoryAware = false
             )
@@ -140,7 +140,7 @@
         var canNavigateBack by Delegates.notNull<Boolean>()
 
         composeRule.setContent {
-            scaffoldNavigator = rememberListDetailPaneScaffoldNavigator(
+            scaffoldNavigator = rememberListDetailPaneScaffoldNavigator<Int>(
                 scaffoldDirective = MockDualPaneScaffoldDirective,
                 isDestinationHistoryAware = true
             )
@@ -172,7 +172,7 @@
         var canNavigateBack by Delegates.notNull<Boolean>()
 
         composeRule.setContent {
-            scaffoldNavigator = rememberListDetailPaneScaffoldNavigator(
+            scaffoldNavigator = rememberListDetailPaneScaffoldNavigator<Int>(
                 scaffoldDirective = MockSinglePaneScaffoldDirective
             )
             canNavigateBack = scaffoldNavigator.canNavigateBack()
diff --git a/compose/material3/adaptive/adaptive-navigation/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation/SupportingPaneScaffoldNavigatorTest.kt b/compose/material3/adaptive/adaptive-navigation/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation/SupportingPaneScaffoldNavigatorTest.kt
index e73f542..bae3704 100644
--- a/compose/material3/adaptive/adaptive-navigation/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation/SupportingPaneScaffoldNavigatorTest.kt
+++ b/compose/material3/adaptive/adaptive-navigation/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation/SupportingPaneScaffoldNavigatorTest.kt
@@ -46,7 +46,7 @@
         var canNavigateBack by Delegates.notNull<Boolean>()
 
         composeRule.setContent {
-            scaffoldNavigator = rememberSupportingPaneScaffoldNavigator(
+            scaffoldNavigator = rememberSupportingPaneScaffoldNavigator<Int>(
                 scaffoldDirective = MockSinglePaneScaffoldDirective
             )
             canNavigateBack = scaffoldNavigator.canNavigateBack()
@@ -77,7 +77,7 @@
         var canNavigateBack by Delegates.notNull<Boolean>()
 
         composeRule.setContent {
-            scaffoldNavigator = rememberSupportingPaneScaffoldNavigator(
+            scaffoldNavigator = rememberSupportingPaneScaffoldNavigator<Int>(
                 scaffoldDirective = MockDualPaneScaffoldDirective
             )
             canNavigateBack = scaffoldNavigator.canNavigateBack()
@@ -186,7 +186,7 @@
         var canNavigateBack by Delegates.notNull<Boolean>()
 
         composeRule.setContent {
-            scaffoldNavigator = rememberSupportingPaneScaffoldNavigator(
+            scaffoldNavigator = rememberSupportingPaneScaffoldNavigator<Int>(
                 scaffoldDirective = MockSinglePaneScaffoldDirective
             )
             canNavigateBack = scaffoldNavigator.canNavigateBack()
diff --git a/compose/material3/adaptive/adaptive-navigation/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation/ThreePaneScaffoldNavigator.kt b/compose/material3/adaptive/adaptive-navigation/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation/ThreePaneScaffoldNavigator.kt
index 74742c8a..7d0d22a 100644
--- a/compose/material3/adaptive/adaptive-navigation/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation/ThreePaneScaffoldNavigator.kt
+++ b/compose/material3/adaptive/adaptive-navigation/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation/ThreePaneScaffoldNavigator.kt
@@ -178,6 +178,36 @@
 
 /**
  * Returns a remembered default implementation of [ThreePaneScaffoldNavigator] for
+ * [ListDetailPaneScaffold], which will be updated automatically when the input values change.
+ * The default navigator is supposed to be used independently from any navigation frameworks and
+ * handles the navigation purely inside the [ListDetailPaneScaffold].
+ *
+ * @param scaffoldDirective the current layout directives to follow. The default value will be
+ *   calculated with [calculatePaneScaffoldDirective] using
+ *   [WindowAdaptiveInfo][androidx.compose.material3.adaptive.WindowAdaptiveInfo] retrieved from
+ *   the current context.
+ * @param adaptStrategies adaptation strategies of each pane.
+ * @param isDestinationHistoryAware `true` if the scaffold value calculation should be aware of the
+ *   full destination history, instead of just the current destination. See
+ *   [calculateThreePaneScaffoldValue] for more relevant details.
+ */
+@ExperimentalMaterial3AdaptiveApi
+@Composable
+fun rememberListDetailPaneScaffoldNavigator(
+    scaffoldDirective: PaneScaffoldDirective =
+        calculatePaneScaffoldDirective(currentWindowAdaptiveInfo()),
+    adaptStrategies: ThreePaneScaffoldAdaptStrategies =
+        ListDetailPaneScaffoldDefaults.adaptStrategies(),
+    isDestinationHistoryAware: Boolean = true,
+): ThreePaneScaffoldNavigator<Nothing> =
+    rememberListDetailPaneScaffoldNavigator<Nothing>(
+        scaffoldDirective,
+        adaptStrategies,
+        isDestinationHistoryAware,
+    )
+
+/**
+ * Returns a remembered default implementation of [ThreePaneScaffoldNavigator] for
  * [SupportingPaneScaffold], which will be updated automatically when the input values change.
  * The default navigator is supposed to be used independently from any navigation frameworks and
  * handles the navigation purely inside the [SupportingPaneScaffold].
@@ -214,6 +244,36 @@
         initialDestinationHistory
     )
 
+/**
+ * Returns a remembered default implementation of [ThreePaneScaffoldNavigator] for
+ * [SupportingPaneScaffold], which will be updated automatically when the input values change.
+ * The default navigator is supposed to be used independently from any navigation frameworks and
+ * handles the navigation purely inside the [SupportingPaneScaffold].
+ *
+ * @param scaffoldDirective the current layout directives to follow. The default value will be
+ *   calculated with [calculatePaneScaffoldDirective] using
+ *   [WindowAdaptiveInfo][androidx.compose.material3.adaptive.WindowAdaptiveInfo] retrieved from
+ *   the current context.
+ * @param adaptStrategies adaptation strategies of each pane.
+ * @param isDestinationHistoryAware `true` if the scaffold value calculation should be aware of the
+ *   full destination history, instead of just the current destination. See
+ *   [calculateThreePaneScaffoldValue] for more relevant details.
+ */
+@ExperimentalMaterial3AdaptiveApi
+@Composable
+fun rememberSupportingPaneScaffoldNavigator(
+    scaffoldDirective: PaneScaffoldDirective =
+        calculatePaneScaffoldDirective(currentWindowAdaptiveInfo()),
+    adaptStrategies: ThreePaneScaffoldAdaptStrategies =
+        SupportingPaneScaffoldDefaults.adaptStrategies(),
+    isDestinationHistoryAware: Boolean = true,
+): ThreePaneScaffoldNavigator<Nothing> =
+    rememberSupportingPaneScaffoldNavigator<Nothing>(
+        scaffoldDirective,
+        adaptStrategies,
+        isDestinationHistoryAware,
+    )
+
 @ExperimentalMaterial3AdaptiveApi
 @Composable
 internal fun <T> rememberThreePaneScaffoldNavigator(
diff --git a/compose/material3/adaptive/samples/src/main/java/androidx/compose/material3/adaptive/samples/ThreePaneScaffoldSample.kt b/compose/material3/adaptive/samples/src/main/java/androidx/compose/material3/adaptive/samples/ThreePaneScaffoldSample.kt
index fa976d5..9db35f3 100644
--- a/compose/material3/adaptive/samples/src/main/java/androidx/compose/material3/adaptive/samples/ThreePaneScaffoldSample.kt
+++ b/compose/material3/adaptive/samples/src/main/java/androidx/compose/material3/adaptive/samples/ThreePaneScaffoldSample.kt
@@ -71,7 +71,7 @@
 @Sampled
 @Composable
 fun ListDetailPaneScaffoldSample() {
-    val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator<Nothing>()
+    val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator()
     ListDetailPaneScaffold(
         directive = scaffoldNavigator.scaffoldDirective,
         value = scaffoldNavigator.scaffoldValue,
@@ -109,7 +109,7 @@
 @Sampled
 @Composable
 fun ListDetailPaneScaffoldSampleWithExtraPane() {
-    val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator<Nothing>()
+    val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator()
     ListDetailPaneScaffold(
         directive = scaffoldNavigator.scaffoldDirective,
         value = scaffoldNavigator.scaffoldValue,
diff --git a/compose/material3/material3-common/api/current.txt b/compose/material3/material3-common/api/current.txt
index cf8d9ee..6ca7d3f 100644
--- a/compose/material3/material3-common/api/current.txt
+++ b/compose/material3/material3-common/api/current.txt
@@ -12,11 +12,9 @@
   }
 
   public final class InteractiveComponentSizeKt {
-    method @SuppressCompatibility @androidx.compose.material3.common.ExperimentalMaterial3CommonApi public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumInteractiveComponentEnforcement();
-    method @Deprecated @SuppressCompatibility @androidx.compose.material3.common.ExperimentalMaterial3CommonApi public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumTouchTargetEnforcement();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> getLocalMinimumInteractiveComponentSize();
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier minimumInteractiveComponentSize(androidx.compose.ui.Modifier);
-    property @SuppressCompatibility @androidx.compose.material3.common.ExperimentalMaterial3CommonApi public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumInteractiveComponentEnforcement;
-    property @Deprecated @SuppressCompatibility @androidx.compose.material3.common.ExperimentalMaterial3CommonApi public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumTouchTargetEnforcement;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> LocalMinimumInteractiveComponentSize;
   }
 
 }
diff --git a/compose/material3/material3-common/api/restricted_current.txt b/compose/material3/material3-common/api/restricted_current.txt
index cf8d9ee..6ca7d3f 100644
--- a/compose/material3/material3-common/api/restricted_current.txt
+++ b/compose/material3/material3-common/api/restricted_current.txt
@@ -12,11 +12,9 @@
   }
 
   public final class InteractiveComponentSizeKt {
-    method @SuppressCompatibility @androidx.compose.material3.common.ExperimentalMaterial3CommonApi public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumInteractiveComponentEnforcement();
-    method @Deprecated @SuppressCompatibility @androidx.compose.material3.common.ExperimentalMaterial3CommonApi public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumTouchTargetEnforcement();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> getLocalMinimumInteractiveComponentSize();
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier minimumInteractiveComponentSize(androidx.compose.ui.Modifier);
-    property @SuppressCompatibility @androidx.compose.material3.common.ExperimentalMaterial3CommonApi public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumInteractiveComponentEnforcement;
-    property @Deprecated @SuppressCompatibility @androidx.compose.material3.common.ExperimentalMaterial3CommonApi public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumTouchTargetEnforcement;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> LocalMinimumInteractiveComponentSize;
   }
 
 }
diff --git a/compose/material3/material3-common/src/commonMain/kotlin/androidx/compose/material3/common/InteractiveComponentSize.kt b/compose/material3/material3-common/src/commonMain/kotlin/androidx/compose/material3/common/InteractiveComponentSize.kt
index 6cb3de9..363de05 100644
--- a/compose/material3/material3-common/src/commonMain/kotlin/androidx/compose/material3/common/InteractiveComponentSize.kt
+++ b/compose/material3/material3-common/src/commonMain/kotlin/androidx/compose/material3/common/InteractiveComponentSize.kt
@@ -20,7 +20,6 @@
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.staticCompositionLocalOf
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.layout.LayoutModifier
 import androidx.compose.ui.layout.Measurable
 import androidx.compose.ui.layout.MeasureResult
 import androidx.compose.ui.layout.MeasureScope
@@ -30,8 +29,10 @@
 import androidx.compose.ui.node.currentValueOf
 import androidx.compose.ui.platform.InspectorInfo
 import androidx.compose.ui.unit.Constraints
-import androidx.compose.ui.unit.DpSize
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.coerceAtLeast
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.isSpecified
 import kotlin.math.roundToInt
 
 /**
@@ -74,24 +75,23 @@
     Modifier.Node(),
     CompositionLocalConsumerModifierNode,
     LayoutModifierNode {
-
-    @OptIn(ExperimentalMaterial3CommonApi::class)
     override fun MeasureScope.measure(
         measurable: Measurable,
         constraints: Constraints
     ): MeasureResult {
-        val size = minimumInteractiveComponentSize
+        val size = currentValueOf(LocalMinimumInteractiveComponentSize).coerceAtLeast(0.dp)
         val placeable = measurable.measure(constraints)
-        val enforcement = isAttached && currentValueOf(LocalMinimumInteractiveComponentEnforcement)
+        val enforcement = isAttached && (size.isSpecified && size > 0.dp)
 
+        val sizePx = if (size.isSpecified) size.roundToPx() else 0
         // Be at least as big as the minimum dimension in both dimensions
         val width = if (enforcement) {
-            maxOf(placeable.width, size.width.roundToPx())
+            maxOf(placeable.width, sizePx)
         } else {
             placeable.width
         }
         val height = if (enforcement) {
-            maxOf(placeable.height, size.height.roundToPx())
+            maxOf(placeable.height, sizePx)
         } else {
             placeable.height
         }
@@ -105,67 +105,12 @@
 }
 
 /**
- * CompositionLocal that configures whether Material components that have a visual size that is
- * lower than the minimum touch target size for accessibility (such as Button) will include
- * extra space outside the component to ensure that they are accessible. If set to false there
- * will be no extra space, and so it is possible that if the component is placed near the edge of
- * a layout / near to another component without any padding, there will not be enough space for
- * an accessible touch target.
+ * CompositionLocal that configures the minimum touch target size for Material components
+ * (such as [Button]) to ensure they are accessible. If a component has a visual size
+ * that is lower than the minimum touch target size, extra space outside the component will be
+ * included. If set to [Dp.Unspecified] there will be no extra space, and so it is possible that if the
+ * component is placed near the edge of a layout / near to another component without any padding,
+ * there will not be enough space for an accessible touch target.
  */
-@Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
-@get:ExperimentalMaterial3CommonApi
-@ExperimentalMaterial3CommonApi
-val LocalMinimumInteractiveComponentEnforcement: ProvidableCompositionLocal<Boolean> =
-    staticCompositionLocalOf { true }
-
-/**
- * CompositionLocal that configures whether Material components that have a visual size that is
- * lower than the minimum touch target size for accessibility (such as [Button]) will include
- * extra space outside the component to ensure that they are accessible. If set to false there
- * will be no extra space, and so it is possible that if the component is placed near the edge of
- * a layout / near to another component without any padding, there will not be enough space for
- * an accessible touch target.
- */
-@Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
-@get:ExperimentalMaterial3CommonApi
-@ExperimentalMaterial3CommonApi
-@Deprecated(
-    message = "Use LocalMinimumInteractiveComponentEnforcement instead.",
-    replaceWith = ReplaceWith(
-        "LocalMinimumInteractiveComponentEnforcement"
-    ),
-    level = DeprecationLevel.WARNING
-)
-val LocalMinimumTouchTargetEnforcement: ProvidableCompositionLocal<Boolean> =
-    LocalMinimumInteractiveComponentEnforcement
-
-private class MinimumInteractiveComponentSizeModifier(val size: DpSize) : LayoutModifier {
-    override fun MeasureScope.measure(
-        measurable: Measurable,
-        constraints: Constraints
-    ): MeasureResult {
-
-        val placeable = measurable.measure(constraints)
-
-        // Be at least as big as the minimum dimension in both dimensions
-        val width = maxOf(placeable.width, size.width.roundToPx())
-        val height = maxOf(placeable.height, size.height.roundToPx())
-
-        return layout(width, height) {
-            val centerX = ((width - placeable.width) / 2f).roundToInt()
-            val centerY = ((height - placeable.height) / 2f).roundToInt()
-            placeable.place(centerX, centerY)
-        }
-    }
-
-    override fun equals(other: Any?): Boolean {
-        val otherModifier = other as? MinimumInteractiveComponentSizeModifier ?: return false
-        return size == otherModifier.size
-    }
-
-    override fun hashCode(): Int {
-        return size.hashCode()
-    }
-}
-
-private val minimumInteractiveComponentSize: DpSize = DpSize(48.dp, 48.dp)
+val LocalMinimumInteractiveComponentSize: ProvidableCompositionLocal<Dp> =
+    staticCompositionLocalOf { 48.dp }
diff --git a/compose/material3/material3/api/current.txt b/compose/material3/material3/api/current.txt
index 7e09505e..4ffad8d 100644
--- a/compose/material3/material3/api/current.txt
+++ b/compose/material3/material3/api/current.txt
@@ -622,17 +622,6 @@
     property public abstract kotlin.ranges.IntRange yearRange;
   }
 
-  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissDirection {
-    enum_constant @Deprecated public static final androidx.compose.material3.DismissDirection EndToStart;
-    enum_constant @Deprecated public static final androidx.compose.material3.DismissDirection StartToEnd;
-  }
-
-  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissValue {
-    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue Default;
-    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue DismissedToEnd;
-    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue DismissedToStart;
-  }
-
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class DisplayMode {
     field public static final androidx.compose.material3.DisplayMode.Companion Companion;
   }
@@ -892,11 +881,11 @@
   }
 
   public final class InteractiveComponentSizeKt {
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumInteractiveComponentEnforcement();
-    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumTouchTargetEnforcement();
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumInteractiveComponentEnforcement();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> getLocalMinimumInteractiveComponentSize();
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier minimumInteractiveComponentSize(androidx.compose.ui.Modifier);
-    property @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumInteractiveComponentEnforcement;
-    property @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumTouchTargetEnforcement;
+    property @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumInteractiveComponentEnforcement;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> LocalMinimumInteractiveComponentSize;
   }
 
   public final class LabelKt {
@@ -1281,6 +1270,7 @@
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SearchBarColors {
+    ctor public SearchBarColors(long containerColor, long dividerColor, androidx.compose.material3.TextFieldColors inputFieldColors);
     method public long getContainerColor();
     method public long getDividerColor();
     method public androidx.compose.material3.TextFieldColors getInputFieldColors();
@@ -1623,7 +1613,6 @@
   }
 
   public final class SwipeToDismissBoxKt {
-    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.SwipeToDismissBoxState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set<? extends androidx.compose.material3.SwipeToDismissBoxValue> directions);
     method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismissBox(androidx.compose.material3.SwipeToDismissBoxState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> backgroundContent, optional androidx.compose.ui.Modifier modifier, optional boolean enableDismissFromStartToEnd, optional boolean enableDismissFromEndToStart, optional boolean gesturesEnabled, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
     method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SwipeToDismissBoxState rememberSwipeToDismissBoxState(optional androidx.compose.material3.SwipeToDismissBoxValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SwipeToDismissBoxValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
   }
@@ -1635,7 +1624,6 @@
     method public androidx.compose.material3.SwipeToDismissBoxValue getDismissDirection();
     method @FloatRange(from=0.0, to=1.0) public float getProgress();
     method public androidx.compose.material3.SwipeToDismissBoxValue getTargetValue();
-    method @Deprecated public boolean isDismissed(androidx.compose.material3.DismissDirection direction);
     method public float requireOffset();
     method public suspend Object? reset(kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public suspend Object? snapTo(androidx.compose.material3.SwipeToDismissBoxValue targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
diff --git a/compose/material3/material3/api/restricted_current.txt b/compose/material3/material3/api/restricted_current.txt
index 7e09505e..4ffad8d 100644
--- a/compose/material3/material3/api/restricted_current.txt
+++ b/compose/material3/material3/api/restricted_current.txt
@@ -622,17 +622,6 @@
     property public abstract kotlin.ranges.IntRange yearRange;
   }
 
-  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissDirection {
-    enum_constant @Deprecated public static final androidx.compose.material3.DismissDirection EndToStart;
-    enum_constant @Deprecated public static final androidx.compose.material3.DismissDirection StartToEnd;
-  }
-
-  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissValue {
-    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue Default;
-    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue DismissedToEnd;
-    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue DismissedToStart;
-  }
-
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class DisplayMode {
     field public static final androidx.compose.material3.DisplayMode.Companion Companion;
   }
@@ -892,11 +881,11 @@
   }
 
   public final class InteractiveComponentSizeKt {
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumInteractiveComponentEnforcement();
-    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumTouchTargetEnforcement();
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumInteractiveComponentEnforcement();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> getLocalMinimumInteractiveComponentSize();
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier minimumInteractiveComponentSize(androidx.compose.ui.Modifier);
-    property @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumInteractiveComponentEnforcement;
-    property @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumTouchTargetEnforcement;
+    property @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumInteractiveComponentEnforcement;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> LocalMinimumInteractiveComponentSize;
   }
 
   public final class LabelKt {
@@ -1281,6 +1270,7 @@
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SearchBarColors {
+    ctor public SearchBarColors(long containerColor, long dividerColor, androidx.compose.material3.TextFieldColors inputFieldColors);
     method public long getContainerColor();
     method public long getDividerColor();
     method public androidx.compose.material3.TextFieldColors getInputFieldColors();
@@ -1623,7 +1613,6 @@
   }
 
   public final class SwipeToDismissBoxKt {
-    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.SwipeToDismissBoxState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set<? extends androidx.compose.material3.SwipeToDismissBoxValue> directions);
     method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismissBox(androidx.compose.material3.SwipeToDismissBoxState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> backgroundContent, optional androidx.compose.ui.Modifier modifier, optional boolean enableDismissFromStartToEnd, optional boolean enableDismissFromEndToStart, optional boolean gesturesEnabled, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
     method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SwipeToDismissBoxState rememberSwipeToDismissBoxState(optional androidx.compose.material3.SwipeToDismissBoxValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SwipeToDismissBoxValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
   }
@@ -1635,7 +1624,6 @@
     method public androidx.compose.material3.SwipeToDismissBoxValue getDismissDirection();
     method @FloatRange(from=0.0, to=1.0) public float getProgress();
     method public androidx.compose.material3.SwipeToDismissBoxValue getTargetValue();
-    method @Deprecated public boolean isDismissed(androidx.compose.material3.DismissDirection direction);
     method public float requireOffset();
     method public suspend Object? reset(kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public suspend Object? snapTo(androidx.compose.material3.SwipeToDismissBoxValue targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/SearchBarSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/SearchBarSamples.kt
index ebd1a75..da7d53d 100644
--- a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/SearchBarSamples.kt
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/SearchBarSamples.kt
@@ -33,6 +33,7 @@
 import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.Icon
 import androidx.compose.material3.ListItem
+import androidx.compose.material3.ListItemDefaults
 import androidx.compose.material3.SearchBar
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
@@ -42,6 +43,7 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.semantics.isTraversalGroup
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.semantics.traversalIndex
@@ -56,7 +58,11 @@
     var text by rememberSaveable { mutableStateOf("") }
     var active by rememberSaveable { mutableStateOf(false) }
 
-    Box(Modifier.fillMaxSize().semantics { isTraversalGroup = true }) {
+    Box(
+        Modifier
+            .fillMaxSize()
+            .semantics { isTraversalGroup = true }
+    ) {
         SearchBar(
             modifier = Modifier
                 .align(Alignment.TopCenter)
@@ -78,6 +84,7 @@
                     headlineContent = { Text(resultText) },
                     supportingContent = { Text("Additional info") },
                     leadingContent = { Icon(Icons.Filled.Star, contentDescription = null) },
+                    colors = ListItemDefaults.colors(containerColor = Color.Transparent),
                     modifier = Modifier
                         .clickable {
                             text = resultText
@@ -95,7 +102,12 @@
         ) {
             val list = List(100) { "Text $it" }
             items(count = list.size) {
-                Text(list[it], Modifier.fillMaxWidth().padding(horizontal = 16.dp))
+                Text(
+                    text = list[it],
+                    modifier = Modifier
+                        .fillMaxWidth()
+                        .padding(horizontal = 16.dp),
+                )
             }
         }
     }
@@ -109,7 +121,11 @@
     var text by rememberSaveable { mutableStateOf("") }
     var active by rememberSaveable { mutableStateOf(false) }
 
-    Box(Modifier.fillMaxSize().semantics { isTraversalGroup = true }) {
+    Box(
+        Modifier
+            .fillMaxSize()
+            .semantics { isTraversalGroup = true }
+    ) {
         DockedSearchBar(
             modifier = Modifier
                 .align(Alignment.TopCenter)
@@ -130,6 +146,7 @@
                     headlineContent = { Text(resultText) },
                     supportingContent = { Text("Additional info") },
                     leadingContent = { Icon(Icons.Filled.Star, contentDescription = null) },
+                    colors = ListItemDefaults.colors(containerColor = Color.Transparent),
                     modifier = Modifier
                         .clickable {
                             text = resultText
@@ -147,7 +164,12 @@
         ) {
             val list = List(100) { "Text $it" }
             items(count = list.size) {
-                Text(list[it], Modifier.fillMaxWidth().padding(horizontal = 16.dp))
+                Text(
+                    text = list[it],
+                    modifier = Modifier
+                        .fillMaxWidth()
+                        .padding(horizontal = 16.dp),
+                )
             }
         }
     }
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/CheckboxTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/CheckboxTest.kt
index ed984d5..5c6a6bf 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/CheckboxTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/CheckboxTest.kt
@@ -54,6 +54,7 @@
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performClick
 import androidx.compose.ui.test.performTouchInput
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
@@ -124,12 +125,17 @@
 
         rule.setMaterialContent(lightColorScheme()) {
             val (checked, _) = remember { mutableStateOf(false) }
-            Box(Modifier.semantics(mergeDescendants = true) {}.testTag(parentTag)) {
+            Box(
+                Modifier
+                    .semantics(mergeDescendants = true) {}
+                    .testTag(parentTag)) {
                 Checkbox(
                     checked,
                     {},
                     enabled = false,
-                    modifier = Modifier.testTag(defaultTag).semantics { focused = true }
+                    modifier = Modifier
+                        .testTag(defaultTag)
+                        .semantics { focused = true }
                 )
             }
         }
@@ -146,7 +152,10 @@
     fun checkBoxTest_untoggleableAndMergeable_whenNullLambda() {
         rule.setMaterialContent(lightColorScheme()) {
             val (checked, _) = remember { mutableStateOf(false) }
-            Box(Modifier.semantics(mergeDescendants = true) {}.testTag(defaultTag)) {
+            Box(
+                Modifier
+                    .semantics(mergeDescendants = true) {}
+                    .testTag(defaultTag)) {
                 Checkbox(
                     checked,
                     null,
@@ -277,7 +286,8 @@
         rule
             .setMaterialContentForSizeAssertions {
                 CompositionLocalProvider(
-                    LocalMinimumInteractiveComponentEnforcement provides minimumTouchTarget
+                    LocalMinimumInteractiveComponentSize provides
+                        if (minimumTouchTarget) 48.dp else Dp.Unspecified
                 ) {
                     TriStateCheckbox(
                         state = checkboxValue,
@@ -307,7 +317,10 @@
                 TriStateCheckbox(
                     state = state,
                     onClick = { state = On },
-                    modifier = Modifier.align(Alignment.Center).requiredSize(2.dp).testTag(tag)
+                    modifier = Modifier
+                        .align(Alignment.Center)
+                        .requiredSize(2.dp)
+                        .testTag(tag)
                 )
             }
         }
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/FloatingActionButtonTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/FloatingActionButtonTest.kt
index 925e620..53fe513 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/FloatingActionButtonTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/FloatingActionButtonTest.kt
@@ -137,7 +137,7 @@
         rule
             .setMaterialContentForSizeAssertions {
                 CompositionLocalProvider(
-                    LocalMinimumInteractiveComponentEnforcement provides false
+                    LocalMinimumInteractiveComponentSize provides Dp.Unspecified
                 ) {
                     SmallFloatingActionButton(onClick = {}) {
                         Icon(
@@ -162,12 +162,8 @@
     fun smallFabHasMinTouchTarget() {
         rule
             .setMaterialContentForSizeAssertions {
-                CompositionLocalProvider(
-                    LocalMinimumInteractiveComponentEnforcement provides true
-                ) {
-                    SmallFloatingActionButton(onClick = {}) {
-                        Icon(Icons.Filled.Favorite, null)
-                    }
+                SmallFloatingActionButton(onClick = {}) {
+                    Icon(Icons.Filled.Favorite, null)
                 }
             }
             // Expecting the size to be equal to the minimum touch target.
@@ -308,14 +304,18 @@
         rule.setMaterialContent(lightColorScheme()) {
             Column {
                 Spacer(
-                    Modifier.requiredSize(10.dp).weight(1f).onGloballyPositioned {
-                        item1Bounds = it.boundsInRoot()
-                    }
+                    Modifier
+                        .requiredSize(10.dp)
+                        .weight(1f)
+                        .onGloballyPositioned {
+                            item1Bounds = it.boundsInRoot()
+                        }
                 )
 
                 FloatingActionButton(
                     onClick = {},
-                    modifier = Modifier.weight(1f)
+                    modifier = Modifier
+                        .weight(1f)
                         .onGloballyPositioned {
                             buttonBounds = it.boundsInRoot()
                         }
@@ -323,7 +323,10 @@
                     Text("Button")
                 }
 
-                Spacer(Modifier.requiredSize(10.dp).weight(1f))
+                Spacer(
+                    Modifier
+                        .requiredSize(10.dp)
+                        .weight(1f))
             }
         }
 
@@ -344,7 +347,8 @@
                     }
                 ) {
                     Box(
-                        Modifier.size(2.dp)
+                        Modifier
+                            .size(2.dp)
                             .onGloballyPositioned { contentCoordinates = it }
                     )
                 }
@@ -375,7 +379,8 @@
                     modifier = Modifier.onGloballyPositioned { buttonCoordinates = it },
                 ) {
                     Box(
-                        Modifier.size(2.dp)
+                        Modifier
+                            .size(2.dp)
                             .onGloballyPositioned { contentCoordinates = it }
                     )
                 }
@@ -405,13 +410,15 @@
                 ExtendedFloatingActionButton(
                     text = {
                         Box(
-                            Modifier.size(2.dp)
+                            Modifier
+                                .size(2.dp)
                                 .onGloballyPositioned { textCoordinates = it }
                         )
                     },
                     icon = {
                         Box(
-                            Modifier.size(10.dp)
+                            Modifier
+                                .size(10.dp)
                                 .onGloballyPositioned { iconCoordinates = it }
                         )
                     },
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/IconButtonTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/IconButtonTest.kt
index f93a36c..66e5938 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/IconButtonTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/IconButtonTest.kt
@@ -54,6 +54,7 @@
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performClick
 import androidx.compose.ui.test.performTouchInput
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
@@ -91,7 +92,7 @@
         rule
             .setMaterialContentForSizeAssertions {
                 CompositionLocalProvider(
-                    LocalMinimumInteractiveComponentEnforcement provides false
+                    LocalMinimumInteractiveComponentSize provides Dp.Unspecified
                 ) {
                     IconButton(onClick = { /* doSomething() */ }) {
                         Icon(Icons.Filled.Favorite, contentDescription = "Localized description")
@@ -105,6 +106,27 @@
     }
 
     @Test
+    fun iconButton_sizeWithCustomMinInteractiveComponentSize() {
+        val customTouchTargetSize = 44.dp
+        rule
+            .setMaterialContentForSizeAssertions {
+                CompositionLocalProvider(
+                    LocalMinimumInteractiveComponentSize provides customTouchTargetSize
+                ) {
+                    IconButton(onClick = { /* doSomething() */ }) {
+                        Icon(
+                            Icons.Outlined.FavoriteBorder,
+                            contentDescription = "Localized description"
+                        )
+                    }
+                }
+            }
+            .assertWidthIsEqualTo(customTouchTargetSize)
+            .assertHeightIsEqualTo(customTouchTargetSize)
+            .assertTouchWidthIsEqualTo(customTouchTargetSize)
+            .assertTouchHeightIsEqualTo(customTouchTargetSize)
+    }
+    @Test
     fun iconButton_defaultSemantics() {
         rule.setMaterialContent(lightColorScheme()) {
             IconButton(onClick = { /* doSomething() */ }) {
@@ -236,7 +258,7 @@
         rule
             .setMaterialContentForSizeAssertions {
                 CompositionLocalProvider(
-                    LocalMinimumInteractiveComponentEnforcement provides false
+                    LocalMinimumInteractiveComponentSize provides Dp.Unspecified
                 ) {
                     IconToggleButton(checked = true, onCheckedChange = { /* doSomething() */ }) {
                         Icon(Icons.Filled.Favorite, contentDescription = "Localized description")
@@ -367,7 +389,7 @@
         rule
             .setMaterialContentForSizeAssertions {
                 CompositionLocalProvider(
-                    LocalMinimumInteractiveComponentEnforcement provides false
+                    LocalMinimumInteractiveComponentSize provides Dp.Unspecified
                 ) {
                     FilledIconButton(onClick = { /* doSomething() */ }) {
                         Icon(Icons.Filled.Favorite, contentDescription = "Localized description")
@@ -489,7 +511,7 @@
         rule
             .setMaterialContentForSizeAssertions {
                 CompositionLocalProvider(
-                    LocalMinimumInteractiveComponentEnforcement provides false
+                    LocalMinimumInteractiveComponentSize provides Dp.Unspecified
                 ) {
                     FilledIconToggleButton(
                         checked = true,
@@ -595,7 +617,7 @@
         rule
             .setMaterialContentForSizeAssertions {
                 CompositionLocalProvider(
-                    LocalMinimumInteractiveComponentEnforcement provides false
+                    LocalMinimumInteractiveComponentSize provides Dp.Unspecified
                 ) {
                     OutlinedIconButton(onClick = { /* doSomething() */ }) {
                         Icon(
@@ -699,7 +721,7 @@
         rule
             .setMaterialContentForSizeAssertions {
                 CompositionLocalProvider(
-                    LocalMinimumInteractiveComponentEnforcement provides false
+                    LocalMinimumInteractiveComponentSize provides Dp.Unspecified
                 ) {
                     OutlinedIconToggleButton(
                         checked = true,
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/RadioButtonTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/RadioButtonTest.kt
index 04e3bfb..1b8b1bf 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/RadioButtonTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/RadioButtonTest.kt
@@ -35,6 +35,7 @@
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performClick
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
@@ -285,7 +286,8 @@
         rule
             .setMaterialContentForSizeAssertions {
                 CompositionLocalProvider(
-                    LocalMinimumInteractiveComponentEnforcement provides minimumTouchTarget
+                    LocalMinimumInteractiveComponentSize provides
+                        if (minimumTouchTarget) 48.dp else Dp.Unspecified
                 ) {
                     RadioButton(
                         selected = selected, onClick = if (clickable) {
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SearchBarScreenshotTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SearchBarScreenshotTest.kt
index 240aa9a..3c5554b 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SearchBarScreenshotTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SearchBarScreenshotTest.kt
@@ -407,17 +407,21 @@
             )
         }
 
-        SearchBarInternal(
+        SearchBarImpl(
             animationProgress = animationProgress,
             finalBackProgress = finalBackProgress,
             firstBackEvent = firstBackEvent,
             currentBackEvent = currentBackEvent,
             modifier = Modifier.testTag(testTag),
-            query = "Query",
-            onQueryChange = {},
-            onSearch = {},
-            active = true,
-            onActiveChange = {},
+            inputField = {
+                SearchBarInputField(
+                    query = "Query",
+                    onQueryChange = {},
+                    onSearch = {},
+                    active = true,
+                    onActiveChange = {},
+                )
+            },
             content = { Text("Content") },
         )
     }
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SwitchTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SwitchTest.kt
index d67ee61..d3d74bd 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SwitchTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SwitchTest.kt
@@ -60,6 +60,7 @@
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performClick
 import androidx.compose.ui.test.performTouchInput
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
@@ -380,7 +381,8 @@
     ) = with(rule.density) {
         rule.setMaterialContentForSizeAssertions {
             CompositionLocalProvider(
-                LocalMinimumInteractiveComponentEnforcement provides minimumTouchTarget
+                LocalMinimumInteractiveComponentSize provides
+                    if (minimumTouchTarget) 48.dp else Dp.Unspecified
             ) {
                 Switch(
                     checked = checked,
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/SearchBar.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/SearchBar.android.kt
index 51db309..6d540f6 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/SearchBar.android.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/SearchBar.android.kt
@@ -38,17 +38,14 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.ColumnScope
-import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.WindowInsets
-import androidx.compose.foundation.layout.asPaddingValues
 import androidx.compose.foundation.layout.consumeWindowInsets
 import androidx.compose.foundation.layout.exclude
 import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.heightIn
 import androidx.compose.foundation.layout.offset
 import androidx.compose.foundation.layout.onConsumedWindowInsetsChanged
-import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.sizeIn
 import androidx.compose.foundation.layout.statusBars
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.shape.GenericShape
@@ -69,8 +66,6 @@
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.MutableFloatState
 import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.Stable
-import androidx.compose.runtime.State
 import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableFloatStateOf
@@ -89,7 +84,8 @@
 import androidx.compose.ui.graphics.SolidColor
 import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.graphics.takeOrElse
-import androidx.compose.ui.layout.layout
+import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.layout.layoutId
 import androidx.compose.ui.platform.LocalConfiguration
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.LocalFocusManager
@@ -104,9 +100,11 @@
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.unit.constrainHeight
+import androidx.compose.ui.unit.constrainWidth
 import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.lerp
-import androidx.compose.ui.unit.offset
+import androidx.compose.ui.util.fastFirst
+import androidx.compose.ui.util.fastFirstOrNull
 import androidx.compose.ui.util.lerp
 import androidx.compose.ui.zIndex
 import kotlin.coroutines.cancellation.CancellationException
@@ -239,179 +237,20 @@
         }
     }
 
-    SearchBarInternal(
+    SearchBarImpl(
         animationProgress = animationProgress,
         finalBackProgress = finalBackProgress,
         firstBackEvent = firstBackEvent,
         currentBackEvent = currentBackEvent,
-        query = query,
-        onQueryChange = onQueryChange,
-        onSearch = onSearch,
-        active = active,
-        onActiveChange = onActiveChange,
         modifier = modifier,
-        enabled = enabled,
-        placeholder = placeholder,
-        leadingIcon = leadingIcon,
-        trailingIcon = trailingIcon,
-        shape = shape,
-        colors = colors,
-        tonalElevation = tonalElevation,
-        shadowElevation = shadowElevation,
-        windowInsets = windowInsets,
-        interactionSource = interactionSource,
-        content = content,
-    )
-}
-
-@ExperimentalMaterial3Api
-@Composable
-internal fun SearchBarInternal(
-    animationProgress: Animatable<Float, AnimationVector1D>,
-    finalBackProgress: MutableFloatState,
-    firstBackEvent: MutableState<BackEventCompat?>,
-    currentBackEvent: MutableState<BackEventCompat?>,
-    query: String,
-    onQueryChange: (String) -> Unit,
-    onSearch: (String) -> Unit,
-    active: Boolean,
-    onActiveChange: (Boolean) -> Unit,
-    modifier: Modifier = Modifier,
-    enabled: Boolean = true,
-    placeholder: @Composable (() -> Unit)? = null,
-    leadingIcon: @Composable (() -> Unit)? = null,
-    trailingIcon: @Composable (() -> Unit)? = null,
-    shape: Shape = SearchBarDefaults.inputFieldShape,
-    colors: SearchBarColors = SearchBarDefaults.colors(),
-    tonalElevation: Dp = SearchBarDefaults.TonalElevation,
-    shadowElevation: Dp = SearchBarDefaults.ShadowElevation,
-    windowInsets: WindowInsets = SearchBarDefaults.windowInsets,
-    interactionSource: MutableInteractionSource? = null,
-    content: @Composable ColumnScope.() -> Unit,
-) {
-    @Suppress("NAME_SHADOWING")
-    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
-    val focusManager = LocalFocusManager.current
-    val density = LocalDensity.current
-
-    val defaultInputFieldShape = SearchBarDefaults.inputFieldShape
-    val defaultFullScreenShape = SearchBarDefaults.fullScreenShape
-    val useFullScreenShape by remember {
-        derivedStateOf(structuralEqualityPolicy()) { animationProgress.value == 1f }
-    }
-    val animatedShape = remember(useFullScreenShape, shape) {
-        when {
-            shape == defaultInputFieldShape ->
-                // The shape can only be animated if it's the default spec value
-                GenericShape { size, _ ->
-                    val radius = with(density) {
-                        (SearchBarCornerRadius * (1 - animationProgress.value)).toPx()
-                    }
-                    addRoundRect(RoundRect(size.toRect(), CornerRadius(radius)))
-                }
-            useFullScreenShape -> defaultFullScreenShape
-            else -> shape
-        }
-    }
-
-    // The main animation complexity is allowing the component to smoothly expand while keeping the
-    // input field at the same relative location on screen. `Modifier.windowInsetsPadding` does not
-    // support animation and thus is not suitable. Instead, we convert the insets to a padding
-    // applied to the Surface, which gradually becomes padding applied to the input field as the
-    // animation proceeds.
-    val unconsumedInsets = remember { MutableWindowInsets() }
-    val topPadding = remember(density) {
-        derivedStateOf {
-            SearchBarVerticalPadding +
-                unconsumedInsets.asPaddingValues(density).calculateTopPadding()
-        }
-    }
-
-    Surface(
-        shape = animatedShape,
-        color = colors.containerColor,
-        contentColor = contentColorFor(colors.containerColor),
-        tonalElevation = tonalElevation,
-        shadowElevation = shadowElevation,
-        modifier = modifier
-            .zIndex(1f)
-            .onConsumedWindowInsetsChanged { consumedInsets ->
-                unconsumedInsets.insets = windowInsets.exclude(consumedInsets)
-            }
-            .consumeWindowInsets(unconsumedInsets)
-            .layout { measurable, constraints ->
-                val animatedTopPadding =
-                    lerp(topPadding.value, 0.dp, animationProgress.value).roundToPx()
-
-                val defaultStartWidth = max(constraints.minWidth, SearchBarMinWidth.roundToPx())
-                    .coerceAtMost(min(constraints.maxWidth, SearchBarMaxWidth.roundToPx()))
-                val defaultStartHeight = max(constraints.minHeight, InputFieldHeight.roundToPx())
-                    .coerceAtMost(constraints.maxHeight)
-                val predictiveBackStartWidth =
-                    (constraints.maxWidth * SearchBarPredictiveBackMinScale).roundToInt()
-                val predictiveBackStartHeight =
-                    (constraints.maxHeight * SearchBarPredictiveBackMinScale).roundToInt()
-                val predictiveBackMultiplier = calculatePredictiveBackMultiplier(
-                    currentBackEvent.value,
-                    animationProgress.value,
-                    finalBackProgress.floatValue
-                )
-                val startWidth =
-                    lerp(defaultStartWidth, predictiveBackStartWidth, predictiveBackMultiplier)
-                val startHeight =
-                    lerp(defaultStartHeight, predictiveBackStartHeight, predictiveBackMultiplier)
-
-                val endWidth = constraints.maxWidth
-                val endHeight = constraints.maxHeight
-
-                val width = lerp(startWidth, endWidth, animationProgress.value)
-                val height =
-                    lerp(startHeight, endHeight, animationProgress.value) + animatedTopPadding
-
-                val minOffsetMargin = SearchBarPredictiveBackMinMargin.roundToPx()
-                val predictiveBackOffsetX = calculatePredictiveBackOffsetX(
-                    constraints,
-                    minOffsetMargin,
-                    currentBackEvent.value,
-                    animationProgress.value,
-                    predictiveBackMultiplier
-                )
-                val predictiveBackOffsetY = calculatePredictiveBackOffsetY(
-                    constraints,
-                    minOffsetMargin,
-                    currentBackEvent.value,
-                    firstBackEvent.value,
-                    height,
-                    SearchBarPredictiveBackMaxOffsetY.roundToPx(),
-                    predictiveBackMultiplier
-                )
-
-                val placeable = measurable.measure(
-                    Constraints
-                        .fixed(width, height)
-                        .offset(
-                            vertical = -animatedTopPadding
-                        )
-                )
-                layout(width, height) {
-                    placeable.placeRelative(
-                        predictiveBackOffsetX,
-                        animatedTopPadding + predictiveBackOffsetY
-                    )
-                }
-            }
-    ) {
-        Column {
-            val animatedInputFieldPadding = remember {
-                AnimatedPaddingValues(animationProgress.asState(), topPadding)
-            }
+        inputField = {
             SearchBarInputField(
                 query = query,
                 onQueryChange = onQueryChange,
                 onSearch = onSearch,
                 active = active,
                 onActiveChange = onActiveChange,
-                modifier = Modifier.padding(paddingValues = animatedInputFieldPadding),
+                modifier = Modifier.fillMaxWidth(),
                 enabled = enabled,
                 placeholder = placeholder,
                 leadingIcon = leadingIcon,
@@ -419,78 +258,14 @@
                 colors = colors.inputFieldColors,
                 interactionSource = interactionSource,
             )
-
-            val showResults by remember {
-                derivedStateOf(structuralEqualityPolicy()) { animationProgress.value > 0 }
-            }
-            if (showResults) {
-                Column(Modifier.graphicsLayer { alpha = animationProgress.value }) {
-                    HorizontalDivider(color = colors.dividerColor)
-                    content()
-                }
-            }
-        }
-    }
-
-    val isFocused = interactionSource.collectIsFocusedAsState().value
-    val shouldClearFocus = !active && isFocused
-    LaunchedEffect(active) {
-        if (shouldClearFocus) {
-            // Not strictly needed according to the motion spec, but since the animation already has
-            // a delay, this works around b/261632544.
-            delay(AnimationDelayMillis.toLong())
-            focusManager.clearFocus()
-        }
-    }
-}
-
-private fun calculatePredictiveBackMultiplier(
-    currentBackEvent: BackEventCompat?,
-    progress: Float,
-    finalBackProgress: Float
-) = when {
-    currentBackEvent == null -> 0f // Not in predictive back at all.
-    finalBackProgress.isNaN() -> 1f // User is currently swiping predictive back.
-    finalBackProgress <= 0 -> 0f // Safety check for divide by zero.
-    else -> progress / finalBackProgress // User has released predictive back swipe.
-}
-
-private fun calculatePredictiveBackOffsetX(
-    constraints: Constraints,
-    minMargin: Int,
-    currentBackEvent: BackEventCompat?,
-    progress: Float,
-    predictiveBackMultiplier: Float
-): Int {
-    if (currentBackEvent == null || predictiveBackMultiplier == 0f) {
-        return 0
-    }
-    val directionMultiplier = if (currentBackEvent.swipeEdge == BackEventCompat.EDGE_LEFT) 1 else -1
-    val maxOffsetX =
-        (constraints.maxWidth * SearchBarPredictiveBackMaxOffsetXRatio) - minMargin
-    val interpolatedOffsetX = maxOffsetX * (1 - progress)
-    return (interpolatedOffsetX * predictiveBackMultiplier * directionMultiplier).roundToInt()
-}
-
-private fun calculatePredictiveBackOffsetY(
-    constraints: Constraints,
-    minMargin: Int,
-    currentBackEvent: BackEventCompat?,
-    firstBackEvent: BackEventCompat?,
-    height: Int,
-    maxOffsetY: Int,
-    predictiveBackMultiplier: Float
-): Int {
-    if (firstBackEvent == null || currentBackEvent == null || predictiveBackMultiplier == 0f) {
-        return 0
-    }
-    val availableVerticalSpace = max(0, (constraints.maxHeight - height) / 2 - minMargin)
-    val adjustedMaxOffsetY = min(availableVerticalSpace, maxOffsetY)
-    val yDelta = currentBackEvent.touchY - firstBackEvent.touchY
-    val yProgress = abs(yDelta) / constraints.maxHeight
-    val directionMultiplier = sign(yDelta)
-    val interpolatedOffsetY = lerp(0, adjustedMaxOffsetY, yProgress)
-    return (interpolatedOffsetY * predictiveBackMultiplier * directionMultiplier).roundToInt()
+        },
+        shape = shape,
+        colors = colors,
+        tonalElevation = tonalElevation,
+        shadowElevation = shadowElevation,
+        windowInsets = windowInsets,
+        content = content,
+    )
 }
 
 /**
@@ -561,7 +336,6 @@
 ) {
     @Suppress("NAME_SHADOWING")
     val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
-    val focusManager = LocalFocusManager.current
 
     Surface(
         shape = shape,
@@ -575,6 +349,7 @@
     ) {
         Column {
             SearchBarInputField(
+                modifier = Modifier.fillMaxWidth(),
                 query = query,
                 onQueryChange = onQueryChange,
                 onSearch = onSearch,
@@ -609,17 +384,6 @@
         }
     }
 
-    val isFocused = interactionSource.collectIsFocusedAsState().value
-    val shouldClearFocus = !active && isFocused
-    LaunchedEffect(active) {
-        if (shouldClearFocus) {
-            // Not strictly needed according to the motion spec, but since the animation already has
-            // a delay, this works around b/261632544.
-            delay(AnimationDelayMillis.toLong())
-            focusManager.clearFocus()
-        }
-    }
-
     BackHandler(enabled = active) {
         onActiveChange(false)
     }
@@ -627,7 +391,7 @@
 
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
-private fun SearchBarInputField(
+internal fun SearchBarInputField(
     query: String,
     onQueryChange: (String) -> Unit,
     onSearch: (String) -> Unit,
@@ -644,6 +408,7 @@
     @Suppress("NAME_SHADOWING")
     val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     val focusRequester = remember { FocusRequester() }
+    val focusManager = LocalFocusManager.current
     val searchSemantics = getString(Strings.SearchBarSearch)
     val suggestionsAvailableSemantics = getString(Strings.SuggestionsAvailable)
     val textColor = LocalTextStyle.current.color.takeOrElse {
@@ -655,8 +420,11 @@
         value = query,
         onValueChange = onQueryChange,
         modifier = modifier
-            .height(InputFieldHeight)
-            .fillMaxWidth()
+            .sizeIn(
+                minWidth = SearchBarMinWidth,
+                maxWidth = SearchBarMaxWidth,
+                minHeight = InputFieldHeight,
+            )
             .focusRequester(focusRequester)
             .onFocusChanged { if (it.isFocused) onActiveChange(true) }
             .semantics {
@@ -698,6 +466,17 @@
             )
         }
     )
+
+    val isFocused = interactionSource.collectIsFocusedAsState().value
+    val shouldClearFocus = !active && isFocused
+    LaunchedEffect(active) {
+        if (shouldClearFocus) {
+            // Not strictly needed according to the motion spec, but since the animation already has
+            // a delay, this works around b/261632544.
+            delay(AnimationDelayMillis.toLong())
+            focusManager.clearFocus()
+        }
+    }
 }
 
 /**
@@ -860,7 +639,7 @@
  */
 @ExperimentalMaterial3Api
 @Immutable
-class SearchBarColors internal constructor(
+class SearchBarColors(
     val containerColor: Color,
     val dividerColor: Color,
     val inputFieldColors: TextFieldColors,
@@ -886,18 +665,274 @@
     }
 }
 
-@Stable
-private class AnimatedPaddingValues(
-    val animationProgress: State<Float>,
-    val topPadding: State<Dp>,
-) : PaddingValues {
-    override fun calculateTopPadding(): Dp = topPadding.value * animationProgress.value
-    override fun calculateBottomPadding(): Dp = SearchBarVerticalPadding * animationProgress.value
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+internal fun SearchBarImpl(
+    animationProgress: Animatable<Float, AnimationVector1D>,
+    finalBackProgress: MutableFloatState,
+    firstBackEvent: MutableState<BackEventCompat?>,
+    currentBackEvent: MutableState<BackEventCompat?>,
+    modifier: Modifier = Modifier,
+    inputField: @Composable () -> Unit,
+    shape: Shape = SearchBarDefaults.inputFieldShape,
+    colors: SearchBarColors = SearchBarDefaults.colors(),
+    tonalElevation: Dp = SearchBarDefaults.TonalElevation,
+    shadowElevation: Dp = SearchBarDefaults.ShadowElevation,
+    windowInsets: WindowInsets = SearchBarDefaults.windowInsets,
+    content: @Composable ColumnScope.() -> Unit,
+) {
+    val density = LocalDensity.current
 
-    override fun calculateLeftPadding(layoutDirection: LayoutDirection): Dp = 0.dp
-    override fun calculateRightPadding(layoutDirection: LayoutDirection): Dp = 0.dp
+    val defaultInputFieldShape = SearchBarDefaults.inputFieldShape
+    val defaultFullScreenShape = SearchBarDefaults.fullScreenShape
+    val useFullScreenShape by remember {
+        derivedStateOf(structuralEqualityPolicy()) { animationProgress.value == 1f }
+    }
+    val animatedShape = remember(useFullScreenShape, shape) {
+        when {
+            shape == defaultInputFieldShape ->
+                // The shape can only be animated if it's the default spec value
+                GenericShape { size, _ ->
+                    val radius = with(density) {
+                        (SearchBarCornerRadius * (1 - animationProgress.value)).toPx()
+                    }
+                    addRoundRect(RoundRect(size.toRect(), CornerRadius(radius)))
+                }
+            useFullScreenShape -> defaultFullScreenShape
+            else -> shape
+        }
+    }
+    val surface = @Composable {
+        Surface(
+            modifier = Modifier,
+            shape = animatedShape,
+            color = colors.containerColor,
+            contentColor = contentColorFor(colors.containerColor),
+            tonalElevation = tonalElevation,
+            shadowElevation = shadowElevation,
+            content = {},
+        )
+    }
+
+    val showContent by remember {
+        derivedStateOf(structuralEqualityPolicy()) { animationProgress.value > 0 }
+    }
+    val wrappedContent: (@Composable () -> Unit)? = if (showContent) {
+        {
+            Column(Modifier.graphicsLayer { alpha = animationProgress.value }) {
+                HorizontalDivider(color = colors.dividerColor)
+                content()
+            }
+        }
+    } else null
+
+    SearchBarLayout(
+        animationProgress = animationProgress,
+        finalBackProgress = finalBackProgress,
+        firstBackEvent = firstBackEvent,
+        currentBackEvent = currentBackEvent,
+        modifier = modifier,
+        windowInsets = windowInsets,
+        inputField = inputField,
+        surface = surface,
+        content = wrappedContent,
+    )
 }
 
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+private fun SearchBarLayout(
+    animationProgress: Animatable<Float, AnimationVector1D>,
+    finalBackProgress: MutableFloatState,
+    firstBackEvent: MutableState<BackEventCompat?>,
+    currentBackEvent: MutableState<BackEventCompat?>,
+    modifier: Modifier,
+    windowInsets: WindowInsets,
+    inputField: @Composable () -> Unit,
+    surface: @Composable () -> Unit,
+    content: (@Composable () -> Unit)?,
+) {
+    // `Modifier.windowInsetsPadding` does not support animation,
+    // so the insets are converted to paddings in the Layout's MeasureScope
+    // and the animation calculations are done manually.
+    val unconsumedInsets = remember { MutableWindowInsets() }
+    Layout(
+        modifier = modifier
+            .zIndex(1f)
+            .onConsumedWindowInsetsChanged { consumedInsets ->
+                unconsumedInsets.insets = windowInsets.exclude(consumedInsets)
+            }
+            .consumeWindowInsets(unconsumedInsets),
+        content = {
+            Box(Modifier.layoutId(LayoutIdSurface), propagateMinConstraints = true) {
+                surface()
+            }
+            Box(Modifier.layoutId(LayoutIdInputField), propagateMinConstraints = true) {
+                inputField()
+            }
+            content?.let { content ->
+                Box(Modifier.layoutId(LayoutIdSearchContent), propagateMinConstraints = true) {
+                    content()
+                }
+            }
+        },
+    ) { measurables, constraints ->
+        @Suppress("NAME_SHADOWING")
+        val animationProgress = animationProgress.value
+
+        val inputFieldMeasurable = measurables.fastFirst { it.layoutId == LayoutIdInputField }
+        val surfaceMeasurable = measurables.fastFirst { it.layoutId == LayoutIdSurface }
+        val contentMeasurable = measurables.fastFirstOrNull { it.layoutId == LayoutIdSearchContent }
+
+        val topPadding = unconsumedInsets.getTop(this) + SearchBarVerticalPadding.roundToPx()
+        val bottomPadding = SearchBarVerticalPadding.roundToPx()
+
+        val defaultStartWidth = constraints
+            .constrainWidth(inputFieldMeasurable.maxIntrinsicWidth(constraints.maxHeight))
+        val defaultStartHeight = constraints
+            .constrainHeight(inputFieldMeasurable.minIntrinsicHeight(constraints.maxWidth))
+
+        val predictiveBackStartWidth =
+            (constraints.maxWidth * SearchBarPredictiveBackMinScale).roundToInt()
+        val predictiveBackStartHeight =
+            (constraints.maxHeight * SearchBarPredictiveBackMinScale).roundToInt()
+        val predictiveBackMultiplier = calculatePredictiveBackMultiplier(
+            currentBackEvent.value,
+            animationProgress,
+            finalBackProgress.floatValue
+        )
+
+        val startWidth =
+            lerp(defaultStartWidth, predictiveBackStartWidth, predictiveBackMultiplier)
+        val startHeight = lerp(
+            topPadding + defaultStartHeight,
+            predictiveBackStartHeight,
+            predictiveBackMultiplier
+        )
+
+        val endWidth = constraints.maxWidth
+        val endHeight = constraints.maxHeight
+
+        val width = lerp(startWidth, endWidth, animationProgress)
+        val height = lerp(startHeight, endHeight, animationProgress)
+
+        // Note: animatedTopPadding decreases w.r.t. animationProgress
+        val animatedTopPadding = lerp(topPadding, 0, animationProgress)
+        val animatedBottomPadding = lerp(0, bottomPadding, animationProgress)
+
+        // As the animation proceeds, the surface loses its padding
+        // and expands to cover the entire container.
+        val surfacePlaceable = surfaceMeasurable
+            .measure(Constraints.fixed(width, height - animatedTopPadding))
+        val inputFieldPlaceable = inputFieldMeasurable
+            .measure(Constraints.fixed(width, defaultStartHeight))
+        val contentPlaceable = contentMeasurable?.measure(
+            Constraints(
+                minWidth = width,
+                maxWidth = width,
+                minHeight = 0,
+                maxHeight = if (constraints.hasBoundedHeight) {
+                    (constraints.maxHeight - (topPadding + defaultStartHeight + bottomPadding))
+                        .coerceAtLeast(0)
+                } else {
+                    constraints.maxHeight
+                }
+            )
+        )
+
+        layout(width, height) {
+            val minOffsetMargin = SearchBarPredictiveBackMinMargin.roundToPx()
+            val predictiveBackOffsetX = calculatePredictiveBackOffsetX(
+                constraints = constraints,
+                minMargin = minOffsetMargin,
+                currentBackEvent = currentBackEvent.value,
+                layoutDirection = layoutDirection,
+                progress = animationProgress,
+                predictiveBackMultiplier = predictiveBackMultiplier,
+            )
+            val predictiveBackOffsetY = calculatePredictiveBackOffsetY(
+                constraints = constraints,
+                minMargin = minOffsetMargin,
+                currentBackEvent = currentBackEvent.value,
+                firstBackEvent = firstBackEvent.value,
+                height = height,
+                maxOffsetY = SearchBarPredictiveBackMaxOffsetY.roundToPx(),
+                predictiveBackMultiplier = predictiveBackMultiplier,
+            )
+
+            surfacePlaceable.placeRelative(
+                predictiveBackOffsetX,
+                predictiveBackOffsetY + animatedTopPadding,
+            )
+            inputFieldPlaceable.placeRelative(
+                predictiveBackOffsetX,
+                predictiveBackOffsetY + topPadding,
+            )
+            contentPlaceable?.placeRelative(
+                predictiveBackOffsetX,
+                predictiveBackOffsetY + topPadding + inputFieldPlaceable.height +
+                    animatedBottomPadding,
+            )
+        }
+    }
+}
+
+private fun calculatePredictiveBackMultiplier(
+    currentBackEvent: BackEventCompat?,
+    progress: Float,
+    finalBackProgress: Float
+) = when {
+    currentBackEvent == null -> 0f // Not in predictive back at all.
+    finalBackProgress.isNaN() -> 1f // User is currently swiping predictive back.
+    finalBackProgress <= 0 -> 0f // Safety check for divide by zero.
+    else -> progress / finalBackProgress // User has released predictive back swipe.
+}
+
+private fun calculatePredictiveBackOffsetX(
+    constraints: Constraints,
+    minMargin: Int,
+    currentBackEvent: BackEventCompat?,
+    layoutDirection: LayoutDirection,
+    progress: Float,
+    predictiveBackMultiplier: Float
+): Int {
+    if (currentBackEvent == null || predictiveBackMultiplier == 0f) {
+        return 0
+    }
+    val directionMultiplier = if (currentBackEvent.swipeEdge == BackEventCompat.EDGE_LEFT) 1 else -1
+    val rtlMultiplier = if (layoutDirection == LayoutDirection.Ltr) 1 else -1
+    val maxOffsetX =
+        (constraints.maxWidth * SearchBarPredictiveBackMaxOffsetXRatio) - minMargin
+    val interpolatedOffsetX = maxOffsetX * (1 - progress)
+    return (interpolatedOffsetX * predictiveBackMultiplier * directionMultiplier * rtlMultiplier)
+        .roundToInt()
+}
+
+private fun calculatePredictiveBackOffsetY(
+    constraints: Constraints,
+    minMargin: Int,
+    currentBackEvent: BackEventCompat?,
+    firstBackEvent: BackEventCompat?,
+    height: Int,
+    maxOffsetY: Int,
+    predictiveBackMultiplier: Float
+): Int {
+    if (firstBackEvent == null || currentBackEvent == null || predictiveBackMultiplier == 0f) {
+        return 0
+    }
+    val availableVerticalSpace = max(0, (constraints.maxHeight - height) / 2 - minMargin)
+    val adjustedMaxOffsetY = min(availableVerticalSpace, maxOffsetY)
+    val yDelta = currentBackEvent.touchY - firstBackEvent.touchY
+    val yProgress = abs(yDelta) / constraints.maxHeight
+    val directionMultiplier = sign(yDelta)
+    val interpolatedOffsetY = lerp(0, adjustedMaxOffsetY, yProgress)
+    return (interpolatedOffsetY * predictiveBackMultiplier * directionMultiplier).roundToInt()
+}
+
+private const val LayoutIdInputField = "InputField"
+private const val LayoutIdSurface = "Surface"
+private const val LayoutIdSearchContent = "Content"
+
 // Measurement specs
 @OptIn(ExperimentalMaterial3Api::class)
 private val SearchBarCornerRadius: Dp = InputFieldHeight / 2
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/InteractiveComponentSize.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/InteractiveComponentSize.kt
index 97c25f6..5a2180c 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/InteractiveComponentSize.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/InteractiveComponentSize.kt
@@ -20,7 +20,6 @@
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.staticCompositionLocalOf
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.layout.LayoutModifier
 import androidx.compose.ui.layout.Measurable
 import androidx.compose.ui.layout.MeasureResult
 import androidx.compose.ui.layout.MeasureScope
@@ -30,8 +29,10 @@
 import androidx.compose.ui.node.currentValueOf
 import androidx.compose.ui.platform.InspectorInfo
 import androidx.compose.ui.unit.Constraints
-import androidx.compose.ui.unit.DpSize
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.coerceAtLeast
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.isSpecified
 import kotlin.math.roundToInt
 
 /**
@@ -73,24 +74,23 @@
     Modifier.Node(),
     CompositionLocalConsumerModifierNode,
     LayoutModifierNode {
-
-    @OptIn(ExperimentalMaterial3Api::class)
     override fun MeasureScope.measure(
         measurable: Measurable,
         constraints: Constraints
     ): MeasureResult {
-        val size = minimumInteractiveComponentSize
+        val size = currentValueOf(LocalMinimumInteractiveComponentSize).coerceAtLeast(0.dp)
         val placeable = measurable.measure(constraints)
-        val enforcement = isAttached && currentValueOf(LocalMinimumInteractiveComponentEnforcement)
+        val enforcement = isAttached && (size.isSpecified && size > 0.dp)
 
+        val sizePx = if (size.isSpecified) size.roundToPx() else 0
         // Be at least as big as the minimum dimension in both dimensions
         val width = if (enforcement) {
-            maxOf(placeable.width, size.width.roundToPx())
+            maxOf(placeable.width, sizePx)
         } else {
             placeable.width
         }
         val height = if (enforcement) {
-            maxOf(placeable.height, size.height.roundToPx())
+            maxOf(placeable.height, sizePx)
         } else {
             placeable.height
         }
@@ -114,57 +114,24 @@
 @Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
 @get:ExperimentalMaterial3Api
 @ExperimentalMaterial3Api
+@Deprecated(
+    message = "Use LocalMinimumInteractiveComponentSize with Dp.Unspecified to turn off " +
+        "enforcement instead.",
+    replaceWith = ReplaceWith(
+        "LocalMinimumInteractiveComponentSize"
+    ),
+    level = DeprecationLevel.WARNING
+)
 val LocalMinimumInteractiveComponentEnforcement: ProvidableCompositionLocal<Boolean> =
     staticCompositionLocalOf { true }
 
 /**
- * CompositionLocal that configures whether Material components that have a visual size that is
- * lower than the minimum touch target size for accessibility (such as [Button]) will include
- * extra space outside the component to ensure that they are accessible. If set to false there
- * will be no extra space, and so it is possible that if the component is placed near the edge of
- * a layout / near to another component without any padding, there will not be enough space for
- * an accessible touch target.
+ * CompositionLocal that configures the minimum touch target size for Material components
+ * (such as [Button]) to ensure they are accessible. If a component has a visual size
+ * that is lower than the minimum touch target size, extra space outside the component will be
+ * included. If set to [Dp.Unspecified] there will be no extra space, and so it is possible that if the
+ * component is placed near the edge of a layout / near to another component without any padding,
+ * there will not be enough space for an accessible touch target.
  */
-@Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
-@get:ExperimentalMaterial3Api
-@ExperimentalMaterial3Api
-@Deprecated(
-    message = "Use LocalMinimumInteractiveComponentEnforcement instead.",
-    replaceWith = ReplaceWith(
-        "LocalMinimumInteractiveComponentEnforcement"
-    ),
-    level = DeprecationLevel.WARNING
-)
-val LocalMinimumTouchTargetEnforcement: ProvidableCompositionLocal<Boolean> =
-    LocalMinimumInteractiveComponentEnforcement
-
-private class MinimumInteractiveComponentSizeModifier(val size: DpSize) : LayoutModifier {
-    override fun MeasureScope.measure(
-        measurable: Measurable,
-        constraints: Constraints
-    ): MeasureResult {
-
-        val placeable = measurable.measure(constraints)
-
-        // Be at least as big as the minimum dimension in both dimensions
-        val width = maxOf(placeable.width, size.width.roundToPx())
-        val height = maxOf(placeable.height, size.height.roundToPx())
-
-        return layout(width, height) {
-            val centerX = ((width - placeable.width) / 2f).roundToInt()
-            val centerY = ((height - placeable.height) / 2f).roundToInt()
-            placeable.place(centerX, centerY)
-        }
-    }
-
-    override fun equals(other: Any?): Boolean {
-        val otherModifier = other as? MinimumInteractiveComponentSizeModifier ?: return false
-        return size == otherModifier.size
-    }
-
-    override fun hashCode(): Int {
-        return size.hashCode()
-    }
-}
-
-private val minimumInteractiveComponentSize: DpSize = DpSize(48.dp, 48.dp)
+val LocalMinimumInteractiveComponentSize: ProvidableCompositionLocal<Dp> =
+    staticCompositionLocalOf { 48.dp }
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationDrawer.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationDrawer.kt
index 24bdd24..e9da174 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationDrawer.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationDrawer.kt
@@ -111,7 +111,6 @@
  */
 @Suppress("NotCloseable")
 @Stable
-@OptIn(ExperimentalMaterial3Api::class)
 class DrawerState(
     initialValue: DrawerValue,
     confirmStateChange: (DrawerValue) -> Boolean = { true }
@@ -308,7 +307,6 @@
  * @param scrimColor color of the scrim that obscures content when the drawer is open
  * @param content content of the rest of the UI
  */
-@OptIn(ExperimentalMaterial3Api::class)
 @Composable
 fun ModalNavigationDrawer(
     drawerContent: @Composable () -> Unit,
@@ -411,7 +409,6 @@
  * @param gesturesEnabled whether or not the drawer can be interacted by gestures
  * @param content content of the rest of the UI
  */
-@OptIn(ExperimentalMaterial3Api::class)
 @Composable
 fun DismissibleNavigationDrawer(
     drawerContent: @Composable () -> Unit,
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismissBox.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismissBox.kt
index c55ac5116..05b7a1b 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismissBox.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismissBox.kt
@@ -122,25 +122,6 @@
         }
 
     /**
-     * Whether the component has been dismissed in the given [direction].
-     *
-     * @param direction The dismiss direction.
-     */
-    @Deprecated(
-        message = "DismissDirection is no longer used by SwipeToDismissBoxState. Please compare " +
-            "currentValue against SwipeToDismissValue instead.",
-        level = DeprecationLevel.HIDDEN
-    )
-    @Suppress("DEPRECATION")
-    fun isDismissed(direction: DismissDirection): Boolean {
-        val directionalDismissValue = when (direction) {
-            DismissDirection.StartToEnd -> SwipeToDismissBoxValue.StartToEnd
-            DismissDirection.EndToStart -> SwipeToDismissBoxValue.EndToStart
-        }
-        return currentValue == directionalDismissValue
-    }
-
-    /**
      * Set the state without any animation and suspend until it's set
      *
      * @param targetValue The new target value
@@ -226,47 +207,6 @@
  * @sample androidx.compose.material3.samples.SwipeToDismissListItems
  *
  * @param state The state of this component.
- * @param background A composable that is stacked behind the content and is exposed when the
- * content is swiped. You can/should use the [state] to have different backgrounds on each side.
- * @param dismissContent The content that can be dismissed.
- * @param modifier Optional [Modifier] for this component.
- * @param directions The set of directions in which the component can be dismissed.
- */
-@Composable
-@Deprecated(
-    level = DeprecationLevel.WARNING,
-    message = "Use SwipeToDismissBox instead",
-    replaceWith =
-    ReplaceWith(
-        "SwipeToDismissBox(state, background, modifier, " +
-            "enableDismissFromStartToEnd, enableDismissFromEndToStart, dismissContent)"
-    )
-)
-@ExperimentalMaterial3Api
-fun SwipeToDismiss(
-    state: SwipeToDismissBoxState,
-    background: @Composable RowScope.() -> Unit,
-    dismissContent: @Composable RowScope.() -> Unit,
-    modifier: Modifier = Modifier,
-    directions: Set<SwipeToDismissBoxValue> = setOf(
-        SwipeToDismissBoxValue.EndToStart,
-        SwipeToDismissBoxValue.StartToEnd
-    ),
-) = SwipeToDismissBox(
-    state = state,
-    backgroundContent = background,
-    modifier = modifier,
-    enableDismissFromStartToEnd = SwipeToDismissBoxValue.StartToEnd in directions,
-    enableDismissFromEndToStart = SwipeToDismissBoxValue.EndToStart in directions,
-    content = dismissContent
-)
-
-/**
- * A composable that can be dismissed by swiping left or right.
- *
- * @sample androidx.compose.material3.samples.SwipeToDismissListItems
- *
- * @param state The state of this component.
  * @param backgroundContent A composable that is stacked behind the [content] and is exposed when
  * the content is swiped. You can/should use the [state] to have different backgrounds on each side.
  * @param modifier Optional [Modifier] for this component.
@@ -332,51 +272,4 @@
         }
 }
 
-/**
- * The directions in which a [SwipeToDismissBox] can be dismissed.
- */
-@ExperimentalMaterial3Api
-@Deprecated(
-    message = "Dismiss direction is no longer used by SwipeToDismissBoxState. Please use " +
-        "SwipeToDismissBoxValue instead.",
-    level = DeprecationLevel.WARNING
-)
-enum class DismissDirection {
-    /**
-     * Can be dismissed by swiping in the reading direction.
-     */
-    StartToEnd,
-
-    /**
-     * Can be dismissed by swiping in the reverse of the reading direction.
-     */
-    EndToStart,
-}
-
-/**
- * Possible values of [SwipeToDismissBoxState].
- */
-@ExperimentalMaterial3Api
-@Deprecated(
-    message = "DismissValue is no longer used by SwipeToDismissBoxState. Please use " +
-        "SwipeToDismissBoxValue instead.",
-    level = DeprecationLevel.WARNING
-)
-enum class DismissValue {
-    /**
-     * Indicates the component has not been dismissed yet.
-     */
-    Default,
-
-    /**
-     * Indicates the component has been dismissed in the reading direction.
-     */
-    DismissedToEnd,
-
-    /**
-     * Indicates the component has been dismissed in the reverse of the reading direction.
-     */
-    DismissedToStart
-}
-
 private val DismissVelocityThreshold = 125.dp
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 d57031f..d21e787 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
@@ -2219,7 +2219,9 @@
         val providers: PersistentCompositionLocalMap
         val invalid: Boolean
         if (inserting) {
-            providers = parentScope.putValue(local, state)
+            providers = if (value.canOverride || !parentScope.contains(local)) {
+                parentScope.putValue(local, state)
+            } else { parentScope }
             invalid = false
             writerHasAProvider = true
         } else {
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/CompositionLocalTests.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/CompositionLocalTests.kt
index 4144ccd..ddfcc02 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/CompositionLocalTests.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/CompositionLocalTests.kt
@@ -702,6 +702,18 @@
 
         revalidate()
     }
+
+    @Test // Regression test for: b/330036209
+    fun testSingleProvideDefaultValue() = compositionTest {
+        val local = compositionLocalOf { 0 }
+        compose {
+            CompositionLocalProvider(local provides 1) {
+                CompositionLocalProvider(local providesDefault 2) {
+                    assertEquals(1, local.current)
+                }
+            }
+        }
+    }
 }
 
 val cacheLocal = staticCompositionLocalOf { "Unset" }
diff --git a/compose/ui/ui/api/current.txt b/compose/ui/ui/api/current.txt
index d7a30f9..45b08d7 100644
--- a/compose/ui/ui/api/current.txt
+++ b/compose/ui/ui/api/current.txt
@@ -2847,6 +2847,7 @@
   public final class ClipEntry {
     ctor public ClipEntry(android.content.ClipData clipData);
     method public android.content.ClipData getClipData();
+    method public androidx.compose.ui.platform.ClipMetadata getMetadata();
     property public final android.content.ClipData clipData;
   }
 
@@ -2862,10 +2863,8 @@
 
   public interface ClipboardManager {
     method public default androidx.compose.ui.platform.ClipEntry? getClip();
-    method public default androidx.compose.ui.platform.ClipMetadata? getClipMetadata();
     method public default android.content.ClipboardManager getNativeClipboard();
     method public androidx.compose.ui.text.AnnotatedString? getText();
-    method public default boolean hasClip();
     method public default boolean hasText();
     method public default void setClip(androidx.compose.ui.platform.ClipEntry? clipEntry);
     method public void setText(androidx.compose.ui.text.AnnotatedString annotatedString);
@@ -3380,7 +3379,6 @@
     method public <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
     method public void setClearingSemantics(boolean);
     method public void setMergingSemanticsOfDescendants(boolean);
-    method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public <T> void unset(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
     property public final boolean isClearingSemantics;
     property public final boolean isMergingSemanticsOfDescendants;
   }
@@ -3463,7 +3461,6 @@
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getInvisibleToUser();
     method @Deprecated public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getIsContainer();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getIsDialog();
-    method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getIsOpaque();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getIsPopup();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getIsShowingTextSubstitution();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getIsTraversalGroup();
@@ -3498,7 +3495,6 @@
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> InvisibleToUser;
     property @Deprecated public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> IsContainer;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> IsDialog;
-    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> IsOpaque;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> IsPopup;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> IsShowingTextSubstitution;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> IsTraversalGroup;
@@ -3567,7 +3563,6 @@
     method public static void insertTextAtCursor(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString,java.lang.Boolean>? action);
     method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static void invisibleToUser(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method @Deprecated public static boolean isContainer(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
-    method public static void isOpaque(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static boolean isShowingTextSubstitution(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static boolean isTraversalGroup(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static void onClick(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
@@ -3634,7 +3629,6 @@
 
   public interface SemanticsPropertyReceiver {
     method public operator <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
-    method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public <T> void unset(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
   }
 
 }
diff --git a/compose/ui/ui/api/restricted_current.txt b/compose/ui/ui/api/restricted_current.txt
index 8abe50e..d2a9c77 100644
--- a/compose/ui/ui/api/restricted_current.txt
+++ b/compose/ui/ui/api/restricted_current.txt
@@ -2900,6 +2900,7 @@
   public final class ClipEntry {
     ctor public ClipEntry(android.content.ClipData clipData);
     method public android.content.ClipData getClipData();
+    method public androidx.compose.ui.platform.ClipMetadata getMetadata();
     property public final android.content.ClipData clipData;
   }
 
@@ -2915,10 +2916,8 @@
 
   public interface ClipboardManager {
     method public default androidx.compose.ui.platform.ClipEntry? getClip();
-    method public default androidx.compose.ui.platform.ClipMetadata? getClipMetadata();
     method public default android.content.ClipboardManager getNativeClipboard();
     method public androidx.compose.ui.text.AnnotatedString? getText();
-    method public default boolean hasClip();
     method public default boolean hasText();
     method public default void setClip(androidx.compose.ui.platform.ClipEntry? clipEntry);
     method public void setText(androidx.compose.ui.text.AnnotatedString annotatedString);
@@ -3440,7 +3439,6 @@
     method public <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
     method public void setClearingSemantics(boolean);
     method public void setMergingSemanticsOfDescendants(boolean);
-    method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public <T> void unset(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
     property public final boolean isClearingSemantics;
     property public final boolean isMergingSemanticsOfDescendants;
   }
@@ -3523,7 +3521,6 @@
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getInvisibleToUser();
     method @Deprecated public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getIsContainer();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getIsDialog();
-    method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getIsOpaque();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getIsPopup();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getIsShowingTextSubstitution();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getIsTraversalGroup();
@@ -3558,7 +3555,6 @@
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> InvisibleToUser;
     property @Deprecated public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> IsContainer;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> IsDialog;
-    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> IsOpaque;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> IsPopup;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> IsShowingTextSubstitution;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> IsTraversalGroup;
@@ -3627,7 +3623,6 @@
     method public static void insertTextAtCursor(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString,java.lang.Boolean>? action);
     method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static void invisibleToUser(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method @Deprecated public static boolean isContainer(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
-    method public static void isOpaque(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static boolean isShowingTextSubstitution(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static boolean isTraversalGroup(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static void onClick(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
@@ -3694,7 +3689,6 @@
 
   public interface SemanticsPropertyReceiver {
     method public operator <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
-    method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public <T> void unset(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
   }
 
 }
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/ClipboardDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/ClipboardDemo.kt
index 94804da..5c309ab 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/ClipboardDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/ClipboardDemo.kt
@@ -185,9 +185,9 @@
 }
 
 fun ClipboardManager.hasImage(): Boolean {
-    if (!hasClip()) return false
+    val clipMetadata = getClip()?.getMetadata() ?: return false
 
-    return getClipMetadata()?.clipDescription?.hasMimeType("image/*") ?: false
+    return clipMetadata.clipDescription.hasMimeType("image/*")
 }
 
 @Suppress("ClassVerificationFailure", "DEPRECATION")
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
index 64797a5..c6f8ea58 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
@@ -139,8 +139,6 @@
 import androidx.compose.ui.semantics.contentDescription
 import androidx.compose.ui.semantics.getOrNull
 import androidx.compose.ui.semantics.invisibleToUser
-import androidx.compose.ui.semantics.isContainer
-import androidx.compose.ui.semantics.isOpaque
 import androidx.compose.ui.semantics.isTraversalGroup
 import androidx.compose.ui.semantics.paneTitle
 import androidx.compose.ui.semantics.role
@@ -3960,144 +3958,6 @@
         }
     }
 
-    @OptIn(ExperimentalComposeUiApi::class)
-    @Test
-    fun testSemanticsHitTest_unimportantTraversalProperties() {
-        // Arrange.
-        setContent {
-            Box(
-                Modifier
-                    .size(100.dp)
-                    .testTag(tag)
-                    .semantics { isTraversalGroup = true; traversalIndex = 1f }) {
-            }
-        }
-        val bounds = with(rule.density) { rule.onNodeWithTag(tag).getBoundsInRoot().toRect() }
-
-        // Act.
-        val hitNodeId = rule.runOnIdle {
-            delegate.hitTestSemanticsAt(
-                bounds.left + bounds.width / 2,
-                bounds.top + bounds.height / 2
-            )
-        }
-
-        // Assert it doesn't hit the tagged node since it only has unimportant properties.
-        rule.runOnIdle { assertThat(hitNodeId).isEqualTo(InvalidId) }
-    }
-
-    @Test
-    @OptIn(ExperimentalComposeUiApi::class)
-    @Suppress("DEPRECATION")
-    fun testAccessibilityNodeInfoTreePruned_isContainerFalseDoesNotPrune() {
-        // Arrange.
-        val parentTag = "ParentForOverlappedChildren"
-        val childOneTag = "OverlappedChildOne"
-        val childTwoTag = "OverlappedChildTwo"
-        setContent {
-            Box(Modifier.testTag(parentTag)) {
-                with(LocalDensity.current) {
-                    Box(
-                        Modifier
-                            .zIndex(1f)
-                            .testTag(childOneTag)
-                            .semantics { isContainer = false }
-                            .semantics { isContainer = true }
-                            .requiredSize(50.toDp())
-                    )
-                    BasicText(
-                        "Child Two",
-                        Modifier
-                            .testTag(childTwoTag)
-                            .requiredSize(50.toDp())
-                    )
-                }
-            }
-        }
-        val parentNodeId = rule.onNodeWithTag(parentTag).semanticsId
-        val overlappedChildTwoNodeId = rule.onNodeWithTag(childTwoTag).semanticsId
-
-        rule.runOnIdle {
-            assertThat(createAccessibilityNodeInfo(parentNodeId).childCount).isEqualTo(2)
-            assertThat(createAccessibilityNodeInfo(overlappedChildTwoNodeId).text.toString())
-                .isEqualTo("Child Two")
-        }
-    }
-
-    @Test
-    @OptIn(ExperimentalComposeUiApi::class)
-    fun testAccessibilityNodeInfoTreePruned_invisibleDoesNotPrune() {
-        // Arrange.
-        val parentTag = "ParentForOverlappedChildren"
-        val childOneTag = "OverlappedChildOne"
-        val childTwoTag = "OverlappedChildTwo"
-        setContent {
-            Box(Modifier.testTag(parentTag)) {
-                with(LocalDensity.current) {
-                    BasicText(
-                        "Child One",
-                        Modifier
-                            .zIndex(1f)
-                            .testTag(childOneTag)
-                            .semantics { invisibleToUser() }
-                            .requiredSize(50.toDp())
-                    )
-                    BasicText(
-                        "Child Two",
-                        Modifier
-                            .testTag(childTwoTag)
-                            .requiredSize(50.toDp())
-                    )
-                }
-            }
-        }
-        val parentNodeId = rule.onNodeWithTag(parentTag).semanticsId
-        val overlappedChildTwoNodeId = rule.onNodeWithTag(childTwoTag).semanticsId
-
-        rule.runOnIdle {
-            assertThat(createAccessibilityNodeInfo(parentNodeId).childCount).isEqualTo(2)
-            assertThat(createAccessibilityNodeInfo(overlappedChildTwoNodeId).text.toString())
-                .isEqualTo("Child Two")
-        }
-    }
-
-    @Test
-    @OptIn(ExperimentalComposeUiApi::class)
-    fun testAccessibilityNodeInfoTreePruned_isOpaquePrunes() {
-        // Arrange.
-        val parentTag = "ParentForOverlappedChildren"
-        val childOneTag = "OverlappedChildOne"
-        val childTwoTag = "OverlappedChildTwo"
-        setContent {
-            Box(Modifier.testTag(parentTag)) {
-                with(LocalDensity.current) {
-                    Box(
-                        Modifier
-                            .zIndex(1f)
-                            .testTag(childOneTag)
-                            .semantics { isOpaque() }
-                            .requiredSize(50.toDp())
-                    )
-                    BasicText(
-                        "Child Two",
-                        Modifier
-                            .testTag(childTwoTag)
-                            .requiredSize(50.toDp())
-                    )
-                }
-            }
-        }
-        val parentNodeId = rule.onNodeWithTag(parentTag).semanticsId
-        val overlappedChildOneNodeId = rule.onNodeWithTag(childOneTag).semanticsId
-        val overlappedChildTwoNodeId = rule.onNodeWithTag(childTwoTag).semanticsId
-
-        rule.runOnIdle {
-            assertThat(createAccessibilityNodeInfo(parentNodeId).childCount).isEqualTo(1)
-            assertThat(provider.createAccessibilityNodeInfo(overlappedChildOneNodeId)).isNotNull()
-            assertThat(provider.createAccessibilityNodeInfo(overlappedChildTwoNodeId)).isNull()
-        }
-    }
-
     @Test
     fun testPaneAppear() {
         var isPaneVisible by mutableStateOf(false)
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusTargetAttachDetachTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusTargetAttachDetachTest.kt
index 85b3f11..cea72d9 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusTargetAttachDetachTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusTargetAttachDetachTest.kt
@@ -20,8 +20,29 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
+import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.input.InputMode
+import androidx.compose.ui.input.InputModeManager
+import androidx.compose.ui.input.key.Key
+import androidx.compose.ui.input.key.KeyEvent
+import androidx.compose.ui.input.key.KeyInputModifierNode
+import androidx.compose.ui.input.key.NativeKeyEvent
+import androidx.compose.ui.input.key.SoftKeyboardInterceptionModifierNode
+import androidx.compose.ui.input.key.key
+import androidx.compose.ui.input.pointer.elementFor
+import androidx.compose.ui.input.rotary.RotaryInputModifierNode
+import androidx.compose.ui.input.rotary.RotaryScrollEvent
+import androidx.compose.ui.node.DelegatingNode
+import androidx.compose.ui.platform.LocalInputModeManager
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.ExperimentalTestApi
 import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.onRoot
+import androidx.compose.ui.test.performKeyInput
+import androidx.compose.ui.test.performKeyPress
+import androidx.compose.ui.test.performRotaryScrollInput
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
@@ -980,6 +1001,407 @@
         }
     }
 
+    @OptIn(ExperimentalComposeUiApi::class, ExperimentalTestApi::class)
+    @Test
+    fun focusTarget_nodeThatIsKeyInputNodeKind_implementing_receivesKeyEventsWhenFocused() {
+        class FocusTargetAndKeyInputNode : DelegatingNode(), KeyInputModifierNode {
+            val keyEvents = mutableListOf<KeyEvent>()
+            val focusTargetNode = FocusTargetNode()
+
+            init {
+                delegate(focusTargetNode)
+            }
+
+            override fun onKeyEvent(event: KeyEvent): Boolean {
+                keyEvents.add(event)
+                return true
+            }
+
+            override fun onPreKeyEvent(event: KeyEvent) = false
+        }
+
+        val focusTargetAndKeyInputNode = FocusTargetAndKeyInputNode()
+        val focusTargetAndKeyInputModifier = elementFor(key1 = null, focusTargetAndKeyInputNode)
+
+        val focusRequester = FocusRequester()
+        val targetTestTag = "target"
+        lateinit var inputModeManager: InputModeManager
+
+        rule.setFocusableContent(extraItemForInitialFocus = false) {
+            inputModeManager = LocalInputModeManager.current
+            Box(
+                modifier = Modifier
+                    .testTag(targetTestTag)
+                    .focusRequester(focusRequester)
+                    .then(focusTargetAndKeyInputModifier)
+            )
+        }
+
+        rule.runOnUiThread {
+            inputModeManager.requestInputMode(InputMode.Keyboard)
+            focusRequester.requestFocus()
+        }
+
+        assertThat(focusTargetAndKeyInputNode.focusTargetNode.focusState.isFocused).isTrue()
+
+        rule.onNodeWithTag(targetTestTag).performKeyInput { keyDown(Key.Enter) }
+
+        assertThat(focusTargetAndKeyInputNode.keyEvents).hasSize(1)
+        assertThat(focusTargetAndKeyInputNode.keyEvents[0].key).isEqualTo(Key.Enter)
+    }
+
+    @OptIn(ExperimentalComposeUiApi::class, ExperimentalTestApi::class)
+    @Test
+    fun focusTarget_nodeThatIsKeyInputNodeKind_delegating_receivesKeyEventsWhenFocused() {
+        class FocusTargetAndKeyInputNode : DelegatingNode() {
+            val keyEvents = mutableListOf<KeyEvent>()
+            val focusTargetNode = FocusTargetNode()
+            val keyInputNode = object : KeyInputModifierNode, Modifier.Node() {
+                override fun onKeyEvent(event: KeyEvent): Boolean {
+                    keyEvents.add(event)
+                    return true
+                }
+
+                override fun onPreKeyEvent(event: KeyEvent) = false
+            }
+
+            init {
+                delegate(focusTargetNode)
+                delegate(keyInputNode)
+            }
+        }
+
+        val focusTargetAndKeyInputNode = FocusTargetAndKeyInputNode()
+        val focusTargetAndKeyInputModifier = elementFor(key1 = null, focusTargetAndKeyInputNode)
+
+        val focusRequester = FocusRequester()
+        val targetTestTag = "target"
+        lateinit var inputModeManager: InputModeManager
+
+        rule.setFocusableContent(extraItemForInitialFocus = false) {
+            inputModeManager = LocalInputModeManager.current
+            Box(
+                modifier = Modifier
+                    .testTag(targetTestTag)
+                    .focusRequester(focusRequester)
+                    .then(focusTargetAndKeyInputModifier)
+            )
+        }
+
+        rule.runOnUiThread {
+            inputModeManager.requestInputMode(InputMode.Keyboard)
+            focusRequester.requestFocus()
+        }
+
+        assertThat(focusTargetAndKeyInputNode.focusTargetNode.focusState.isFocused).isTrue()
+
+        rule.onNodeWithTag(targetTestTag).performKeyInput { keyDown(Key.Enter) }
+
+        assertThat(focusTargetAndKeyInputNode.keyEvents).hasSize(1)
+        assertThat(focusTargetAndKeyInputNode.keyEvents[0].key).isEqualTo(Key.Enter)
+    }
+
+    @OptIn(ExperimentalComposeUiApi::class)
+    @Test
+    fun focusTarget_nodeThatIsSoftKeyInputNodeKind_implementing_receivesSoftKeyEventsWhenFocused() {
+        class FocusTargetAndSoftKeyboardNode : DelegatingNode(),
+            SoftKeyboardInterceptionModifierNode {
+            val keyEvents = mutableListOf<KeyEvent>()
+            val focusTargetNode = FocusTargetNode()
+
+            init {
+                delegate(focusTargetNode)
+            }
+
+            override fun onInterceptKeyBeforeSoftKeyboard(event: KeyEvent) = keyEvents.add(event)
+
+            override fun onPreInterceptKeyBeforeSoftKeyboard(event: KeyEvent) = false
+        }
+
+        val focusTargetAndSoftKeyboardNode = FocusTargetAndSoftKeyboardNode()
+        val focusTargetAndSoftKeyboardModifier =
+            elementFor(key1 = null, focusTargetAndSoftKeyboardNode)
+
+        val focusRequester = FocusRequester()
+        val targetTestTag = "target"
+
+        rule.setFocusableContent(extraItemForInitialFocus = false) {
+            Box(
+                modifier = Modifier
+                    .testTag(targetTestTag)
+                    .focusRequester(focusRequester)
+                    .then(focusTargetAndSoftKeyboardModifier)
+            )
+        }
+
+        rule.runOnUiThread { focusRequester.requestFocus() }
+        assertThat(focusTargetAndSoftKeyboardNode.focusTargetNode.focusState.isFocused).isTrue()
+
+        // This test specifically uses performKeyPress over performKeyInput as performKeyPress calls
+        // sendKeyEvent, which in turn notifies FocusOwner that there's a
+        // SoftKeyboardInterceptionModifierNode-interceptable key event first. performKeyInput goes
+        // through dispatchKeyEvent which does not notify SoftKeyboardInterceptionModifierNodes.
+        rule.onRoot().performKeyPress(
+            KeyEvent(
+                NativeKeyEvent(
+                    android.view.KeyEvent.ACTION_DOWN,
+                    android.view.KeyEvent.KEYCODE_ENTER
+                )
+            )
+        )
+
+        assertThat(focusTargetAndSoftKeyboardNode.keyEvents).hasSize(1)
+        assertThat(focusTargetAndSoftKeyboardNode.keyEvents[0].key).isEqualTo(Key.Enter)
+    }
+
+    @OptIn(ExperimentalComposeUiApi::class)
+    @Test
+    fun focusTarget_nodeThatIsSoftKeyInputNodeKind_delegating_receivesSoftKeyEventsWhenFocused() {
+        class FocusTargetAndSoftKeyboardNode : DelegatingNode() {
+            val keyEvents = mutableListOf<KeyEvent>()
+            val focusTargetNode = FocusTargetNode()
+            val softKeyboardInterceptionNode = object : SoftKeyboardInterceptionModifierNode,
+                Modifier.Node() {
+                override fun onInterceptKeyBeforeSoftKeyboard(event: KeyEvent) =
+                    keyEvents.add(event)
+
+                override fun onPreInterceptKeyBeforeSoftKeyboard(event: KeyEvent) = false
+            }
+
+            init {
+                delegate(focusTargetNode)
+                delegate(softKeyboardInterceptionNode)
+            }
+        }
+
+        val focusTargetAndSoftKeyboardNode = FocusTargetAndSoftKeyboardNode()
+        val focusTargetAndSoftKeyboardModifier =
+            elementFor(key1 = null, focusTargetAndSoftKeyboardNode)
+
+        val focusRequester = FocusRequester()
+        val targetTestTag = "target"
+
+        rule.setFocusableContent(extraItemForInitialFocus = false) {
+            Box(
+                modifier = Modifier
+                    .testTag(targetTestTag)
+                    .focusRequester(focusRequester)
+                    .then(focusTargetAndSoftKeyboardModifier)
+            )
+        }
+
+        rule.runOnUiThread { focusRequester.requestFocus() }
+        assertThat(focusTargetAndSoftKeyboardNode.focusTargetNode.focusState.isFocused).isTrue()
+
+        // This test specifically uses performKeyPress over performKeyInput as performKeyPress calls
+        // sendKeyEvent, which in turn notifies FocusOwner that there's a
+        // SoftKeyboardInterceptionModifierNode-interceptable key event first. performKeyInput goes
+        // through dispatchKeyEvent which does not notify SoftKeyboardInterceptionModifierNodes.
+        rule.onRoot().performKeyPress(
+            KeyEvent(
+                NativeKeyEvent(
+                    android.view.KeyEvent.ACTION_DOWN,
+                    android.view.KeyEvent.KEYCODE_ENTER
+                )
+            )
+        )
+
+        assertThat(focusTargetAndSoftKeyboardNode.keyEvents).hasSize(1)
+        assertThat(focusTargetAndSoftKeyboardNode.keyEvents[0].key).isEqualTo(Key.Enter)
+    }
+
+    @OptIn(ExperimentalTestApi::class)
+    @Test
+    fun focusTarget_nodeThatIsRotaryInputNodeKind_implementing_receivesRotaryEventsWhenFocused() {
+        class FocusTargetAndRotaryNode : DelegatingNode(), RotaryInputModifierNode {
+            val events = mutableListOf<RotaryScrollEvent>()
+            val focusTargetNode = FocusTargetNode()
+
+            init {
+                delegate(focusTargetNode)
+            }
+
+            override fun onRotaryScrollEvent(event: RotaryScrollEvent) = events.add(event)
+
+            override fun onPreRotaryScrollEvent(event: RotaryScrollEvent) = false
+        }
+
+        val focusTargetAndRotaryNode = FocusTargetAndRotaryNode()
+        val focusTargetAndRotaryModifier = elementFor(key1 = null, focusTargetAndRotaryNode)
+
+        val focusRequester = FocusRequester()
+        val targetTestTag = "target"
+
+        rule.setFocusableContent(extraItemForInitialFocus = false) {
+            Box(
+                modifier = Modifier
+                    .testTag(targetTestTag)
+                    .focusRequester(focusRequester)
+                    .then(focusTargetAndRotaryModifier)
+            )
+        }
+
+        rule.runOnUiThread { focusRequester.requestFocus() }
+        assertThat(focusTargetAndRotaryNode.focusTargetNode.focusState.isFocused).isTrue()
+
+        rule.onNodeWithTag(targetTestTag).performRotaryScrollInput {
+            rotateToScrollVertically(100f)
+        }
+
+        assertThat(focusTargetAndRotaryNode.events).hasSize(1)
+        assertThat(focusTargetAndRotaryNode.events[0].verticalScrollPixels).isEqualTo(100f)
+    }
+
+    @OptIn(ExperimentalTestApi::class)
+    @Test
+    fun focusTarget_nodeThatIsRotaryInputNodeKind_delegating_receivesRotaryEventsWhenFocused() {
+        class FocusTargetAndRotaryNode : DelegatingNode() {
+            val events = mutableListOf<RotaryScrollEvent>()
+            val focusTargetNode = FocusTargetNode()
+            val rotaryInputNode = object : RotaryInputModifierNode, Modifier.Node() {
+                override fun onRotaryScrollEvent(event: RotaryScrollEvent) = events.add(event)
+                override fun onPreRotaryScrollEvent(event: RotaryScrollEvent) = false
+            }
+
+            init {
+                delegate(focusTargetNode)
+                delegate(rotaryInputNode)
+            }
+        }
+
+        val focusTargetAndRotaryNode = FocusTargetAndRotaryNode()
+        val focusTargetAndRotaryModifier = elementFor(key1 = null, focusTargetAndRotaryNode)
+
+        val focusRequester = FocusRequester()
+        val targetTestTag = "target"
+
+        rule.setFocusableContent(extraItemForInitialFocus = false) {
+            Box(
+                modifier = Modifier
+                    .testTag(targetTestTag)
+                    .focusRequester(focusRequester)
+                    .then(focusTargetAndRotaryModifier)
+            )
+        }
+
+        rule.runOnUiThread { focusRequester.requestFocus() }
+        assertThat(focusTargetAndRotaryNode.focusTargetNode.focusState.isFocused).isTrue()
+
+        rule.onNodeWithTag(targetTestTag).performRotaryScrollInput {
+            rotateToScrollVertically(100f)
+        }
+
+        assertThat(focusTargetAndRotaryNode.events).hasSize(1)
+        assertThat(focusTargetAndRotaryNode.events[0].verticalScrollPixels).isEqualTo(100f)
+    }
+
+    /**
+     * Tests that when a node is both a NodeKind.FocusEvent and NodeKind.FocusTarget, the node
+     * receives events on detach.
+     */
+    @Test
+    fun focusEventNodeDelegatingToFocusTarget_invalidatedOnRemoval() {
+        var composeFocusableBox by mutableStateOf(true)
+        val focusTargetNode = FocusTargetNode()
+
+        class FocusEventAndFocusTargetNode : DelegatingNode(), FocusEventModifierNode {
+            val focusStates = mutableListOf<FocusState>()
+            override fun onFocusEvent(focusState: FocusState) {
+                focusStates.add(focusState)
+            }
+            init {
+                delegate(focusTargetNode)
+            }
+        }
+
+        val focusEventAndFocusTargetNode = FocusEventAndFocusTargetNode()
+        val focusEventAndFocusTargetModifier = elementFor(key1 = null, focusEventAndFocusTargetNode)
+
+        val focusRequester = FocusRequester()
+
+        rule.setFocusableContent(extraItemForInitialFocus = false) {
+            if (composeFocusableBox) {
+                Box(
+                    modifier = Modifier
+                        .focusRequester(focusRequester)
+                        .then(focusEventAndFocusTargetModifier)
+                )
+            }
+        }
+
+        assertThat(focusEventAndFocusTargetNode.focusStates).hasSize(1)
+        assertThat(focusEventAndFocusTargetNode.focusStates[0].isFocused).isFalse()
+
+        rule.runOnUiThread { focusRequester.requestFocus() }
+        rule.waitForIdle()
+
+        assertThat(focusEventAndFocusTargetNode.focusStates).hasSize(2)
+        assertThat(focusEventAndFocusTargetNode.focusStates[0].isFocused).isFalse()
+        assertThat(focusEventAndFocusTargetNode.focusStates[1].isFocused).isTrue()
+
+        composeFocusableBox = false
+        rule.waitForIdle()
+
+        assertThat(focusEventAndFocusTargetNode.focusStates).hasSize(3)
+        assertThat(focusEventAndFocusTargetNode.focusStates[0].isFocused).isFalse()
+        assertThat(focusEventAndFocusTargetNode.focusStates[1].isFocused).isTrue()
+        assertThat(focusEventAndFocusTargetNode.focusStates[2].isFocused).isFalse()
+    }
+
+    @Test
+    fun modifierDelegatingToFocusEventAndFocusTarget_invalidatedOnRemoval() {
+        var composeFocusableBox by mutableStateOf(true)
+
+        class MyFocusEventNode : Modifier.Node(), FocusEventModifierNode {
+            val focusStates = mutableListOf<FocusState>()
+            override fun onFocusEvent(focusState: FocusState) {
+                focusStates.add(focusState)
+            }
+        }
+
+        val eventNode = MyFocusEventNode()
+        val focusTargetNode = FocusTargetNode()
+
+        class FocusEventAndFocusTargetNode : DelegatingNode() {
+            init {
+                delegate(focusTargetNode)
+                delegate(eventNode)
+            }
+        }
+
+        val focusEventAndFocusTargetNode = FocusEventAndFocusTargetNode()
+        val focusEventAndFocusTargetModifier = elementFor(key1 = null, focusEventAndFocusTargetNode)
+
+        val focusRequester = FocusRequester()
+
+        rule.setFocusableContent(extraItemForInitialFocus = false) {
+            if (composeFocusableBox) {
+                Box(modifier = Modifier
+                    .focusRequester(focusRequester)
+                    .then(focusEventAndFocusTargetModifier)
+                )
+            }
+        }
+
+        assertThat(eventNode.focusStates).hasSize(1)
+        assertThat(eventNode.focusStates[0].isFocused).isFalse()
+
+        rule.runOnUiThread { focusRequester.requestFocus() }
+        rule.waitForIdle()
+
+        assertThat(eventNode.focusStates).hasSize(2)
+        assertThat(eventNode.focusStates[0].isFocused).isFalse()
+        assertThat(eventNode.focusStates[1].isFocused).isTrue()
+
+        composeFocusableBox = false
+        rule.waitForIdle()
+
+        assertThat(eventNode.focusStates).hasSize(3)
+        assertThat(eventNode.focusStates[0].isFocused).isFalse()
+        assertThat(eventNode.focusStates[1].isFocused).isTrue()
+        assertThat(eventNode.focusStates[2].isFocused).isFalse()
+    }
+
     private inline fun Modifier.thenIf(condition: Boolean, block: () -> Modifier): Modifier {
         return if (condition) then(block()) else this
     }
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/AndroidClipboardManagerTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/AndroidClipboardManagerTest.kt
index 2d1dcff..28f3cfc 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/AndroidClipboardManagerTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/AndroidClipboardManagerTest.kt
@@ -44,7 +44,6 @@
 import org.mockito.kotlin.argumentCaptor
 import org.mockito.kotlin.doReturn
 import org.mockito.kotlin.mock
-import org.mockito.kotlin.never
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
@@ -261,33 +260,6 @@
     }
 
     @Test
-    fun getPrimaryClipDescription_returnsClipDescription() {
-        val clipboardManager = mock<ClipboardManager>()
-        val clipDescription = mock<ClipDescription>()
-        whenever(clipboardManager.primaryClipDescription).thenReturn(clipDescription)
-        val subject = AndroidClipboardManager(clipboardManager)
-
-        assertThat(subject.getClipMetadata()?.clipDescription).isSameInstanceAs(clipDescription)
-        verify(clipboardManager, never()).primaryClip
-    }
-
-    @Test
-    fun hasPrimaryClipEntry_returnsHasClipData() {
-        val clipboardManager = mock<ClipboardManager>()
-        whenever(clipboardManager.hasPrimaryClip()).thenReturn(true)
-        val subject = AndroidClipboardManager(clipboardManager)
-
-        assertThat(subject.hasClip()).isEqualTo(true)
-
-        whenever(clipboardManager.hasPrimaryClip()).thenReturn(false)
-
-        assertThat(subject.hasClip()).isEqualTo(false)
-
-        verify(clipboardManager, never()).primaryClip
-        verify(clipboardManager, never()).primaryClipDescription
-    }
-
-    @Test
     fun setPrimaryClip_callsSetPrimaryClip() {
         val clipboardManager = mock<ClipboardManager>()
         val clipData = mock<ClipData>()
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt
index d12c772..5312b3d 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt
@@ -32,7 +32,6 @@
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
-import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Rect
@@ -205,68 +204,6 @@
     }
 
     @Test
-    @OptIn(ExperimentalComposeUiApi::class)
-    fun unsetSimpleProperty() {
-        rule.setContent {
-            Surface {
-                Box(Modifier
-                    .semantics { unset(SemanticsProperties.Heading) }.semantics { heading() }
-                    .semantics { traversalIndex = 1f; unset(SemanticsProperties.TraversalIndex) }
-                    .testTag(TestTag)
-                ) {
-                    Text("Hello World", modifier = Modifier.padding(8.dp))
-                }
-            }
-        }
-
-        rule.onNodeWithTag(TestTag)
-            .assertDoesNotHaveProperty(SemanticsProperties.Heading)
-        rule.onNodeWithTag(TestTag)
-            .assertDoesNotHaveProperty(SemanticsProperties.TraversalIndex)
-    }
-
-    @Test
-    @OptIn(ExperimentalComposeUiApi::class)
-    fun unsetDuplicateProperty() {
-        rule.setContent {
-            Surface {
-                Box(Modifier
-                    .semantics { unset(SemanticsProperties.TraversalIndex) }
-                    .semantics { traversalIndex = 2f }
-                    .semantics { traversalIndex = 1f }
-                    .testTag(TestTag)
-                ) {
-                    Text("Hello World", modifier = Modifier.padding(8.dp))
-                }
-            }
-        }
-
-        rule.onNodeWithTag(TestTag)
-            .assertDoesNotHaveProperty(SemanticsProperties.TraversalIndex)
-    }
-
-    @Test
-    @OptIn(ExperimentalComposeUiApi::class)
-    fun unsetDuplicatePropertySandwiched() {
-        rule.setContent {
-            Surface {
-                Box(Modifier
-                    .semantics { traversalIndex = 2f }
-                    .semantics { unset(SemanticsProperties.TraversalIndex) }
-                    .semantics { traversalIndex = 1f }
-                    .testTag(TestTag)
-                ) {
-                    Text("Hello World", modifier = Modifier.padding(8.dp))
-                }
-            }
-        }
-
-        rule.onNodeWithTag(TestTag)
-            .assert(SemanticsMatcher.expectValue(
-                SemanticsProperties.TraversalIndex, 2f))
-    }
-
-    @Test
     @Suppress("DEPRECATION")
     fun isContainerPropertyDeprecated() {
         rule.setContent {
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidClipboardManager.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidClipboardManager.android.kt
index f450a04..1dcec61 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidClipboardManager.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidClipboardManager.android.kt
@@ -85,10 +85,6 @@
         return clipboardManager.primaryClip?.let(::ClipEntry)
     }
 
-    override fun getClipMetadata(): ClipMetadata? {
-        return clipboardManager.primaryClipDescription?.let(::ClipMetadata)
-    }
-
     override fun setClip(clipEntry: ClipEntry?) {
         if (clipEntry == null) {
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
@@ -101,8 +97,6 @@
         }
     }
 
-    override fun hasClip(): Boolean = clipboardManager.hasPrimaryClip()
-
     override val nativeClipboard: NativeClipboard
         get() = clipboardManager
 }
@@ -112,7 +106,12 @@
  */
 // Defining this class not as a typealias but a wrapper gives us flexibility in the future to
 // add more functionality in it.
-actual class ClipEntry(val clipData: ClipData)
+actual class ClipEntry(val clipData: ClipData) {
+
+    actual fun getMetadata(): ClipMetadata {
+        return clipData.description.toClipMetadata()
+    }
+}
 
 fun ClipData.toClipEntry(): ClipEntry = ClipEntry(this)
 
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 df549cf..078b92c 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
@@ -724,17 +724,14 @@
     private fun isScreenReaderFocusable(
         node: SemanticsNode
     ): Boolean {
-        // TODO(aelias): This may not behave correctly in combination with fake nodes, see b/283968786
         val nodeContentDescriptionOrNull =
             node.unmergedConfig.getOrNull(SemanticsProperties.ContentDescription)?.firstOrNull()
         val isSpeakingNode = nodeContentDescriptionOrNull != null ||
             getInfoText(node) != null || getInfoStateDescriptionOrNull(node) != null ||
             getInfoIsCheckable(node)
 
-        return node.isVisible &&
-            (node.unmergedConfig.isMergingSemanticsOfDescendants ||
-            node.isUnmergedLeafNode &&
-            isSpeakingNode)
+        return node.unmergedConfig.isMergingSemanticsOfDescendants ||
+            node.isUnmergedLeafNode && isSpeakingNode
     }
 
     @OptIn(ExperimentalComposeUiApi::class)
@@ -776,7 +773,6 @@
 
         // This property exists to distinguish semantically meaningful nodes from purely structural
         // or decorative UI elements.  Most nodes are considered important, except:
-        // * Invisible nodes.
         // * Non-merging nodes with only non-accessibility-speakable properties.
         //     * Of the built-in ones, the key example is testTag.
         //     * Custom SemanticsPropertyKeys defined outside the UI package
@@ -2102,40 +2098,29 @@
             hitSemanticsEntities = hitSemanticsEntities
         )
 
-        // Iterate front-to-back until we find a node with semantics that are important-for-a11y
-        for (i in hitSemanticsEntities.lastIndex downTo 0) {
-            val layoutNode = hitSemanticsEntities[i].requireLayoutNode()
+        val layoutNode = hitSemanticsEntities.lastOrNull()?.requireLayoutNode()
 
-            // If this node corresponds to an AndroidView, then we should return InvalidId
-            // to let the View System handle it.
-            val androidView = view
-                .androidViewsHandler
-                .layoutNodeToHolder[layoutNode]
-            if (androidView != null) {
-                return InvalidId
-            }
-
-            if (layoutNode.nodes.has(Nodes.Semantics) == false) {
-                continue
-            }
-
-            val virtualViewId = semanticsNodeIdToAccessibilityVirtualNodeId(
-                layoutNode.semanticsId
-            )
+        var virtualViewId = InvalidId
+        if (layoutNode?.nodes?.has(Nodes.Semantics) == true) {
 
             // The node below is not added to the tree; it's a wrapper around outer semantics to
             // use the methods available to the SemanticsNode
             val semanticsNode = SemanticsNode(layoutNode, false)
 
-            // Continue to the next items in the hit test if it's not considered important.
-            if (!semanticsNode.isImportantForAccessibility()) {
-                continue
+            // Do not 'find' invisible nodes when exploring by touch. This will prevent us from
+            // sending events for invisible nodes
+            if (semanticsNode.isVisible) {
+                val androidView = view
+                    .androidViewsHandler
+                    .layoutNodeToHolder[layoutNode]
+                if (androidView == null) {
+                    virtualViewId = semanticsNodeIdToAccessibilityVirtualNodeId(
+                        layoutNode.semanticsId
+                    )
+                }
             }
-
-            return virtualViewId
         }
-
-        return InvalidId
+        return virtualViewId
     }
 
     /**
@@ -3221,6 +3206,10 @@
 // shorter and more readable.
 private fun SemanticsNode.enabled() = (!config.contains(SemanticsProperties.Disabled))
 
+@OptIn(ExperimentalComposeUiApi::class)
+private val SemanticsNode.isVisible: Boolean
+    get() = !isTransparent && !unmergedConfig.contains(SemanticsProperties.InvisibleToUser)
+
 private fun SemanticsNode.propertiesDeleted(oldConfig: SemanticsConfiguration): Boolean {
     for (entry in oldConfig) {
         if (!config.contains(entry.key)) {
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ClipboardExtensions.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ClipboardExtensions.android.kt
index 32ec68d..2dd16b8 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ClipboardExtensions.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ClipboardExtensions.android.kt
@@ -23,9 +23,11 @@
 /**
  * Returns the first non-null [Uri] from the list of [ClipData.Item]s in this [ClipEntry].
  *
- * Do not forget that each [ClipEntry] can contain multiple [ClipData.Item]s in its [ClipData],
- * therefore it can have multiple [Uri]s. Always check whether you are processing all the items in
- * a given [ClipEntry].
+ * ClipEntry can contain single or multiple [ClipData.Item]s. This function is useful when you are
+ * only interested in processing just a single [Uri] item inside the [ClipEntry].
+ *
+ * It's advised that you consider checking all the items inside [ClipEntry.clipData] to thoroughly
+ * process a given [ClipEntry].
  */
 @ExperimentalComposeUiApi
 fun ClipEntry.firstUriOrNull(): Uri? {
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/SemanticsUtils.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/SemanticsUtils.android.kt
index 314fa5c..9e94664 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/SemanticsUtils.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/SemanticsUtils.android.kt
@@ -23,7 +23,6 @@
 import androidx.collection.MutableIntSet
 import androidx.collection.mutableIntObjectMapOf
 import androidx.collection.mutableIntSetOf
-import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.node.LayoutNode
 import androidx.compose.ui.node.OwnerScope
@@ -33,7 +32,6 @@
 import androidx.compose.ui.semantics.SemanticsConfiguration
 import androidx.compose.ui.semantics.SemanticsNode
 import androidx.compose.ui.semantics.SemanticsOwner
-import androidx.compose.ui.semantics.SemanticsProperties
 import androidx.compose.ui.semantics.getOrNull
 import androidx.compose.ui.text.TextLayoutResult
 import androidx.compose.ui.util.fastForEach
@@ -119,13 +117,8 @@
     }
 
 internal fun SemanticsNode.isImportantForAccessibility() =
-    isVisible &&
-        (unmergedConfig.isMergingSemanticsOfDescendants ||
-            unmergedConfig.containsImportantForAccessibility())
-
-@OptIn(ExperimentalComposeUiApi::class)
-internal val SemanticsNode.isVisible: Boolean
-    get() = !isTransparent && !unmergedConfig.contains(SemanticsProperties.InvisibleToUser)
+    unmergedConfig.isMergingSemanticsOfDescendants ||
+        unmergedConfig.containsImportantForAccessibility()
 
 internal val DefaultFakeNodeBounds = Rect(0f, 0f, 10f, 10f)
 
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/scrollcapture/ComposeScrollCaptureCallback.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/scrollcapture/ComposeScrollCaptureCallback.android.kt
index f7e23b3..3f05d03 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/scrollcapture/ComposeScrollCaptureCallback.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/scrollcapture/ComposeScrollCaptureCallback.android.kt
@@ -37,14 +37,13 @@
 import androidx.compose.ui.semantics.SemanticsNode
 import androidx.compose.ui.unit.IntRect
 import java.util.function.Consumer
-import kotlin.coroutines.CoroutineContext
-import kotlin.coroutines.EmptyCoroutineContext
 import kotlin.math.roundToInt
 import kotlin.random.Random
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.NonCancellable
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.plus
 
 private const val DEBUG = false
 
@@ -60,8 +59,11 @@
 internal class ComposeScrollCaptureCallback(
     private val node: SemanticsNode,
     private val viewportBoundsInWindow: IntRect,
-    private val coroutineScope: CoroutineScope,
+    coroutineScope: CoroutineScope,
 ) : ScrollCaptureCallback {
+    // Don't animate scrollByOffset calls.
+    private val coroutineScope = coroutineScope + DisableAnimationMotionDurationScale
+
     private val scrollTracker = RelativeScroller(
         viewportSize = viewportBoundsInWindow.height,
         scrollBy = { amount ->
@@ -94,11 +96,7 @@
         captureArea: AndroidRect,
         onComplete: Consumer<AndroidRect>
     ) {
-        coroutineScope.launchWithCancellationSignal(
-            signal = signal,
-            // Don't animate scrollByOffset calls.
-            context = DisableAnimationMotionDurationScale
-        ) {
+        coroutineScope.launchWithCancellationSignal(signal) {
             val result = onScrollCaptureImageRequest(session, captureArea.toComposeIntRect())
             onComplete.accept(result.toAndroidRect())
         }
@@ -206,10 +204,9 @@
 
 private fun CoroutineScope.launchWithCancellationSignal(
     signal: CancellationSignal,
-    context: CoroutineContext = EmptyCoroutineContext,
     block: suspend CoroutineScope.() -> Unit
 ): Job {
-    val job = launch(context = context, block = block)
+    val job = launch(block = block)
     job.invokeOnCompletion { cause ->
         if (cause != null) {
             signal.cancel()
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/scrollcapture/ScrollCapture.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/scrollcapture/ScrollCapture.android.kt
index f4ba501..81e18e2 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/scrollcapture/ScrollCapture.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/scrollcapture/ScrollCapture.android.kt
@@ -26,15 +26,16 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
+import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.graphics.toAndroidRect
 import androidx.compose.ui.internal.checkPreconditionNotNull
 import androidx.compose.ui.layout.LayoutCoordinates
 import androidx.compose.ui.layout.boundsInRoot
 import androidx.compose.ui.layout.boundsInWindow
-import androidx.compose.ui.platform.isVisible
 import androidx.compose.ui.semantics.SemanticsActions.ScrollByOffset
 import androidx.compose.ui.semantics.SemanticsNode
 import androidx.compose.ui.semantics.SemanticsOwner
+import androidx.compose.ui.semantics.SemanticsProperties
 import androidx.compose.ui.semantics.SemanticsProperties.Disabled
 import androidx.compose.ui.semantics.SemanticsProperties.VerticalScrollAxisRange
 import androidx.compose.ui.semantics.getOrNull
@@ -182,6 +183,11 @@
 
 internal val SemanticsNode.scrollCaptureScrollByAction get() = config.getOrNull(ScrollByOffset)
 
+// TODO(mnuzen): Port this back to the SemanticsUtil file
+@OptIn(ExperimentalComposeUiApi::class)
+private val SemanticsNode.isVisible: Boolean
+    get() = !isTransparent && !unmergedConfig.contains(SemanticsProperties.InvisibleToUser)
+
 private val SemanticsNode.canScrollVertically: Boolean
     get() {
         val scrollByOffset = scrollCaptureScrollByAction
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/platform/ClipboardManagerTest.kt b/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/platform/ClipboardManagerTest.kt
index 734d0d2..35fd899 100644
--- a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/platform/ClipboardManagerTest.kt
+++ b/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/platform/ClipboardManagerTest.kt
@@ -53,9 +53,5 @@
 
     override fun getClip(): ClipEntry? = null
 
-    override fun getClipMetadata(): ClipMetadata? = null
-
-    override fun hasClip(): Boolean = false
-
     override fun setClip(clipEntry: ClipEntry?) = Unit
 }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusOwnerImpl.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusOwnerImpl.kt
index c78b8ef..257922e 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusOwnerImpl.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusOwnerImpl.kt
@@ -42,6 +42,7 @@
 import androidx.compose.ui.node.ancestors
 import androidx.compose.ui.node.dispatchForKind
 import androidx.compose.ui.node.nearestAncestor
+import androidx.compose.ui.node.visitAncestors
 import androidx.compose.ui.node.visitLocalDescendants
 import androidx.compose.ui.platform.InspectorInfo
 import androidx.compose.ui.unit.LayoutDirection
@@ -266,10 +267,10 @@
 
         val activeFocusTarget = rootFocusNode.findActiveFocusNode()
         val focusedKeyInputNode = activeFocusTarget?.lastLocalKeyInputNode()
-            ?: activeFocusTarget?.nearestAncestor(Nodes.KeyInput)?.node
+            ?: activeFocusTarget?.nearestAncestorIncludingSelf(Nodes.KeyInput)?.node
             ?: rootFocusNode.nearestAncestor(Nodes.KeyInput)?.node
 
-        focusedKeyInputNode?.traverseAncestors(
+        focusedKeyInputNode?.traverseAncestorsIncludingSelf(
             type = Nodes.KeyInput,
             onPreVisit = { if (it.onPreKeyEvent(keyEvent)) return true },
             onVisit = { if (onFocusedItem.invoke()) return true },
@@ -285,9 +286,9 @@
         }
 
         val focusedSoftKeyboardInterceptionNode = rootFocusNode.findActiveFocusNode()
-            ?.nearestAncestor(Nodes.SoftKeyboardKeyInput)
+            ?.nearestAncestorIncludingSelf(Nodes.SoftKeyboardKeyInput)
 
-        focusedSoftKeyboardInterceptionNode?.traverseAncestors(
+        focusedSoftKeyboardInterceptionNode?.traverseAncestorsIncludingSelf(
             type = Nodes.SoftKeyboardKeyInput,
             onPreVisit = { if (it.onPreInterceptKeyBeforeSoftKeyboard(keyEvent)) return true },
             onVisit = { /* TODO(b/320510084): dispatch soft keyboard events to embedded views. */ },
@@ -305,9 +306,9 @@
         }
 
         val focusedRotaryInputNode = rootFocusNode.findActiveFocusNode()
-            ?.nearestAncestor(Nodes.RotaryInput)
+            ?.nearestAncestorIncludingSelf(Nodes.RotaryInput)
 
-        focusedRotaryInputNode?.traverseAncestors(
+        focusedRotaryInputNode?.traverseAncestorsIncludingSelf(
             type = Nodes.RotaryInput,
             onPreVisit = { if (it.onPreRotaryScrollEvent(event)) return true },
             onVisit = { /* TODO(b/320510084): dispatch rotary events to embedded views. */ },
@@ -341,7 +342,7 @@
         }
     }
 
-    private inline fun <reified T : DelegatableNode> DelegatableNode.traverseAncestors(
+    private inline fun <reified T : DelegatableNode> DelegatableNode.traverseAncestorsIncludingSelf(
         type: NodeKind<T>,
         onPreVisit: (T) -> Unit,
         onVisit: () -> Unit,
@@ -355,6 +356,15 @@
         ancestors?.fastForEach(onPostVisit)
     }
 
+    private inline fun <reified T : Any> DelegatableNode.nearestAncestorIncludingSelf(
+        type: NodeKind<T>
+    ): T? {
+        visitAncestors(type, includeSelf = true) {
+            return it
+        }
+        return null
+    }
+
     /**
      * Searches for the currently focused item, and returns its coordinates as a rect.
      */
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusTargetNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusTargetNode.kt
index d58b427..d4f1682 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusTargetNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusTargetNode.kt
@@ -212,7 +212,13 @@
             mask = Nodes.FocusEvent or Nodes.FocusTarget,
             includeSelf = true
         ) {
-            if (it.isKind(Nodes.FocusTarget)) return@visitAncestors
+            // We want invalidation to propagate until the next focus target in the hierarchy, but
+            // if the current node is both a FocusEvent and FocusTarget node, we still want to
+            // visit this node and invalidate the focus event nodes. This case is not recommended,
+            // using the state from the FocusTarget node directly is preferred to the indirection of
+            // listening to events from the state you already own, but we should support this case
+            // anyway to be safe.
+            if (it !== this.node && it.isKind(Nodes.FocusTarget)) return@visitAncestors
 
             if (it.isAttached) {
                 it.dispatchForKind(Nodes.FocusEvent) { eventNode ->
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/ClipboardManager.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/ClipboardManager.kt
index c96125f..56b5817 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/ClipboardManager.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/ClipboardManager.kt
@@ -50,21 +50,12 @@
      * This item can include arbitrary content like images, videos, or any data that may be provided
      * through a mediator. Returned entry may contain multiple items with different types.
      *
-     * Calling this method may show a Clipboard access warning message to the user on mobile
-     * platforms since it usually accesses the Clipboard contents.
+     * It's safe to call this function without triggering Clipboard access warnings on mobile
+     * platforms.
      */
     fun getClip(): ClipEntry? = null
 
     /**
-     * Returns a [ClipMetadata] which describes the existing clip entry. This is an ideal way to
-     * check whether to accept or reject what may be pasted from the clipboard without explicitly
-     * reading the content.
-     *
-     * Calling this function does not trigger any content access warnings on any platform.
-     */
-    fun getClipMetadata(): ClipMetadata? = null
-
-    /**
      * Puts the given [clipEntry] in platform's ClipboardManager.
      *
      * @param clipEntry Platform specific clip object that either holds data or links to it. Pass
@@ -74,13 +65,6 @@
     fun setClip(clipEntry: ClipEntry?) = Unit
 
     /**
-     * Returns true if there is currently a clip entry on the platform Clipboard. Even though
-     * [getClip] should be available immediately if this function returns true, [getClipMetadata]
-     * may still return null if the platform doesn't support clip descriptions.
-     */
-    fun hasClip(): Boolean = false
-
-    /**
      * Returns the native clipboard that exposes the full functionality of platform clipboard.
      *
      * @throws UnsupportedOperationException If the current platform does not offer a native
@@ -95,7 +79,17 @@
 /**
  * Platform specific protocol that expresses an item in the native Clipboard.
  */
-expect class ClipEntry
+expect class ClipEntry {
+
+    /**
+     * Returns a [ClipMetadata] which describes the contents of this [ClipEntry]. This is an ideal
+     * way to check whether to accept or reject what may be pasted from the clipboard without
+     * explicitly reading the content.
+     *
+     * Calling this function does not trigger any content access warnings on any platform.
+     */
+    fun getMetadata(): ClipMetadata
+}
 
 /**
  * Platform specific protocol that describes an item in the native Clipboard. This object should
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsConfiguration.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsConfiguration.kt
index 5ebaf46..000dd66 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsConfiguration.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsConfiguration.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.ui.semantics
 
-import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.platform.simpleIdentityToString
 
 /**
@@ -71,11 +70,6 @@
         }
     }
 
-    @ExperimentalComposeUiApi
-    override fun <T> unset(key: SemanticsPropertyKey<T>) {
-       props.remove(key)
-    }
-
     operator fun <T> contains(key: SemanticsPropertyKey<T>): Boolean {
         return props.containsKey(key)
     }
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 f1938fe..eae2518 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
@@ -99,24 +99,16 @@
     /**
      * @see SemanticsPropertyReceiver.isContainer
      */
-    @Deprecated("Use `isTraversalGroup` and `isOpaque` instead.")
+    @Deprecated("Use `isTraversalGroup` instead.",
+        replaceWith = ReplaceWith("IsTraversalGroup"),
+    )
     val IsContainer: SemanticsPropertyKey<Boolean>
         get() = IsTraversalGroup
 
     /**
      * @see SemanticsPropertyReceiver.isTraversalGroup
      */
-    val IsTraversalGroup = SemanticsPropertyKey<Boolean>("IsTraversalGroup")
-
-    /**
-     * @see SemanticsPropertyReceiver.isOpaque
-     */
-    val IsOpaque = AccessibilityKey<Unit>(
-        name = "IsOpaque",
-        mergePolicy = { parentValue, _ ->
-            parentValue
-        }
-    )
+    val IsTraversalGroup = AccessibilityKey<Boolean>("IsTraversalGroup")
 
     /**
      * @see SemanticsPropertyReceiver.invisibleToUser
@@ -132,7 +124,7 @@
     /**
      * @see SemanticsPropertyReceiver.traversalIndex
      */
-    val TraversalIndex = SemanticsPropertyKey<Float>(
+    val TraversalIndex = AccessibilityKey<Float>(
         name = "TraversalIndex",
         mergePolicy = { parentValue, _ ->
             // Never merge traversal indices
@@ -829,43 +821,6 @@
  */
 interface SemanticsPropertyReceiver {
     operator fun <T> set(key: SemanticsPropertyKey<T>, value: T)
-
-    /**
-     * Unset an individual property.
-     *
-     * Note: this can only unset properties originally on the same modifier chain, not properties
-     * merged from children (for those, use [clearAndSetSemantics] instead). And because the
-     * semantics system processes modifier chains back-to-front, the unset must be ordered earlier
-     * on the modifier chain if it's in a separate `semantics {}` block.
-
-     * 1. Examples of correct uses (resulting in empty semantics):
-     *
-     *   ```
-     *   Modifier.semantics { heading(); unset(SemanticsProperties.Heading) }
-     *   Modifier.semantics { unset(SemanticsProperties.Heading) }.semantics { heading() }
-     *   ```
-     *
-     * 2. Examples of ineffective, no-op uses (where the heading remains instead of being unset):
-     *
-     *   ```
-     *   Modifier.semantics { unset(SemanticsProperties.Heading); heading() } // order
-     *   Modifier.semantics { heading() }.semantics { unset(SemanticsProperties.Heading) } // order
-     *   Box(Modifier.semantics(mergeDescendants = true) { unset(SemanticsProperties.Heading) }) {
-     *       Box(Modifier.semantics { heading() }) // not originally on the same modifier chain`
-     *   }
-     *
-     * 3. Examples of complex cases where there is more than one set:
-     *
-     *   ```
-     *   // Result is empty semantics:
-     *   Modifier.semantics { unset(SemanticsProperties.TestTag) }.testTag("b").testTag("a")
-     *
-     *   // Result is testTag = "b":`
-     *   Modifier.testTag("b").semantics { unset(SemanticsProperties.TestTag) }.testTag("a")
-     *   ```
-     */
-    @ExperimentalComposeUiApi
-    fun <T> unset(key: SemanticsPropertyKey<T>)
 }
 
 /**
@@ -958,46 +913,20 @@
  *
  * @see SemanticsProperties.IsContainer
  */
-@Deprecated("Use `isTraversalGroup` and `isOpaque` instead.")
-@get:Deprecated("Use `isTraversalGroup` and `isOpaque` instead.")
-@set:Deprecated("Use `isTraversalGroup` and `isOpaque` instead.")
-@OptIn(ExperimentalComposeUiApi::class)
-var SemanticsPropertyReceiver.isContainer: Boolean
-    get() = throwSemanticsGetNotSupported()
-    set(bool) {
-        isTraversalGroup = bool
-        if (bool) {
-            this[SemanticsProperties.IsOpaque] = Unit
-        } else {
-            unset(SemanticsProperties.IsOpaque)
-        }
-    }
+@Deprecated("Use `isTraversalGroup` instead.",
+    replaceWith = ReplaceWith("isTraversalGroup"),
+)
+var SemanticsPropertyReceiver.isContainer by SemanticsProperties.IsTraversalGroup
 
 /**
- * Whether this semantics node is a traversal group.
- *
- * See https://developer.android.com/jetpack/compose/accessibility#modify-traversal-order
+ * Whether this semantics node is a traversal group. This is defined as a node whose function
+ * is to serve as a boundary or border in organizing its children.
  *
  * @see SemanticsProperties.IsTraversalGroup
  */
 var SemanticsPropertyReceiver.isTraversalGroup by SemanticsProperties.IsTraversalGroup
 
 /**
- * Non-mergeable property used to mark that whether a node is semantically opaque.
- *
- * In other words, whether nodes fully covered by it ought to be pruned from the a11y tree.  (Note
- * that most semantic properties other than testTag also have this effect, so it should be rarely
- * needed.)
- *
- * If true, then a11y nodes behind will be pruned unless this node's graphics alpha is 0.
- *
- * @see SemanticsProperties.IsOpaque
- */
-fun SemanticsPropertyReceiver.isOpaque() {
-    this[SemanticsProperties.IsOpaque] = Unit
-}
-
-/**
  * Whether this node is specially known to be invisible to the user.
  *
  * For example, if the node is currently occluded by a dark semitransparent
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/PlatformClipboardManager.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/PlatformClipboardManager.desktop.kt
index 30b1ee6..5d3abb7 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/PlatformClipboardManager.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/PlatformClipboardManager.desktop.kt
@@ -54,27 +54,11 @@
         }
     }
 
-    override fun getClipMetadata(): ClipMetadata? {
-        return try {
-            systemClipboard?.getContents(this)?.let(::ClipMetadata)
-        } catch (_: IllegalStateException) {
-            null
-        }
-    }
-
     override fun setClip(clipEntry: ClipEntry?) {
         // Ignore clipDescription.
         systemClipboard?.setContents(clipEntry?.transferable, null)
     }
 
-    override fun hasClip(): Boolean {
-        return try {
-            systemClipboard?.availableDataFlavors?.isNotEmpty() ?: false
-        } catch (_: IllegalStateException) {
-            false
-        }
-    }
-
     /**
      * Returns the system clipboard.
      *
@@ -95,6 +79,10 @@
     fun getTransferData(flavor: DataFlavor): Any? {
         return transferable.getTransferData(flavor)
     }
+
+    actual fun getMetadata(): ClipMetadata {
+        return ClipMetadata(transferable)
+    }
 }
 
 // Defining this class not as a typealias but a wrapper gives us flexibility in the future to
diff --git a/core/core-remoteviews/api/1.1.0-beta01.txt b/core/core-remoteviews/api/1.1.0-beta01.txt
new file mode 100644
index 0000000..8bd3b49
--- /dev/null
+++ b/core/core-remoteviews/api/1.1.0-beta01.txt
@@ -0,0 +1,294 @@
+// Signature format: 4.0
+package androidx.core.widget {
+
+  public final class AppWidgetManagerCompat {
+    method public static android.widget.RemoteViews createExactSizeAppWidget(android.appwidget.AppWidgetManager appWidgetManager, int appWidgetId, kotlin.jvm.functions.Function1<? super androidx.core.util.SizeFCompat,? extends android.widget.RemoteViews> factory);
+    method public static android.widget.RemoteViews createResponsiveSizeAppWidget(android.appwidget.AppWidgetManager appWidgetManager, int appWidgetId, java.util.Collection<androidx.core.util.SizeFCompat> dpSizes, kotlin.jvm.functions.Function1<? super androidx.core.util.SizeFCompat,? extends android.widget.RemoteViews> factory);
+    method public static void updateAppWidget(android.appwidget.AppWidgetManager, int appWidgetId, java.util.Collection<androidx.core.util.SizeFCompat> dpSizes, kotlin.jvm.functions.Function1<? super androidx.core.util.SizeFCompat,? extends android.widget.RemoteViews> factory);
+    method public static void updateAppWidget(android.appwidget.AppWidgetManager, int appWidgetId, kotlin.jvm.functions.Function1<? super androidx.core.util.SizeFCompat,? extends android.widget.RemoteViews> factory);
+  }
+
+  public final class RemoteViewsCompat {
+    method public static void setChronometerBase(android.widget.RemoteViews, @IdRes int viewId, long base);
+    method public static void setChronometerFormat(android.widget.RemoteViews, @IdRes int viewId, String? format);
+    method @RequiresApi(31) public static void setCompoundButtonDrawable(android.widget.RemoteViews, @IdRes int viewId, @DrawableRes int resId);
+    method @RequiresApi(31) public static void setCompoundButtonIcon(android.widget.RemoteViews, @IdRes int viewId, android.graphics.drawable.Icon? icon);
+    method @RequiresApi(31) public static void setCompoundButtonTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? tintMode);
+    method @RequiresApi(31) public static void setCompoundButtonTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setCompoundButtonTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNight, android.content.res.ColorStateList? night);
+    method @RequiresApi(31) public static void setCompoundButtonTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setCompoundButtonTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setFrameLayoutForegroundGravity(android.widget.RemoteViews, @IdRes int viewId, int foregroundGravity);
+    method public static void setFrameLayoutMeasureAllChildren(android.widget.RemoteViews, @IdRes int viewId, boolean measureAll);
+    method @RequiresApi(31) public static void setGridLayoutAlignmentMode(android.widget.RemoteViews, @IdRes int viewId, int alignmentMode);
+    method @RequiresApi(31) public static void setGridLayoutColumnCount(android.widget.RemoteViews, @IdRes int viewId, int columnCount);
+    method @RequiresApi(31) public static void setGridLayoutRowCount(android.widget.RemoteViews, @IdRes int viewId, int rowCount);
+    method @RequiresApi(31) public static void setGridViewColumnWidth(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setGridViewColumnWidthDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int columnWidth);
+    method @RequiresApi(31) public static void setGridViewColumnWidthDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int columnWidth);
+    method @RequiresApi(31) public static void setGridViewGravity(android.widget.RemoteViews, @IdRes int viewId, int gravity);
+    method @RequiresApi(31) public static void setGridViewHorizontalSpacing(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setGridViewHorizontalSpacingDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setGridViewHorizontalSpacingDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setGridViewNumColumns(android.widget.RemoteViews, @IdRes int viewId, int numColumns);
+    method @RequiresApi(31) public static void setGridViewStretchMode(android.widget.RemoteViews, @IdRes int viewId, int stretchMode);
+    method @RequiresApi(31) public static void setGridViewVerticalSpacing(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setGridViewVerticalSpacingDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setGridViewVerticalSpacingDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setImageViewAdjustViewBounds(android.widget.RemoteViews, @IdRes int viewId, boolean adjustViewBounds);
+    method public static void setImageViewColorFilter(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int color);
+    method @RequiresApi(31) public static void setImageViewColorFilter(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int notNight, @ColorInt int night);
+    method @RequiresApi(31) public static void setImageViewColorFilterAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setImageViewColorFilterResource(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method public static void setImageViewImageAlpha(android.widget.RemoteViews, @IdRes int viewId, int alpha);
+    method public static void setImageViewImageLevel(android.widget.RemoteViews, @IdRes int viewId, int level);
+    method @RequiresApi(31) public static void setImageViewImageTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setImageViewImageTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setImageViewImageTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNightTint, android.content.res.ColorStateList? nightTint);
+    method @RequiresApi(31) public static void setImageViewImageTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setImageViewImageTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setImageViewMaxHeight(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setImageViewMaxHeight(android.widget.RemoteViews, @IdRes int viewId, @Px int maxHeight);
+    method @RequiresApi(31) public static void setImageViewMaxHeightDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setImageViewMaxHeightDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setImageViewMaxWidth(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setImageViewMaxWidth(android.widget.RemoteViews, @IdRes int viewId, @Px int maxWidth);
+    method @RequiresApi(31) public static void setImageViewMaxWidthDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setImageViewMaxWidthDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setLinearLayoutBaselineAligned(android.widget.RemoteViews, @IdRes int viewId, boolean baselineAligned);
+    method public static void setLinearLayoutBaselineAlignedChildIndex(android.widget.RemoteViews, @IdRes int viewId, int i);
+    method public static void setLinearLayoutGravity(android.widget.RemoteViews, @IdRes int viewId, int gravity);
+    method public static void setLinearLayoutHorizontalGravity(android.widget.RemoteViews, @IdRes int viewId, int horizontalGravity);
+    method public static void setLinearLayoutMeasureWithLargestChildEnabled(android.widget.RemoteViews, @IdRes int viewId, boolean enabled);
+    method public static void setLinearLayoutVerticalGravity(android.widget.RemoteViews, @IdRes int viewId, int verticalGravity);
+    method public static void setLinearLayoutWeightSum(android.widget.RemoteViews, @IdRes int viewId, float weightSum);
+    method public static void setProgressBarIndeterminate(android.widget.RemoteViews, @IdRes int viewId, boolean indeterminate);
+    method @RequiresApi(31) public static void setProgressBarIndeterminateTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setProgressBarIndeterminateTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setProgressBarIndeterminateTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNightTint, android.content.res.ColorStateList? nightTint);
+    method @RequiresApi(31) public static void setProgressBarIndeterminateTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setProgressBarIndeterminateTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setProgressBarMax(android.widget.RemoteViews, @IdRes int viewId, int max);
+    method @RequiresApi(26) public static void setProgressBarMin(android.widget.RemoteViews, @IdRes int viewId, int min);
+    method public static void setProgressBarProgress(android.widget.RemoteViews, @IdRes int viewId, int progress);
+    method @RequiresApi(31) public static void setProgressBarProgressBackgroundTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setProgressBarProgressBackgroundTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setProgressBarProgressBackgroundTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNightTint, android.content.res.ColorStateList? nightTint);
+    method @RequiresApi(31) public static void setProgressBarProgressBackgroundTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setProgressBarProgressBackgroundTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setProgressBarProgressTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setProgressBarProgressTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setProgressBarProgressTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNightTint, android.content.res.ColorStateList? nightTint);
+    method @RequiresApi(31) public static void setProgressBarProgressTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setProgressBarProgressTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setProgressBarSecondaryProgress(android.widget.RemoteViews, @IdRes int viewId, int secondaryProgress);
+    method @RequiresApi(31) public static void setProgressBarSecondaryProgressTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setProgressBarSecondaryProgressTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setProgressBarSecondaryProgressTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNightTint, android.content.res.ColorStateList? nightTint);
+    method @RequiresApi(31) public static void setProgressBarSecondaryProgressTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setProgressBarSecondaryProgressTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setProgressBarStateDescription(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method @RequiresApi(31) public static void setProgressBarStateDescription(android.widget.RemoteViews, @IdRes int viewId, CharSequence? stateDescription);
+    method @RequiresApi(31) public static void setProgressBarStateDescriptionAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setRelativeLayoutGravity(android.widget.RemoteViews, @IdRes int viewId, int gravity);
+    method public static void setRelativeLayoutHorizontalGravity(android.widget.RemoteViews, @IdRes int viewId, int horizontalGravity);
+    method public static void setRelativeLayoutIgnoreGravity(android.widget.RemoteViews, @IdRes int viewId, @IdRes int childViewId);
+    method public static void setRelativeLayoutVerticalGravity(android.widget.RemoteViews, @IdRes int viewId, int verticalGravity);
+    method public static void setRemoteAdapter(android.content.Context context, android.widget.RemoteViews remoteViews, int appWidgetId, @IdRes int viewId, androidx.core.widget.RemoteViewsCompat.RemoteCollectionItems items);
+    method @RequiresApi(31) public static void setSwitchMinWidth(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setSwitchMinWidthDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setSwitchMinWidthDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setSwitchPadding(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setSwitchPaddingDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setSwitchPaddingDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setSwitchShowText(android.widget.RemoteViews, @IdRes int viewId, boolean showText);
+    method @RequiresApi(31) public static void setSwitchSplitTrack(android.widget.RemoteViews, @IdRes int viewId, boolean splitTrack);
+    method @RequiresApi(31) public static void setSwitchTextOff(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method @RequiresApi(31) public static void setSwitchTextOff(android.widget.RemoteViews, @IdRes int viewId, CharSequence? textOff);
+    method @RequiresApi(31) public static void setSwitchTextOffAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setSwitchTextOn(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method @RequiresApi(31) public static void setSwitchTextOn(android.widget.RemoteViews, @IdRes int viewId, CharSequence? textOn);
+    method @RequiresApi(31) public static void setSwitchTextOnAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setSwitchThumbIcon(android.widget.RemoteViews, @IdRes int viewId, android.graphics.drawable.Icon? icon);
+    method @RequiresApi(31) public static void setSwitchThumbIcon(android.widget.RemoteViews, @IdRes int viewId, android.graphics.drawable.Icon? notNight, android.graphics.drawable.Icon? night);
+    method @RequiresApi(31) public static void setSwitchThumbResource(android.widget.RemoteViews, @IdRes int viewId, @DrawableRes int resId);
+    method @RequiresApi(31) public static void setSwitchThumbTextPadding(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setSwitchThumbTextPaddingDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setSwitchThumbTextPaddingDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setSwitchThumbTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setSwitchThumbTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setSwitchThumbTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNight, android.content.res.ColorStateList? night);
+    method @RequiresApi(31) public static void setSwitchThumbTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setSwitchThumbTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setSwitchTrackIcon(android.widget.RemoteViews, @IdRes int viewId, android.graphics.drawable.Icon? icon);
+    method @RequiresApi(31) public static void setSwitchTrackIcon(android.widget.RemoteViews, @IdRes int viewId, android.graphics.drawable.Icon? notNight, android.graphics.drawable.Icon? night);
+    method @RequiresApi(31) public static void setSwitchTrackResource(android.widget.RemoteViews, @IdRes int viewId, @DrawableRes int resId);
+    method @RequiresApi(31) public static void setSwitchTrackTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setSwitchTrackTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setSwitchTrackTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNight, android.content.res.ColorStateList? night);
+    method @RequiresApi(31) public static void setSwitchTrackTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setSwitchTrackTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setTextClockFormat12Hour(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method public static void setTextClockFormat12Hour(android.widget.RemoteViews, @IdRes int viewId, CharSequence? format);
+    method @RequiresApi(31) public static void setTextClockFormat12HourAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setTextClockFormat24Hour(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method public static void setTextClockFormat24Hour(android.widget.RemoteViews, @IdRes int viewId, CharSequence? format);
+    method @RequiresApi(31) public static void setTextClockFormat24HourAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextClockTimeZone(android.widget.RemoteViews, @IdRes int viewId, String? timeZone);
+    method @RequiresApi(31) public static void setTextViewAllCaps(android.widget.RemoteViews, @IdRes int viewId, boolean allCaps);
+    method public static void setTextViewAutoLinkMask(android.widget.RemoteViews, @IdRes int viewId, int mask);
+    method @RequiresApi(31) public static void setTextViewCompoundDrawablePadding(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setTextViewCompoundDrawablePadding(android.widget.RemoteViews, @IdRes int viewId, @Px int pad);
+    method @RequiresApi(31) public static void setTextViewCompoundDrawablePaddingDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewCompoundDrawablePaddingDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextViewEms(android.widget.RemoteViews, @IdRes int viewId, int ems);
+    method @RequiresApi(31) public static void setTextViewError(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method public static void setTextViewError(android.widget.RemoteViews, @IdRes int viewId, CharSequence? error);
+    method @RequiresApi(31) public static void setTextViewErrorAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(21) public static void setTextViewFontFeatureSettings(android.widget.RemoteViews, @IdRes int viewId, String fontFeatureSettings);
+    method @RequiresApi(31) public static void setTextViewGravity(android.widget.RemoteViews, @IdRes int viewId, int gravity);
+    method @RequiresApi(31) public static void setTextViewHeight(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setTextViewHeight(android.widget.RemoteViews, @IdRes int viewId, @Px int pixels);
+    method @RequiresApi(31) public static void setTextViewHeightDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewHeightDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextViewHighlightColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int color);
+    method @RequiresApi(31) public static void setTextViewHighlightColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int notNight, @ColorInt int night);
+    method @RequiresApi(31) public static void setTextViewHighlightColorAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setTextViewHighlightColorResource(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method public static void setTextViewHint(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method public static void setTextViewHint(android.widget.RemoteViews, @IdRes int viewId, CharSequence? hint);
+    method @RequiresApi(31) public static void setTextViewHintAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextViewHintTextColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int color);
+    method @RequiresApi(31) public static void setTextViewHintTextColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int notNight, @ColorInt int night);
+    method @RequiresApi(31) public static void setTextViewHintTextColorAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setTextViewHintTextColorResource(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setTextViewJustificationMode(android.widget.RemoteViews, @IdRes int viewId, int justificationMode);
+    method @RequiresApi(21) public static void setTextViewLetterSpacing(android.widget.RemoteViews, @IdRes int viewId, float letterSpacing);
+    method @RequiresApi(31) public static void setTextViewLineHeight(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setTextViewLineHeightDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewLineHeightDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextViewLines(android.widget.RemoteViews, @IdRes int viewId, int lines);
+    method public static void setTextViewLinkTextColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int color);
+    method @RequiresApi(31) public static void setTextViewLinkTextColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int notNight, @ColorInt int night);
+    method @RequiresApi(31) public static void setTextViewLinkTextColorAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setTextViewLinkTextColorResource(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method public static void setTextViewLinksClickable(android.widget.RemoteViews, @IdRes int viewId, boolean whether);
+    method public static void setTextViewMaxEms(android.widget.RemoteViews, @IdRes int viewId, int maxems);
+    method @RequiresApi(31) public static void setTextViewMaxHeight(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setTextViewMaxHeight(android.widget.RemoteViews, @IdRes int viewId, @Px int maxHeight);
+    method @RequiresApi(31) public static void setTextViewMaxHeightDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewMaxHeightDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextViewMaxLines(android.widget.RemoteViews, @IdRes int viewId, int maxLines);
+    method @RequiresApi(31) public static void setTextViewMaxWidth(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setTextViewMaxWidth(android.widget.RemoteViews, @IdRes int viewId, @Px int maxWidth);
+    method @RequiresApi(31) public static void setTextViewMaxWidthDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewMaxWidthDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextViewMinEms(android.widget.RemoteViews, @IdRes int viewId, int minems);
+    method @RequiresApi(31) public static void setTextViewMinHeight(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setTextViewMinHeight(android.widget.RemoteViews, @IdRes int viewId, @Px int minHeight);
+    method @RequiresApi(31) public static void setTextViewMinHeightDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewMinHeightDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextViewMinLines(android.widget.RemoteViews, @IdRes int viewId, int minLines);
+    method @RequiresApi(31) public static void setTextViewMinWidth(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setTextViewMinWidth(android.widget.RemoteViews, @IdRes int viewId, @Px int minWidth);
+    method @RequiresApi(31) public static void setTextViewMinWidthDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewMinWidthDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextViewPaintFlags(android.widget.RemoteViews, @IdRes int viewId, int flags);
+    method public static void setTextViewSelectAllOnFocus(android.widget.RemoteViews, @IdRes int viewId, boolean selectAllOnFocus);
+    method public static void setTextViewSingleLine(android.widget.RemoteViews, @IdRes int viewId, boolean singleLine);
+    method public static void setTextViewText(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method @RequiresApi(31) public static void setTextViewTextAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setTextViewTextColor(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList colors);
+    method @RequiresApi(31) public static void setTextViewTextColor(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList notNight, android.content.res.ColorStateList night);
+    method public static void setTextViewTextColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int color);
+    method @RequiresApi(31) public static void setTextViewTextColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int notNight, @ColorInt int night);
+    method @RequiresApi(31) public static void setTextViewTextColorAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setTextViewTextColorResource(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method public static void setTextViewTextScaleX(android.widget.RemoteViews, @IdRes int viewId, float size);
+    method @RequiresApi(31) public static void setTextViewTextSizeDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewTextSizeDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setTextViewWidth(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setTextViewWidth(android.widget.RemoteViews, @IdRes int viewId, @Px int pixels);
+    method @RequiresApi(31) public static void setTextViewWidthDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewWidthDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setViewAlpha(android.widget.RemoteViews, @IdRes int viewId, float alpha);
+    method public static void setViewBackgroundColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int color);
+    method @RequiresApi(31) public static void setViewBackgroundColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int notNight, @ColorInt int night);
+    method @RequiresApi(31) public static void setViewBackgroundColorAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setViewBackgroundColorResource(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method public static void setViewBackgroundResource(android.widget.RemoteViews, @IdRes int viewId, @DrawableRes int resId);
+    method @RequiresApi(31) public static void setViewBackgroundTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setViewBackgroundTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setViewBackgroundTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNightTint, android.content.res.ColorStateList? nightTint);
+    method @RequiresApi(31) public static void setViewBackgroundTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setViewBackgroundTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setViewClipToOutline(android.widget.RemoteViews, @IdRes int viewId, boolean clipToOutline);
+    method @RequiresApi(31) public static void setViewContentDescription(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method public static void setViewContentDescription(android.widget.RemoteViews, @IdRes int viewId, CharSequence? contentDescription);
+    method @RequiresApi(31) public static void setViewContentDescriptionAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setViewElevationDimen(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setViewElevationDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setViewElevationDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(24) public static void setViewEnabled(android.widget.RemoteViews, @IdRes int viewId, boolean enabled);
+    method @RequiresApi(31) public static void setViewFocusable(android.widget.RemoteViews, @IdRes int viewId, boolean focusable);
+    method @RequiresApi(31) public static void setViewFocusable(android.widget.RemoteViews, @IdRes int viewId, int focusable);
+    method @RequiresApi(31) public static void setViewFocusableInTouchMode(android.widget.RemoteViews, @IdRes int viewId, boolean focusableInTouchMode);
+    method @RequiresApi(31) public static void setViewFocusedByDefault(android.widget.RemoteViews, @IdRes int viewId, boolean isFocusedByDefault);
+    method @RequiresApi(31) public static void setViewForegroundTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setViewForegroundTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setViewForegroundTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNightTint, android.content.res.ColorStateList? nightTint);
+    method @RequiresApi(31) public static void setViewForegroundTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setViewForegroundTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setViewLayoutDirection(android.widget.RemoteViews, @IdRes int viewId, int layoutDirection);
+    method @RequiresApi(31) public static void setViewMinimumHeight(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(24) public static void setViewMinimumHeight(android.widget.RemoteViews, @IdRes int viewId, @Px int minHeight);
+    method @RequiresApi(31) public static void setViewMinimumHeightDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setViewMinimumHeightDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setViewMinimumWidth(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setViewMinimumWidthDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setViewMinimumWidthDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setViewPivotX(android.widget.RemoteViews, @IdRes int viewId, float pivotX);
+    method @RequiresApi(31) public static void setViewPivotY(android.widget.RemoteViews, @IdRes int viewId, float pivotY);
+    method @RequiresApi(31) public static void setViewRotation(android.widget.RemoteViews, @IdRes int viewId, float rotation);
+    method @RequiresApi(31) public static void setViewRotationX(android.widget.RemoteViews, @IdRes int viewId, float rotationX);
+    method @RequiresApi(31) public static void setViewRotationY(android.widget.RemoteViews, @IdRes int viewId, float rotationY);
+    method @RequiresApi(31) public static void setViewScaleX(android.widget.RemoteViews, @IdRes int viewId, float scaleX);
+    method @RequiresApi(31) public static void setViewScaleY(android.widget.RemoteViews, @IdRes int viewId, float scaleY);
+    method @RequiresApi(31) public static void setViewScrollIndicators(android.widget.RemoteViews, @IdRes int viewId, int scrollIndicators);
+    method @RequiresApi(31) public static void setViewStateDescription(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method @RequiresApi(30) public static void setViewStateDescription(android.widget.RemoteViews, @IdRes int viewId, CharSequence? stateDescription);
+    method @RequiresApi(31) public static void setViewStateDescriptionAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setViewStubInflatedId(android.widget.RemoteViews, @IdRes int viewId, int inflatedId);
+    method public static void setViewStubLayoutResource(android.widget.RemoteViews, @IdRes int viewId, @LayoutRes int layoutResource);
+    method @RequiresApi(31) public static void setViewTranslationXDimen(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setViewTranslationXDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setViewTranslationXDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setViewTranslationYDimen(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setViewTranslationYDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setViewTranslationYDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setViewTranslationZDimen(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setViewTranslationZDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setViewTranslationZDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    field public static final androidx.core.widget.RemoteViewsCompat INSTANCE;
+  }
+
+  public static final class RemoteViewsCompat.RemoteCollectionItems {
+    method public int getItemCount();
+    method public long getItemId(int position);
+    method public android.widget.RemoteViews getItemView(int position);
+    method public int getViewTypeCount();
+    method public boolean hasStableIds();
+    property public final int itemCount;
+    property public final int viewTypeCount;
+  }
+
+  public static final class RemoteViewsCompat.RemoteCollectionItems.Builder {
+    ctor public RemoteViewsCompat.RemoteCollectionItems.Builder();
+    method public androidx.core.widget.RemoteViewsCompat.RemoteCollectionItems.Builder addItem(long id, android.widget.RemoteViews view);
+    method public androidx.core.widget.RemoteViewsCompat.RemoteCollectionItems build();
+    method public androidx.core.widget.RemoteViewsCompat.RemoteCollectionItems.Builder setHasStableIds(boolean hasStableIds);
+    method public androidx.core.widget.RemoteViewsCompat.RemoteCollectionItems.Builder setViewTypeCount(int viewTypeCount);
+  }
+
+}
+
diff --git a/core/core-remoteviews/api/res-1.1.0-beta01.txt b/core/core-remoteviews/api/res-1.1.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/core/core-remoteviews/api/res-1.1.0-beta01.txt
diff --git a/core/core-remoteviews/api/restricted_1.1.0-beta01.txt b/core/core-remoteviews/api/restricted_1.1.0-beta01.txt
new file mode 100644
index 0000000..07071af
--- /dev/null
+++ b/core/core-remoteviews/api/restricted_1.1.0-beta01.txt
@@ -0,0 +1,299 @@
+// Signature format: 4.0
+package androidx.core.widget {
+
+  public final class AppWidgetManagerCompat {
+    method public static android.widget.RemoteViews createExactSizeAppWidget(android.appwidget.AppWidgetManager appWidgetManager, int appWidgetId, kotlin.jvm.functions.Function1<? super androidx.core.util.SizeFCompat,? extends android.widget.RemoteViews> factory);
+    method public static android.widget.RemoteViews createResponsiveSizeAppWidget(android.appwidget.AppWidgetManager appWidgetManager, int appWidgetId, java.util.Collection<androidx.core.util.SizeFCompat> dpSizes, kotlin.jvm.functions.Function1<? super androidx.core.util.SizeFCompat,? extends android.widget.RemoteViews> factory);
+    method public static void updateAppWidget(android.appwidget.AppWidgetManager, int appWidgetId, java.util.Collection<androidx.core.util.SizeFCompat> dpSizes, kotlin.jvm.functions.Function1<? super androidx.core.util.SizeFCompat,? extends android.widget.RemoteViews> factory);
+    method public static void updateAppWidget(android.appwidget.AppWidgetManager, int appWidgetId, kotlin.jvm.functions.Function1<? super androidx.core.util.SizeFCompat,? extends android.widget.RemoteViews> factory);
+  }
+
+  public final class RemoteViewsCompat {
+    method public static void setChronometerBase(android.widget.RemoteViews, @IdRes int viewId, long base);
+    method public static void setChronometerFormat(android.widget.RemoteViews, @IdRes int viewId, String? format);
+    method @RequiresApi(31) public static void setCompoundButtonDrawable(android.widget.RemoteViews, @IdRes int viewId, @DrawableRes int resId);
+    method @RequiresApi(31) public static void setCompoundButtonIcon(android.widget.RemoteViews, @IdRes int viewId, android.graphics.drawable.Icon? icon);
+    method @RequiresApi(31) public static void setCompoundButtonTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? tintMode);
+    method @RequiresApi(31) public static void setCompoundButtonTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setCompoundButtonTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNight, android.content.res.ColorStateList? night);
+    method @RequiresApi(31) public static void setCompoundButtonTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setCompoundButtonTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setFrameLayoutForegroundGravity(android.widget.RemoteViews, @IdRes int viewId, int foregroundGravity);
+    method public static void setFrameLayoutMeasureAllChildren(android.widget.RemoteViews, @IdRes int viewId, boolean measureAll);
+    method @RequiresApi(31) public static void setGridLayoutAlignmentMode(android.widget.RemoteViews, @IdRes int viewId, int alignmentMode);
+    method @RequiresApi(31) public static void setGridLayoutColumnCount(android.widget.RemoteViews, @IdRes int viewId, int columnCount);
+    method @RequiresApi(31) public static void setGridLayoutRowCount(android.widget.RemoteViews, @IdRes int viewId, int rowCount);
+    method @RequiresApi(31) public static void setGridViewColumnWidth(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setGridViewColumnWidthDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int columnWidth);
+    method @RequiresApi(31) public static void setGridViewColumnWidthDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int columnWidth);
+    method @RequiresApi(31) public static void setGridViewGravity(android.widget.RemoteViews, @IdRes int viewId, int gravity);
+    method @RequiresApi(31) public static void setGridViewHorizontalSpacing(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setGridViewHorizontalSpacingDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setGridViewHorizontalSpacingDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setGridViewNumColumns(android.widget.RemoteViews, @IdRes int viewId, int numColumns);
+    method @RequiresApi(31) public static void setGridViewStretchMode(android.widget.RemoteViews, @IdRes int viewId, int stretchMode);
+    method @RequiresApi(31) public static void setGridViewVerticalSpacing(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setGridViewVerticalSpacingDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setGridViewVerticalSpacingDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setImageViewAdjustViewBounds(android.widget.RemoteViews, @IdRes int viewId, boolean adjustViewBounds);
+    method public static void setImageViewColorFilter(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int color);
+    method @RequiresApi(31) public static void setImageViewColorFilter(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int notNight, @ColorInt int night);
+    method @RequiresApi(31) public static void setImageViewColorFilterAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setImageViewColorFilterResource(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method public static void setImageViewImageAlpha(android.widget.RemoteViews, @IdRes int viewId, int alpha);
+    method public static void setImageViewImageLevel(android.widget.RemoteViews, @IdRes int viewId, int level);
+    method @RequiresApi(31) public static void setImageViewImageTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setImageViewImageTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setImageViewImageTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNightTint, android.content.res.ColorStateList? nightTint);
+    method @RequiresApi(31) public static void setImageViewImageTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setImageViewImageTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setImageViewMaxHeight(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setImageViewMaxHeight(android.widget.RemoteViews, @IdRes int viewId, @Px int maxHeight);
+    method @RequiresApi(31) public static void setImageViewMaxHeightDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setImageViewMaxHeightDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setImageViewMaxWidth(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setImageViewMaxWidth(android.widget.RemoteViews, @IdRes int viewId, @Px int maxWidth);
+    method @RequiresApi(31) public static void setImageViewMaxWidthDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setImageViewMaxWidthDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setLinearLayoutBaselineAligned(android.widget.RemoteViews, @IdRes int viewId, boolean baselineAligned);
+    method public static void setLinearLayoutBaselineAlignedChildIndex(android.widget.RemoteViews, @IdRes int viewId, int i);
+    method public static void setLinearLayoutGravity(android.widget.RemoteViews, @IdRes int viewId, int gravity);
+    method public static void setLinearLayoutHorizontalGravity(android.widget.RemoteViews, @IdRes int viewId, int horizontalGravity);
+    method public static void setLinearLayoutMeasureWithLargestChildEnabled(android.widget.RemoteViews, @IdRes int viewId, boolean enabled);
+    method public static void setLinearLayoutVerticalGravity(android.widget.RemoteViews, @IdRes int viewId, int verticalGravity);
+    method public static void setLinearLayoutWeightSum(android.widget.RemoteViews, @IdRes int viewId, float weightSum);
+    method public static void setProgressBarIndeterminate(android.widget.RemoteViews, @IdRes int viewId, boolean indeterminate);
+    method @RequiresApi(31) public static void setProgressBarIndeterminateTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setProgressBarIndeterminateTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setProgressBarIndeterminateTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNightTint, android.content.res.ColorStateList? nightTint);
+    method @RequiresApi(31) public static void setProgressBarIndeterminateTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setProgressBarIndeterminateTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setProgressBarMax(android.widget.RemoteViews, @IdRes int viewId, int max);
+    method @RequiresApi(26) public static void setProgressBarMin(android.widget.RemoteViews, @IdRes int viewId, int min);
+    method public static void setProgressBarProgress(android.widget.RemoteViews, @IdRes int viewId, int progress);
+    method @RequiresApi(31) public static void setProgressBarProgressBackgroundTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setProgressBarProgressBackgroundTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setProgressBarProgressBackgroundTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNightTint, android.content.res.ColorStateList? nightTint);
+    method @RequiresApi(31) public static void setProgressBarProgressBackgroundTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setProgressBarProgressBackgroundTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setProgressBarProgressTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setProgressBarProgressTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setProgressBarProgressTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNightTint, android.content.res.ColorStateList? nightTint);
+    method @RequiresApi(31) public static void setProgressBarProgressTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setProgressBarProgressTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setProgressBarSecondaryProgress(android.widget.RemoteViews, @IdRes int viewId, int secondaryProgress);
+    method @RequiresApi(31) public static void setProgressBarSecondaryProgressTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setProgressBarSecondaryProgressTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setProgressBarSecondaryProgressTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNightTint, android.content.res.ColorStateList? nightTint);
+    method @RequiresApi(31) public static void setProgressBarSecondaryProgressTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setProgressBarSecondaryProgressTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setProgressBarStateDescription(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method @RequiresApi(31) public static void setProgressBarStateDescription(android.widget.RemoteViews, @IdRes int viewId, CharSequence? stateDescription);
+    method @RequiresApi(31) public static void setProgressBarStateDescriptionAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setRelativeLayoutGravity(android.widget.RemoteViews, @IdRes int viewId, int gravity);
+    method public static void setRelativeLayoutHorizontalGravity(android.widget.RemoteViews, @IdRes int viewId, int horizontalGravity);
+    method public static void setRelativeLayoutIgnoreGravity(android.widget.RemoteViews, @IdRes int viewId, @IdRes int childViewId);
+    method public static void setRelativeLayoutVerticalGravity(android.widget.RemoteViews, @IdRes int viewId, int verticalGravity);
+    method public static void setRemoteAdapter(android.content.Context context, android.widget.RemoteViews remoteViews, int appWidgetId, @IdRes int viewId, androidx.core.widget.RemoteViewsCompat.RemoteCollectionItems items);
+    method @RequiresApi(31) public static void setSwitchMinWidth(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setSwitchMinWidthDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setSwitchMinWidthDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setSwitchPadding(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setSwitchPaddingDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setSwitchPaddingDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setSwitchShowText(android.widget.RemoteViews, @IdRes int viewId, boolean showText);
+    method @RequiresApi(31) public static void setSwitchSplitTrack(android.widget.RemoteViews, @IdRes int viewId, boolean splitTrack);
+    method @RequiresApi(31) public static void setSwitchTextOff(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method @RequiresApi(31) public static void setSwitchTextOff(android.widget.RemoteViews, @IdRes int viewId, CharSequence? textOff);
+    method @RequiresApi(31) public static void setSwitchTextOffAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setSwitchTextOn(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method @RequiresApi(31) public static void setSwitchTextOn(android.widget.RemoteViews, @IdRes int viewId, CharSequence? textOn);
+    method @RequiresApi(31) public static void setSwitchTextOnAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setSwitchThumbIcon(android.widget.RemoteViews, @IdRes int viewId, android.graphics.drawable.Icon? icon);
+    method @RequiresApi(31) public static void setSwitchThumbIcon(android.widget.RemoteViews, @IdRes int viewId, android.graphics.drawable.Icon? notNight, android.graphics.drawable.Icon? night);
+    method @RequiresApi(31) public static void setSwitchThumbResource(android.widget.RemoteViews, @IdRes int viewId, @DrawableRes int resId);
+    method @RequiresApi(31) public static void setSwitchThumbTextPadding(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setSwitchThumbTextPaddingDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setSwitchThumbTextPaddingDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setSwitchThumbTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setSwitchThumbTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setSwitchThumbTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNight, android.content.res.ColorStateList? night);
+    method @RequiresApi(31) public static void setSwitchThumbTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setSwitchThumbTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setSwitchTrackIcon(android.widget.RemoteViews, @IdRes int viewId, android.graphics.drawable.Icon? icon);
+    method @RequiresApi(31) public static void setSwitchTrackIcon(android.widget.RemoteViews, @IdRes int viewId, android.graphics.drawable.Icon? notNight, android.graphics.drawable.Icon? night);
+    method @RequiresApi(31) public static void setSwitchTrackResource(android.widget.RemoteViews, @IdRes int viewId, @DrawableRes int resId);
+    method @RequiresApi(31) public static void setSwitchTrackTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setSwitchTrackTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setSwitchTrackTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNight, android.content.res.ColorStateList? night);
+    method @RequiresApi(31) public static void setSwitchTrackTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setSwitchTrackTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setTextClockFormat12Hour(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method public static void setTextClockFormat12Hour(android.widget.RemoteViews, @IdRes int viewId, CharSequence? format);
+    method @RequiresApi(31) public static void setTextClockFormat12HourAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setTextClockFormat24Hour(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method public static void setTextClockFormat24Hour(android.widget.RemoteViews, @IdRes int viewId, CharSequence? format);
+    method @RequiresApi(31) public static void setTextClockFormat24HourAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextClockTimeZone(android.widget.RemoteViews, @IdRes int viewId, String? timeZone);
+    method @RequiresApi(31) public static void setTextViewAllCaps(android.widget.RemoteViews, @IdRes int viewId, boolean allCaps);
+    method public static void setTextViewAutoLinkMask(android.widget.RemoteViews, @IdRes int viewId, int mask);
+    method @RequiresApi(31) public static void setTextViewCompoundDrawablePadding(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setTextViewCompoundDrawablePadding(android.widget.RemoteViews, @IdRes int viewId, @Px int pad);
+    method @RequiresApi(31) public static void setTextViewCompoundDrawablePaddingDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewCompoundDrawablePaddingDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextViewEms(android.widget.RemoteViews, @IdRes int viewId, int ems);
+    method @RequiresApi(31) public static void setTextViewError(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method public static void setTextViewError(android.widget.RemoteViews, @IdRes int viewId, CharSequence? error);
+    method @RequiresApi(31) public static void setTextViewErrorAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(21) public static void setTextViewFontFeatureSettings(android.widget.RemoteViews, @IdRes int viewId, String fontFeatureSettings);
+    method @RequiresApi(31) public static void setTextViewGravity(android.widget.RemoteViews, @IdRes int viewId, int gravity);
+    method @RequiresApi(31) public static void setTextViewHeight(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setTextViewHeight(android.widget.RemoteViews, @IdRes int viewId, @Px int pixels);
+    method @RequiresApi(31) public static void setTextViewHeightDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewHeightDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextViewHighlightColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int color);
+    method @RequiresApi(31) public static void setTextViewHighlightColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int notNight, @ColorInt int night);
+    method @RequiresApi(31) public static void setTextViewHighlightColorAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setTextViewHighlightColorResource(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method public static void setTextViewHint(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method public static void setTextViewHint(android.widget.RemoteViews, @IdRes int viewId, CharSequence? hint);
+    method @RequiresApi(31) public static void setTextViewHintAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextViewHintTextColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int color);
+    method @RequiresApi(31) public static void setTextViewHintTextColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int notNight, @ColorInt int night);
+    method @RequiresApi(31) public static void setTextViewHintTextColorAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setTextViewHintTextColorResource(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setTextViewJustificationMode(android.widget.RemoteViews, @IdRes int viewId, int justificationMode);
+    method @RequiresApi(21) public static void setTextViewLetterSpacing(android.widget.RemoteViews, @IdRes int viewId, float letterSpacing);
+    method @RequiresApi(31) public static void setTextViewLineHeight(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setTextViewLineHeightDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewLineHeightDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextViewLines(android.widget.RemoteViews, @IdRes int viewId, int lines);
+    method public static void setTextViewLinkTextColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int color);
+    method @RequiresApi(31) public static void setTextViewLinkTextColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int notNight, @ColorInt int night);
+    method @RequiresApi(31) public static void setTextViewLinkTextColorAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setTextViewLinkTextColorResource(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method public static void setTextViewLinksClickable(android.widget.RemoteViews, @IdRes int viewId, boolean whether);
+    method public static void setTextViewMaxEms(android.widget.RemoteViews, @IdRes int viewId, int maxems);
+    method @RequiresApi(31) public static void setTextViewMaxHeight(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setTextViewMaxHeight(android.widget.RemoteViews, @IdRes int viewId, @Px int maxHeight);
+    method @RequiresApi(31) public static void setTextViewMaxHeightDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewMaxHeightDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextViewMaxLines(android.widget.RemoteViews, @IdRes int viewId, int maxLines);
+    method @RequiresApi(31) public static void setTextViewMaxWidth(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setTextViewMaxWidth(android.widget.RemoteViews, @IdRes int viewId, @Px int maxWidth);
+    method @RequiresApi(31) public static void setTextViewMaxWidthDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewMaxWidthDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextViewMinEms(android.widget.RemoteViews, @IdRes int viewId, int minems);
+    method @RequiresApi(31) public static void setTextViewMinHeight(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setTextViewMinHeight(android.widget.RemoteViews, @IdRes int viewId, @Px int minHeight);
+    method @RequiresApi(31) public static void setTextViewMinHeightDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewMinHeightDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextViewMinLines(android.widget.RemoteViews, @IdRes int viewId, int minLines);
+    method @RequiresApi(31) public static void setTextViewMinWidth(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setTextViewMinWidth(android.widget.RemoteViews, @IdRes int viewId, @Px int minWidth);
+    method @RequiresApi(31) public static void setTextViewMinWidthDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewMinWidthDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setTextViewPaintFlags(android.widget.RemoteViews, @IdRes int viewId, int flags);
+    method public static void setTextViewSelectAllOnFocus(android.widget.RemoteViews, @IdRes int viewId, boolean selectAllOnFocus);
+    method public static void setTextViewSingleLine(android.widget.RemoteViews, @IdRes int viewId, boolean singleLine);
+    method public static void setTextViewText(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method @RequiresApi(31) public static void setTextViewTextAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setTextViewTextColor(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList colors);
+    method @RequiresApi(31) public static void setTextViewTextColor(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList notNight, android.content.res.ColorStateList night);
+    method public static void setTextViewTextColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int color);
+    method @RequiresApi(31) public static void setTextViewTextColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int notNight, @ColorInt int night);
+    method @RequiresApi(31) public static void setTextViewTextColorAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setTextViewTextColorResource(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method public static void setTextViewTextScaleX(android.widget.RemoteViews, @IdRes int viewId, float size);
+    method @RequiresApi(31) public static void setTextViewTextSizeDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewTextSizeDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setTextViewWidth(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method public static void setTextViewWidth(android.widget.RemoteViews, @IdRes int viewId, @Px int pixels);
+    method @RequiresApi(31) public static void setTextViewWidthDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setTextViewWidthDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setViewAlpha(android.widget.RemoteViews, @IdRes int viewId, float alpha);
+    method public static void setViewBackgroundColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int color);
+    method @RequiresApi(31) public static void setViewBackgroundColor(android.widget.RemoteViews, @IdRes int viewId, @ColorInt int notNight, @ColorInt int night);
+    method @RequiresApi(31) public static void setViewBackgroundColorAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setViewBackgroundColorResource(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method public static void setViewBackgroundResource(android.widget.RemoteViews, @IdRes int viewId, @DrawableRes int resId);
+    method @RequiresApi(31) public static void setViewBackgroundTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setViewBackgroundTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setViewBackgroundTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNightTint, android.content.res.ColorStateList? nightTint);
+    method @RequiresApi(31) public static void setViewBackgroundTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setViewBackgroundTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setViewClipToOutline(android.widget.RemoteViews, @IdRes int viewId, boolean clipToOutline);
+    method @RequiresApi(31) public static void setViewContentDescription(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method public static void setViewContentDescription(android.widget.RemoteViews, @IdRes int viewId, CharSequence? contentDescription);
+    method @RequiresApi(31) public static void setViewContentDescriptionAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setViewElevationDimen(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setViewElevationDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setViewElevationDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(24) public static void setViewEnabled(android.widget.RemoteViews, @IdRes int viewId, boolean enabled);
+    method @RequiresApi(31) public static void setViewFocusable(android.widget.RemoteViews, @IdRes int viewId, boolean focusable);
+    method @RequiresApi(31) public static void setViewFocusable(android.widget.RemoteViews, @IdRes int viewId, int focusable);
+    method @RequiresApi(31) public static void setViewFocusableInTouchMode(android.widget.RemoteViews, @IdRes int viewId, boolean focusableInTouchMode);
+    method @RequiresApi(31) public static void setViewFocusedByDefault(android.widget.RemoteViews, @IdRes int viewId, boolean isFocusedByDefault);
+    method @RequiresApi(31) public static void setViewForegroundTintBlendMode(android.widget.RemoteViews, @IdRes int viewId, android.graphics.BlendMode? blendMode);
+    method @RequiresApi(31) public static void setViewForegroundTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? tint);
+    method @RequiresApi(31) public static void setViewForegroundTintList(android.widget.RemoteViews, @IdRes int viewId, android.content.res.ColorStateList? notNightTint, android.content.res.ColorStateList? nightTint);
+    method @RequiresApi(31) public static void setViewForegroundTintList(android.widget.RemoteViews, @IdRes int viewId, @ColorRes int resId);
+    method @RequiresApi(31) public static void setViewForegroundTintListAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setViewLayoutDirection(android.widget.RemoteViews, @IdRes int viewId, int layoutDirection);
+    method @RequiresApi(31) public static void setViewMinimumHeight(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(24) public static void setViewMinimumHeight(android.widget.RemoteViews, @IdRes int viewId, @Px int minHeight);
+    method @RequiresApi(31) public static void setViewMinimumHeightDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setViewMinimumHeightDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setViewMinimumWidth(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setViewMinimumWidthDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setViewMinimumWidthDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setViewPivotX(android.widget.RemoteViews, @IdRes int viewId, float pivotX);
+    method @RequiresApi(31) public static void setViewPivotY(android.widget.RemoteViews, @IdRes int viewId, float pivotY);
+    method @RequiresApi(31) public static void setViewRotation(android.widget.RemoteViews, @IdRes int viewId, float rotation);
+    method @RequiresApi(31) public static void setViewRotationX(android.widget.RemoteViews, @IdRes int viewId, float rotationX);
+    method @RequiresApi(31) public static void setViewRotationY(android.widget.RemoteViews, @IdRes int viewId, float rotationY);
+    method @RequiresApi(31) public static void setViewScaleX(android.widget.RemoteViews, @IdRes int viewId, float scaleX);
+    method @RequiresApi(31) public static void setViewScaleY(android.widget.RemoteViews, @IdRes int viewId, float scaleY);
+    method @RequiresApi(31) public static void setViewScrollIndicators(android.widget.RemoteViews, @IdRes int viewId, int scrollIndicators);
+    method @RequiresApi(31) public static void setViewStateDescription(android.widget.RemoteViews, @IdRes int viewId, @StringRes int resId);
+    method @RequiresApi(30) public static void setViewStateDescription(android.widget.RemoteViews, @IdRes int viewId, CharSequence? stateDescription);
+    method @RequiresApi(31) public static void setViewStateDescriptionAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method public static void setViewStubInflatedId(android.widget.RemoteViews, @IdRes int viewId, int inflatedId);
+    method public static void setViewStubLayoutResource(android.widget.RemoteViews, @IdRes int viewId, @LayoutRes int layoutResource);
+    method @RequiresApi(31) public static void setViewTranslationXDimen(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setViewTranslationXDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setViewTranslationXDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setViewTranslationYDimen(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setViewTranslationYDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setViewTranslationYDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    method @RequiresApi(31) public static void setViewTranslationZDimen(android.widget.RemoteViews, @IdRes int viewId, float value, int unit);
+    method @RequiresApi(31) public static void setViewTranslationZDimen(android.widget.RemoteViews, @IdRes int viewId, @DimenRes int resId);
+    method @RequiresApi(31) public static void setViewTranslationZDimenAttr(android.widget.RemoteViews, @IdRes int viewId, @AttrRes int resId);
+    field public static final androidx.core.widget.RemoteViewsCompat INSTANCE;
+  }
+
+  public static final class RemoteViewsCompat.RemoteCollectionItems {
+    method public int getItemCount();
+    method public long getItemId(int position);
+    method public android.widget.RemoteViews getItemView(int position);
+    method public int getViewTypeCount();
+    method public boolean hasStableIds();
+    property public final int itemCount;
+    property public final int viewTypeCount;
+  }
+
+  public static final class RemoteViewsCompat.RemoteCollectionItems.Builder {
+    ctor public RemoteViewsCompat.RemoteCollectionItems.Builder();
+    method public androidx.core.widget.RemoteViewsCompat.RemoteCollectionItems.Builder addItem(long id, android.widget.RemoteViews view);
+    method public androidx.core.widget.RemoteViewsCompat.RemoteCollectionItems build();
+    method public androidx.core.widget.RemoteViewsCompat.RemoteCollectionItems.Builder setHasStableIds(boolean hasStableIds);
+    method public androidx.core.widget.RemoteViewsCompat.RemoteCollectionItems.Builder setViewTypeCount(int viewTypeCount);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final class RemoteViewsCompatService extends android.widget.RemoteViewsService {
+    ctor public RemoteViewsCompatService();
+    method public android.widget.RemoteViewsService.RemoteViewsFactory onGetViewFactory(android.content.Intent intent);
+  }
+
+}
+
diff --git a/core/core/src/main/java/androidx/core/hardware/fingerprint/FingerprintManagerCompat.java b/core/core/src/main/java/androidx/core/hardware/fingerprint/FingerprintManagerCompat.java
index 244b776..e8e1bbf3 100644
--- a/core/core/src/main/java/androidx/core/hardware/fingerprint/FingerprintManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/hardware/fingerprint/FingerprintManagerCompat.java
@@ -18,11 +18,16 @@
 
 import android.Manifest;
 import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.Build;
 import android.os.CancellationSignal;
 import android.os.Handler;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
 import androidx.annotation.RequiresPermission;
 import androidx.annotation.RestrictTo;
 
@@ -34,53 +39,62 @@
 /**
  * A class that coordinates access to the fingerprint hardware.
  * <p>
- * This class has been deprecated and should no longer be used. On all platform versions, it behaves
- * as though no fingerprint hardware is available.
+ * On platforms before {@link android.os.Build.VERSION_CODES#M}, this class behaves as there would
+ * be no fingerprint hardware available.
  *
- * @deprecated {@code FingerprintManager} was removed from the platform SDK in Android V, use
- * {@code androidx.biometrics.BiometricPrompt} instead.
+ * @deprecated Use {@code androidx.biometrics.BiometricPrompt} instead.
  */
 @SuppressWarnings({"deprecation", "unused"})
 @Deprecated
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
 public class FingerprintManagerCompat {
 
+    private final Context mContext;
+
     /** Get a {@link FingerprintManagerCompat} instance for a provided context. */
     @NonNull
     public static FingerprintManagerCompat from(@NonNull Context context) {
-        return new FingerprintManagerCompat();
+        return new FingerprintManagerCompat(context);
     }
 
-    private FingerprintManagerCompat() {
+    private FingerprintManagerCompat(Context context) {
+        mContext = context;
     }
 
     /**
-     * Prior to deprecation, this method would determine if there is at least one fingerprint
-     * enrolled.
+     * Determine if there is at least one fingerprint enrolled.
      *
-     * @return false
+     * @return true if at least one fingerprint is enrolled, false otherwise
      */
     @RequiresPermission(Manifest.permission.USE_FINGERPRINT)
     public boolean hasEnrolledFingerprints() {
-        return false;
+        if (Build.VERSION.SDK_INT >= 23) {
+            final FingerprintManager fp = getFingerprintManagerOrNull(mContext);
+            return (fp != null) && Api23Impl.hasEnrolledFingerprints(fp);
+        } else {
+            return false;
+        }
     }
 
     /**
-     * Prior to deprecation, this method would determine if fingerprint hardware is present and
-     * functional.
+     * Determine if fingerprint hardware is present and functional.
      *
-     * @return false
+     * @return true if hardware is present and functional, false otherwise.
      */
     @RequiresPermission(Manifest.permission.USE_FINGERPRINT)
     public boolean isHardwareDetected() {
-        return false;
+        if (Build.VERSION.SDK_INT >= 23) {
+            final FingerprintManager fp = getFingerprintManagerOrNull(mContext);
+            return (fp != null) && Api23Impl.isHardwareDetected(fp);
+        } else {
+            return false;
+        }
     }
 
     /**
-     * Prior to deprecation, this method would request authentication of a crypto object.
-     * <p>
-     * This call warms up the fingerprint hardware and starts scanning for a fingerprint. It
-     * terminates when {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
+     * Request authentication of a crypto object. This call warms up the fingerprint hardware
+     * and starts scanning for a fingerprint. It terminates when
+     * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
      * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult)} is called, at
      * which point the object is no longer valid. The operation can be canceled by using the
      * provided cancel object.
@@ -100,14 +114,15 @@
             @Nullable androidx.core.os.CancellationSignal cancel,
             @NonNull AuthenticationCallback callback,
             @Nullable Handler handler) {
-        // No-op.
+        authenticate(crypto, flags,
+                cancel != null ? (CancellationSignal) cancel.getCancellationSignalObject() : null,
+                callback, handler);
     }
 
     /**
-     * Prior to deprecation, this method would request authentication of a crypto object.
-     * <p>
-     * This call warms up the fingerprint hardware and starts scanning for a fingerprint.
-     * It terminates when {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
+     * Request authentication of a crypto object. This call warms up the fingerprint hardware
+     * and starts scanning for a fingerprint. It terminates when
+     * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
      * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult)} is called, at
      * which point the object is no longer valid. The operation can be canceled by using the
      * provided cancel object.
@@ -122,7 +137,56 @@
     public void authenticate(@Nullable CryptoObject crypto, int flags,
             @Nullable CancellationSignal cancel, @NonNull AuthenticationCallback callback,
             @Nullable Handler handler) {
-        // No-op.
+        if (Build.VERSION.SDK_INT >= 23) {
+            final FingerprintManager fp = getFingerprintManagerOrNull(mContext);
+            if (fp != null) {
+                Api23Impl.authenticate(fp, wrapCryptoObject(crypto), cancel, flags,
+                        wrapCallback(callback), handler);
+            }
+        }
+    }
+
+    @Nullable
+    @RequiresApi(23)
+    private static FingerprintManager getFingerprintManagerOrNull(@NonNull Context context) {
+        return Api23Impl.getFingerprintManagerOrNull(context);
+    }
+
+    @RequiresApi(23)
+    private static FingerprintManager.CryptoObject wrapCryptoObject(CryptoObject cryptoObject) {
+        return Api23Impl.wrapCryptoObject(cryptoObject);
+    }
+
+    @RequiresApi(23)
+    static CryptoObject unwrapCryptoObject(FingerprintManager.CryptoObject cryptoObject) {
+        return Api23Impl.unwrapCryptoObject(cryptoObject);
+    }
+
+    @RequiresApi(23)
+    private static FingerprintManager.AuthenticationCallback wrapCallback(
+            final AuthenticationCallback callback) {
+        return new FingerprintManager.AuthenticationCallback() {
+            @Override
+            public void onAuthenticationError(int errMsgId, CharSequence errString) {
+                callback.onAuthenticationError(errMsgId, errString);
+            }
+
+            @Override
+            public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
+                callback.onAuthenticationHelp(helpMsgId, helpString);
+            }
+
+            @Override
+            public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
+                callback.onAuthenticationSucceeded(new AuthenticationResult(
+                        unwrapCryptoObject(Api23Impl.getCryptoObject(result))));
+            }
+
+            @Override
+            public void onAuthenticationFailed() {
+                callback.onAuthenticationFailed();
+            }
+        };
     }
 
     /**
@@ -232,4 +296,82 @@
          */
         public void onAuthenticationFailed() { }
     }
+
+    @RequiresApi(23)
+    static class Api23Impl {
+        private Api23Impl() {
+            // This class is not instantiable.
+        }
+
+        @RequiresPermission(Manifest.permission.USE_FINGERPRINT)
+        @DoNotInline
+        static boolean hasEnrolledFingerprints(Object fingerprintManager) {
+            return ((FingerprintManager) fingerprintManager).hasEnrolledFingerprints();
+        }
+
+        @RequiresPermission(Manifest.permission.USE_FINGERPRINT)
+        @DoNotInline
+        static boolean isHardwareDetected(Object fingerprintManager) {
+            return ((FingerprintManager) fingerprintManager).isHardwareDetected();
+        }
+
+        @RequiresPermission(Manifest.permission.USE_FINGERPRINT)
+        @DoNotInline
+        static void authenticate(Object fingerprintManager, Object crypto,
+                CancellationSignal cancel, int flags, Object callback, Handler handler) {
+            ((FingerprintManager) fingerprintManager).authenticate(
+                    (FingerprintManager.CryptoObject) crypto, cancel, flags,
+                    (FingerprintManager.AuthenticationCallback) callback, handler);
+        }
+
+        @DoNotInline
+        static FingerprintManager.CryptoObject getCryptoObject(Object authenticationResult) {
+            return ((FingerprintManager.AuthenticationResult) authenticationResult)
+                    .getCryptoObject();
+        }
+
+        @DoNotInline
+        public static FingerprintManager getFingerprintManagerOrNull(Context context) {
+            if (Build.VERSION.SDK_INT == 23) {
+                return context.getSystemService(FingerprintManager.class);
+            } else if (Build.VERSION.SDK_INT > 23 && context.getPackageManager()
+                    .hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
+                return context.getSystemService(FingerprintManager.class);
+            } else {
+                return null;
+            }
+        }
+
+        @DoNotInline
+        public static FingerprintManager.CryptoObject wrapCryptoObject(CryptoObject cryptoObject) {
+            if (cryptoObject == null) {
+                return null;
+            } else if (cryptoObject.getCipher() != null) {
+                return new FingerprintManager.CryptoObject(cryptoObject.getCipher());
+            } else if (cryptoObject.getSignature() != null) {
+                return new FingerprintManager.CryptoObject(cryptoObject.getSignature());
+            } else if (cryptoObject.getMac() != null) {
+                return new FingerprintManager.CryptoObject(cryptoObject.getMac());
+            } else {
+                return null;
+            }
+        }
+
+        @DoNotInline
+        public static CryptoObject unwrapCryptoObject(Object cryptoObjectObj) {
+            FingerprintManager.CryptoObject cryptoObject =
+                    (FingerprintManager.CryptoObject) cryptoObjectObj;
+            if (cryptoObject == null) {
+                return null;
+            } else if (cryptoObject.getCipher() != null) {
+                return new CryptoObject(cryptoObject.getCipher());
+            } else if (cryptoObject.getSignature() != null) {
+                return new CryptoObject(cryptoObject.getSignature());
+            } else if (cryptoObject.getMac() != null) {
+                return new CryptoObject(cryptoObject.getMac());
+            } else {
+                return null;
+            }
+        }
+    }
 }
diff --git a/development/bench-flame-diff/bench-flame-diff.sh b/development/bench-flame-diff/bench-flame-diff.sh
index 66a6e40..4f75303 100755
--- a/development/bench-flame-diff/bench-flame-diff.sh
+++ b/development/bench-flame-diff/bench-flame-diff.sh
@@ -1,3 +1,11 @@
 #!/usr/bin/env bash
 
+script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)"
+pushd "$script_dir" >/dev/null
+
 ./gradlew --quiet installDist && ./app/build/install/bench-flame-diff/bin/bench-flame-diff "$@"
+exit_code=$?
+
+popd >/dev/null
+
+exit $exit_code
diff --git a/glance/glance-appwidget-testing/api/1.1.0-beta01.txt b/glance/glance-appwidget-testing/api/1.1.0-beta01.txt
new file mode 100644
index 0000000..63b53e2
--- /dev/null
+++ b/glance/glance-appwidget-testing/api/1.1.0-beta01.txt
@@ -0,0 +1,54 @@
+// Signature format: 4.0
+package androidx.glance.appwidget.testing.unit {
+
+  public sealed interface GlanceAppWidgetUnitTest extends androidx.glance.testing.GlanceNodeAssertionsProvider<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> {
+    method public void awaitIdle();
+    method public void provideComposable(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+    method public void setAppWidgetSize(long size);
+    method public void setContext(android.content.Context context);
+    method public <T> void setState(T state);
+  }
+
+  public final class GlanceAppWidgetUnitTestDefaults {
+    method public androidx.glance.GlanceId glanceId();
+    method public int hostCategory();
+    method public long size();
+    field public static final androidx.glance.appwidget.testing.unit.GlanceAppWidgetUnitTestDefaults INSTANCE;
+  }
+
+  public final class GlanceAppWidgetUnitTestKt {
+    method public static void runGlanceAppWidgetUnitTest(optional long timeout, kotlin.jvm.functions.Function1<? super androidx.glance.appwidget.testing.unit.GlanceAppWidgetUnitTest,kotlin.Unit> block);
+  }
+
+  public final class UnitTestAssertionExtensionsKt {
+    method public static inline <reified T extends androidx.glance.appwidget.action.ActionCallback> androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasRunCallbackClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, optional androidx.glance.action.ActionParameters parameters);
+    method public static inline <reified T extends android.content.BroadcastReceiver> androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasSendBroadcastClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasSendBroadcastClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, android.content.ComponentName componentName);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasSendBroadcastClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, android.content.Intent intent);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasSendBroadcastClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, String intentAction, optional android.content.ComponentName? componentName);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasStartActivityClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, android.content.Intent intent, optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasStartServiceClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, android.content.ComponentName componentName, optional boolean isForegroundService);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasStartServiceClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, android.content.Intent intent, optional boolean isForegroundService);
+    method public static inline <reified T extends android.app.Service> androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasStartServiceClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, optional boolean isForegroundService);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertIsChecked(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertIsNotChecked(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>);
+  }
+
+  public final class UnitTestFiltersKt {
+    method public static inline <reified T extends androidx.glance.appwidget.action.ActionCallback> androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasRunCallbackClickAction(optional androidx.glance.action.ActionParameters parameters);
+    method public static inline <reified T extends android.content.BroadcastReceiver> androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasSendBroadcastAction();
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasSendBroadcastAction(android.content.ComponentName componentName);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasSendBroadcastAction(android.content.Intent intent);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasSendBroadcastAction(String intentAction, optional android.content.ComponentName? componentName);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasStartActivityClickAction(android.content.Intent intent, optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasStartServiceAction(android.content.Intent intent, optional boolean isForegroundService);
+    method public static inline <reified T extends android.app.Service> androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasStartServiceAction(optional boolean isForegroundService);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> isChecked();
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> isIndeterminateCircularProgressIndicator();
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> isIndeterminateLinearProgressIndicator();
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> isLinearProgressIndicator(float progress);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> isNotChecked();
+  }
+
+}
+
diff --git a/glance/glance-appwidget-testing/api/res-1.1.0-beta01.txt b/glance/glance-appwidget-testing/api/res-1.1.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/glance/glance-appwidget-testing/api/res-1.1.0-beta01.txt
diff --git a/glance/glance-appwidget-testing/api/restricted_1.1.0-beta01.txt b/glance/glance-appwidget-testing/api/restricted_1.1.0-beta01.txt
new file mode 100644
index 0000000..b3ace96
--- /dev/null
+++ b/glance/glance-appwidget-testing/api/restricted_1.1.0-beta01.txt
@@ -0,0 +1,60 @@
+// Signature format: 4.0
+package androidx.glance.appwidget.testing.unit {
+
+  public sealed interface GlanceAppWidgetUnitTest extends androidx.glance.testing.GlanceNodeAssertionsProvider<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> {
+    method public void awaitIdle();
+    method public void provideComposable(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+    method public void setAppWidgetSize(long size);
+    method public void setContext(android.content.Context context);
+    method public <T> void setState(T state);
+  }
+
+  public final class GlanceAppWidgetUnitTestDefaults {
+    method public androidx.glance.GlanceId glanceId();
+    method public int hostCategory();
+    method public long size();
+    field public static final androidx.glance.appwidget.testing.unit.GlanceAppWidgetUnitTestDefaults INSTANCE;
+  }
+
+  public final class GlanceAppWidgetUnitTestKt {
+    method public static void runGlanceAppWidgetUnitTest(optional long timeout, kotlin.jvm.functions.Function1<? super androidx.glance.appwidget.testing.unit.GlanceAppWidgetUnitTest,kotlin.Unit> block);
+  }
+
+  public final class UnitTestAssertionExtensionsKt {
+    method public static inline <reified T extends androidx.glance.appwidget.action.ActionCallback> androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasRunCallbackClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, optional androidx.glance.action.ActionParameters parameters);
+    method @kotlin.PublishedApi internal static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasRunCallbackClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, Class<? extends androidx.glance.appwidget.action.ActionCallback> callbackClass, optional androidx.glance.action.ActionParameters parameters);
+    method public static inline <reified T extends android.content.BroadcastReceiver> androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasSendBroadcastClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasSendBroadcastClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, android.content.ComponentName componentName);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasSendBroadcastClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, android.content.Intent intent);
+    method @kotlin.PublishedApi internal static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasSendBroadcastClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, Class<? extends android.content.BroadcastReceiver> receiverClass);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasSendBroadcastClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, String intentAction, optional android.content.ComponentName? componentName);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasStartActivityClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, android.content.Intent intent, optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasStartServiceClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, android.content.ComponentName componentName, optional boolean isForegroundService);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasStartServiceClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, android.content.Intent intent, optional boolean isForegroundService);
+    method public static inline <reified T extends android.app.Service> androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasStartServiceClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, optional boolean isForegroundService);
+    method @kotlin.PublishedApi internal static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasStartServiceClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, Class<? extends android.app.Service> serviceClass, optional boolean isForegroundService);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertIsChecked(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertIsNotChecked(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>);
+  }
+
+  public final class UnitTestFiltersKt {
+    method public static inline <reified T extends androidx.glance.appwidget.action.ActionCallback> androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasRunCallbackClickAction(optional androidx.glance.action.ActionParameters parameters);
+    method @kotlin.PublishedApi internal static <T extends androidx.glance.appwidget.action.ActionCallback> androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasRunCallbackClickAction(Class<T> callbackClass, optional androidx.glance.action.ActionParameters parameters);
+    method public static inline <reified T extends android.content.BroadcastReceiver> androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasSendBroadcastAction();
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasSendBroadcastAction(android.content.ComponentName componentName);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasSendBroadcastAction(android.content.Intent intent);
+    method @kotlin.PublishedApi internal static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasSendBroadcastAction(Class<? extends android.content.BroadcastReceiver> receiverClass);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasSendBroadcastAction(String intentAction, optional android.content.ComponentName? componentName);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasStartActivityClickAction(android.content.Intent intent, optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasStartServiceAction(android.content.Intent intent, optional boolean isForegroundService);
+    method public static inline <reified T extends android.app.Service> androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasStartServiceAction(optional boolean isForegroundService);
+    method @kotlin.PublishedApi internal static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasStartServiceAction(Class<? extends android.app.Service> serviceClass, optional boolean isForegroundService);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> isChecked();
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> isIndeterminateCircularProgressIndicator();
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> isIndeterminateLinearProgressIndicator();
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> isLinearProgressIndicator(float progress);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> isNotChecked();
+  }
+
+}
+
diff --git a/glance/glance-appwidget/api/1.1.0-beta01.txt b/glance/glance-appwidget/api/1.1.0-beta01.txt
new file mode 100644
index 0000000..c2b95cf
--- /dev/null
+++ b/glance/glance-appwidget/api/1.1.0-beta01.txt
@@ -0,0 +1,311 @@
+// Signature format: 4.0
+package androidx.glance.appwidget {
+
+  public final class AndroidRemoteViewsKt {
+    method @androidx.compose.runtime.Composable public static void AndroidRemoteViews(android.widget.RemoteViews remoteViews, optional androidx.glance.GlanceModifier modifier);
+    method @androidx.compose.runtime.Composable public static void AndroidRemoteViews(android.widget.RemoteViews remoteViews, @IdRes int containerViewId, optional androidx.glance.GlanceModifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class AppWidgetBackgroundKt {
+    method public static androidx.glance.GlanceModifier appWidgetBackground(androidx.glance.GlanceModifier);
+  }
+
+  public final class AppWidgetComposerKt {
+    method public static suspend Object? compose(androidx.glance.appwidget.GlanceAppWidget, android.content.Context context, optional androidx.glance.GlanceId id, optional android.os.Bundle? options, optional androidx.compose.ui.unit.DpSize? size, optional Object? state, kotlin.coroutines.Continuation<? super android.widget.RemoteViews>);
+    method @SuppressCompatibility @androidx.glance.ExperimentalGlanceApi public static kotlinx.coroutines.flow.Flow<android.widget.RemoteViews> runComposition(androidx.glance.appwidget.GlanceAppWidget, android.content.Context context, optional androidx.glance.GlanceId id, optional android.os.Bundle options, optional java.util.List<androidx.compose.ui.unit.DpSize>? sizes, optional Object? state);
+  }
+
+  public final class BackgroundKt {
+    method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, long day, long night);
+  }
+
+  public abstract sealed class CheckBoxColors {
+  }
+
+  public final class CheckBoxKt {
+    method @androidx.compose.runtime.Composable public static void CheckBox(boolean checked, androidx.glance.action.Action? onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines);
+    method @androidx.compose.runtime.Composable public static void CheckBox(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines);
+    method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.glance.ExperimentalGlanceApi public static void CheckBox(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines, optional String? key);
+  }
+
+  public final class CheckboxDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors();
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors(long checkedColor, long uncheckedColor);
+    field public static final androidx.glance.appwidget.CheckboxDefaults INSTANCE;
+  }
+
+  public final class CircularProgressIndicatorKt {
+    method @androidx.compose.runtime.Composable public static void CircularProgressIndicator(optional androidx.glance.GlanceModifier modifier, optional androidx.glance.unit.ColorProvider color);
+  }
+
+  public final class CompositionLocalsKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<android.os.Bundle> getLocalAppWidgetOptions();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<android.os.Bundle> LocalAppWidgetOptions;
+  }
+
+  public final class CornerRadiusKt {
+    method public static androidx.glance.GlanceModifier cornerRadius(androidx.glance.GlanceModifier, float radius);
+    method public static androidx.glance.GlanceModifier cornerRadius(androidx.glance.GlanceModifier, @DimenRes int radius);
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalGlanceRemoteViewsApi {
+  }
+
+  public abstract class GlanceAppWidget {
+    ctor public GlanceAppWidget(optional @LayoutRes int errorUiLayout);
+    method public androidx.glance.appwidget.SizeMode getSizeMode();
+    method public androidx.glance.state.GlanceStateDefinition<?>? getStateDefinition();
+    method @kotlin.jvm.Throws(exceptionClasses=Throwable::class) public void onCompositionError(android.content.Context context, androidx.glance.GlanceId glanceId, int appWidgetId, Throwable throwable) throws java.lang.Throwable;
+    method public suspend Object? onDelete(android.content.Context context, androidx.glance.GlanceId glanceId, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public abstract suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public final suspend Object? update(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public androidx.glance.appwidget.SizeMode sizeMode;
+    property public androidx.glance.state.GlanceStateDefinition<?>? stateDefinition;
+  }
+
+  public final class GlanceAppWidgetKt {
+    method public static suspend Object? provideContent(androidx.glance.appwidget.GlanceAppWidget, kotlin.jvm.functions.Function0<kotlin.Unit> content, kotlin.coroutines.Continuation<?>);
+    method public static suspend Object? updateAll(androidx.glance.appwidget.GlanceAppWidget, android.content.Context context, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend inline <reified State> Object? updateIf(androidx.glance.appwidget.GlanceAppWidget, android.content.Context context, kotlin.jvm.functions.Function1<? super State,java.lang.Boolean> predicate, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  public final class GlanceAppWidgetManager {
+    ctor public GlanceAppWidgetManager(android.content.Context context);
+    method public int getAppWidgetId(androidx.glance.GlanceId glanceId);
+    method public suspend Object? getAppWidgetSizes(androidx.glance.GlanceId glanceId, kotlin.coroutines.Continuation<? super java.util.List<? extends androidx.compose.ui.unit.DpSize>>);
+    method public androidx.glance.GlanceId? getGlanceIdBy(android.content.Intent configurationIntent);
+    method public androidx.glance.GlanceId getGlanceIdBy(int appWidgetId);
+    method public suspend <T extends androidx.glance.appwidget.GlanceAppWidget> Object? getGlanceIds(Class<T> provider, kotlin.coroutines.Continuation<? super java.util.List<? extends androidx.glance.GlanceId>>);
+    method public suspend <T extends androidx.glance.appwidget.GlanceAppWidgetReceiver> Object? requestPinGlanceAppWidget(Class<T> receiver, optional androidx.glance.appwidget.GlanceAppWidget? preview, optional Object? previewState, optional android.app.PendingIntent? successCallback, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+  }
+
+  public abstract class GlanceAppWidgetReceiver extends android.appwidget.AppWidgetProvider {
+    ctor public GlanceAppWidgetReceiver();
+    method @SuppressCompatibility @androidx.glance.ExperimentalGlanceApi public kotlin.coroutines.CoroutineContext getCoroutineContext();
+    method public abstract androidx.glance.appwidget.GlanceAppWidget getGlanceAppWidget();
+    property @SuppressCompatibility @androidx.glance.ExperimentalGlanceApi public kotlin.coroutines.CoroutineContext coroutineContext;
+    property public abstract androidx.glance.appwidget.GlanceAppWidget glanceAppWidget;
+    field public static final String ACTION_DEBUG_UPDATE = "androidx.glance.appwidget.action.DEBUG_UPDATE";
+    field public static final androidx.glance.appwidget.GlanceAppWidgetReceiver.Companion Companion;
+  }
+
+  public static final class GlanceAppWidgetReceiver.Companion {
+  }
+
+  @SuppressCompatibility @androidx.glance.appwidget.ExperimentalGlanceRemoteViewsApi public final class GlanceRemoteViews {
+    ctor public GlanceRemoteViews();
+    method public suspend Object? compose(android.content.Context context, long size, optional Object? state, optional android.os.Bundle appWidgetOptions, kotlin.jvm.functions.Function0<kotlin.Unit> content, kotlin.coroutines.Continuation<? super androidx.glance.appwidget.RemoteViewsCompositionResult>);
+  }
+
+  public final class ImageProvidersKt {
+    method public static androidx.glance.ImageProvider ImageProvider(android.net.Uri uri);
+  }
+
+  public final class LinearProgressIndicatorKt {
+    method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.glance.GlanceModifier modifier, optional androidx.glance.unit.ColorProvider color, optional androidx.glance.unit.ColorProvider backgroundColor);
+    method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(float progress, optional androidx.glance.GlanceModifier modifier, optional androidx.glance.unit.ColorProvider color, optional androidx.glance.unit.ColorProvider backgroundColor);
+  }
+
+  public final class ProgressIndicatorDefaults {
+    method public androidx.glance.unit.ColorProvider getBackgroundColorProvider();
+    method public androidx.glance.unit.ColorProvider getIndicatorColorProvider();
+    property public final androidx.glance.unit.ColorProvider BackgroundColorProvider;
+    property public final androidx.glance.unit.ColorProvider IndicatorColorProvider;
+    field public static final androidx.glance.appwidget.ProgressIndicatorDefaults INSTANCE;
+  }
+
+  public final class RadioButtonColors {
+  }
+
+  public final class RadioButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.RadioButtonColors colors();
+    method public androidx.glance.appwidget.RadioButtonColors colors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
+    method public androidx.glance.appwidget.RadioButtonColors colors(long checkedColor, long uncheckedColor);
+    field public static final androidx.glance.appwidget.RadioButtonDefaults INSTANCE;
+  }
+
+  public final class RadioButtonKt {
+    method @androidx.compose.runtime.Composable public static void RadioButton(boolean checked, androidx.glance.action.Action? onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines);
+    method @androidx.compose.runtime.Composable public static void RadioButton(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines);
+    method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.glance.ExperimentalGlanceApi public static void RadioButton(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines, optional String? key);
+    method public static androidx.glance.GlanceModifier selectableGroup(androidx.glance.GlanceModifier);
+  }
+
+  @SuppressCompatibility @androidx.glance.appwidget.ExperimentalGlanceRemoteViewsApi public final class RemoteViewsCompositionResult {
+    ctor public RemoteViewsCompositionResult(android.widget.RemoteViews remoteViews);
+    method public android.widget.RemoteViews getRemoteViews();
+    property public final android.widget.RemoteViews remoteViews;
+  }
+
+  public sealed interface SizeMode {
+  }
+
+  public static final class SizeMode.Exact implements androidx.glance.appwidget.SizeMode {
+    field public static final androidx.glance.appwidget.SizeMode.Exact INSTANCE;
+  }
+
+  public static final class SizeMode.Responsive implements androidx.glance.appwidget.SizeMode {
+    ctor public SizeMode.Responsive(java.util.Set<androidx.compose.ui.unit.DpSize> sizes);
+    method public java.util.Set<androidx.compose.ui.unit.DpSize> getSizes();
+    property public final java.util.Set<androidx.compose.ui.unit.DpSize> sizes;
+  }
+
+  public static final class SizeMode.Single implements androidx.glance.appwidget.SizeMode {
+    field public static final androidx.glance.appwidget.SizeMode.Single INSTANCE;
+  }
+
+  public abstract sealed class SwitchColors {
+  }
+
+  public final class SwitchDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.SwitchColors colors();
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.SwitchColors colors(androidx.glance.unit.ColorProvider checkedThumbColor, androidx.glance.unit.ColorProvider uncheckedThumbColor, androidx.glance.unit.ColorProvider checkedTrackColor, androidx.glance.unit.ColorProvider uncheckedTrackColor);
+    field public static final androidx.glance.appwidget.SwitchDefaults INSTANCE;
+  }
+
+  public final class SwitchKt {
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, androidx.glance.action.Action? onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines);
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines);
+    method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.glance.ExperimentalGlanceApi public static void Switch(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines, optional String? key);
+  }
+
+}
+
+package androidx.glance.appwidget.action {
+
+  public interface ActionCallback {
+    method public suspend Object? onAction(android.content.Context context, androidx.glance.GlanceId glanceId, androidx.glance.action.ActionParameters parameters, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  public final class RunCallbackActionKt {
+    method public static inline <reified T extends androidx.glance.appwidget.action.ActionCallback> androidx.glance.action.Action actionRunCallback(optional androidx.glance.action.ActionParameters parameters);
+    method public static <T extends androidx.glance.appwidget.action.ActionCallback> androidx.glance.action.Action actionRunCallback(Class<T> callbackClass, optional androidx.glance.action.ActionParameters parameters);
+  }
+
+  public final class SendBroadcastActionKt {
+    method public static inline <reified T extends android.content.BroadcastReceiver> androidx.glance.action.Action actionSendBroadcast();
+    method public static androidx.glance.action.Action actionSendBroadcast(android.content.ComponentName componentName);
+    method public static androidx.glance.action.Action actionSendBroadcast(android.content.Intent intent);
+    method public static <T extends android.content.BroadcastReceiver> androidx.glance.action.Action actionSendBroadcast(Class<T> receiver);
+    method public static androidx.glance.action.Action actionSendBroadcast(String action, optional android.content.ComponentName? componentName);
+  }
+
+  public final class StartActivityIntentActionKt {
+    method public static androidx.glance.action.Action actionStartActivity(android.content.Intent intent, optional androidx.glance.action.ActionParameters parameters);
+    method @SuppressCompatibility @androidx.glance.ExperimentalGlanceApi public static androidx.glance.action.Action actionStartActivity(android.content.Intent intent, optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+  }
+
+  public final class StartServiceActionKt {
+    method public static androidx.glance.action.Action actionStartService(android.content.ComponentName componentName, optional boolean isForegroundService);
+    method public static androidx.glance.action.Action actionStartService(android.content.Intent intent, optional boolean isForegroundService);
+    method public static inline <reified T extends android.app.Service> androidx.glance.action.Action actionStartService(optional boolean isForegroundService);
+    method public static <T extends android.app.Service> androidx.glance.action.Action actionStartService(Class<T> service, optional boolean isForegroundService);
+  }
+
+  public final class ToggleableKt {
+    method public static androidx.glance.action.ActionParameters.Key<java.lang.Boolean> getToggleableStateKey();
+    property public static final androidx.glance.action.ActionParameters.Key<java.lang.Boolean> ToggleableStateKey;
+  }
+
+}
+
+package androidx.glance.appwidget.components {
+
+  public final class ButtonsKt {
+    method @androidx.compose.runtime.Composable public static void CircleIconButton(androidx.glance.ImageProvider imageProvider, String? contentDescription, androidx.glance.action.Action onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.unit.ColorProvider? backgroundColor, optional androidx.glance.unit.ColorProvider contentColor);
+    method @androidx.compose.runtime.Composable public static void CircleIconButton(androidx.glance.ImageProvider imageProvider, String? contentDescription, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.unit.ColorProvider? backgroundColor, optional androidx.glance.unit.ColorProvider contentColor, optional String? key);
+    method @androidx.compose.runtime.Composable public static void FilledButton(String text, androidx.glance.action.Action onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.ImageProvider? icon, optional androidx.glance.ButtonColors colors, optional int maxLines);
+    method @androidx.compose.runtime.Composable public static void FilledButton(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.ImageProvider? icon, optional androidx.glance.ButtonColors colors, optional int maxLines, optional String? key);
+    method @androidx.compose.runtime.Composable public static void OutlineButton(String text, androidx.glance.unit.ColorProvider contentColor, androidx.glance.action.Action onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.ImageProvider? icon, optional int maxLines);
+    method @androidx.compose.runtime.Composable public static void OutlineButton(String text, androidx.glance.unit.ColorProvider contentColor, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.ImageProvider? icon, optional int maxLines, optional String? key);
+    method @androidx.compose.runtime.Composable public static void SquareIconButton(androidx.glance.ImageProvider imageProvider, String? contentDescription, androidx.glance.action.Action onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.unit.ColorProvider backgroundColor, optional androidx.glance.unit.ColorProvider contentColor);
+    method @androidx.compose.runtime.Composable public static void SquareIconButton(androidx.glance.ImageProvider imageProvider, String? contentDescription, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.unit.ColorProvider backgroundColor, optional androidx.glance.unit.ColorProvider contentColor, optional String? key);
+  }
+
+  public final class ScaffoldKt {
+    method @androidx.compose.runtime.Composable public static void Scaffold(kotlin.jvm.functions.Function0<kotlin.Unit> titleBar, optional androidx.glance.GlanceModifier modifier, optional androidx.glance.unit.ColorProvider backgroundColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class TitleBarKt {
+    method @androidx.compose.runtime.Composable public static void TitleBar(androidx.glance.ImageProvider startIcon, String title, optional androidx.glance.unit.ColorProvider? iconColor, optional androidx.glance.unit.ColorProvider textColor, optional androidx.glance.GlanceModifier modifier, optional androidx.glance.text.FontFamily? fontFamily, optional kotlin.jvm.functions.Function1<? super androidx.glance.layout.RowScope,kotlin.Unit> actions);
+  }
+
+}
+
+package androidx.glance.appwidget.lazy {
+
+  public abstract sealed class GridCells {
+  }
+
+  @RequiresApi(31) public static final class GridCells.Adaptive extends androidx.glance.appwidget.lazy.GridCells {
+    ctor public GridCells.Adaptive(float minSize);
+    method public float getMinSize();
+    property public final float minSize;
+  }
+
+  public static final class GridCells.Fixed extends androidx.glance.appwidget.lazy.GridCells {
+    ctor public GridCells.Fixed(int count);
+    method public int getCount();
+    property public final int count;
+  }
+
+  @androidx.glance.appwidget.lazy.LazyScopeMarker public interface LazyItemScope {
+  }
+
+  public final class LazyListKt {
+    method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.glance.ExperimentalGlanceApi public static void LazyColumn(android.os.Bundle activityOptions, optional androidx.glance.GlanceModifier modifier, optional int horizontalAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.appwidget.lazy.LazyListScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void LazyColumn(optional androidx.glance.GlanceModifier modifier, optional int horizontalAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.appwidget.lazy.LazyListScope,kotlin.Unit> content);
+    method public static inline <T> void items(androidx.glance.appwidget.lazy.LazyListScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function1<? super T,java.lang.Long> itemId, kotlin.jvm.functions.Function2<? super androidx.glance.appwidget.lazy.LazyItemScope,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void items(androidx.glance.appwidget.lazy.LazyListScope, T[] items, optional kotlin.jvm.functions.Function1<? super T,java.lang.Long> itemId, kotlin.jvm.functions.Function2<? super androidx.glance.appwidget.lazy.LazyItemScope,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void itemsIndexed(androidx.glance.appwidget.lazy.LazyListScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,java.lang.Long> itemId, kotlin.jvm.functions.Function3<? super androidx.glance.appwidget.lazy.LazyItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void itemsIndexed(androidx.glance.appwidget.lazy.LazyListScope, T[] items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,java.lang.Long> itemId, kotlin.jvm.functions.Function3<? super androidx.glance.appwidget.lazy.LazyItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+  }
+
+  @androidx.glance.appwidget.lazy.LazyScopeMarker @kotlin.jvm.JvmDefaultWithCompatibility public interface LazyListScope {
+    method public void item(optional long itemId, kotlin.jvm.functions.Function1<? super androidx.glance.appwidget.lazy.LazyItemScope,kotlin.Unit> content);
+    method public void items(int count, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Long> itemId, kotlin.jvm.functions.Function2<? super androidx.glance.appwidget.lazy.LazyItemScope,? super java.lang.Integer,kotlin.Unit> itemContent);
+    field public static final androidx.glance.appwidget.lazy.LazyListScope.Companion Companion;
+    field public static final long UnspecifiedItemId = -9223372036854775808L; // 0x8000000000000000L
+  }
+
+  public static final class LazyListScope.Companion {
+    field public static final long UnspecifiedItemId = -9223372036854775808L; // 0x8000000000000000L
+  }
+
+  @kotlin.DslMarker public @interface LazyScopeMarker {
+  }
+
+  public final class LazyVerticalGridKt {
+    method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.glance.ExperimentalGlanceApi public static void LazyVerticalGrid(androidx.glance.appwidget.lazy.GridCells gridCells, android.os.Bundle activityOptions, optional androidx.glance.GlanceModifier modifier, optional int horizontalAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.appwidget.lazy.LazyVerticalGridScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void LazyVerticalGrid(androidx.glance.appwidget.lazy.GridCells gridCells, optional androidx.glance.GlanceModifier modifier, optional int horizontalAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.appwidget.lazy.LazyVerticalGridScope,kotlin.Unit> content);
+    method public static inline <T> void items(androidx.glance.appwidget.lazy.LazyVerticalGridScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function1<? super T,java.lang.Long> itemId, kotlin.jvm.functions.Function2<? super androidx.glance.appwidget.lazy.LazyItemScope,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void items(androidx.glance.appwidget.lazy.LazyVerticalGridScope, T[] items, optional kotlin.jvm.functions.Function1<? super T,java.lang.Long> itemId, kotlin.jvm.functions.Function2<? super androidx.glance.appwidget.lazy.LazyItemScope,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void itemsIndexed(androidx.glance.appwidget.lazy.LazyVerticalGridScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,java.lang.Long> itemId, kotlin.jvm.functions.Function3<? super androidx.glance.appwidget.lazy.LazyItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void itemsIndexed(androidx.glance.appwidget.lazy.LazyVerticalGridScope, T[] items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,java.lang.Long> itemId, kotlin.jvm.functions.Function3<? super androidx.glance.appwidget.lazy.LazyItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+  }
+
+  @androidx.glance.appwidget.lazy.LazyScopeMarker @kotlin.jvm.JvmDefaultWithCompatibility public interface LazyVerticalGridScope {
+    method public void item(optional long itemId, kotlin.jvm.functions.Function1<? super androidx.glance.appwidget.lazy.LazyItemScope,kotlin.Unit> content);
+    method public void items(int count, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Long> itemId, kotlin.jvm.functions.Function2<? super androidx.glance.appwidget.lazy.LazyItemScope,? super java.lang.Integer,kotlin.Unit> itemContent);
+    field public static final androidx.glance.appwidget.lazy.LazyVerticalGridScope.Companion Companion;
+    field public static final long UnspecifiedItemId = -9223372036854775808L; // 0x8000000000000000L
+  }
+
+  public static final class LazyVerticalGridScope.Companion {
+    field public static final long UnspecifiedItemId = -9223372036854775808L; // 0x8000000000000000L
+  }
+
+}
+
+package androidx.glance.appwidget.state {
+
+  public final class GlanceAppWidgetStateKt {
+    method public static suspend <T> Object? getAppWidgetState(android.content.Context context, androidx.glance.state.GlanceStateDefinition<T> definition, androidx.glance.GlanceId glanceId, kotlin.coroutines.Continuation<? super T>);
+    method public static suspend <T> Object? getAppWidgetState(androidx.glance.appwidget.GlanceAppWidget, android.content.Context context, androidx.glance.GlanceId glanceId, kotlin.coroutines.Continuation<? super T>);
+    method public static suspend Object? updateAppWidgetState(android.content.Context context, androidx.glance.GlanceId glanceId, kotlin.jvm.functions.Function2<? super androidx.datastore.preferences.core.MutablePreferences,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> updateState, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend <T> Object? updateAppWidgetState(android.content.Context context, androidx.glance.state.GlanceStateDefinition<T> definition, androidx.glance.GlanceId glanceId, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super T>,?> updateState, kotlin.coroutines.Continuation<? super T>);
+  }
+
+}
+
diff --git a/glance/glance-appwidget/api/res-1.1.0-beta01.txt b/glance/glance-appwidget/api/res-1.1.0-beta01.txt
new file mode 100644
index 0000000..dba4906
--- /dev/null
+++ b/glance/glance-appwidget/api/res-1.1.0-beta01.txt
@@ -0,0 +1,2 @@
+bool glance_appwidget_available
+layout glance_default_loading_layout
diff --git a/glance/glance-appwidget/api/restricted_1.1.0-beta01.txt b/glance/glance-appwidget/api/restricted_1.1.0-beta01.txt
new file mode 100644
index 0000000..c2b95cf
--- /dev/null
+++ b/glance/glance-appwidget/api/restricted_1.1.0-beta01.txt
@@ -0,0 +1,311 @@
+// Signature format: 4.0
+package androidx.glance.appwidget {
+
+  public final class AndroidRemoteViewsKt {
+    method @androidx.compose.runtime.Composable public static void AndroidRemoteViews(android.widget.RemoteViews remoteViews, optional androidx.glance.GlanceModifier modifier);
+    method @androidx.compose.runtime.Composable public static void AndroidRemoteViews(android.widget.RemoteViews remoteViews, @IdRes int containerViewId, optional androidx.glance.GlanceModifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class AppWidgetBackgroundKt {
+    method public static androidx.glance.GlanceModifier appWidgetBackground(androidx.glance.GlanceModifier);
+  }
+
+  public final class AppWidgetComposerKt {
+    method public static suspend Object? compose(androidx.glance.appwidget.GlanceAppWidget, android.content.Context context, optional androidx.glance.GlanceId id, optional android.os.Bundle? options, optional androidx.compose.ui.unit.DpSize? size, optional Object? state, kotlin.coroutines.Continuation<? super android.widget.RemoteViews>);
+    method @SuppressCompatibility @androidx.glance.ExperimentalGlanceApi public static kotlinx.coroutines.flow.Flow<android.widget.RemoteViews> runComposition(androidx.glance.appwidget.GlanceAppWidget, android.content.Context context, optional androidx.glance.GlanceId id, optional android.os.Bundle options, optional java.util.List<androidx.compose.ui.unit.DpSize>? sizes, optional Object? state);
+  }
+
+  public final class BackgroundKt {
+    method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, long day, long night);
+  }
+
+  public abstract sealed class CheckBoxColors {
+  }
+
+  public final class CheckBoxKt {
+    method @androidx.compose.runtime.Composable public static void CheckBox(boolean checked, androidx.glance.action.Action? onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines);
+    method @androidx.compose.runtime.Composable public static void CheckBox(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines);
+    method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.glance.ExperimentalGlanceApi public static void CheckBox(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines, optional String? key);
+  }
+
+  public final class CheckboxDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors();
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors(long checkedColor, long uncheckedColor);
+    field public static final androidx.glance.appwidget.CheckboxDefaults INSTANCE;
+  }
+
+  public final class CircularProgressIndicatorKt {
+    method @androidx.compose.runtime.Composable public static void CircularProgressIndicator(optional androidx.glance.GlanceModifier modifier, optional androidx.glance.unit.ColorProvider color);
+  }
+
+  public final class CompositionLocalsKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<android.os.Bundle> getLocalAppWidgetOptions();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<android.os.Bundle> LocalAppWidgetOptions;
+  }
+
+  public final class CornerRadiusKt {
+    method public static androidx.glance.GlanceModifier cornerRadius(androidx.glance.GlanceModifier, float radius);
+    method public static androidx.glance.GlanceModifier cornerRadius(androidx.glance.GlanceModifier, @DimenRes int radius);
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalGlanceRemoteViewsApi {
+  }
+
+  public abstract class GlanceAppWidget {
+    ctor public GlanceAppWidget(optional @LayoutRes int errorUiLayout);
+    method public androidx.glance.appwidget.SizeMode getSizeMode();
+    method public androidx.glance.state.GlanceStateDefinition<?>? getStateDefinition();
+    method @kotlin.jvm.Throws(exceptionClasses=Throwable::class) public void onCompositionError(android.content.Context context, androidx.glance.GlanceId glanceId, int appWidgetId, Throwable throwable) throws java.lang.Throwable;
+    method public suspend Object? onDelete(android.content.Context context, androidx.glance.GlanceId glanceId, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public abstract suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public final suspend Object? update(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public androidx.glance.appwidget.SizeMode sizeMode;
+    property public androidx.glance.state.GlanceStateDefinition<?>? stateDefinition;
+  }
+
+  public final class GlanceAppWidgetKt {
+    method public static suspend Object? provideContent(androidx.glance.appwidget.GlanceAppWidget, kotlin.jvm.functions.Function0<kotlin.Unit> content, kotlin.coroutines.Continuation<?>);
+    method public static suspend Object? updateAll(androidx.glance.appwidget.GlanceAppWidget, android.content.Context context, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend inline <reified State> Object? updateIf(androidx.glance.appwidget.GlanceAppWidget, android.content.Context context, kotlin.jvm.functions.Function1<? super State,java.lang.Boolean> predicate, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  public final class GlanceAppWidgetManager {
+    ctor public GlanceAppWidgetManager(android.content.Context context);
+    method public int getAppWidgetId(androidx.glance.GlanceId glanceId);
+    method public suspend Object? getAppWidgetSizes(androidx.glance.GlanceId glanceId, kotlin.coroutines.Continuation<? super java.util.List<? extends androidx.compose.ui.unit.DpSize>>);
+    method public androidx.glance.GlanceId? getGlanceIdBy(android.content.Intent configurationIntent);
+    method public androidx.glance.GlanceId getGlanceIdBy(int appWidgetId);
+    method public suspend <T extends androidx.glance.appwidget.GlanceAppWidget> Object? getGlanceIds(Class<T> provider, kotlin.coroutines.Continuation<? super java.util.List<? extends androidx.glance.GlanceId>>);
+    method public suspend <T extends androidx.glance.appwidget.GlanceAppWidgetReceiver> Object? requestPinGlanceAppWidget(Class<T> receiver, optional androidx.glance.appwidget.GlanceAppWidget? preview, optional Object? previewState, optional android.app.PendingIntent? successCallback, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+  }
+
+  public abstract class GlanceAppWidgetReceiver extends android.appwidget.AppWidgetProvider {
+    ctor public GlanceAppWidgetReceiver();
+    method @SuppressCompatibility @androidx.glance.ExperimentalGlanceApi public kotlin.coroutines.CoroutineContext getCoroutineContext();
+    method public abstract androidx.glance.appwidget.GlanceAppWidget getGlanceAppWidget();
+    property @SuppressCompatibility @androidx.glance.ExperimentalGlanceApi public kotlin.coroutines.CoroutineContext coroutineContext;
+    property public abstract androidx.glance.appwidget.GlanceAppWidget glanceAppWidget;
+    field public static final String ACTION_DEBUG_UPDATE = "androidx.glance.appwidget.action.DEBUG_UPDATE";
+    field public static final androidx.glance.appwidget.GlanceAppWidgetReceiver.Companion Companion;
+  }
+
+  public static final class GlanceAppWidgetReceiver.Companion {
+  }
+
+  @SuppressCompatibility @androidx.glance.appwidget.ExperimentalGlanceRemoteViewsApi public final class GlanceRemoteViews {
+    ctor public GlanceRemoteViews();
+    method public suspend Object? compose(android.content.Context context, long size, optional Object? state, optional android.os.Bundle appWidgetOptions, kotlin.jvm.functions.Function0<kotlin.Unit> content, kotlin.coroutines.Continuation<? super androidx.glance.appwidget.RemoteViewsCompositionResult>);
+  }
+
+  public final class ImageProvidersKt {
+    method public static androidx.glance.ImageProvider ImageProvider(android.net.Uri uri);
+  }
+
+  public final class LinearProgressIndicatorKt {
+    method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.glance.GlanceModifier modifier, optional androidx.glance.unit.ColorProvider color, optional androidx.glance.unit.ColorProvider backgroundColor);
+    method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(float progress, optional androidx.glance.GlanceModifier modifier, optional androidx.glance.unit.ColorProvider color, optional androidx.glance.unit.ColorProvider backgroundColor);
+  }
+
+  public final class ProgressIndicatorDefaults {
+    method public androidx.glance.unit.ColorProvider getBackgroundColorProvider();
+    method public androidx.glance.unit.ColorProvider getIndicatorColorProvider();
+    property public final androidx.glance.unit.ColorProvider BackgroundColorProvider;
+    property public final androidx.glance.unit.ColorProvider IndicatorColorProvider;
+    field public static final androidx.glance.appwidget.ProgressIndicatorDefaults INSTANCE;
+  }
+
+  public final class RadioButtonColors {
+  }
+
+  public final class RadioButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.RadioButtonColors colors();
+    method public androidx.glance.appwidget.RadioButtonColors colors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
+    method public androidx.glance.appwidget.RadioButtonColors colors(long checkedColor, long uncheckedColor);
+    field public static final androidx.glance.appwidget.RadioButtonDefaults INSTANCE;
+  }
+
+  public final class RadioButtonKt {
+    method @androidx.compose.runtime.Composable public static void RadioButton(boolean checked, androidx.glance.action.Action? onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines);
+    method @androidx.compose.runtime.Composable public static void RadioButton(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines);
+    method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.glance.ExperimentalGlanceApi public static void RadioButton(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines, optional String? key);
+    method public static androidx.glance.GlanceModifier selectableGroup(androidx.glance.GlanceModifier);
+  }
+
+  @SuppressCompatibility @androidx.glance.appwidget.ExperimentalGlanceRemoteViewsApi public final class RemoteViewsCompositionResult {
+    ctor public RemoteViewsCompositionResult(android.widget.RemoteViews remoteViews);
+    method public android.widget.RemoteViews getRemoteViews();
+    property public final android.widget.RemoteViews remoteViews;
+  }
+
+  public sealed interface SizeMode {
+  }
+
+  public static final class SizeMode.Exact implements androidx.glance.appwidget.SizeMode {
+    field public static final androidx.glance.appwidget.SizeMode.Exact INSTANCE;
+  }
+
+  public static final class SizeMode.Responsive implements androidx.glance.appwidget.SizeMode {
+    ctor public SizeMode.Responsive(java.util.Set<androidx.compose.ui.unit.DpSize> sizes);
+    method public java.util.Set<androidx.compose.ui.unit.DpSize> getSizes();
+    property public final java.util.Set<androidx.compose.ui.unit.DpSize> sizes;
+  }
+
+  public static final class SizeMode.Single implements androidx.glance.appwidget.SizeMode {
+    field public static final androidx.glance.appwidget.SizeMode.Single INSTANCE;
+  }
+
+  public abstract sealed class SwitchColors {
+  }
+
+  public final class SwitchDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.SwitchColors colors();
+    method @androidx.compose.runtime.Composable public androidx.glance.appwidget.SwitchColors colors(androidx.glance.unit.ColorProvider checkedThumbColor, androidx.glance.unit.ColorProvider uncheckedThumbColor, androidx.glance.unit.ColorProvider checkedTrackColor, androidx.glance.unit.ColorProvider uncheckedTrackColor);
+    field public static final androidx.glance.appwidget.SwitchDefaults INSTANCE;
+  }
+
+  public final class SwitchKt {
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, androidx.glance.action.Action? onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines);
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines);
+    method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.glance.ExperimentalGlanceApi public static void Switch(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines, optional String? key);
+  }
+
+}
+
+package androidx.glance.appwidget.action {
+
+  public interface ActionCallback {
+    method public suspend Object? onAction(android.content.Context context, androidx.glance.GlanceId glanceId, androidx.glance.action.ActionParameters parameters, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  public final class RunCallbackActionKt {
+    method public static inline <reified T extends androidx.glance.appwidget.action.ActionCallback> androidx.glance.action.Action actionRunCallback(optional androidx.glance.action.ActionParameters parameters);
+    method public static <T extends androidx.glance.appwidget.action.ActionCallback> androidx.glance.action.Action actionRunCallback(Class<T> callbackClass, optional androidx.glance.action.ActionParameters parameters);
+  }
+
+  public final class SendBroadcastActionKt {
+    method public static inline <reified T extends android.content.BroadcastReceiver> androidx.glance.action.Action actionSendBroadcast();
+    method public static androidx.glance.action.Action actionSendBroadcast(android.content.ComponentName componentName);
+    method public static androidx.glance.action.Action actionSendBroadcast(android.content.Intent intent);
+    method public static <T extends android.content.BroadcastReceiver> androidx.glance.action.Action actionSendBroadcast(Class<T> receiver);
+    method public static androidx.glance.action.Action actionSendBroadcast(String action, optional android.content.ComponentName? componentName);
+  }
+
+  public final class StartActivityIntentActionKt {
+    method public static androidx.glance.action.Action actionStartActivity(android.content.Intent intent, optional androidx.glance.action.ActionParameters parameters);
+    method @SuppressCompatibility @androidx.glance.ExperimentalGlanceApi public static androidx.glance.action.Action actionStartActivity(android.content.Intent intent, optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+  }
+
+  public final class StartServiceActionKt {
+    method public static androidx.glance.action.Action actionStartService(android.content.ComponentName componentName, optional boolean isForegroundService);
+    method public static androidx.glance.action.Action actionStartService(android.content.Intent intent, optional boolean isForegroundService);
+    method public static inline <reified T extends android.app.Service> androidx.glance.action.Action actionStartService(optional boolean isForegroundService);
+    method public static <T extends android.app.Service> androidx.glance.action.Action actionStartService(Class<T> service, optional boolean isForegroundService);
+  }
+
+  public final class ToggleableKt {
+    method public static androidx.glance.action.ActionParameters.Key<java.lang.Boolean> getToggleableStateKey();
+    property public static final androidx.glance.action.ActionParameters.Key<java.lang.Boolean> ToggleableStateKey;
+  }
+
+}
+
+package androidx.glance.appwidget.components {
+
+  public final class ButtonsKt {
+    method @androidx.compose.runtime.Composable public static void CircleIconButton(androidx.glance.ImageProvider imageProvider, String? contentDescription, androidx.glance.action.Action onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.unit.ColorProvider? backgroundColor, optional androidx.glance.unit.ColorProvider contentColor);
+    method @androidx.compose.runtime.Composable public static void CircleIconButton(androidx.glance.ImageProvider imageProvider, String? contentDescription, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.unit.ColorProvider? backgroundColor, optional androidx.glance.unit.ColorProvider contentColor, optional String? key);
+    method @androidx.compose.runtime.Composable public static void FilledButton(String text, androidx.glance.action.Action onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.ImageProvider? icon, optional androidx.glance.ButtonColors colors, optional int maxLines);
+    method @androidx.compose.runtime.Composable public static void FilledButton(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.ImageProvider? icon, optional androidx.glance.ButtonColors colors, optional int maxLines, optional String? key);
+    method @androidx.compose.runtime.Composable public static void OutlineButton(String text, androidx.glance.unit.ColorProvider contentColor, androidx.glance.action.Action onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.ImageProvider? icon, optional int maxLines);
+    method @androidx.compose.runtime.Composable public static void OutlineButton(String text, androidx.glance.unit.ColorProvider contentColor, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.ImageProvider? icon, optional int maxLines, optional String? key);
+    method @androidx.compose.runtime.Composable public static void SquareIconButton(androidx.glance.ImageProvider imageProvider, String? contentDescription, androidx.glance.action.Action onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.unit.ColorProvider backgroundColor, optional androidx.glance.unit.ColorProvider contentColor);
+    method @androidx.compose.runtime.Composable public static void SquareIconButton(androidx.glance.ImageProvider imageProvider, String? contentDescription, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.unit.ColorProvider backgroundColor, optional androidx.glance.unit.ColorProvider contentColor, optional String? key);
+  }
+
+  public final class ScaffoldKt {
+    method @androidx.compose.runtime.Composable public static void Scaffold(kotlin.jvm.functions.Function0<kotlin.Unit> titleBar, optional androidx.glance.GlanceModifier modifier, optional androidx.glance.unit.ColorProvider backgroundColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class TitleBarKt {
+    method @androidx.compose.runtime.Composable public static void TitleBar(androidx.glance.ImageProvider startIcon, String title, optional androidx.glance.unit.ColorProvider? iconColor, optional androidx.glance.unit.ColorProvider textColor, optional androidx.glance.GlanceModifier modifier, optional androidx.glance.text.FontFamily? fontFamily, optional kotlin.jvm.functions.Function1<? super androidx.glance.layout.RowScope,kotlin.Unit> actions);
+  }
+
+}
+
+package androidx.glance.appwidget.lazy {
+
+  public abstract sealed class GridCells {
+  }
+
+  @RequiresApi(31) public static final class GridCells.Adaptive extends androidx.glance.appwidget.lazy.GridCells {
+    ctor public GridCells.Adaptive(float minSize);
+    method public float getMinSize();
+    property public final float minSize;
+  }
+
+  public static final class GridCells.Fixed extends androidx.glance.appwidget.lazy.GridCells {
+    ctor public GridCells.Fixed(int count);
+    method public int getCount();
+    property public final int count;
+  }
+
+  @androidx.glance.appwidget.lazy.LazyScopeMarker public interface LazyItemScope {
+  }
+
+  public final class LazyListKt {
+    method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.glance.ExperimentalGlanceApi public static void LazyColumn(android.os.Bundle activityOptions, optional androidx.glance.GlanceModifier modifier, optional int horizontalAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.appwidget.lazy.LazyListScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void LazyColumn(optional androidx.glance.GlanceModifier modifier, optional int horizontalAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.appwidget.lazy.LazyListScope,kotlin.Unit> content);
+    method public static inline <T> void items(androidx.glance.appwidget.lazy.LazyListScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function1<? super T,java.lang.Long> itemId, kotlin.jvm.functions.Function2<? super androidx.glance.appwidget.lazy.LazyItemScope,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void items(androidx.glance.appwidget.lazy.LazyListScope, T[] items, optional kotlin.jvm.functions.Function1<? super T,java.lang.Long> itemId, kotlin.jvm.functions.Function2<? super androidx.glance.appwidget.lazy.LazyItemScope,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void itemsIndexed(androidx.glance.appwidget.lazy.LazyListScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,java.lang.Long> itemId, kotlin.jvm.functions.Function3<? super androidx.glance.appwidget.lazy.LazyItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void itemsIndexed(androidx.glance.appwidget.lazy.LazyListScope, T[] items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,java.lang.Long> itemId, kotlin.jvm.functions.Function3<? super androidx.glance.appwidget.lazy.LazyItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+  }
+
+  @androidx.glance.appwidget.lazy.LazyScopeMarker @kotlin.jvm.JvmDefaultWithCompatibility public interface LazyListScope {
+    method public void item(optional long itemId, kotlin.jvm.functions.Function1<? super androidx.glance.appwidget.lazy.LazyItemScope,kotlin.Unit> content);
+    method public void items(int count, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Long> itemId, kotlin.jvm.functions.Function2<? super androidx.glance.appwidget.lazy.LazyItemScope,? super java.lang.Integer,kotlin.Unit> itemContent);
+    field public static final androidx.glance.appwidget.lazy.LazyListScope.Companion Companion;
+    field public static final long UnspecifiedItemId = -9223372036854775808L; // 0x8000000000000000L
+  }
+
+  public static final class LazyListScope.Companion {
+    field public static final long UnspecifiedItemId = -9223372036854775808L; // 0x8000000000000000L
+  }
+
+  @kotlin.DslMarker public @interface LazyScopeMarker {
+  }
+
+  public final class LazyVerticalGridKt {
+    method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.glance.ExperimentalGlanceApi public static void LazyVerticalGrid(androidx.glance.appwidget.lazy.GridCells gridCells, android.os.Bundle activityOptions, optional androidx.glance.GlanceModifier modifier, optional int horizontalAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.appwidget.lazy.LazyVerticalGridScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void LazyVerticalGrid(androidx.glance.appwidget.lazy.GridCells gridCells, optional androidx.glance.GlanceModifier modifier, optional int horizontalAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.appwidget.lazy.LazyVerticalGridScope,kotlin.Unit> content);
+    method public static inline <T> void items(androidx.glance.appwidget.lazy.LazyVerticalGridScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function1<? super T,java.lang.Long> itemId, kotlin.jvm.functions.Function2<? super androidx.glance.appwidget.lazy.LazyItemScope,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void items(androidx.glance.appwidget.lazy.LazyVerticalGridScope, T[] items, optional kotlin.jvm.functions.Function1<? super T,java.lang.Long> itemId, kotlin.jvm.functions.Function2<? super androidx.glance.appwidget.lazy.LazyItemScope,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void itemsIndexed(androidx.glance.appwidget.lazy.LazyVerticalGridScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,java.lang.Long> itemId, kotlin.jvm.functions.Function3<? super androidx.glance.appwidget.lazy.LazyItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void itemsIndexed(androidx.glance.appwidget.lazy.LazyVerticalGridScope, T[] items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,java.lang.Long> itemId, kotlin.jvm.functions.Function3<? super androidx.glance.appwidget.lazy.LazyItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+  }
+
+  @androidx.glance.appwidget.lazy.LazyScopeMarker @kotlin.jvm.JvmDefaultWithCompatibility public interface LazyVerticalGridScope {
+    method public void item(optional long itemId, kotlin.jvm.functions.Function1<? super androidx.glance.appwidget.lazy.LazyItemScope,kotlin.Unit> content);
+    method public void items(int count, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Long> itemId, kotlin.jvm.functions.Function2<? super androidx.glance.appwidget.lazy.LazyItemScope,? super java.lang.Integer,kotlin.Unit> itemContent);
+    field public static final androidx.glance.appwidget.lazy.LazyVerticalGridScope.Companion Companion;
+    field public static final long UnspecifiedItemId = -9223372036854775808L; // 0x8000000000000000L
+  }
+
+  public static final class LazyVerticalGridScope.Companion {
+    field public static final long UnspecifiedItemId = -9223372036854775808L; // 0x8000000000000000L
+  }
+
+}
+
+package androidx.glance.appwidget.state {
+
+  public final class GlanceAppWidgetStateKt {
+    method public static suspend <T> Object? getAppWidgetState(android.content.Context context, androidx.glance.state.GlanceStateDefinition<T> definition, androidx.glance.GlanceId glanceId, kotlin.coroutines.Continuation<? super T>);
+    method public static suspend <T> Object? getAppWidgetState(androidx.glance.appwidget.GlanceAppWidget, android.content.Context context, androidx.glance.GlanceId glanceId, kotlin.coroutines.Continuation<? super T>);
+    method public static suspend Object? updateAppWidgetState(android.content.Context context, androidx.glance.GlanceId glanceId, kotlin.jvm.functions.Function2<? super androidx.datastore.preferences.core.MutablePreferences,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> updateState, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend <T> Object? updateAppWidgetState(android.content.Context context, androidx.glance.state.GlanceStateDefinition<T> definition, androidx.glance.GlanceId glanceId, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super T>,?> updateState, kotlin.coroutines.Continuation<? super T>);
+  }
+
+}
+
diff --git a/glance/glance-material/api/1.1.0-beta01.txt b/glance/glance-material/api/1.1.0-beta01.txt
new file mode 100644
index 0000000..3df106d
--- /dev/null
+++ b/glance/glance-material/api/1.1.0-beta01.txt
@@ -0,0 +1,10 @@
+// Signature format: 4.0
+package androidx.glance.material {
+
+  public final class MaterialThemesKt {
+    method public static androidx.glance.color.ColorProviders ColorProviders(androidx.compose.material.Colors colors);
+    method public static androidx.glance.color.ColorProviders ColorProviders(androidx.compose.material.Colors light, androidx.compose.material.Colors dark);
+  }
+
+}
+
diff --git a/glance/glance-material/api/res-1.1.0-beta01.txt b/glance/glance-material/api/res-1.1.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/glance/glance-material/api/res-1.1.0-beta01.txt
diff --git a/glance/glance-material/api/restricted_1.1.0-beta01.txt b/glance/glance-material/api/restricted_1.1.0-beta01.txt
new file mode 100644
index 0000000..3df106d
--- /dev/null
+++ b/glance/glance-material/api/restricted_1.1.0-beta01.txt
@@ -0,0 +1,10 @@
+// Signature format: 4.0
+package androidx.glance.material {
+
+  public final class MaterialThemesKt {
+    method public static androidx.glance.color.ColorProviders ColorProviders(androidx.compose.material.Colors colors);
+    method public static androidx.glance.color.ColorProviders ColorProviders(androidx.compose.material.Colors light, androidx.compose.material.Colors dark);
+  }
+
+}
+
diff --git a/glance/glance-material3/api/1.1.0-beta01.txt b/glance/glance-material3/api/1.1.0-beta01.txt
new file mode 100644
index 0000000..36479f9
--- /dev/null
+++ b/glance/glance-material3/api/1.1.0-beta01.txt
@@ -0,0 +1,10 @@
+// Signature format: 4.0
+package androidx.glance.material3 {
+
+  public final class Material3ThemesKt {
+    method public static androidx.glance.color.ColorProviders ColorProviders(androidx.compose.material3.ColorScheme scheme);
+    method public static androidx.glance.color.ColorProviders ColorProviders(androidx.compose.material3.ColorScheme light, androidx.compose.material3.ColorScheme dark);
+  }
+
+}
+
diff --git a/glance/glance-material3/api/res-1.1.0-beta01.txt b/glance/glance-material3/api/res-1.1.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/glance/glance-material3/api/res-1.1.0-beta01.txt
diff --git a/glance/glance-material3/api/restricted_1.1.0-beta01.txt b/glance/glance-material3/api/restricted_1.1.0-beta01.txt
new file mode 100644
index 0000000..36479f9
--- /dev/null
+++ b/glance/glance-material3/api/restricted_1.1.0-beta01.txt
@@ -0,0 +1,10 @@
+// Signature format: 4.0
+package androidx.glance.material3 {
+
+  public final class Material3ThemesKt {
+    method public static androidx.glance.color.ColorProviders ColorProviders(androidx.compose.material3.ColorScheme scheme);
+    method public static androidx.glance.color.ColorProviders ColorProviders(androidx.compose.material3.ColorScheme light, androidx.compose.material3.ColorScheme dark);
+  }
+
+}
+
diff --git a/glance/glance-testing/api/1.1.0-beta01.txt b/glance/glance-testing/api/1.1.0-beta01.txt
new file mode 100644
index 0000000..cb3b9ca
--- /dev/null
+++ b/glance/glance-testing/api/1.1.0-beta01.txt
@@ -0,0 +1,79 @@
+// Signature format: 4.0
+package androidx.glance.testing {
+
+  public abstract class GlanceNode<T> {
+    method public abstract java.util.List<androidx.glance.testing.GlanceNode<T>> children();
+    method public final T getValue();
+    method public abstract String toDebugString();
+    property public final T value;
+  }
+
+  public final class GlanceNodeAssertion<R, T extends androidx.glance.testing.GlanceNode<R>> {
+    method public androidx.glance.testing.GlanceNodeAssertion<R,T> assert(androidx.glance.testing.GlanceNodeMatcher<R> matcher, optional kotlin.jvm.functions.Function0<java.lang.String>? messagePrefixOnError);
+    method public androidx.glance.testing.GlanceNodeAssertion<R,T> assertDoesNotExist();
+    method public androidx.glance.testing.GlanceNodeAssertion<R,T> assertExists();
+    method public androidx.glance.testing.GlanceNodeAssertionCollection<R,T> onChildren();
+  }
+
+  public final class GlanceNodeAssertionCollection<R, T extends androidx.glance.testing.GlanceNode<R>> {
+    method public androidx.glance.testing.GlanceNodeAssertionCollection<R,T> assertAll(androidx.glance.testing.GlanceNodeMatcher<R> matcher);
+    method public androidx.glance.testing.GlanceNodeAssertionCollection<R,T> assertAny(androidx.glance.testing.GlanceNodeMatcher<R> matcher);
+    method public androidx.glance.testing.GlanceNodeAssertionCollection<R,T> assertCountEquals(int expectedCount);
+    method public androidx.glance.testing.GlanceNodeAssertionCollection<R,T> filter(androidx.glance.testing.GlanceNodeMatcher<R> matcher);
+    method public operator androidx.glance.testing.GlanceNodeAssertion<R,T> get(int index);
+  }
+
+  public interface GlanceNodeAssertionsProvider<R, T extends androidx.glance.testing.GlanceNode<R>> {
+    method public androidx.glance.testing.GlanceNodeAssertionCollection<R,T> onAllNodes(androidx.glance.testing.GlanceNodeMatcher<R> matcher);
+    method public androidx.glance.testing.GlanceNodeAssertion<R,T> onNode(androidx.glance.testing.GlanceNodeMatcher<R> matcher);
+  }
+
+  public final class GlanceNodeMatcher<R> {
+    ctor public GlanceNodeMatcher(String description, kotlin.jvm.functions.Function1<? super androidx.glance.testing.GlanceNode<R>,java.lang.Boolean> matcher);
+    method public infix androidx.glance.testing.GlanceNodeMatcher<R> and(androidx.glance.testing.GlanceNodeMatcher<R> other);
+    method public boolean matches(androidx.glance.testing.GlanceNode<R> node);
+    method public boolean matchesAny(Iterable<? extends androidx.glance.testing.GlanceNode<R>> nodes);
+    method public operator androidx.glance.testing.GlanceNodeMatcher<R> not();
+    method public infix androidx.glance.testing.GlanceNodeMatcher<R> or(androidx.glance.testing.GlanceNodeMatcher<R> other);
+  }
+
+}
+
+package androidx.glance.testing.unit {
+
+  public final class GlanceMappedNode extends androidx.glance.testing.GlanceNode<androidx.glance.testing.unit.MappedNode> {
+    ctor public GlanceMappedNode(androidx.glance.testing.unit.MappedNode mappedNode);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public java.util.List<androidx.glance.testing.GlanceNode<androidx.glance.testing.unit.MappedNode>> children();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public String toDebugString();
+  }
+
+  public final class MappedNode {
+  }
+
+  public final class UnitTestAssertionExtensionsKt {
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasContentDescription(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, String value, optional boolean ignoreCase);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasContentDescriptionEqualTo(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, String value, optional boolean ignoreCase);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasNoClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasStartActivityClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, android.content.ComponentName componentName, optional androidx.glance.action.ActionParameters parameters);
+    method public static inline <reified T extends android.app.Activity> androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasStartActivityClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasTestTag(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, String testTag);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasText(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, String text, optional boolean ignoreCase);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasTextEqualTo(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, String text, optional boolean ignoreCase);
+  }
+
+  public final class UnitTestFiltersKt {
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasAnyDescendant(androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> matcher);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasClickAction();
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasContentDescription(String value, optional boolean ignoreCase);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasContentDescriptionEqualTo(String value, optional boolean ignoreCase);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasNoClickAction();
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasStartActivityClickAction(android.content.ComponentName componentName, optional androidx.glance.action.ActionParameters parameters);
+    method public static inline <reified T extends android.app.Activity> androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasStartActivityClickAction(optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasTestTag(String testTag);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasText(String text, optional boolean ignoreCase);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasTextEqualTo(String text, optional boolean ignoreCase);
+  }
+
+}
+
diff --git a/glance/glance-testing/api/res-1.1.0-beta01.txt b/glance/glance-testing/api/res-1.1.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/glance/glance-testing/api/res-1.1.0-beta01.txt
diff --git a/glance/glance-testing/api/restricted_1.1.0-beta01.txt b/glance/glance-testing/api/restricted_1.1.0-beta01.txt
new file mode 100644
index 0000000..1412248
--- /dev/null
+++ b/glance/glance-testing/api/restricted_1.1.0-beta01.txt
@@ -0,0 +1,81 @@
+// Signature format: 4.0
+package androidx.glance.testing {
+
+  public abstract class GlanceNode<T> {
+    method public abstract java.util.List<androidx.glance.testing.GlanceNode<T>> children();
+    method public final T getValue();
+    method public abstract String toDebugString();
+    property public final T value;
+  }
+
+  public final class GlanceNodeAssertion<R, T extends androidx.glance.testing.GlanceNode<R>> {
+    method public androidx.glance.testing.GlanceNodeAssertion<R,T> assert(androidx.glance.testing.GlanceNodeMatcher<R> matcher, optional kotlin.jvm.functions.Function0<java.lang.String>? messagePrefixOnError);
+    method public androidx.glance.testing.GlanceNodeAssertion<R,T> assertDoesNotExist();
+    method public androidx.glance.testing.GlanceNodeAssertion<R,T> assertExists();
+    method public androidx.glance.testing.GlanceNodeAssertionCollection<R,T> onChildren();
+  }
+
+  public final class GlanceNodeAssertionCollection<R, T extends androidx.glance.testing.GlanceNode<R>> {
+    method public androidx.glance.testing.GlanceNodeAssertionCollection<R,T> assertAll(androidx.glance.testing.GlanceNodeMatcher<R> matcher);
+    method public androidx.glance.testing.GlanceNodeAssertionCollection<R,T> assertAny(androidx.glance.testing.GlanceNodeMatcher<R> matcher);
+    method public androidx.glance.testing.GlanceNodeAssertionCollection<R,T> assertCountEquals(int expectedCount);
+    method public androidx.glance.testing.GlanceNodeAssertionCollection<R,T> filter(androidx.glance.testing.GlanceNodeMatcher<R> matcher);
+    method public operator androidx.glance.testing.GlanceNodeAssertion<R,T> get(int index);
+  }
+
+  public interface GlanceNodeAssertionsProvider<R, T extends androidx.glance.testing.GlanceNode<R>> {
+    method public androidx.glance.testing.GlanceNodeAssertionCollection<R,T> onAllNodes(androidx.glance.testing.GlanceNodeMatcher<R> matcher);
+    method public androidx.glance.testing.GlanceNodeAssertion<R,T> onNode(androidx.glance.testing.GlanceNodeMatcher<R> matcher);
+  }
+
+  public final class GlanceNodeMatcher<R> {
+    ctor public GlanceNodeMatcher(String description, kotlin.jvm.functions.Function1<? super androidx.glance.testing.GlanceNode<R>,java.lang.Boolean> matcher);
+    method public infix androidx.glance.testing.GlanceNodeMatcher<R> and(androidx.glance.testing.GlanceNodeMatcher<R> other);
+    method public boolean matches(androidx.glance.testing.GlanceNode<R> node);
+    method public boolean matchesAny(Iterable<? extends androidx.glance.testing.GlanceNode<R>> nodes);
+    method public operator androidx.glance.testing.GlanceNodeMatcher<R> not();
+    method public infix androidx.glance.testing.GlanceNodeMatcher<R> or(androidx.glance.testing.GlanceNodeMatcher<R> other);
+  }
+
+}
+
+package androidx.glance.testing.unit {
+
+  public final class GlanceMappedNode extends androidx.glance.testing.GlanceNode<androidx.glance.testing.unit.MappedNode> {
+    ctor public GlanceMappedNode(androidx.glance.testing.unit.MappedNode mappedNode);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public java.util.List<androidx.glance.testing.GlanceNode<androidx.glance.testing.unit.MappedNode>> children();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public String toDebugString();
+  }
+
+  public final class MappedNode {
+  }
+
+  public final class UnitTestAssertionExtensionsKt {
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasContentDescription(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, String value, optional boolean ignoreCase);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasContentDescriptionEqualTo(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, String value, optional boolean ignoreCase);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasNoClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasStartActivityClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, android.content.ComponentName componentName, optional androidx.glance.action.ActionParameters parameters);
+    method public static inline <reified T extends android.app.Activity> androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasStartActivityClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+    method @kotlin.PublishedApi internal static <T extends android.app.Activity> androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasStartActivityClickAction(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, Class<T> activityClass, optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasTestTag(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, String testTag);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasText(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, String text, optional boolean ignoreCase);
+    method public static androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode> assertHasTextEqualTo(androidx.glance.testing.GlanceNodeAssertion<androidx.glance.testing.unit.MappedNode,androidx.glance.testing.unit.GlanceMappedNode>, String text, optional boolean ignoreCase);
+  }
+
+  public final class UnitTestFiltersKt {
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasAnyDescendant(androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> matcher);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasClickAction();
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasContentDescription(String value, optional boolean ignoreCase);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasContentDescriptionEqualTo(String value, optional boolean ignoreCase);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasNoClickAction();
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasStartActivityClickAction(android.content.ComponentName componentName, optional androidx.glance.action.ActionParameters parameters);
+    method public static inline <reified T extends android.app.Activity> androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasStartActivityClickAction(optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+    method @kotlin.PublishedApi internal static <T extends android.app.Activity> androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasStartActivityClickAction(Class<T> activityClass, optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasTestTag(String testTag);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasText(String text, optional boolean ignoreCase);
+    method public static androidx.glance.testing.GlanceNodeMatcher<androidx.glance.testing.unit.MappedNode> hasTextEqualTo(String text, optional boolean ignoreCase);
+  }
+
+}
+
diff --git a/glance/glance/api/1.1.0-beta01.txt b/glance/glance/api/1.1.0-beta01.txt
new file mode 100644
index 0000000..d7d9a71
--- /dev/null
+++ b/glance/glance/api/1.1.0-beta01.txt
@@ -0,0 +1,579 @@
+// Signature format: 4.0
+package androidx.glance {
+
+  public final class BackgroundKt {
+    method @Deprecated public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, androidx.glance.ImageProvider imageProvider, optional int contentScale);
+    method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, androidx.glance.ImageProvider imageProvider, optional int contentScale, optional androidx.glance.ColorFilter? colorFilter);
+    method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, androidx.glance.unit.ColorProvider colorProvider);
+    method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, @ColorRes int color);
+    method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, long color);
+  }
+
+  public final class ButtonColors {
+    method public androidx.glance.unit.ColorProvider getBackgroundColor();
+    method public androidx.glance.unit.ColorProvider getContentColor();
+    property public final androidx.glance.unit.ColorProvider backgroundColor;
+    property public final androidx.glance.unit.ColorProvider contentColor;
+  }
+
+  public final class ButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.ButtonColors buttonColors(optional androidx.glance.unit.ColorProvider backgroundColor, optional androidx.glance.unit.ColorProvider contentColor);
+    field public static final androidx.glance.ButtonDefaults INSTANCE;
+  }
+
+  public final class ButtonKt {
+    method @androidx.compose.runtime.Composable public static void Button(String text, androidx.glance.action.Action onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines);
+    method @androidx.compose.runtime.Composable public static void Button(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines);
+    method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.glance.ExperimentalGlanceApi public static void Button(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines, optional String? key);
+  }
+
+  public final class ColorFilter {
+    field public static final androidx.glance.ColorFilter.Companion Companion;
+  }
+
+  public static final class ColorFilter.Companion {
+    method public androidx.glance.ColorFilter tint(androidx.glance.unit.ColorProvider colorProvider);
+  }
+
+  public final class CombinedGlanceModifier implements androidx.glance.GlanceModifier {
+    ctor public CombinedGlanceModifier(androidx.glance.GlanceModifier outer, androidx.glance.GlanceModifier inner);
+    method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
+    method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+  }
+
+  public final class CompositionLocalsKt {
+    method @androidx.compose.runtime.Composable public static inline <reified T> T currentState();
+    method @androidx.compose.runtime.Composable public static inline <reified T> T? currentState(androidx.datastore.preferences.core.Preferences.Key<T> key);
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<android.content.Context> getLocalContext();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.glance.GlanceId> getLocalGlanceId();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.DpSize> getLocalSize();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Object?> getLocalState();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<android.content.Context> LocalContext;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.glance.GlanceId> LocalGlanceId;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.DpSize> LocalSize;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Object?> LocalState;
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalGlanceApi {
+  }
+
+  @androidx.compose.runtime.ComposableTargetMarker(description="Glance Composable") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FILE, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.TYPE, kotlin.annotation.AnnotationTarget.TYPE_PARAMETER}) public @interface GlanceComposable {
+  }
+
+  public interface GlanceId {
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface GlanceModifier {
+    method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
+    method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+    method public default infix androidx.glance.GlanceModifier then(androidx.glance.GlanceModifier other);
+    field public static final androidx.glance.GlanceModifier.Companion Companion;
+  }
+
+  public static final class GlanceModifier.Companion implements androidx.glance.GlanceModifier {
+    method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
+    method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public static interface GlanceModifier.Element extends androidx.glance.GlanceModifier {
+    method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
+    method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
+    method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+  }
+
+  public final class GlanceTheme {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable @androidx.glance.GlanceComposable public androidx.glance.color.ColorProviders getColors();
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable @androidx.glance.GlanceComposable public final androidx.glance.color.ColorProviders colors;
+    field public static final androidx.glance.GlanceTheme INSTANCE;
+  }
+
+  public final class GlanceThemeKt {
+    method @androidx.compose.runtime.Composable public static void GlanceTheme(optional androidx.glance.color.ColorProviders colors, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class ImageKt {
+    method @androidx.compose.runtime.Composable public static void Image(androidx.glance.ImageProvider provider, String? contentDescription, optional androidx.glance.GlanceModifier modifier, optional int contentScale, optional androidx.glance.ColorFilter? colorFilter);
+    method public static androidx.glance.ImageProvider ImageProvider(android.graphics.Bitmap bitmap);
+    method @RequiresApi(android.os.Build.VERSION_CODES.M) public static androidx.glance.ImageProvider ImageProvider(android.graphics.drawable.Icon icon);
+    method public static androidx.glance.ImageProvider ImageProvider(@DrawableRes int resId);
+  }
+
+  public interface ImageProvider {
+  }
+
+  public enum Visibility {
+    enum_constant public static final androidx.glance.Visibility Gone;
+    enum_constant public static final androidx.glance.Visibility Invisible;
+    enum_constant public static final androidx.glance.Visibility Visible;
+  }
+
+  public final class VisibilityKt {
+    method public static androidx.glance.GlanceModifier visibility(androidx.glance.GlanceModifier, androidx.glance.Visibility visibility);
+  }
+
+}
+
+package androidx.glance.action {
+
+  public interface Action {
+  }
+
+  public final class ActionKt {
+    method public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, androidx.glance.action.Action onClick);
+    method public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, androidx.glance.action.Action onClick, optional @DrawableRes int rippleOverride);
+    method @androidx.compose.runtime.Composable public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, optional @DrawableRes int rippleOverride, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.glance.ExperimentalGlanceApi public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, optional String? key, optional @DrawableRes int rippleOverride, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method @androidx.compose.runtime.Composable public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    field @DrawableRes public static final int NoRippleOverride = 0; // 0x0
+  }
+
+  public abstract class ActionParameters {
+    method public abstract java.util.Map<androidx.glance.action.ActionParameters.Key<?>,java.lang.Object> asMap();
+    method public abstract operator <T> boolean contains(androidx.glance.action.ActionParameters.Key<T> key);
+    method public abstract operator <T> T? get(androidx.glance.action.ActionParameters.Key<T> key);
+    method public abstract <T> T getOrDefault(androidx.glance.action.ActionParameters.Key<T> key, T defaultValue);
+    method public abstract boolean isEmpty();
+  }
+
+  public static final class ActionParameters.Key<T> {
+    ctor public ActionParameters.Key(String name);
+    method public String getName();
+    method public infix androidx.glance.action.ActionParameters.Pair<T> to(T value);
+    property public final String name;
+  }
+
+  public static final class ActionParameters.Pair<T> {
+  }
+
+  public final class ActionParametersKt {
+    method public static androidx.glance.action.ActionParameters actionParametersOf(androidx.glance.action.ActionParameters.Pair<?>... pairs);
+    method public static androidx.glance.action.MutableActionParameters mutableActionParametersOf(androidx.glance.action.ActionParameters.Pair<?>... pairs);
+    method public static androidx.glance.action.MutableActionParameters toMutableParameters(androidx.glance.action.ActionParameters);
+    method public static androidx.glance.action.ActionParameters toParameters(androidx.glance.action.ActionParameters);
+    method public static <T> androidx.glance.action.ActionParameters.Key<T> toParametersKey(androidx.datastore.preferences.core.Preferences.Key<T>);
+  }
+
+  public final class LambdaActionKt {
+    method @androidx.compose.runtime.Composable public static androidx.glance.action.Action action(optional String? key, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+  }
+
+  public final class MutableActionParameters extends androidx.glance.action.ActionParameters {
+    method public java.util.Map<androidx.glance.action.ActionParameters.Key<?>,java.lang.Object> asMap();
+    method public void clear();
+    method public operator <T> boolean contains(androidx.glance.action.ActionParameters.Key<T> key);
+    method public operator <T> T? get(androidx.glance.action.ActionParameters.Key<T> key);
+    method public <T> T getOrDefault(androidx.glance.action.ActionParameters.Key<T> key, T defaultValue);
+    method public boolean isEmpty();
+    method public <T> T? remove(androidx.glance.action.ActionParameters.Key<T> key);
+    method public operator <T> T? set(androidx.glance.action.ActionParameters.Key<T> key, T? value);
+  }
+
+  public final class StartActivityActionKt {
+    method public static androidx.glance.action.Action actionStartActivity(android.content.ComponentName componentName, optional androidx.glance.action.ActionParameters parameters);
+    method @SuppressCompatibility @androidx.glance.ExperimentalGlanceApi public static androidx.glance.action.Action actionStartActivity(android.content.ComponentName componentName, optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+    method public static inline <reified T extends android.app.Activity> androidx.glance.action.Action actionStartActivity(optional androidx.glance.action.ActionParameters parameters);
+    method @SuppressCompatibility @androidx.glance.ExperimentalGlanceApi public static inline <reified T extends android.app.Activity> androidx.glance.action.Action actionStartActivity(optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+    method public static <T extends android.app.Activity> androidx.glance.action.Action actionStartActivity(Class<T> activity, optional androidx.glance.action.ActionParameters parameters);
+    method @SuppressCompatibility @androidx.glance.ExperimentalGlanceApi public static <T extends android.app.Activity> androidx.glance.action.Action actionStartActivity(Class<T> activity, optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+  }
+
+}
+
+package androidx.glance.color {
+
+  public abstract sealed class ColorProviders {
+    method public final androidx.glance.unit.ColorProvider getBackground();
+    method public final androidx.glance.unit.ColorProvider getError();
+    method public final androidx.glance.unit.ColorProvider getErrorContainer();
+    method public final androidx.glance.unit.ColorProvider getInverseOnSurface();
+    method public final androidx.glance.unit.ColorProvider getInversePrimary();
+    method public final androidx.glance.unit.ColorProvider getInverseSurface();
+    method public final androidx.glance.unit.ColorProvider getOnBackground();
+    method public final androidx.glance.unit.ColorProvider getOnError();
+    method public final androidx.glance.unit.ColorProvider getOnErrorContainer();
+    method public final androidx.glance.unit.ColorProvider getOnPrimary();
+    method public final androidx.glance.unit.ColorProvider getOnPrimaryContainer();
+    method public final androidx.glance.unit.ColorProvider getOnSecondary();
+    method public final androidx.glance.unit.ColorProvider getOnSecondaryContainer();
+    method public final androidx.glance.unit.ColorProvider getOnSurface();
+    method public final androidx.glance.unit.ColorProvider getOnSurfaceVariant();
+    method public final androidx.glance.unit.ColorProvider getOnTertiary();
+    method public final androidx.glance.unit.ColorProvider getOnTertiaryContainer();
+    method public final androidx.glance.unit.ColorProvider getOutline();
+    method public final androidx.glance.unit.ColorProvider getPrimary();
+    method public final androidx.glance.unit.ColorProvider getPrimaryContainer();
+    method public final androidx.glance.unit.ColorProvider getSecondary();
+    method public final androidx.glance.unit.ColorProvider getSecondaryContainer();
+    method public final androidx.glance.unit.ColorProvider getSurface();
+    method public final androidx.glance.unit.ColorProvider getSurfaceVariant();
+    method public final androidx.glance.unit.ColorProvider getTertiary();
+    method public final androidx.glance.unit.ColorProvider getTertiaryContainer();
+    method public final androidx.glance.unit.ColorProvider getWidgetBackground();
+    property public final androidx.glance.unit.ColorProvider background;
+    property public final androidx.glance.unit.ColorProvider error;
+    property public final androidx.glance.unit.ColorProvider errorContainer;
+    property public final androidx.glance.unit.ColorProvider inverseOnSurface;
+    property public final androidx.glance.unit.ColorProvider inversePrimary;
+    property public final androidx.glance.unit.ColorProvider inverseSurface;
+    property public final androidx.glance.unit.ColorProvider onBackground;
+    property public final androidx.glance.unit.ColorProvider onError;
+    property public final androidx.glance.unit.ColorProvider onErrorContainer;
+    property public final androidx.glance.unit.ColorProvider onPrimary;
+    property public final androidx.glance.unit.ColorProvider onPrimaryContainer;
+    property public final androidx.glance.unit.ColorProvider onSecondary;
+    property public final androidx.glance.unit.ColorProvider onSecondaryContainer;
+    property public final androidx.glance.unit.ColorProvider onSurface;
+    property public final androidx.glance.unit.ColorProvider onSurfaceVariant;
+    property public final androidx.glance.unit.ColorProvider onTertiary;
+    property public final androidx.glance.unit.ColorProvider onTertiaryContainer;
+    property public final androidx.glance.unit.ColorProvider outline;
+    property public final androidx.glance.unit.ColorProvider primary;
+    property public final androidx.glance.unit.ColorProvider primaryContainer;
+    property public final androidx.glance.unit.ColorProvider secondary;
+    property public final androidx.glance.unit.ColorProvider secondaryContainer;
+    property public final androidx.glance.unit.ColorProvider surface;
+    property public final androidx.glance.unit.ColorProvider surfaceVariant;
+    property public final androidx.glance.unit.ColorProvider tertiary;
+    property public final androidx.glance.unit.ColorProvider tertiaryContainer;
+    property public final androidx.glance.unit.ColorProvider widgetBackground;
+  }
+
+  public final class ColorProvidersKt {
+    method public static androidx.glance.color.ColorProviders colorProviders(androidx.glance.unit.ColorProvider primary, androidx.glance.unit.ColorProvider onPrimary, androidx.glance.unit.ColorProvider primaryContainer, androidx.glance.unit.ColorProvider onPrimaryContainer, androidx.glance.unit.ColorProvider secondary, androidx.glance.unit.ColorProvider onSecondary, androidx.glance.unit.ColorProvider secondaryContainer, androidx.glance.unit.ColorProvider onSecondaryContainer, androidx.glance.unit.ColorProvider tertiary, androidx.glance.unit.ColorProvider onTertiary, androidx.glance.unit.ColorProvider tertiaryContainer, androidx.glance.unit.ColorProvider onTertiaryContainer, androidx.glance.unit.ColorProvider error, androidx.glance.unit.ColorProvider errorContainer, androidx.glance.unit.ColorProvider onError, androidx.glance.unit.ColorProvider onErrorContainer, androidx.glance.unit.ColorProvider background, androidx.glance.unit.ColorProvider onBackground, androidx.glance.unit.ColorProvider surface, androidx.glance.unit.ColorProvider onSurface, androidx.glance.unit.ColorProvider surfaceVariant, androidx.glance.unit.ColorProvider onSurfaceVariant, androidx.glance.unit.ColorProvider outline, androidx.glance.unit.ColorProvider inverseOnSurface, androidx.glance.unit.ColorProvider inverseSurface, androidx.glance.unit.ColorProvider inversePrimary);
+    method public static androidx.glance.color.ColorProviders colorProviders(androidx.glance.unit.ColorProvider primary, androidx.glance.unit.ColorProvider onPrimary, androidx.glance.unit.ColorProvider primaryContainer, androidx.glance.unit.ColorProvider onPrimaryContainer, androidx.glance.unit.ColorProvider secondary, androidx.glance.unit.ColorProvider onSecondary, androidx.glance.unit.ColorProvider secondaryContainer, androidx.glance.unit.ColorProvider onSecondaryContainer, androidx.glance.unit.ColorProvider tertiary, androidx.glance.unit.ColorProvider onTertiary, androidx.glance.unit.ColorProvider tertiaryContainer, androidx.glance.unit.ColorProvider onTertiaryContainer, androidx.glance.unit.ColorProvider error, androidx.glance.unit.ColorProvider errorContainer, androidx.glance.unit.ColorProvider onError, androidx.glance.unit.ColorProvider onErrorContainer, androidx.glance.unit.ColorProvider background, androidx.glance.unit.ColorProvider onBackground, androidx.glance.unit.ColorProvider surface, androidx.glance.unit.ColorProvider onSurface, androidx.glance.unit.ColorProvider surfaceVariant, androidx.glance.unit.ColorProvider onSurfaceVariant, androidx.glance.unit.ColorProvider outline, androidx.glance.unit.ColorProvider inverseOnSurface, androidx.glance.unit.ColorProvider inverseSurface, androidx.glance.unit.ColorProvider inversePrimary, androidx.glance.unit.ColorProvider widgetBackground);
+  }
+
+  public final class DayNightColorProvidersKt {
+    method public static androidx.glance.unit.ColorProvider ColorProvider(long day, long night);
+  }
+
+}
+
+package androidx.glance.layout {
+
+  public final class Alignment {
+    ctor public Alignment(int horizontal, int vertical);
+    method public int getHorizontal();
+    method public int getVertical();
+    property public final int horizontal;
+    property public final int vertical;
+    field public static final androidx.glance.layout.Alignment.Companion Companion;
+  }
+
+  public static final class Alignment.Companion {
+    method public int getBottom();
+    method public androidx.glance.layout.Alignment getBottomCenter();
+    method public androidx.glance.layout.Alignment getBottomEnd();
+    method public androidx.glance.layout.Alignment getBottomStart();
+    method public androidx.glance.layout.Alignment getCenter();
+    method public androidx.glance.layout.Alignment getCenterEnd();
+    method public int getCenterHorizontally();
+    method public androidx.glance.layout.Alignment getCenterStart();
+    method public int getCenterVertically();
+    method public int getEnd();
+    method public int getStart();
+    method public int getTop();
+    method public androidx.glance.layout.Alignment getTopCenter();
+    method public androidx.glance.layout.Alignment getTopEnd();
+    method public androidx.glance.layout.Alignment getTopStart();
+    property public final int Bottom;
+    property public final androidx.glance.layout.Alignment BottomCenter;
+    property public final androidx.glance.layout.Alignment BottomEnd;
+    property public final androidx.glance.layout.Alignment BottomStart;
+    property public final androidx.glance.layout.Alignment Center;
+    property public final androidx.glance.layout.Alignment CenterEnd;
+    property public final int CenterHorizontally;
+    property public final androidx.glance.layout.Alignment CenterStart;
+    property public final int CenterVertically;
+    property public final int End;
+    property public final int Start;
+    property public final int Top;
+    property public final androidx.glance.layout.Alignment TopCenter;
+    property public final androidx.glance.layout.Alignment TopEnd;
+    property public final androidx.glance.layout.Alignment TopStart;
+  }
+
+  @kotlin.jvm.JvmInline public static final value class Alignment.Horizontal {
+    field public static final androidx.glance.layout.Alignment.Horizontal.Companion Companion;
+  }
+
+  public static final class Alignment.Horizontal.Companion {
+    method public int getCenterHorizontally();
+    method public int getEnd();
+    method public int getStart();
+    property public final int CenterHorizontally;
+    property public final int End;
+    property public final int Start;
+  }
+
+  @kotlin.jvm.JvmInline public static final value class Alignment.Vertical {
+    field public static final androidx.glance.layout.Alignment.Vertical.Companion Companion;
+  }
+
+  public static final class Alignment.Vertical.Companion {
+    method public int getBottom();
+    method public int getCenterVertically();
+    method public int getTop();
+    property public final int Bottom;
+    property public final int CenterVertically;
+    property public final int Top;
+  }
+
+  public final class BoxKt {
+    method @androidx.compose.runtime.Composable public static void Box(optional androidx.glance.GlanceModifier modifier, optional androidx.glance.layout.Alignment contentAlignment, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class ColumnKt {
+    method @androidx.compose.runtime.Composable public static void Column(optional androidx.glance.GlanceModifier modifier, optional int verticalAlignment, optional int horizontalAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  public interface ColumnScope {
+    method public androidx.glance.GlanceModifier defaultWeight(androidx.glance.GlanceModifier);
+  }
+
+  @kotlin.jvm.JvmInline public final value class ContentScale {
+    ctor public ContentScale(int value);
+    field public static final androidx.glance.layout.ContentScale.Companion Companion;
+  }
+
+  public static final class ContentScale.Companion {
+    method public int getCrop();
+    method public int getFillBounds();
+    method public int getFit();
+    property public final int Crop;
+    property public final int FillBounds;
+    property public final int Fit;
+  }
+
+  public final class PaddingKt {
+    method public static androidx.glance.GlanceModifier absolutePadding(androidx.glance.GlanceModifier, optional float left, optional float top, optional float right, optional float bottom);
+    method public static androidx.glance.GlanceModifier absolutePadding(androidx.glance.GlanceModifier, optional @DimenRes int left, optional @DimenRes int top, optional @DimenRes int right, optional @DimenRes int bottom);
+    method public static androidx.glance.GlanceModifier padding(androidx.glance.GlanceModifier, float all);
+    method public static androidx.glance.GlanceModifier padding(androidx.glance.GlanceModifier, optional float horizontal, optional float vertical);
+    method public static androidx.glance.GlanceModifier padding(androidx.glance.GlanceModifier, optional float start, optional float top, optional float end, optional float bottom);
+    method public static androidx.glance.GlanceModifier padding(androidx.glance.GlanceModifier, @DimenRes int all);
+    method public static androidx.glance.GlanceModifier padding(androidx.glance.GlanceModifier, optional @DimenRes int horizontal, optional @DimenRes int vertical);
+    method public static androidx.glance.GlanceModifier padding(androidx.glance.GlanceModifier, optional @DimenRes int start, optional @DimenRes int top, optional @DimenRes int end, optional @DimenRes int bottom);
+  }
+
+  public final class RowKt {
+    method @androidx.compose.runtime.Composable public static void Row(optional androidx.glance.GlanceModifier modifier, optional int horizontalAlignment, optional int verticalAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.layout.RowScope,kotlin.Unit> content);
+  }
+
+  public interface RowScope {
+    method public androidx.glance.GlanceModifier defaultWeight(androidx.glance.GlanceModifier);
+  }
+
+  public final class SizeModifiersKt {
+    method public static androidx.glance.GlanceModifier fillMaxHeight(androidx.glance.GlanceModifier);
+    method public static androidx.glance.GlanceModifier fillMaxSize(androidx.glance.GlanceModifier);
+    method public static androidx.glance.GlanceModifier fillMaxWidth(androidx.glance.GlanceModifier);
+    method public static androidx.glance.GlanceModifier height(androidx.glance.GlanceModifier, float height);
+    method public static androidx.glance.GlanceModifier height(androidx.glance.GlanceModifier, @DimenRes int height);
+    method public static androidx.glance.GlanceModifier size(androidx.glance.GlanceModifier, float size);
+    method public static androidx.glance.GlanceModifier size(androidx.glance.GlanceModifier, float width, float height);
+    method public static androidx.glance.GlanceModifier size(androidx.glance.GlanceModifier, @DimenRes int size);
+    method public static androidx.glance.GlanceModifier size(androidx.glance.GlanceModifier, @DimenRes int width, @DimenRes int height);
+    method public static androidx.glance.GlanceModifier width(androidx.glance.GlanceModifier, float width);
+    method public static androidx.glance.GlanceModifier width(androidx.glance.GlanceModifier, @DimenRes int width);
+    method public static androidx.glance.GlanceModifier wrapContentHeight(androidx.glance.GlanceModifier);
+    method public static androidx.glance.GlanceModifier wrapContentSize(androidx.glance.GlanceModifier);
+    method public static androidx.glance.GlanceModifier wrapContentWidth(androidx.glance.GlanceModifier);
+  }
+
+  public final class SpacerKt {
+    method @androidx.compose.runtime.Composable public static void Spacer(optional androidx.glance.GlanceModifier modifier);
+  }
+
+}
+
+package androidx.glance.semantics {
+
+  public final class SemanticsConfiguration implements androidx.glance.semantics.SemanticsPropertyReceiver {
+    ctor public SemanticsConfiguration();
+    method public operator <T> T get(androidx.glance.semantics.SemanticsPropertyKey<T> key);
+    method public <T> T? getOrElseNullable(androidx.glance.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T?> defaultValue);
+    method public <T> T? getOrNull(androidx.glance.semantics.SemanticsPropertyKey<T> key);
+    method public <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T value);
+  }
+
+  public final class SemanticsModifierKt {
+    method public static androidx.glance.GlanceModifier semantics(androidx.glance.GlanceModifier, kotlin.jvm.functions.Function1<? super androidx.glance.semantics.SemanticsPropertyReceiver,kotlin.Unit> properties);
+  }
+
+  public final class SemanticsProperties {
+    method public androidx.glance.semantics.SemanticsPropertyKey<java.util.List<java.lang.String>> getContentDescription();
+    method public androidx.glance.semantics.SemanticsPropertyKey<java.lang.String> getTestTag();
+    property public final androidx.glance.semantics.SemanticsPropertyKey<java.util.List<java.lang.String>> ContentDescription;
+    property public final androidx.glance.semantics.SemanticsPropertyKey<java.lang.String> TestTag;
+    field public static final androidx.glance.semantics.SemanticsProperties INSTANCE;
+  }
+
+  public final class SemanticsPropertiesKt {
+    method public static String getContentDescription(androidx.glance.semantics.SemanticsPropertyReceiver);
+    method public static String getTestTag(androidx.glance.semantics.SemanticsPropertyReceiver);
+    method public static void setContentDescription(androidx.glance.semantics.SemanticsPropertyReceiver, String);
+    method public static void setTestTag(androidx.glance.semantics.SemanticsPropertyReceiver, String);
+  }
+
+  public final class SemanticsPropertyKey<T> {
+    ctor public SemanticsPropertyKey(String name, optional kotlin.jvm.functions.Function2<? super T?,? super T,? extends T?> mergePolicy);
+    method public String getName();
+    method public T? merge(T? parentValue, T childValue);
+    property public final String name;
+  }
+
+  public interface SemanticsPropertyReceiver {
+    method public operator <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T value);
+  }
+
+}
+
+package androidx.glance.state {
+
+  public interface GlanceStateDefinition<T> {
+    method public suspend Object? getDataStore(android.content.Context context, String fileKey, kotlin.coroutines.Continuation<? super androidx.datastore.core.DataStore<T>>);
+    method public java.io.File getLocation(android.content.Context context, String fileKey);
+  }
+
+  public final class PreferencesGlanceStateDefinition implements androidx.glance.state.GlanceStateDefinition<androidx.datastore.preferences.core.Preferences> {
+    method public suspend Object? getDataStore(android.content.Context context, String fileKey, kotlin.coroutines.Continuation<? super androidx.datastore.core.DataStore<androidx.datastore.preferences.core.Preferences>>);
+    method public java.io.File getLocation(android.content.Context context, String fileKey);
+    field public static final androidx.glance.state.PreferencesGlanceStateDefinition INSTANCE;
+  }
+
+}
+
+package androidx.glance.text {
+
+  public final class FontFamily {
+    ctor public FontFamily(String family);
+    method public String getFamily();
+    property public final String family;
+    field public static final androidx.glance.text.FontFamily.Companion Companion;
+  }
+
+  public static final class FontFamily.Companion {
+    method public androidx.glance.text.FontFamily getCursive();
+    method public androidx.glance.text.FontFamily getMonospace();
+    method public androidx.glance.text.FontFamily getSansSerif();
+    method public androidx.glance.text.FontFamily getSerif();
+    property public final androidx.glance.text.FontFamily Cursive;
+    property public final androidx.glance.text.FontFamily Monospace;
+    property public final androidx.glance.text.FontFamily SansSerif;
+    property public final androidx.glance.text.FontFamily Serif;
+  }
+
+  @kotlin.jvm.JvmInline public final value class FontStyle {
+    field public static final androidx.glance.text.FontStyle.Companion Companion;
+  }
+
+  public static final class FontStyle.Companion {
+    method public int getItalic();
+    method public int getNormal();
+    method public java.util.List<androidx.glance.text.FontStyle> values();
+    property public final int Italic;
+    property public final int Normal;
+  }
+
+  @kotlin.jvm.JvmInline public final value class FontWeight {
+    method public int getValue();
+    property public final int value;
+    field public static final androidx.glance.text.FontWeight.Companion Companion;
+  }
+
+  public static final class FontWeight.Companion {
+    method public int getBold();
+    method public int getMedium();
+    method public int getNormal();
+    property public final int Bold;
+    property public final int Medium;
+    property public final int Normal;
+  }
+
+  @kotlin.jvm.JvmInline public final value class TextAlign {
+    field public static final androidx.glance.text.TextAlign.Companion Companion;
+  }
+
+  public static final class TextAlign.Companion {
+    method public int getCenter();
+    method public int getEnd();
+    method public int getLeft();
+    method public int getRight();
+    method public int getStart();
+    method public java.util.List<androidx.glance.text.TextAlign> values();
+    property public final int Center;
+    property public final int End;
+    property public final int Left;
+    property public final int Right;
+    property public final int Start;
+  }
+
+  @kotlin.jvm.JvmInline public final value class TextDecoration {
+    method @androidx.compose.runtime.Stable public operator boolean contains(int other);
+    method @androidx.compose.runtime.Stable public operator int plus(int decoration);
+    field public static final androidx.glance.text.TextDecoration.Companion Companion;
+  }
+
+  public static final class TextDecoration.Companion {
+    method public int combine(java.util.List<androidx.glance.text.TextDecoration> decorations);
+    method public int getLineThrough();
+    method public int getNone();
+    method public int getUnderline();
+    property public final int LineThrough;
+    property public final int None;
+    property public final int Underline;
+  }
+
+  public final class TextDefaults {
+    method public androidx.glance.unit.ColorProvider getDefaultTextColor();
+    method public androidx.glance.text.TextStyle getDefaultTextStyle();
+    property public final androidx.glance.unit.ColorProvider defaultTextColor;
+    property public final androidx.glance.text.TextStyle defaultTextStyle;
+    field public static final androidx.glance.text.TextDefaults INSTANCE;
+  }
+
+  public final class TextKt {
+    method @androidx.compose.runtime.Composable public static void Text(String text, optional androidx.glance.GlanceModifier modifier, optional androidx.glance.text.TextStyle style, optional int maxLines);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextStyle {
+    ctor public TextStyle(optional androidx.glance.unit.ColorProvider color, optional androidx.compose.ui.unit.TextUnit? fontSize, optional androidx.glance.text.FontWeight? fontWeight, optional androidx.glance.text.FontStyle? fontStyle, optional androidx.glance.text.TextAlign? textAlign, optional androidx.glance.text.TextDecoration? textDecoration, optional androidx.glance.text.FontFamily? fontFamily);
+    method public androidx.glance.text.TextStyle copy(optional androidx.glance.unit.ColorProvider color, optional androidx.compose.ui.unit.TextUnit? fontSize, optional androidx.glance.text.FontWeight? fontWeight, optional androidx.glance.text.FontStyle? fontStyle, optional androidx.glance.text.TextAlign? textAlign, optional androidx.glance.text.TextDecoration? textDecoration, optional androidx.glance.text.FontFamily? fontFamily);
+    method public androidx.glance.unit.ColorProvider getColor();
+    method public androidx.glance.text.FontFamily? getFontFamily();
+    method public androidx.compose.ui.unit.TextUnit? getFontSize();
+    method public androidx.glance.text.FontStyle? getFontStyle();
+    method public androidx.glance.text.FontWeight? getFontWeight();
+    method public androidx.glance.text.TextAlign? getTextAlign();
+    method public androidx.glance.text.TextDecoration? getTextDecoration();
+    property public final androidx.glance.unit.ColorProvider color;
+    property public final androidx.glance.text.FontFamily? fontFamily;
+    property public final androidx.compose.ui.unit.TextUnit? fontSize;
+    property public final androidx.glance.text.FontStyle? fontStyle;
+    property public final androidx.glance.text.FontWeight? fontWeight;
+    property public final androidx.glance.text.TextAlign? textAlign;
+    property public final androidx.glance.text.TextDecoration? textDecoration;
+  }
+
+}
+
+package androidx.glance.unit {
+
+  public interface ColorProvider {
+    method public long getColor(android.content.Context context);
+  }
+
+  public final class ColorProviderKt {
+    method public static androidx.glance.unit.ColorProvider ColorProvider(long color);
+  }
+
+}
+
diff --git a/glance/glance/api/res-1.1.0-beta01.txt b/glance/glance/api/res-1.1.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/glance/glance/api/res-1.1.0-beta01.txt
diff --git a/glance/glance/api/restricted_1.1.0-beta01.txt b/glance/glance/api/restricted_1.1.0-beta01.txt
new file mode 100644
index 0000000..d7d9a71
--- /dev/null
+++ b/glance/glance/api/restricted_1.1.0-beta01.txt
@@ -0,0 +1,579 @@
+// Signature format: 4.0
+package androidx.glance {
+
+  public final class BackgroundKt {
+    method @Deprecated public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, androidx.glance.ImageProvider imageProvider, optional int contentScale);
+    method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, androidx.glance.ImageProvider imageProvider, optional int contentScale, optional androidx.glance.ColorFilter? colorFilter);
+    method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, androidx.glance.unit.ColorProvider colorProvider);
+    method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, @ColorRes int color);
+    method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, long color);
+  }
+
+  public final class ButtonColors {
+    method public androidx.glance.unit.ColorProvider getBackgroundColor();
+    method public androidx.glance.unit.ColorProvider getContentColor();
+    property public final androidx.glance.unit.ColorProvider backgroundColor;
+    property public final androidx.glance.unit.ColorProvider contentColor;
+  }
+
+  public final class ButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.glance.ButtonColors buttonColors(optional androidx.glance.unit.ColorProvider backgroundColor, optional androidx.glance.unit.ColorProvider contentColor);
+    field public static final androidx.glance.ButtonDefaults INSTANCE;
+  }
+
+  public final class ButtonKt {
+    method @androidx.compose.runtime.Composable public static void Button(String text, androidx.glance.action.Action onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines);
+    method @androidx.compose.runtime.Composable public static void Button(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines);
+    method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.glance.ExperimentalGlanceApi public static void Button(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines, optional String? key);
+  }
+
+  public final class ColorFilter {
+    field public static final androidx.glance.ColorFilter.Companion Companion;
+  }
+
+  public static final class ColorFilter.Companion {
+    method public androidx.glance.ColorFilter tint(androidx.glance.unit.ColorProvider colorProvider);
+  }
+
+  public final class CombinedGlanceModifier implements androidx.glance.GlanceModifier {
+    ctor public CombinedGlanceModifier(androidx.glance.GlanceModifier outer, androidx.glance.GlanceModifier inner);
+    method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
+    method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+  }
+
+  public final class CompositionLocalsKt {
+    method @androidx.compose.runtime.Composable public static inline <reified T> T currentState();
+    method @androidx.compose.runtime.Composable public static inline <reified T> T? currentState(androidx.datastore.preferences.core.Preferences.Key<T> key);
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<android.content.Context> getLocalContext();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.glance.GlanceId> getLocalGlanceId();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.DpSize> getLocalSize();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Object?> getLocalState();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<android.content.Context> LocalContext;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.glance.GlanceId> LocalGlanceId;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.DpSize> LocalSize;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Object?> LocalState;
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalGlanceApi {
+  }
+
+  @androidx.compose.runtime.ComposableTargetMarker(description="Glance Composable") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FILE, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.TYPE, kotlin.annotation.AnnotationTarget.TYPE_PARAMETER}) public @interface GlanceComposable {
+  }
+
+  public interface GlanceId {
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface GlanceModifier {
+    method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
+    method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+    method public default infix androidx.glance.GlanceModifier then(androidx.glance.GlanceModifier other);
+    field public static final androidx.glance.GlanceModifier.Companion Companion;
+  }
+
+  public static final class GlanceModifier.Companion implements androidx.glance.GlanceModifier {
+    method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
+    method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public static interface GlanceModifier.Element extends androidx.glance.GlanceModifier {
+    method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
+    method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
+    method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+    method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+  }
+
+  public final class GlanceTheme {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable @androidx.glance.GlanceComposable public androidx.glance.color.ColorProviders getColors();
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable @androidx.glance.GlanceComposable public final androidx.glance.color.ColorProviders colors;
+    field public static final androidx.glance.GlanceTheme INSTANCE;
+  }
+
+  public final class GlanceThemeKt {
+    method @androidx.compose.runtime.Composable public static void GlanceTheme(optional androidx.glance.color.ColorProviders colors, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class ImageKt {
+    method @androidx.compose.runtime.Composable public static void Image(androidx.glance.ImageProvider provider, String? contentDescription, optional androidx.glance.GlanceModifier modifier, optional int contentScale, optional androidx.glance.ColorFilter? colorFilter);
+    method public static androidx.glance.ImageProvider ImageProvider(android.graphics.Bitmap bitmap);
+    method @RequiresApi(android.os.Build.VERSION_CODES.M) public static androidx.glance.ImageProvider ImageProvider(android.graphics.drawable.Icon icon);
+    method public static androidx.glance.ImageProvider ImageProvider(@DrawableRes int resId);
+  }
+
+  public interface ImageProvider {
+  }
+
+  public enum Visibility {
+    enum_constant public static final androidx.glance.Visibility Gone;
+    enum_constant public static final androidx.glance.Visibility Invisible;
+    enum_constant public static final androidx.glance.Visibility Visible;
+  }
+
+  public final class VisibilityKt {
+    method public static androidx.glance.GlanceModifier visibility(androidx.glance.GlanceModifier, androidx.glance.Visibility visibility);
+  }
+
+}
+
+package androidx.glance.action {
+
+  public interface Action {
+  }
+
+  public final class ActionKt {
+    method public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, androidx.glance.action.Action onClick);
+    method public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, androidx.glance.action.Action onClick, optional @DrawableRes int rippleOverride);
+    method @androidx.compose.runtime.Composable public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, optional @DrawableRes int rippleOverride, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.glance.ExperimentalGlanceApi public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, optional String? key, optional @DrawableRes int rippleOverride, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method @androidx.compose.runtime.Composable public static androidx.glance.GlanceModifier clickable(androidx.glance.GlanceModifier, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    field @DrawableRes public static final int NoRippleOverride = 0; // 0x0
+  }
+
+  public abstract class ActionParameters {
+    method public abstract java.util.Map<androidx.glance.action.ActionParameters.Key<?>,java.lang.Object> asMap();
+    method public abstract operator <T> boolean contains(androidx.glance.action.ActionParameters.Key<T> key);
+    method public abstract operator <T> T? get(androidx.glance.action.ActionParameters.Key<T> key);
+    method public abstract <T> T getOrDefault(androidx.glance.action.ActionParameters.Key<T> key, T defaultValue);
+    method public abstract boolean isEmpty();
+  }
+
+  public static final class ActionParameters.Key<T> {
+    ctor public ActionParameters.Key(String name);
+    method public String getName();
+    method public infix androidx.glance.action.ActionParameters.Pair<T> to(T value);
+    property public final String name;
+  }
+
+  public static final class ActionParameters.Pair<T> {
+  }
+
+  public final class ActionParametersKt {
+    method public static androidx.glance.action.ActionParameters actionParametersOf(androidx.glance.action.ActionParameters.Pair<?>... pairs);
+    method public static androidx.glance.action.MutableActionParameters mutableActionParametersOf(androidx.glance.action.ActionParameters.Pair<?>... pairs);
+    method public static androidx.glance.action.MutableActionParameters toMutableParameters(androidx.glance.action.ActionParameters);
+    method public static androidx.glance.action.ActionParameters toParameters(androidx.glance.action.ActionParameters);
+    method public static <T> androidx.glance.action.ActionParameters.Key<T> toParametersKey(androidx.datastore.preferences.core.Preferences.Key<T>);
+  }
+
+  public final class LambdaActionKt {
+    method @androidx.compose.runtime.Composable public static androidx.glance.action.Action action(optional String? key, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+  }
+
+  public final class MutableActionParameters extends androidx.glance.action.ActionParameters {
+    method public java.util.Map<androidx.glance.action.ActionParameters.Key<?>,java.lang.Object> asMap();
+    method public void clear();
+    method public operator <T> boolean contains(androidx.glance.action.ActionParameters.Key<T> key);
+    method public operator <T> T? get(androidx.glance.action.ActionParameters.Key<T> key);
+    method public <T> T getOrDefault(androidx.glance.action.ActionParameters.Key<T> key, T defaultValue);
+    method public boolean isEmpty();
+    method public <T> T? remove(androidx.glance.action.ActionParameters.Key<T> key);
+    method public operator <T> T? set(androidx.glance.action.ActionParameters.Key<T> key, T? value);
+  }
+
+  public final class StartActivityActionKt {
+    method public static androidx.glance.action.Action actionStartActivity(android.content.ComponentName componentName, optional androidx.glance.action.ActionParameters parameters);
+    method @SuppressCompatibility @androidx.glance.ExperimentalGlanceApi public static androidx.glance.action.Action actionStartActivity(android.content.ComponentName componentName, optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+    method public static inline <reified T extends android.app.Activity> androidx.glance.action.Action actionStartActivity(optional androidx.glance.action.ActionParameters parameters);
+    method @SuppressCompatibility @androidx.glance.ExperimentalGlanceApi public static inline <reified T extends android.app.Activity> androidx.glance.action.Action actionStartActivity(optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+    method public static <T extends android.app.Activity> androidx.glance.action.Action actionStartActivity(Class<T> activity, optional androidx.glance.action.ActionParameters parameters);
+    method @SuppressCompatibility @androidx.glance.ExperimentalGlanceApi public static <T extends android.app.Activity> androidx.glance.action.Action actionStartActivity(Class<T> activity, optional androidx.glance.action.ActionParameters parameters, optional android.os.Bundle? activityOptions);
+  }
+
+}
+
+package androidx.glance.color {
+
+  public abstract sealed class ColorProviders {
+    method public final androidx.glance.unit.ColorProvider getBackground();
+    method public final androidx.glance.unit.ColorProvider getError();
+    method public final androidx.glance.unit.ColorProvider getErrorContainer();
+    method public final androidx.glance.unit.ColorProvider getInverseOnSurface();
+    method public final androidx.glance.unit.ColorProvider getInversePrimary();
+    method public final androidx.glance.unit.ColorProvider getInverseSurface();
+    method public final androidx.glance.unit.ColorProvider getOnBackground();
+    method public final androidx.glance.unit.ColorProvider getOnError();
+    method public final androidx.glance.unit.ColorProvider getOnErrorContainer();
+    method public final androidx.glance.unit.ColorProvider getOnPrimary();
+    method public final androidx.glance.unit.ColorProvider getOnPrimaryContainer();
+    method public final androidx.glance.unit.ColorProvider getOnSecondary();
+    method public final androidx.glance.unit.ColorProvider getOnSecondaryContainer();
+    method public final androidx.glance.unit.ColorProvider getOnSurface();
+    method public final androidx.glance.unit.ColorProvider getOnSurfaceVariant();
+    method public final androidx.glance.unit.ColorProvider getOnTertiary();
+    method public final androidx.glance.unit.ColorProvider getOnTertiaryContainer();
+    method public final androidx.glance.unit.ColorProvider getOutline();
+    method public final androidx.glance.unit.ColorProvider getPrimary();
+    method public final androidx.glance.unit.ColorProvider getPrimaryContainer();
+    method public final androidx.glance.unit.ColorProvider getSecondary();
+    method public final androidx.glance.unit.ColorProvider getSecondaryContainer();
+    method public final androidx.glance.unit.ColorProvider getSurface();
+    method public final androidx.glance.unit.ColorProvider getSurfaceVariant();
+    method public final androidx.glance.unit.ColorProvider getTertiary();
+    method public final androidx.glance.unit.ColorProvider getTertiaryContainer();
+    method public final androidx.glance.unit.ColorProvider getWidgetBackground();
+    property public final androidx.glance.unit.ColorProvider background;
+    property public final androidx.glance.unit.ColorProvider error;
+    property public final androidx.glance.unit.ColorProvider errorContainer;
+    property public final androidx.glance.unit.ColorProvider inverseOnSurface;
+    property public final androidx.glance.unit.ColorProvider inversePrimary;
+    property public final androidx.glance.unit.ColorProvider inverseSurface;
+    property public final androidx.glance.unit.ColorProvider onBackground;
+    property public final androidx.glance.unit.ColorProvider onError;
+    property public final androidx.glance.unit.ColorProvider onErrorContainer;
+    property public final androidx.glance.unit.ColorProvider onPrimary;
+    property public final androidx.glance.unit.ColorProvider onPrimaryContainer;
+    property public final androidx.glance.unit.ColorProvider onSecondary;
+    property public final androidx.glance.unit.ColorProvider onSecondaryContainer;
+    property public final androidx.glance.unit.ColorProvider onSurface;
+    property public final androidx.glance.unit.ColorProvider onSurfaceVariant;
+    property public final androidx.glance.unit.ColorProvider onTertiary;
+    property public final androidx.glance.unit.ColorProvider onTertiaryContainer;
+    property public final androidx.glance.unit.ColorProvider outline;
+    property public final androidx.glance.unit.ColorProvider primary;
+    property public final androidx.glance.unit.ColorProvider primaryContainer;
+    property public final androidx.glance.unit.ColorProvider secondary;
+    property public final androidx.glance.unit.ColorProvider secondaryContainer;
+    property public final androidx.glance.unit.ColorProvider surface;
+    property public final androidx.glance.unit.ColorProvider surfaceVariant;
+    property public final androidx.glance.unit.ColorProvider tertiary;
+    property public final androidx.glance.unit.ColorProvider tertiaryContainer;
+    property public final androidx.glance.unit.ColorProvider widgetBackground;
+  }
+
+  public final class ColorProvidersKt {
+    method public static androidx.glance.color.ColorProviders colorProviders(androidx.glance.unit.ColorProvider primary, androidx.glance.unit.ColorProvider onPrimary, androidx.glance.unit.ColorProvider primaryContainer, androidx.glance.unit.ColorProvider onPrimaryContainer, androidx.glance.unit.ColorProvider secondary, androidx.glance.unit.ColorProvider onSecondary, androidx.glance.unit.ColorProvider secondaryContainer, androidx.glance.unit.ColorProvider onSecondaryContainer, androidx.glance.unit.ColorProvider tertiary, androidx.glance.unit.ColorProvider onTertiary, androidx.glance.unit.ColorProvider tertiaryContainer, androidx.glance.unit.ColorProvider onTertiaryContainer, androidx.glance.unit.ColorProvider error, androidx.glance.unit.ColorProvider errorContainer, androidx.glance.unit.ColorProvider onError, androidx.glance.unit.ColorProvider onErrorContainer, androidx.glance.unit.ColorProvider background, androidx.glance.unit.ColorProvider onBackground, androidx.glance.unit.ColorProvider surface, androidx.glance.unit.ColorProvider onSurface, androidx.glance.unit.ColorProvider surfaceVariant, androidx.glance.unit.ColorProvider onSurfaceVariant, androidx.glance.unit.ColorProvider outline, androidx.glance.unit.ColorProvider inverseOnSurface, androidx.glance.unit.ColorProvider inverseSurface, androidx.glance.unit.ColorProvider inversePrimary);
+    method public static androidx.glance.color.ColorProviders colorProviders(androidx.glance.unit.ColorProvider primary, androidx.glance.unit.ColorProvider onPrimary, androidx.glance.unit.ColorProvider primaryContainer, androidx.glance.unit.ColorProvider onPrimaryContainer, androidx.glance.unit.ColorProvider secondary, androidx.glance.unit.ColorProvider onSecondary, androidx.glance.unit.ColorProvider secondaryContainer, androidx.glance.unit.ColorProvider onSecondaryContainer, androidx.glance.unit.ColorProvider tertiary, androidx.glance.unit.ColorProvider onTertiary, androidx.glance.unit.ColorProvider tertiaryContainer, androidx.glance.unit.ColorProvider onTertiaryContainer, androidx.glance.unit.ColorProvider error, androidx.glance.unit.ColorProvider errorContainer, androidx.glance.unit.ColorProvider onError, androidx.glance.unit.ColorProvider onErrorContainer, androidx.glance.unit.ColorProvider background, androidx.glance.unit.ColorProvider onBackground, androidx.glance.unit.ColorProvider surface, androidx.glance.unit.ColorProvider onSurface, androidx.glance.unit.ColorProvider surfaceVariant, androidx.glance.unit.ColorProvider onSurfaceVariant, androidx.glance.unit.ColorProvider outline, androidx.glance.unit.ColorProvider inverseOnSurface, androidx.glance.unit.ColorProvider inverseSurface, androidx.glance.unit.ColorProvider inversePrimary, androidx.glance.unit.ColorProvider widgetBackground);
+  }
+
+  public final class DayNightColorProvidersKt {
+    method public static androidx.glance.unit.ColorProvider ColorProvider(long day, long night);
+  }
+
+}
+
+package androidx.glance.layout {
+
+  public final class Alignment {
+    ctor public Alignment(int horizontal, int vertical);
+    method public int getHorizontal();
+    method public int getVertical();
+    property public final int horizontal;
+    property public final int vertical;
+    field public static final androidx.glance.layout.Alignment.Companion Companion;
+  }
+
+  public static final class Alignment.Companion {
+    method public int getBottom();
+    method public androidx.glance.layout.Alignment getBottomCenter();
+    method public androidx.glance.layout.Alignment getBottomEnd();
+    method public androidx.glance.layout.Alignment getBottomStart();
+    method public androidx.glance.layout.Alignment getCenter();
+    method public androidx.glance.layout.Alignment getCenterEnd();
+    method public int getCenterHorizontally();
+    method public androidx.glance.layout.Alignment getCenterStart();
+    method public int getCenterVertically();
+    method public int getEnd();
+    method public int getStart();
+    method public int getTop();
+    method public androidx.glance.layout.Alignment getTopCenter();
+    method public androidx.glance.layout.Alignment getTopEnd();
+    method public androidx.glance.layout.Alignment getTopStart();
+    property public final int Bottom;
+    property public final androidx.glance.layout.Alignment BottomCenter;
+    property public final androidx.glance.layout.Alignment BottomEnd;
+    property public final androidx.glance.layout.Alignment BottomStart;
+    property public final androidx.glance.layout.Alignment Center;
+    property public final androidx.glance.layout.Alignment CenterEnd;
+    property public final int CenterHorizontally;
+    property public final androidx.glance.layout.Alignment CenterStart;
+    property public final int CenterVertically;
+    property public final int End;
+    property public final int Start;
+    property public final int Top;
+    property public final androidx.glance.layout.Alignment TopCenter;
+    property public final androidx.glance.layout.Alignment TopEnd;
+    property public final androidx.glance.layout.Alignment TopStart;
+  }
+
+  @kotlin.jvm.JvmInline public static final value class Alignment.Horizontal {
+    field public static final androidx.glance.layout.Alignment.Horizontal.Companion Companion;
+  }
+
+  public static final class Alignment.Horizontal.Companion {
+    method public int getCenterHorizontally();
+    method public int getEnd();
+    method public int getStart();
+    property public final int CenterHorizontally;
+    property public final int End;
+    property public final int Start;
+  }
+
+  @kotlin.jvm.JvmInline public static final value class Alignment.Vertical {
+    field public static final androidx.glance.layout.Alignment.Vertical.Companion Companion;
+  }
+
+  public static final class Alignment.Vertical.Companion {
+    method public int getBottom();
+    method public int getCenterVertically();
+    method public int getTop();
+    property public final int Bottom;
+    property public final int CenterVertically;
+    property public final int Top;
+  }
+
+  public final class BoxKt {
+    method @androidx.compose.runtime.Composable public static void Box(optional androidx.glance.GlanceModifier modifier, optional androidx.glance.layout.Alignment contentAlignment, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class ColumnKt {
+    method @androidx.compose.runtime.Composable public static void Column(optional androidx.glance.GlanceModifier modifier, optional int verticalAlignment, optional int horizontalAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  public interface ColumnScope {
+    method public androidx.glance.GlanceModifier defaultWeight(androidx.glance.GlanceModifier);
+  }
+
+  @kotlin.jvm.JvmInline public final value class ContentScale {
+    ctor public ContentScale(int value);
+    field public static final androidx.glance.layout.ContentScale.Companion Companion;
+  }
+
+  public static final class ContentScale.Companion {
+    method public int getCrop();
+    method public int getFillBounds();
+    method public int getFit();
+    property public final int Crop;
+    property public final int FillBounds;
+    property public final int Fit;
+  }
+
+  public final class PaddingKt {
+    method public static androidx.glance.GlanceModifier absolutePadding(androidx.glance.GlanceModifier, optional float left, optional float top, optional float right, optional float bottom);
+    method public static androidx.glance.GlanceModifier absolutePadding(androidx.glance.GlanceModifier, optional @DimenRes int left, optional @DimenRes int top, optional @DimenRes int right, optional @DimenRes int bottom);
+    method public static androidx.glance.GlanceModifier padding(androidx.glance.GlanceModifier, float all);
+    method public static androidx.glance.GlanceModifier padding(androidx.glance.GlanceModifier, optional float horizontal, optional float vertical);
+    method public static androidx.glance.GlanceModifier padding(androidx.glance.GlanceModifier, optional float start, optional float top, optional float end, optional float bottom);
+    method public static androidx.glance.GlanceModifier padding(androidx.glance.GlanceModifier, @DimenRes int all);
+    method public static androidx.glance.GlanceModifier padding(androidx.glance.GlanceModifier, optional @DimenRes int horizontal, optional @DimenRes int vertical);
+    method public static androidx.glance.GlanceModifier padding(androidx.glance.GlanceModifier, optional @DimenRes int start, optional @DimenRes int top, optional @DimenRes int end, optional @DimenRes int bottom);
+  }
+
+  public final class RowKt {
+    method @androidx.compose.runtime.Composable public static void Row(optional androidx.glance.GlanceModifier modifier, optional int horizontalAlignment, optional int verticalAlignment, kotlin.jvm.functions.Function1<? super androidx.glance.layout.RowScope,kotlin.Unit> content);
+  }
+
+  public interface RowScope {
+    method public androidx.glance.GlanceModifier defaultWeight(androidx.glance.GlanceModifier);
+  }
+
+  public final class SizeModifiersKt {
+    method public static androidx.glance.GlanceModifier fillMaxHeight(androidx.glance.GlanceModifier);
+    method public static androidx.glance.GlanceModifier fillMaxSize(androidx.glance.GlanceModifier);
+    method public static androidx.glance.GlanceModifier fillMaxWidth(androidx.glance.GlanceModifier);
+    method public static androidx.glance.GlanceModifier height(androidx.glance.GlanceModifier, float height);
+    method public static androidx.glance.GlanceModifier height(androidx.glance.GlanceModifier, @DimenRes int height);
+    method public static androidx.glance.GlanceModifier size(androidx.glance.GlanceModifier, float size);
+    method public static androidx.glance.GlanceModifier size(androidx.glance.GlanceModifier, float width, float height);
+    method public static androidx.glance.GlanceModifier size(androidx.glance.GlanceModifier, @DimenRes int size);
+    method public static androidx.glance.GlanceModifier size(androidx.glance.GlanceModifier, @DimenRes int width, @DimenRes int height);
+    method public static androidx.glance.GlanceModifier width(androidx.glance.GlanceModifier, float width);
+    method public static androidx.glance.GlanceModifier width(androidx.glance.GlanceModifier, @DimenRes int width);
+    method public static androidx.glance.GlanceModifier wrapContentHeight(androidx.glance.GlanceModifier);
+    method public static androidx.glance.GlanceModifier wrapContentSize(androidx.glance.GlanceModifier);
+    method public static androidx.glance.GlanceModifier wrapContentWidth(androidx.glance.GlanceModifier);
+  }
+
+  public final class SpacerKt {
+    method @androidx.compose.runtime.Composable public static void Spacer(optional androidx.glance.GlanceModifier modifier);
+  }
+
+}
+
+package androidx.glance.semantics {
+
+  public final class SemanticsConfiguration implements androidx.glance.semantics.SemanticsPropertyReceiver {
+    ctor public SemanticsConfiguration();
+    method public operator <T> T get(androidx.glance.semantics.SemanticsPropertyKey<T> key);
+    method public <T> T? getOrElseNullable(androidx.glance.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T?> defaultValue);
+    method public <T> T? getOrNull(androidx.glance.semantics.SemanticsPropertyKey<T> key);
+    method public <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T value);
+  }
+
+  public final class SemanticsModifierKt {
+    method public static androidx.glance.GlanceModifier semantics(androidx.glance.GlanceModifier, kotlin.jvm.functions.Function1<? super androidx.glance.semantics.SemanticsPropertyReceiver,kotlin.Unit> properties);
+  }
+
+  public final class SemanticsProperties {
+    method public androidx.glance.semantics.SemanticsPropertyKey<java.util.List<java.lang.String>> getContentDescription();
+    method public androidx.glance.semantics.SemanticsPropertyKey<java.lang.String> getTestTag();
+    property public final androidx.glance.semantics.SemanticsPropertyKey<java.util.List<java.lang.String>> ContentDescription;
+    property public final androidx.glance.semantics.SemanticsPropertyKey<java.lang.String> TestTag;
+    field public static final androidx.glance.semantics.SemanticsProperties INSTANCE;
+  }
+
+  public final class SemanticsPropertiesKt {
+    method public static String getContentDescription(androidx.glance.semantics.SemanticsPropertyReceiver);
+    method public static String getTestTag(androidx.glance.semantics.SemanticsPropertyReceiver);
+    method public static void setContentDescription(androidx.glance.semantics.SemanticsPropertyReceiver, String);
+    method public static void setTestTag(androidx.glance.semantics.SemanticsPropertyReceiver, String);
+  }
+
+  public final class SemanticsPropertyKey<T> {
+    ctor public SemanticsPropertyKey(String name, optional kotlin.jvm.functions.Function2<? super T?,? super T,? extends T?> mergePolicy);
+    method public String getName();
+    method public T? merge(T? parentValue, T childValue);
+    property public final String name;
+  }
+
+  public interface SemanticsPropertyReceiver {
+    method public operator <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T value);
+  }
+
+}
+
+package androidx.glance.state {
+
+  public interface GlanceStateDefinition<T> {
+    method public suspend Object? getDataStore(android.content.Context context, String fileKey, kotlin.coroutines.Continuation<? super androidx.datastore.core.DataStore<T>>);
+    method public java.io.File getLocation(android.content.Context context, String fileKey);
+  }
+
+  public final class PreferencesGlanceStateDefinition implements androidx.glance.state.GlanceStateDefinition<androidx.datastore.preferences.core.Preferences> {
+    method public suspend Object? getDataStore(android.content.Context context, String fileKey, kotlin.coroutines.Continuation<? super androidx.datastore.core.DataStore<androidx.datastore.preferences.core.Preferences>>);
+    method public java.io.File getLocation(android.content.Context context, String fileKey);
+    field public static final androidx.glance.state.PreferencesGlanceStateDefinition INSTANCE;
+  }
+
+}
+
+package androidx.glance.text {
+
+  public final class FontFamily {
+    ctor public FontFamily(String family);
+    method public String getFamily();
+    property public final String family;
+    field public static final androidx.glance.text.FontFamily.Companion Companion;
+  }
+
+  public static final class FontFamily.Companion {
+    method public androidx.glance.text.FontFamily getCursive();
+    method public androidx.glance.text.FontFamily getMonospace();
+    method public androidx.glance.text.FontFamily getSansSerif();
+    method public androidx.glance.text.FontFamily getSerif();
+    property public final androidx.glance.text.FontFamily Cursive;
+    property public final androidx.glance.text.FontFamily Monospace;
+    property public final androidx.glance.text.FontFamily SansSerif;
+    property public final androidx.glance.text.FontFamily Serif;
+  }
+
+  @kotlin.jvm.JvmInline public final value class FontStyle {
+    field public static final androidx.glance.text.FontStyle.Companion Companion;
+  }
+
+  public static final class FontStyle.Companion {
+    method public int getItalic();
+    method public int getNormal();
+    method public java.util.List<androidx.glance.text.FontStyle> values();
+    property public final int Italic;
+    property public final int Normal;
+  }
+
+  @kotlin.jvm.JvmInline public final value class FontWeight {
+    method public int getValue();
+    property public final int value;
+    field public static final androidx.glance.text.FontWeight.Companion Companion;
+  }
+
+  public static final class FontWeight.Companion {
+    method public int getBold();
+    method public int getMedium();
+    method public int getNormal();
+    property public final int Bold;
+    property public final int Medium;
+    property public final int Normal;
+  }
+
+  @kotlin.jvm.JvmInline public final value class TextAlign {
+    field public static final androidx.glance.text.TextAlign.Companion Companion;
+  }
+
+  public static final class TextAlign.Companion {
+    method public int getCenter();
+    method public int getEnd();
+    method public int getLeft();
+    method public int getRight();
+    method public int getStart();
+    method public java.util.List<androidx.glance.text.TextAlign> values();
+    property public final int Center;
+    property public final int End;
+    property public final int Left;
+    property public final int Right;
+    property public final int Start;
+  }
+
+  @kotlin.jvm.JvmInline public final value class TextDecoration {
+    method @androidx.compose.runtime.Stable public operator boolean contains(int other);
+    method @androidx.compose.runtime.Stable public operator int plus(int decoration);
+    field public static final androidx.glance.text.TextDecoration.Companion Companion;
+  }
+
+  public static final class TextDecoration.Companion {
+    method public int combine(java.util.List<androidx.glance.text.TextDecoration> decorations);
+    method public int getLineThrough();
+    method public int getNone();
+    method public int getUnderline();
+    property public final int LineThrough;
+    property public final int None;
+    property public final int Underline;
+  }
+
+  public final class TextDefaults {
+    method public androidx.glance.unit.ColorProvider getDefaultTextColor();
+    method public androidx.glance.text.TextStyle getDefaultTextStyle();
+    property public final androidx.glance.unit.ColorProvider defaultTextColor;
+    property public final androidx.glance.text.TextStyle defaultTextStyle;
+    field public static final androidx.glance.text.TextDefaults INSTANCE;
+  }
+
+  public final class TextKt {
+    method @androidx.compose.runtime.Composable public static void Text(String text, optional androidx.glance.GlanceModifier modifier, optional androidx.glance.text.TextStyle style, optional int maxLines);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextStyle {
+    ctor public TextStyle(optional androidx.glance.unit.ColorProvider color, optional androidx.compose.ui.unit.TextUnit? fontSize, optional androidx.glance.text.FontWeight? fontWeight, optional androidx.glance.text.FontStyle? fontStyle, optional androidx.glance.text.TextAlign? textAlign, optional androidx.glance.text.TextDecoration? textDecoration, optional androidx.glance.text.FontFamily? fontFamily);
+    method public androidx.glance.text.TextStyle copy(optional androidx.glance.unit.ColorProvider color, optional androidx.compose.ui.unit.TextUnit? fontSize, optional androidx.glance.text.FontWeight? fontWeight, optional androidx.glance.text.FontStyle? fontStyle, optional androidx.glance.text.TextAlign? textAlign, optional androidx.glance.text.TextDecoration? textDecoration, optional androidx.glance.text.FontFamily? fontFamily);
+    method public androidx.glance.unit.ColorProvider getColor();
+    method public androidx.glance.text.FontFamily? getFontFamily();
+    method public androidx.compose.ui.unit.TextUnit? getFontSize();
+    method public androidx.glance.text.FontStyle? getFontStyle();
+    method public androidx.glance.text.FontWeight? getFontWeight();
+    method public androidx.glance.text.TextAlign? getTextAlign();
+    method public androidx.glance.text.TextDecoration? getTextDecoration();
+    property public final androidx.glance.unit.ColorProvider color;
+    property public final androidx.glance.text.FontFamily? fontFamily;
+    property public final androidx.compose.ui.unit.TextUnit? fontSize;
+    property public final androidx.glance.text.FontStyle? fontStyle;
+    property public final androidx.glance.text.FontWeight? fontWeight;
+    property public final androidx.glance.text.TextAlign? textAlign;
+    property public final androidx.glance.text.TextDecoration? textDecoration;
+  }
+
+}
+
+package androidx.glance.unit {
+
+  public interface ColorProvider {
+    method public long getColor(android.content.Context context);
+  }
+
+  public final class ColorProviderKt {
+    method public static androidx.glance.unit.ColorProvider ColorProvider(long color);
+  }
+
+}
+
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/data/DataType.kt b/health/health-services-client/src/main/java/androidx/health/services/client/data/DataType.kt
index 40bde13..575812e 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/data/DataType.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/data/DataType.kt
@@ -651,16 +651,20 @@
             createStatsDataType("Vertical Oscillation")
 
         /**
-         * Vertical oscillation / stride length. Divide vertical oscillation (converted to meters)
-         * by stride length (in meters) in `double` format.
+         * Vertical oscillation / stride length.
+         *
+         * For example, a vertical oscillation of 5.0cm and stride length .8m (80 cm) would have a
+         * vertical ratio of 0.625.
          */
         @JvmField
         val VERTICAL_RATIO: DeltaDataType<Double, SampleDataPoint<Double>> =
             createSampleDataType("Vertical Ratio")
 
         /**
-         * Statistics on vertical oscillation / stride length. Divide vertical oscillation
-         * (converted to meters) by stride length (in meters) in `double` format.
+         * Statistics on vertical oscillation / stride length.
+         *
+         * For example, a vertical oscillation of 5.0cm and stride length .8m (80 cm) would have a
+         * vertical ratio of 0.625.
          */
         @JvmField
         val VERTICAL_RATIO_STATS: AggregateDataType<Double, StatisticalDataPoint<Double>> =
diff --git a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/IterableSubject.kt b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/IterableSubject.kt
index 2d62acb..3fa55bf 100644
--- a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/IterableSubject.kt
+++ b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/IterableSubject.kt
@@ -165,6 +165,15 @@
         containsAnyIn(requireNonNull(expected).asList())
     }
 
+    /**
+     * Checks that the actual iterable contains at least all of the expected elements or fails. If
+     * an element appears more than once in the expected elements to this call then it must appear
+     * at least that number of times in the actual elements.
+     *
+     * To also test that the contents appear in the given order, make a call to `inOrder()` on the
+     * object returned by this method. The expected elements must appear in the given order within
+     * the actual elements, but they are not required to be consecutive.
+     */
     fun containsAtLeast(
         firstExpected: Any?,
         secondExpected: Any?,
@@ -172,6 +181,15 @@
     ): Ordered =
         containsAtLeastElementsIn(listOf(firstExpected, secondExpected, *restOfExpected))
 
+    /**
+     * Checks that the actual iterable contains at least all of the expected elements or fails. If
+     * an element appears more than once in the expected elements then it must appear at least that
+     * number of times in the actual elements.
+     *
+     * To also test that the contents appear in the given order, make a call to `inOrder()` on the
+     * object returned by this method. The expected elements must appear in the given order within
+     * the actual elements, but they are not required to be consecutive.
+     */
     fun containsAtLeastElementsIn(expected: Iterable<*>?): Ordered {
         requireNonNull(expected)
         val actualList = requireNonNull(actual).toMutableList()
@@ -520,9 +538,6 @@
             }
     }
 
-    /**
-     * @deprecated You probably meant to call [containsNoneOf] instead.
-     */
     @Deprecated(
         message = "You probably meant to call containsNoneOf instead.",
         replaceWith = ReplaceWith(expression = "containsNoneOf"),
diff --git a/libraryversions.toml b/libraryversions.toml
index cd81f35..1ae4757 100644
--- a/libraryversions.toml
+++ b/libraryversions.toml
@@ -14,10 +14,10 @@
 BLUETOOTH = "1.0.0-alpha02"
 BROWSER = "1.9.0-alpha01"
 BUILDSRC_TESTS = "1.0.0-alpha01"
-CAMERA = "1.4.0-alpha04"
+CAMERA = "1.4.0-beta01"
 CAMERA_PIPE = "1.0.0-alpha01"
 CAMERA_TESTING = "1.0.0-alpha01"
-CAMERA_VIEWFINDER = "1.4.0-alpha04"
+CAMERA_VIEWFINDER = "1.4.0-alpha05"
 CAMERA_VIEWFINDER_COMPOSE = "1.0.0-alpha01"
 CARDVIEW = "1.1.0-alpha01"
 CAR_APP = "1.7.0-alpha01"
@@ -43,7 +43,7 @@
 CORE_I18N = "1.0.0-alpha02"
 CORE_LOCATION_ALTITUDE = "1.0.0-alpha02"
 CORE_PERFORMANCE = "1.0.0"
-CORE_REMOTEVIEWS = "1.1.0-alpha01"
+CORE_REMOTEVIEWS = "1.1.0-beta01"
 CORE_ROLE = "1.2.0-alpha01"
 CORE_SPLASHSCREEN = "1.1.0-alpha02"
 CORE_TELECOM = "1.0.0-alpha02"
@@ -65,7 +65,7 @@
 EXIFINTERFACE = "1.4.0-alpha01"
 FRAGMENT = "1.7.0-rc01"
 FUTURES = "1.2.0-alpha03"
-GLANCE = "1.1.0-alpha01"
+GLANCE = "1.1.0-beta01"
 GLANCE_PREVIEW = "1.0.0-alpha06"
 GLANCE_TEMPLATE = "1.0.0-alpha06"
 GLANCE_WEAR_TILES = "1.0.0-alpha06"
@@ -155,7 +155,7 @@
 VIEWPAGER = "1.1.0-alpha02"
 VIEWPAGER2 = "1.1.0-beta03"
 WEAR = "1.4.0-alpha01"
-WEAR_COMPOSE = "1.4.0-alpha05"
+WEAR_COMPOSE = "1.4.0-alpha06"
 WEAR_COMPOSE_MATERIAL3 = "1.0.0-alpha20"
 WEAR_INPUT = "1.2.0-alpha03"
 WEAR_INPUT_TESTING = "1.2.0-alpha03"
diff --git a/lifecycle/lifecycle-runtime/build.gradle b/lifecycle/lifecycle-runtime/build.gradle
index bcb9ce0..323d017 100644
--- a/lifecycle/lifecycle-runtime/build.gradle
+++ b/lifecycle/lifecycle-runtime/build.gradle
@@ -136,5 +136,4 @@
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear "2017"
     description "Android Lifecycle Runtime"
-    metalavaK2UastEnabled = true
 }
diff --git a/lifecycle/lifecycle-viewmodel/api/current.txt b/lifecycle/lifecycle-viewmodel/api/current.txt
index 417a0af..558185d 100644
--- a/lifecycle/lifecycle-viewmodel/api/current.txt
+++ b/lifecycle/lifecycle-viewmodel/api/current.txt
@@ -43,8 +43,8 @@
     ctor public ViewModelProvider(androidx.lifecycle.ViewModelStore store, androidx.lifecycle.ViewModelProvider.Factory factory, optional androidx.lifecycle.viewmodel.CreationExtras defaultCreationExtras);
     ctor public ViewModelProvider(androidx.lifecycle.ViewModelStoreOwner owner);
     ctor public ViewModelProvider(androidx.lifecycle.ViewModelStoreOwner owner, androidx.lifecycle.ViewModelProvider.Factory factory);
-    method public static final androidx.lifecycle.ViewModelProvider create(androidx.lifecycle.ViewModelStore store, androidx.lifecycle.ViewModelProvider.Factory factory, androidx.lifecycle.viewmodel.CreationExtras extras);
-    method public static final androidx.lifecycle.ViewModelProvider create(androidx.lifecycle.ViewModelStoreOwner owner, androidx.lifecycle.ViewModelProvider.Factory factory, androidx.lifecycle.viewmodel.CreationExtras extras);
+    method public static final androidx.lifecycle.ViewModelProvider create(androidx.lifecycle.ViewModelStore store, optional androidx.lifecycle.ViewModelProvider.Factory factory, optional androidx.lifecycle.viewmodel.CreationExtras extras);
+    method public static final androidx.lifecycle.ViewModelProvider create(androidx.lifecycle.ViewModelStoreOwner owner, optional androidx.lifecycle.ViewModelProvider.Factory factory, optional androidx.lifecycle.viewmodel.CreationExtras extras);
     method @MainThread public operator <T extends androidx.lifecycle.ViewModel> T get(Class<T> modelClass);
     method @MainThread public operator <T extends androidx.lifecycle.ViewModel> T get(String key, Class<T> modelClass);
     method @MainThread public final operator <T extends androidx.lifecycle.ViewModel> T get(String key, kotlin.reflect.KClass<T> modelClass);
@@ -66,8 +66,8 @@
   }
 
   public static final class ViewModelProvider.Companion {
-    method public androidx.lifecycle.ViewModelProvider create(androidx.lifecycle.ViewModelStore store, androidx.lifecycle.ViewModelProvider.Factory factory, androidx.lifecycle.viewmodel.CreationExtras extras);
-    method public androidx.lifecycle.ViewModelProvider create(androidx.lifecycle.ViewModelStoreOwner owner, androidx.lifecycle.ViewModelProvider.Factory factory, androidx.lifecycle.viewmodel.CreationExtras extras);
+    method public androidx.lifecycle.ViewModelProvider create(androidx.lifecycle.ViewModelStore store, optional androidx.lifecycle.ViewModelProvider.Factory factory, optional androidx.lifecycle.viewmodel.CreationExtras extras);
+    method public androidx.lifecycle.ViewModelProvider create(androidx.lifecycle.ViewModelStoreOwner owner, optional androidx.lifecycle.ViewModelProvider.Factory factory, optional androidx.lifecycle.viewmodel.CreationExtras extras);
   }
 
   public static interface ViewModelProvider.Factory {
diff --git a/lifecycle/lifecycle-viewmodel/api/restricted_current.txt b/lifecycle/lifecycle-viewmodel/api/restricted_current.txt
index 417a0af..558185d 100644
--- a/lifecycle/lifecycle-viewmodel/api/restricted_current.txt
+++ b/lifecycle/lifecycle-viewmodel/api/restricted_current.txt
@@ -43,8 +43,8 @@
     ctor public ViewModelProvider(androidx.lifecycle.ViewModelStore store, androidx.lifecycle.ViewModelProvider.Factory factory, optional androidx.lifecycle.viewmodel.CreationExtras defaultCreationExtras);
     ctor public ViewModelProvider(androidx.lifecycle.ViewModelStoreOwner owner);
     ctor public ViewModelProvider(androidx.lifecycle.ViewModelStoreOwner owner, androidx.lifecycle.ViewModelProvider.Factory factory);
-    method public static final androidx.lifecycle.ViewModelProvider create(androidx.lifecycle.ViewModelStore store, androidx.lifecycle.ViewModelProvider.Factory factory, androidx.lifecycle.viewmodel.CreationExtras extras);
-    method public static final androidx.lifecycle.ViewModelProvider create(androidx.lifecycle.ViewModelStoreOwner owner, androidx.lifecycle.ViewModelProvider.Factory factory, androidx.lifecycle.viewmodel.CreationExtras extras);
+    method public static final androidx.lifecycle.ViewModelProvider create(androidx.lifecycle.ViewModelStore store, optional androidx.lifecycle.ViewModelProvider.Factory factory, optional androidx.lifecycle.viewmodel.CreationExtras extras);
+    method public static final androidx.lifecycle.ViewModelProvider create(androidx.lifecycle.ViewModelStoreOwner owner, optional androidx.lifecycle.ViewModelProvider.Factory factory, optional androidx.lifecycle.viewmodel.CreationExtras extras);
     method @MainThread public operator <T extends androidx.lifecycle.ViewModel> T get(Class<T> modelClass);
     method @MainThread public operator <T extends androidx.lifecycle.ViewModel> T get(String key, Class<T> modelClass);
     method @MainThread public final operator <T extends androidx.lifecycle.ViewModel> T get(String key, kotlin.reflect.KClass<T> modelClass);
@@ -66,8 +66,8 @@
   }
 
   public static final class ViewModelProvider.Companion {
-    method public androidx.lifecycle.ViewModelProvider create(androidx.lifecycle.ViewModelStore store, androidx.lifecycle.ViewModelProvider.Factory factory, androidx.lifecycle.viewmodel.CreationExtras extras);
-    method public androidx.lifecycle.ViewModelProvider create(androidx.lifecycle.ViewModelStoreOwner owner, androidx.lifecycle.ViewModelProvider.Factory factory, androidx.lifecycle.viewmodel.CreationExtras extras);
+    method public androidx.lifecycle.ViewModelProvider create(androidx.lifecycle.ViewModelStore store, optional androidx.lifecycle.ViewModelProvider.Factory factory, optional androidx.lifecycle.viewmodel.CreationExtras extras);
+    method public androidx.lifecycle.ViewModelProvider create(androidx.lifecycle.ViewModelStoreOwner owner, optional androidx.lifecycle.ViewModelProvider.Factory factory, optional androidx.lifecycle.viewmodel.CreationExtras extras);
   }
 
   public static interface ViewModelProvider.Factory {
diff --git a/lifecycle/lifecycle-viewmodel/src/androidMain/kotlin/androidx/lifecycle/ViewModelProvider.android.kt b/lifecycle/lifecycle-viewmodel/src/androidMain/kotlin/androidx/lifecycle/ViewModelProvider.android.kt
index 5e5f45f..6909499 100644
--- a/lifecycle/lifecycle-viewmodel/src/androidMain/kotlin/androidx/lifecycle/ViewModelProvider.android.kt
+++ b/lifecycle/lifecycle-viewmodel/src/androidMain/kotlin/androidx/lifecycle/ViewModelProvider.android.kt
@@ -344,6 +344,7 @@
 
     public actual companion object {
         @JvmStatic
+        @Suppress("MissingJvmstatic")
         public actual fun create(
             owner: ViewModelStoreOwner,
             factory: Factory,
@@ -351,6 +352,7 @@
         ): ViewModelProvider = ViewModelProvider(owner.viewModelStore, factory, extras)
 
         @JvmStatic
+        @Suppress("MissingJvmstatic")
         public actual fun create(
             store: ViewModelStore,
             factory: Factory,
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavGraphTest.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavGraphTest.kt
index db7b497..7160edf 100644
--- a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavGraphTest.kt
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavGraphTest.kt
@@ -205,7 +205,7 @@
             addDestination(NavDestinationBuilder(navGraphNavigator, TestClass::class).build())
         }
 
-        val dest = graph.findNode(TestClass::class)
+        val dest = graph.findNode<TestClass>()
         assertThat(dest).isNotNull()
     }
 
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/NavGraph.kt b/navigation/navigation-common/src/main/java/androidx/navigation/NavGraph.kt
index bff9da7..d175f19 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/NavGraph.kt
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/NavGraph.kt
@@ -192,8 +192,8 @@
      * @return the node with route - the node must have been created with a route from [KClass]
      */
     @OptIn(InternalSerializationApi::class)
-    internal fun <T : Any> findNode(route: KClass<T>?): NavDestination? {
-        return if (route != null) findNode(route.serializer().hashCode()) else null
+    internal inline fun <reified T> findNode(): NavDestination? {
+        return findNode(serializer<T>().hashCode())
     }
 
     /**
@@ -524,8 +524,8 @@
  * @throws IllegalArgumentException if no destination is found with that route.
  */
 @Suppress("NOTHING_TO_INLINE")
-internal inline operator fun <T : Any> NavGraph.get(route: KClass<T>): NavDestination =
-    findNode(route)
+internal inline operator fun <reified T : Any> NavGraph.get(route: KClass<T>): NavDestination =
+    findNode<T>()
         ?: throw IllegalArgumentException("No destination for $route was found in $this")
 
 /**
@@ -545,8 +545,9 @@
 public operator fun NavGraph.contains(route: String): Boolean = findNode(route) != null
 
 /** Returns `true` if a destination with `route` is found in this navigation graph. */
-internal operator fun <T : Any> NavGraph.contains(route: KClass<T>): Boolean =
-    findNode(route) != null
+@Suppress("UNUSED_PARAMETER")
+internal inline operator fun <reified T : Any> NavGraph.contains(route: KClass<T>): Boolean =
+    findNode<T>() != null
 
 /** Returns `true` if a destination with `route` is found in this navigation graph. */
 internal operator fun <T> NavGraph.contains(route: T): Boolean = findNode(route) != null
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkProviderTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkProviderTest.kt
index a2f9bbe..ac306ec 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkProviderTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkProviderTest.kt
@@ -35,6 +35,8 @@
 import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
 import androidx.privacysandbox.sdkruntime.core.controller.LoadSdkCallback
 import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+import androidx.privacysandbox.sdkruntime.core.internal.ClientApiVersion
+import androidx.privacysandbox.sdkruntime.core.internal.ClientFeature
 import androidx.test.core.app.ActivityScenario
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.filters.LargeTest
@@ -119,10 +121,7 @@
 
     @Test
     fun getSandboxedSdks_delegateToSdkController() {
-        assumeTrue(
-            "Requires Versions.API_VERSION >= 2",
-            sdkVersion >= 2
-        )
+        assumeFeatureAvailable(ClientFeature.SDK_SANDBOX_CONTROLLER)
 
         val expectedResult = SandboxedSdkCompat(
             sdkInterface = Binder(),
@@ -147,10 +146,7 @@
 
     @Test
     fun getAppOwnedSdkSandboxInterfaces_delegateToSdkController() {
-        assumeTrue(
-            "Requires Versions.API_VERSION >= 4",
-            sdkVersion >= 4
-        )
+        assumeFeatureAvailable(ClientFeature.APP_OWNED_INTERFACES)
 
         val expectedResult = AppOwnedSdkSandboxInterfaceCompat(
             name = "TestAppOwnedSdk",
@@ -173,10 +169,7 @@
 
     @Test
     fun registerSdkSandboxActivityHandler_delegateToSdkController() {
-        assumeTrue(
-            "Requires Versions.API_VERSION >= 3",
-            sdkVersion >= 3
-        )
+        assumeFeatureAvailable(ClientFeature.SDK_ACTIVITY_HANDLER)
 
         val catchingHandler = CatchingSdkActivityHandler()
 
@@ -198,10 +191,7 @@
 
     @Test
     fun sdkSandboxActivityHandler_ReceivesLifecycleEventsFromOriginalActivityHolder() {
-        assumeTrue(
-            "Requires Versions.API_VERSION >= 3",
-            sdkVersion >= 3
-        )
+        assumeFeatureAvailable(ClientFeature.SDK_ACTIVITY_HANDLER)
 
         val catchingHandler = CatchingSdkActivityHandler()
 
@@ -226,10 +216,7 @@
 
     @Test
     fun unregisterSdkSandboxActivityHandler_delegateToSdkController() {
-        assumeTrue(
-            "Requires Versions.API_VERSION >= 3",
-            sdkVersion >= 3
-        )
+        assumeFeatureAvailable(ClientFeature.SDK_ACTIVITY_HANDLER)
 
         val handler = CatchingSdkActivityHandler()
 
@@ -242,10 +229,7 @@
 
     @Test
     fun loadSdk_returnsResultFromSdkController() {
-        assumeTrue(
-            "Requires Versions.API_VERSION >= 5",
-            sdkVersion >= 5
-        )
+        assumeFeatureAvailable(ClientFeature.LOAD_SDK)
 
         val sdkName = "SDK"
         val sdkParams = Bundle()
@@ -265,10 +249,7 @@
 
     @Test
     fun loadSdk_rethrowsExceptionFromSdkController() {
-        assumeTrue(
-            "Requires Versions.API_VERSION >= 5",
-            sdkVersion >= 5
-        )
+        assumeFeatureAvailable(ClientFeature.LOAD_SDK)
 
         val expectedError = LoadSdkCompatException(
             LoadSdkCompatException.LOAD_SDK_INTERNAL_ERROR,
@@ -311,10 +292,17 @@
         }
     }
 
+    private fun assumeFeatureAvailable(clientFeature: ClientFeature) {
+        assumeTrue(
+            "Requires $clientFeature available (API >= ${clientFeature.availableFrom})",
+            clientFeature.isAvailable(sdkVersion)
+        )
+    }
+
     companion object {
 
         /**
-         * Create test params for each previously released [Versions.API_VERSION] + current one.
+         * Create test params for each supported [ClientApiVersion] + current one.
          * Each released version must have test-sdk named as "vX" (where X is version to test).
          * These TestSDKs should be registered in RuntimeEnabledSdkTable.xml and be compatible with
          * [TestSdkWrapper].
@@ -322,16 +310,16 @@
         @Parameterized.Parameters(name = "sdk: {0}, version: {1}")
         @JvmStatic
         fun params(): List<Array<Any>> = buildList {
-            for (apiVersion in 1..Versions.API_VERSION) {
-                if (apiVersion == 3) {
-                    continue // V3 was released as V4 (original release postponed)
-                }
-                add(
-                    arrayOf(
-                        "v$apiVersion",
-                        apiVersion,
+            ClientApiVersion.values().forEach { version ->
+                // FUTURE_VERSION tested separately
+                if (version != ClientApiVersion.FUTURE_VERSION) {
+                    add(
+                        arrayOf(
+                            "v${version.apiLevel}",
+                            version.apiLevel,
+                        )
                     )
-                )
+                }
             }
 
             add(
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoader.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoader.kt
index adf7a7ee..bf5f248 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoader.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoader.kt
@@ -22,6 +22,7 @@
 import androidx.privacysandbox.sdkruntime.client.loader.storage.CachedLocalSdkStorage
 import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
 import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+import androidx.privacysandbox.sdkruntime.core.internal.ClientFeature
 
 /**
  * Load SDK bundled with App.
@@ -63,17 +64,17 @@
     private fun getParentClassLoader(): ClassLoader = appContext.classLoader.parent!!
 
     private fun createLocalSdk(
-        classLoader: ClassLoader,
+        sdkClassLoader: ClassLoader,
         sdkConfig: LocalSdkConfig
     ): LocalSdkProvider {
         try {
-            val apiVersion = VersionHandshake.perform(classLoader)
-            ResourceRemapping.apply(classLoader, sdkConfig.resourceRemapping)
-            if (apiVersion >= 2) {
-                return createSdkProviderV2(classLoader, apiVersion, sdkConfig)
-            } else if (apiVersion >= 1) {
-                return createSdkProviderV1(classLoader, sdkConfig)
+            val sdkApiVersion = VersionHandshake.perform(sdkClassLoader)
+            ResourceRemapping.apply(sdkClassLoader, sdkConfig.resourceRemapping)
+            if (ClientFeature.SDK_SANDBOX_CONTROLLER.isAvailable(sdkApiVersion)) {
+                val controller = controllerFactory.createControllerFor(sdkConfig)
+                SandboxControllerInjector.inject(sdkClassLoader, sdkApiVersion, controller)
             }
+            return SdkProviderV1.create(sdkClassLoader, sdkConfig, appContext)
         } catch (ex: Exception) {
             throw LoadSdkCompatException(
                 LoadSdkCompatException.LOAD_SDK_INTERNAL_ERROR,
@@ -81,28 +82,6 @@
                 ex
             )
         }
-
-        throw LoadSdkCompatException(
-            LoadSdkCompatException.LOAD_SDK_NOT_FOUND,
-            "Incorrect Api version"
-        )
-    }
-
-    private fun createSdkProviderV1(
-        sdkClassLoader: ClassLoader,
-        sdkConfig: LocalSdkConfig
-    ): LocalSdkProvider {
-        return SdkProviderV1.create(sdkClassLoader, sdkConfig, appContext)
-    }
-
-    private fun createSdkProviderV2(
-        sdkClassLoader: ClassLoader,
-        sdkVersion: Int,
-        sdkConfig: LocalSdkConfig
-    ): LocalSdkProvider {
-        val controller = controllerFactory.createControllerFor(sdkConfig)
-        SandboxControllerInjector.inject(sdkClassLoader, sdkVersion, controller)
-        return SdkProviderV1.create(sdkClassLoader, sdkConfig, appContext)
     }
 
     companion object {
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SandboxControllerInjector.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SandboxControllerInjector.kt
index e6441a0..56f29f7 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SandboxControllerInjector.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SandboxControllerInjector.kt
@@ -24,6 +24,7 @@
 import androidx.privacysandbox.sdkruntime.client.loader.impl.injector.SdkActivityHandlerWrapper
 import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
 import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+import androidx.privacysandbox.sdkruntime.core.internal.ClientFeature
 import java.lang.reflect.InvocationHandler
 import java.lang.reflect.Method
 import java.lang.reflect.Proxy
@@ -65,20 +66,23 @@
         val sandboxedSdkCompatProxyFactory =
             SandboxedSdkCompatProxyFactory.createFor(sdkClassLoader)
 
-        val sdkActivityHandlerWrapper = if (sdkVersion >= 3)
-            SdkActivityHandlerWrapper.createFor(sdkClassLoader)
-        else
-            null
+        val sdkActivityHandlerWrapper =
+            if (ClientFeature.SDK_ACTIVITY_HANDLER.isAvailable(sdkVersion))
+                SdkActivityHandlerWrapper.createFor(sdkClassLoader)
+            else
+                null
 
-        val appOwnedSdkInterfaceProxyFactory = if (sdkVersion >= 4)
-            AppOwnedSdkInterfaceProxyFactory.createFor(sdkClassLoader)
-        else
-            null
+        val appOwnedSdkInterfaceProxyFactory =
+            if (ClientFeature.APP_OWNED_INTERFACES.isAvailable(sdkVersion))
+                AppOwnedSdkInterfaceProxyFactory.createFor(sdkClassLoader)
+            else
+                null
 
-        val loadSdkCallbackWrapper = if (sdkVersion >= 5)
-            LoadSdkCallbackWrapper.createFor(sdkClassLoader)
-        else
-            null
+        val loadSdkCallbackWrapper =
+            if (ClientFeature.LOAD_SDK.isAvailable(sdkVersion))
+                LoadSdkCallbackWrapper.createFor(sdkClassLoader)
+            else
+                null
 
         val proxy = Proxy.newProxyInstance(
             sdkClassLoader,
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatLocalTest.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatLocalTest.kt
index 84faafc..2995cca 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatLocalTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatLocalTest.kt
@@ -26,6 +26,8 @@
 import androidx.privacysandbox.sdkruntime.core.Versions
 import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
 import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
+import androidx.privacysandbox.sdkruntime.core.internal.ClientApiVersion
+import androidx.privacysandbox.sdkruntime.core.internal.ClientFeature
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -46,8 +48,8 @@
 
     @Before
     fun setUp() {
-        // Emulate loading via client lib
-        Versions.handShake(Versions.API_VERSION)
+        // Emulate loading via client lib with only base features available
+        clientHandShakeForMinSupportedVersion()
 
         context = ApplicationProvider.getApplicationContext()
     }
@@ -67,10 +69,7 @@
     }
 
     @Test
-    fun loadSdk_clientApiBelow5_throwsLoadSdkNotFoundException() {
-        // Emulate loading via client lib with version below 5
-        Versions.handShake(4)
-
+    fun loadSdk_whenNotAvailable_throwsLoadSdkNotFoundException() {
         SdkSandboxControllerCompat.injectLocalImpl(TestStubImpl())
         val controllerCompat = SdkSandboxControllerCompat.from(context)
 
@@ -85,6 +84,8 @@
 
     @Test
     fun loadSdk_returnsLoadedSdkFromLocalImpl() {
+        clientHandShakeForVersionIncluding(ClientFeature.LOAD_SDK)
+
         val expectedResult = SandboxedSdkCompat(Binder())
         val stubLocalImpl = TestStubImpl(
             loadSdkResult = expectedResult
@@ -105,6 +106,8 @@
 
     @Test
     fun loadSdk_rethrowsExceptionFromLocalImpl() {
+        clientHandShakeForVersionIncluding(ClientFeature.LOAD_SDK)
+
         val expectedError = LoadSdkCompatException(RuntimeException(), Bundle())
         SdkSandboxControllerCompat.injectLocalImpl(
             TestStubImpl(
@@ -137,10 +140,7 @@
     }
 
     @Test
-    fun getAppOwnedSdkSandboxInterfaces_clientApiBelow4_returnsEmptyList() {
-        // Emulate loading via client lib with version below 4
-        Versions.handShake(3)
-
+    fun getAppOwnedSdkSandboxInterfaces_whenNotAvailable_returnsEmptyList() {
         SdkSandboxControllerCompat.injectLocalImpl(
             TestStubImpl(
                 appOwnedSdks = listOf(
@@ -160,6 +160,8 @@
 
     @Test
     fun getAppOwnedSdkSandboxInterfaces_returnsListFromLocalImpl() {
+        clientHandShakeForVersionIncluding(ClientFeature.APP_OWNED_INTERFACES)
+
         val expectedResult = listOf(
             AppOwnedSdkSandboxInterfaceCompat(
                 name = "TestSdk",
@@ -180,6 +182,8 @@
 
     @Test
     fun registerSdkSandboxActivityHandler_registerItInLocalImpl() {
+        clientHandShakeForVersionIncluding(ClientFeature.SDK_ACTIVITY_HANDLER)
+
         val localImpl = TestStubImpl()
         SdkSandboxControllerCompat.injectLocalImpl(localImpl)
 
@@ -193,6 +197,8 @@
 
     @Test
     fun unregisterSdkSandboxActivityHandler_unregisterItFromLocalImpl() {
+        clientHandShakeForVersionIncluding(ClientFeature.SDK_ACTIVITY_HANDLER)
+
         val localImpl = TestStubImpl()
         SdkSandboxControllerCompat.injectLocalImpl(localImpl)
 
@@ -208,10 +214,7 @@
     }
 
     @Test
-    fun registerSdkSandboxActivityHandler_clientApiBelow3_throwsUnsupportedOperationException() {
-        // Emulate loading via client lib with version below 3
-        Versions.handShake(2)
-
+    fun registerSdkSandboxActivityHandler_whenNotAvailable_throwsUnsupportedOperationException() {
         SdkSandboxControllerCompat.injectLocalImpl(TestStubImpl())
         val controllerCompat = SdkSandboxControllerCompat.from(context)
 
@@ -225,10 +228,7 @@
     }
 
     @Test
-    fun unregisterSdkSandboxActivityHandler_clientApiBelow3_throwsUnsupportedOperationException() {
-        // Emulate loading via client lib with version below 3
-        Versions.handShake(2)
-
+    fun unregisterSdkSandboxActivityHandler_whenNotAvailable_throwsUnsupportedOperationException() {
         SdkSandboxControllerCompat.injectLocalImpl(TestStubImpl())
         val controllerCompat = SdkSandboxControllerCompat.from(context)
 
@@ -241,6 +241,22 @@
         }
     }
 
+    /**
+     * Call [Versions.handShake] to emulate loading via client lib.
+     * Using version where [clientFeature] available.
+     */
+    private fun clientHandShakeForVersionIncluding(clientFeature: ClientFeature) {
+        Versions.handShake(clientFeature.availableFrom.apiLevel)
+    }
+
+    /**
+     * Call [Versions.handShake] to emulate loading via client lib.
+     * Using [ClientApiVersion.MIN_SUPPORTED] - to check features available in all client versions.
+     */
+    private fun clientHandShakeForMinSupportedVersion() {
+        Versions.handShake(ClientApiVersion.MIN_SUPPORTED.apiLevel)
+    }
+
     internal class TestStubImpl(
         private val sandboxedSdks: List<SandboxedSdkCompat> = emptyList(),
         private val appOwnedSdks: List<AppOwnedSdkSandboxInterfaceCompat> = emptyList(),
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/Versions.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/Versions.kt
index 69d5126..6d50d2c 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/Versions.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/Versions.kt
@@ -18,19 +18,22 @@
 
 import androidx.annotation.Keep
 import androidx.annotation.RestrictTo
+import androidx.privacysandbox.sdkruntime.core.internal.ClientApiVersion
 import org.jetbrains.annotations.TestOnly
 
 /**
  * Store internal API version (for Client-Core communication).
- * Methods invoked via reflection.
  *
+ * DO NOT CHANGE THIS CLASS.
+ * Methods invoked via reflection from previously released versions of sdkruntime-client.
  */
 @Suppress("unused")
 @Keep
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 object Versions {
 
-    const val API_VERSION = 5
+    @JvmField
+    val API_VERSION = ClientApiVersion.CURRENT_VERSION.apiLevel
 
     @JvmField
     var CLIENT_VERSION: Int? = null
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/LocalImpl.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/LocalImpl.kt
index e07d010..b542c62 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/LocalImpl.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/LocalImpl.kt
@@ -25,6 +25,7 @@
 import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
 import androidx.privacysandbox.sdkruntime.core.controller.LoadSdkCallback
 import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+import androidx.privacysandbox.sdkruntime.core.internal.ClientFeature
 import java.util.concurrent.Executor
 
 /**
@@ -42,7 +43,7 @@
         executor: Executor,
         callback: LoadSdkCallback
     ) {
-        if (clientVersion >= 5) {
+        if (ClientFeature.LOAD_SDK.isAvailable(clientVersion)) {
             implFromClient.loadSdk(sdkName, params, executor, callback)
         } else {
             executor.execute {
@@ -61,7 +62,7 @@
     }
 
     override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> {
-        return if (clientVersion >= 4) {
+        return if (ClientFeature.APP_OWNED_INTERFACES.isAvailable(clientVersion)) {
             implFromClient.getAppOwnedSdkSandboxInterfaces()
         } else {
             emptyList()
@@ -71,22 +72,24 @@
     override fun registerSdkSandboxActivityHandler(
         handlerCompat: SdkSandboxActivityHandlerCompat
     ): IBinder {
-        if (clientVersion < 3) {
+        if (ClientFeature.SDK_ACTIVITY_HANDLER.isAvailable(clientVersion)) {
+            return implFromClient.registerSdkSandboxActivityHandler(handlerCompat)
+        } else {
             throw UnsupportedOperationException(
                 "Client library version doesn't support SdkActivities"
             )
         }
-        return implFromClient.registerSdkSandboxActivityHandler(handlerCompat)
     }
 
     override fun unregisterSdkSandboxActivityHandler(
         handlerCompat: SdkSandboxActivityHandlerCompat
     ) {
-        if (clientVersion < 3) {
+        if (ClientFeature.SDK_ACTIVITY_HANDLER.isAvailable(clientVersion)) {
+            implFromClient.unregisterSdkSandboxActivityHandler(handlerCompat)
+        } else {
             throw UnsupportedOperationException(
                 "Client library version doesn't support SdkActivities"
             )
         }
-        implFromClient.unregisterSdkSandboxActivityHandler(handlerCompat)
     }
 }
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/internal/ClientApiVersion.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/internal/ClientApiVersion.kt
new file mode 100644
index 0000000..dc31b15
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/internal/ClientApiVersion.kt
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2024 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.privacysandbox.sdkruntime.core.internal
+
+import androidx.annotation.RestrictTo
+
+/**
+ * List of all supported internal API versions (Client-Core communication).
+ *
+ * NEVER REMOVE / MODIFY RELEASED VERSIONS:
+ * That could break loading of SDKs built with previous/future library version.
+ *
+ * Adding new version here bumps internal API version for next library release:
+ * [androidx.privacysandbox.sdkruntime.core.Versions.API_VERSION]
+ * When adding a new version, ALL new features from this version should be specified
+ * (NO FUTURE CHANGES SUPPORTED).
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+enum class ClientApiVersion(
+    val apiLevel: Int,
+    private val newFeatures: Set<ClientFeature> = emptySet()
+) {
+    V1__1_0_ALPHA01(apiLevel = 1),
+
+    V2__1_0_ALPHA02(
+        apiLevel = 2,
+        newFeatures = setOf(
+            ClientFeature.SDK_SANDBOX_CONTROLLER
+        )
+    ),
+
+    // V3 was released as V4 (original release postponed)
+    V4__1_0_ALPHA05(
+        apiLevel = 4,
+        newFeatures = setOf(
+            ClientFeature.SDK_ACTIVITY_HANDLER,
+            ClientFeature.APP_OWNED_INTERFACES,
+        )
+    ),
+
+    V5__1_0_ALPHA13(
+        apiLevel = 5,
+        newFeatures = setOf(
+            ClientFeature.LOAD_SDK
+        )
+    ),
+
+    /**
+     * Unreleased API version.
+     * Features not added to other versions will be automatically added here (to allow testing).
+     */
+    FUTURE_VERSION(apiLevel = Int.MAX_VALUE);
+
+    companion object {
+        val MIN_SUPPORTED = values().minBy { v -> v.apiLevel }
+        val CURRENT_VERSION = values().filter { v -> v != FUTURE_VERSION }.maxBy { v -> v.apiLevel }
+
+        private val FEATURE_TO_VERSION_MAP = buildFeatureMap()
+
+        fun minAvailableVersionFor(clientFeature: ClientFeature): ClientApiVersion {
+            return FEATURE_TO_VERSION_MAP[clientFeature]!!
+        }
+
+        /**
+         * Build mapping between [ClientFeature] and version where it first time became available.
+         * Features not added to specific version mapped as [FUTURE_VERSION]
+         */
+        private fun buildFeatureMap(): Map<ClientFeature, ClientApiVersion> {
+            if (FUTURE_VERSION.newFeatures.isNotEmpty()) {
+                throw IllegalStateException("FUTURE_VERSION MUST NOT define any features")
+            }
+            return buildMap {
+                values().forEach { version ->
+                    version.newFeatures.forEach { feature ->
+                        val oldVersion = put(feature, version)
+                        if (oldVersion != null) {
+                            throw IllegalStateException(
+                                "$feature duplicated in $version and $oldVersion"
+                            )
+                        }
+                    }
+                }
+                ClientFeature.values().forEach { feature ->
+                    if (!containsKey(feature)) {
+                        put(feature, FUTURE_VERSION)
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/internal/ClientFeature.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/internal/ClientFeature.kt
new file mode 100644
index 0000000..5e24eb9
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/internal/ClientFeature.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2024 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.privacysandbox.sdkruntime.core.internal
+
+import androidx.annotation.RestrictTo
+import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+
+/**
+ * List of features using Client-Core internal API.
+ * Each feature available since particular ([ClientApiVersion]).
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+enum class ClientFeature {
+    /**
+     * Support for retrieving [SdkSandboxControllerCompat] on SDK side.
+     */
+    SDK_SANDBOX_CONTROLLER,
+
+    /**
+     * Support for starting SDK Activity:
+     * [SdkSandboxControllerCompat.registerSdkSandboxActivityHandler]
+     * [SdkSandboxControllerCompat.unregisterSdkSandboxActivityHandler]
+     */
+    SDK_ACTIVITY_HANDLER,
+
+    /**
+     * Support for retrieving App-owned interfaces:
+     * [SdkSandboxControllerCompat.getAppOwnedSdkSandboxInterfaces]
+     */
+    APP_OWNED_INTERFACES,
+
+    /**
+     * Support for loading SDKs by other SDKs:
+     * [SdkSandboxControllerCompat.loadSdk]
+     */
+    LOAD_SDK;
+
+    val availableFrom: ClientApiVersion
+        get() = ClientApiVersion.minAvailableVersionFor(this)
+
+    fun isAvailable(apiLevel: Int): Boolean {
+        return apiLevel >= availableFrom.apiLevel
+    }
+}
diff --git a/privacysandbox/sdkruntime/test-sdks/v5/build.gradle b/privacysandbox/sdkruntime/test-sdks/v5/build.gradle
index cecf9a2..9b98f82 100644
--- a/privacysandbox/sdkruntime/test-sdks/v5/build.gradle
+++ b/privacysandbox/sdkruntime/test-sdks/v5/build.gradle
@@ -35,7 +35,7 @@
 
 dependencies {
     implementation(libs.kotlinCoroutinesCore)
-    implementation(project(":privacysandbox:sdkruntime:sdkruntime-provider"))
+    implementation("androidx.privacysandbox.sdkruntime:sdkruntime-provider:1.0.0-alpha13")
 }
 
 /*
diff --git a/privacysandbox/tools/tools-testing/build.gradle b/privacysandbox/tools/tools-testing/build.gradle
index a1fd9f3..1a20c8a 100644
--- a/privacysandbox/tools/tools-testing/build.gradle
+++ b/privacysandbox/tools/tools-testing/build.gradle
@@ -38,7 +38,7 @@
 
 androidx {
     name = "androidx.privacysandbox.tools:tools-testing"
-    type = LibraryType.INTERNAL_TEST_LIBRARY
+    type = LibraryType.INTERNAL_HOST_TEST_LIBRARY
     inceptionYear = "2022"
     description = "Testing utilities for privacysandbox tools."
 }
diff --git a/room/room-runtime/api/restricted_current.txt b/room/room-runtime/api/restricted_current.txt
index 4ca2f68..7039636 100644
--- a/room/room-runtime/api/restricted_current.txt
+++ b/room/room-runtime/api/restricted_current.txt
@@ -514,7 +514,7 @@
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class TableInfo {
     ctor @Deprecated public TableInfo(String name, java.util.Map<java.lang.String,androidx.room.util.TableInfo.Column> columns, java.util.Set<androidx.room.util.TableInfo.ForeignKey> foreignKeys);
-    ctor public TableInfo(String name, java.util.Map<java.lang.String,androidx.room.util.TableInfo.Column> columns, java.util.Set<androidx.room.util.TableInfo.ForeignKey> foreignKeys, java.util.Set<androidx.room.util.TableInfo.Index>? indices);
+    ctor public TableInfo(String name, java.util.Map<java.lang.String,androidx.room.util.TableInfo.Column> columns, java.util.Set<androidx.room.util.TableInfo.ForeignKey> foreignKeys, optional java.util.Set<androidx.room.util.TableInfo.Index>? indices);
     method @Deprecated public static androidx.room.util.TableInfo read(androidx.sqlite.db.SupportSQLiteDatabase database, String tableName);
     method public static androidx.room.util.TableInfo read(androidx.sqlite.SQLiteConnection connection, String tableName);
     field public static final int CREATED_FROM_DATABASE = 2; // 0x2
diff --git a/room/room-testing/api/api_lint.ignore b/room/room-testing/api/api_lint.ignore
new file mode 100644
index 0000000..3812179
--- /dev/null
+++ b/room/room-testing/api/api_lint.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+MissingJvmstatic: androidx.room.testing.MigrationTestHelper#runMigrationsAndValidate(int, java.util.List<? extends androidx.room.migration.Migration>):
+    A Kotlin method with default parameter values should be annotated with @JvmOverloads for better Java interoperability; see https://android.github.io/kotlin-guides/interop.html#function-overloads-for-defaults
diff --git a/room/room-testing/api/current.txt b/room/room-testing/api/current.txt
index 8699971..2499cb4 100644
--- a/room/room-testing/api/current.txt
+++ b/room/room-testing/api/current.txt
@@ -12,7 +12,7 @@
     method public void closeWhenFinished(androidx.sqlite.db.SupportSQLiteDatabase db);
     method public final androidx.sqlite.SQLiteConnection createDatabase(int version);
     method @kotlin.jvm.Throws(exceptionClasses=IOException::class) public androidx.sqlite.db.SupportSQLiteDatabase createDatabase(String name, int version) throws java.io.IOException;
-    method public final androidx.sqlite.SQLiteConnection runMigrationsAndValidate(int version, java.util.List<? extends androidx.room.migration.Migration> migrations);
+    method public final androidx.sqlite.SQLiteConnection runMigrationsAndValidate(int version, optional java.util.List<? extends androidx.room.migration.Migration> migrations);
     method public androidx.sqlite.db.SupportSQLiteDatabase runMigrationsAndValidate(String name, int version, boolean validateDroppedTables, androidx.room.migration.Migration... migrations);
   }
 
diff --git a/room/room-testing/api/restricted_current.txt b/room/room-testing/api/restricted_current.txt
index 8699971..2499cb4 100644
--- a/room/room-testing/api/restricted_current.txt
+++ b/room/room-testing/api/restricted_current.txt
@@ -12,7 +12,7 @@
     method public void closeWhenFinished(androidx.sqlite.db.SupportSQLiteDatabase db);
     method public final androidx.sqlite.SQLiteConnection createDatabase(int version);
     method @kotlin.jvm.Throws(exceptionClasses=IOException::class) public androidx.sqlite.db.SupportSQLiteDatabase createDatabase(String name, int version) throws java.io.IOException;
-    method public final androidx.sqlite.SQLiteConnection runMigrationsAndValidate(int version, java.util.List<? extends androidx.room.migration.Migration> migrations);
+    method public final androidx.sqlite.SQLiteConnection runMigrationsAndValidate(int version, optional java.util.List<? extends androidx.room.migration.Migration> migrations);
     method public androidx.sqlite.db.SupportSQLiteDatabase runMigrationsAndValidate(String name, int version, boolean validateDroppedTables, androidx.room.migration.Migration... migrations);
   }
 
diff --git a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObject2Test.java b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObject2Test.java
index bd2948f..8ab1650 100644
--- a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObject2Test.java
+++ b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObject2Test.java
@@ -26,6 +26,7 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -41,6 +42,7 @@
 import androidx.test.uiautomator.BySelector;
 import androidx.test.uiautomator.Direction;
 import androidx.test.uiautomator.EventCondition;
+import androidx.test.uiautomator.StaleObjectException;
 import androidx.test.uiautomator.UiObject2;
 import androidx.test.uiautomator.Until;
 
@@ -389,8 +391,7 @@
     public void testHashCode() {
         launchTestActivity(MainActivity.class);
 
-        // Get the same textView object via different methods.
-        // The same object should have the same hash code.
+        // Same object (found w/ different selectors) should have the same hash code.
         UiObject2 textView1 = mDevice.findObject(By.res(TEST_APP, "example_id"));
         UiObject2 textView2 = mDevice.findObject(By.text("TextView with an id"));
         assertEquals(textView1.hashCode(), textView2.hashCode());
@@ -398,6 +399,15 @@
         // Different objects should have different hash codes.
         UiObject2 linearLayout = mDevice.findObject(By.res(TEST_APP, "nested_elements"));
         assertNotEquals(textView1.hashCode(), linearLayout.hashCode());
+
+        // Use cached hash code for stale objects to avoid unnecessary SOEs.
+        int hashCode = textView1.hashCode();
+        mDevice.pressHome();
+        try {
+            assertEquals(hashCode, textView1.hashCode());
+        } catch (StaleObjectException e) {
+            fail("Unexpected StaleObjectException while calculating hash code");
+        }
     }
 
     @Test
diff --git a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiObject2.java b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiObject2.java
index 74c2c2c..1fa068b 100644
--- a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiObject2.java
+++ b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiObject2.java
@@ -136,7 +136,11 @@
 
     @Override
     public int hashCode() {
-        return getAccessibilityNodeInfo().hashCode();
+        try {
+            return getAccessibilityNodeInfo().hashCode();
+        } catch (StaleObjectException e) {
+            return mCachedNode.hashCode();
+        }
     }
 
     /** Recycle this object. */
diff --git a/testutils/testutils-datastore/build.gradle b/testutils/testutils-datastore/build.gradle
index ef661f7..2721d70 100644
--- a/testutils/testutils-datastore/build.gradle
+++ b/testutils/testutils-datastore/build.gradle
@@ -23,6 +23,8 @@
  */
 import androidx.build.LibraryType
 
+import static org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.*
+
 plugins {
     id("AndroidXPlugin")
 }
@@ -45,7 +47,9 @@
                 api(libs.okio)
             }
         }
-
+        nativeMain {
+            dependsOn(commonMain)
+        }
         jvmMain {
             dependencies {
                 api(libs.kotlinStdlib)
@@ -64,6 +68,13 @@
                 implementation(libs.kotlinTest)
             }
         }
+        targets.all { target ->
+            if (target.platformType == org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.native) {
+                target.compilations["main"].defaultSourceSet {
+                    dependsOn(nativeMain)
+                }
+            }
+        }
     }
 }
 
diff --git a/testutils/testutils-datastore/src/commonMain/kotlin/androidx/datastore/FileSystem.kt b/testutils/testutils-datastore/src/commonMain/kotlin/androidx/datastore/FileSystem.kt
new file mode 100644
index 0000000..d8fb2c1
--- /dev/null
+++ b/testutils/testutils-datastore/src/commonMain/kotlin/androidx/datastore/FileSystem.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2024 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.datastore
+
+import okio.FileSystem
+
+internal expect fun filesystem(): FileSystem
diff --git a/testutils/testutils-datastore/src/jvmMain/kotlin/androidx/datastore/FileSystem.jvm.kt b/testutils/testutils-datastore/src/jvmMain/kotlin/androidx/datastore/FileSystem.jvm.kt
new file mode 100644
index 0000000..9b38043
--- /dev/null
+++ b/testutils/testutils-datastore/src/jvmMain/kotlin/androidx/datastore/FileSystem.jvm.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2024 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.datastore
+
+import okio.FileSystem
+
+internal actual fun filesystem(): FileSystem = FileSystem.SYSTEM
diff --git a/testutils/testutils-datastore/src/nativeMain/kotlin/androidx/datastore/FileSystem.native.kt b/testutils/testutils-datastore/src/nativeMain/kotlin/androidx/datastore/FileSystem.native.kt
new file mode 100644
index 0000000..9b38043
--- /dev/null
+++ b/testutils/testutils-datastore/src/nativeMain/kotlin/androidx/datastore/FileSystem.native.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2024 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.datastore
+
+import okio.FileSystem
+
+internal actual fun filesystem(): FileSystem = FileSystem.SYSTEM
diff --git a/wear/compose/compose-foundation/src/main/AndroidManifest.xml b/wear/compose/compose-foundation/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..601babe
--- /dev/null
+++ b/wear/compose/compose-foundation/src/main/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+    <application>
+        <uses-library
+            android:name="wear-sdk"
+            android:required="false"/>
+    </application>
+</manifest>
\ No newline at end of file
diff --git a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/rotary/Rotary.kt b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/rotary/Rotary.kt
index a82086d..5de31b2 100644
--- a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/rotary/Rotary.kt
+++ b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/rotary/Rotary.kt
@@ -28,14 +28,21 @@
 import androidx.compose.animation.core.spring
 import androidx.compose.animation.core.tween
 import androidx.compose.foundation.MutatePriority
+import androidx.compose.foundation.focusable
 import androidx.compose.foundation.gestures.FlingBehavior
 import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.ScrollableDefaults
 import androidx.compose.foundation.gestures.ScrollableState
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
 import androidx.compose.ui.input.rotary.RotaryInputModifierNode
 import androidx.compose.ui.input.rotary.RotaryScrollEvent
 import androidx.compose.ui.node.ModifierNodeElement
 import androidx.compose.ui.platform.InspectorInfo
+import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.platform.debugInspectorInfo
 import androidx.compose.ui.util.fastSumBy
 import androidx.compose.ui.util.lerp
@@ -56,6 +63,43 @@
 import kotlinx.coroutines.launch
 
 /**
+ * Abstract class for setting rotary parameters.
+ * Has 2 implementations - [RotaryDefaults.scrollSpec] and [RotaryDefaults.snapSpec].
+ */
+// TODO(b/278705775): make it public once haptics and other code is merged.
+@ExperimentalWearFoundationApi
+internal abstract class RotarySpec internal constructor() {
+    internal abstract val rotaryHandler: RotaryHandler
+}
+
+/**
+ * A modifier which connects rotary events with scrollable.
+ *
+ * This modifier supports rotary scrolling and snapping.
+ * The behaviour is configured by the provided [RotarySpec]:
+ * either provide [RotaryDefaults.scrollSpec] for scrolling with/without fling
+ * or pass [RotaryDefaults.snapSpec] when snap is required.
+ *
+ * @param rotarySpec Specified [RotarySpec] for proper rotary handling.
+ * @param focusRequester Requests the focus for rotary input.
+ * @param reverseDirection Reverse the direction of scrolling if required. Should be aligned with
+ * Scrollable `reverseDirection` parameter.
+ */
+@ExperimentalWearFoundationApi
+// TODO(b/278705775): make it public once haptics and other code is merged.
+internal fun Modifier.rotary(
+    rotarySpec: RotarySpec,
+    focusRequester: FocusRequester,
+    reverseDirection: Boolean = false
+): Modifier =
+    rotaryHandler(
+        rotaryHandler = rotarySpec.rotaryHandler,
+        reverseDirection = reverseDirection,
+    )
+        .focusRequester(focusRequester)
+        .focusable()
+
+/**
  * An adapter which connects scrollableState to a rotary input for snapping scroll actions.
  *
  * This interface defines the essential properties and methods required for a scrollable
@@ -64,7 +108,7 @@
  */
 @ExperimentalWearFoundationApi
 // TODO(b/278705775): make it public once haptics and other code is merged.
-/* public */ internal interface RotaryScrollAdapter {
+internal interface RotaryScrollableAdapter {
 
     /**
      * The scrollable state used for performing scroll actions in response to rotary events.
@@ -92,7 +136,6 @@
      */
     fun currentItemOffset(): Float
 
-    // TODO(b/326239879) Investigate and test whether this method can be removed.
     /**
      * The total number of items within the scrollable in [scrollableState]
      */
@@ -106,6 +149,93 @@
 // TODO(b/278705775): make it public once haptics and other code is merged.
 /* public */ internal object RotaryDefaults {
 
+    /**
+     * Implementation of the [RotarySpec] to define scrolling behaviour with or without fling.
+     * Should be set as a parameter of [rotary] modifier.
+     *
+     * If fling is not required [flingBehavior] should be set as null.
+     * Note: If [flingBehavior] is null, flinging will not happen and the scrollable content will
+     * stop scrolling immediately after the user stops interacting with rotary input.
+     *
+     * @param scrollableState Scrollable state which will be scrolled
+     * while receiving rotary events.
+     * @param flingBehavior An optional fling behavior, which controls flinging behavior
+     * with rotary. If null fling will not happen.
+     * @param hapticFeedbackEnabled Responsible for haptic feedback during rotary
+     * rotation. By default is true.
+     */
+    @Composable
+    fun scrollSpec(
+        scrollableState: ScrollableState,
+        flingBehavior: FlingBehavior? = ScrollableDefaults.flingBehavior(),
+        hapticFeedbackEnabled: Boolean = true
+    ): RotarySpec {
+        val isLowRes = isLowResInput()
+        val viewConfiguration = ViewConfiguration.get(LocalContext.current)
+        val rotaryHaptics: RotaryHapticHandler =
+            rememberRotaryHapticHandler(scrollableState, hapticFeedbackEnabled)
+
+        return object : RotarySpec() {
+            override val rotaryHandler =
+                flingHandler(
+                    scrollableState,
+                    rotaryHaptics,
+                    flingBehavior,
+                    isLowRes,
+                    viewConfiguration
+                )
+        }
+    }
+
+    /**
+     * Implementation of the [RotarySpec] to define snap behavior. Should be set as
+     * a parameter of [rotary] modifier.
+     *
+     * @param rotaryScrollableAdapter A connection between scrollable entities and rotary events.
+     * @param snapOffset An optional offset to be applied when snapping the item.
+     * After the snap the snapped items offset will be [snapOffset].
+     * @param hapticFeedbackEnabled Responsible for haptic feedback during rotary
+     * rotation. By default is true.
+     */
+    @Composable
+    fun snapSpec(
+        rotaryScrollableAdapter: RotaryScrollableAdapter,
+        snapOffset: Int = SNAP_OFFSET,
+        hapticFeedbackEnabled: Boolean = true
+    ): RotarySpec {
+        val isLowRes = isLowResInput()
+        val rotaryHaptics: RotaryHapticHandler =
+            rememberRotaryHapticHandler(
+                rotaryScrollableAdapter.scrollableState,
+                hapticFeedbackEnabled
+            )
+
+        return remember(rotaryScrollableAdapter, rotaryHaptics, snapOffset, isLowRes) {
+            object : RotarySpec() {
+                override val rotaryHandler =
+                    snapHandler(
+                        rotaryScrollableAdapter,
+                        rotaryHaptics,
+                        snapOffset,
+                        THRESHOLD_DIVIDER,
+                        RESISTANCE_FACTOR,
+                        isLowRes
+                    )
+            }
+        }
+    }
+
+    /**
+     * Returns whether the input is Low-res (a bezel) or high-res (a crown/rsb).
+     */
+    @Composable
+    private fun isLowResInput(): Boolean = LocalContext.current.packageManager
+        .hasSystemFeature("android.hardware.rotaryencoder.lowres")
+
+    private const val SNAP_OFFSET: Int = 0
+    private const val THRESHOLD_DIVIDER: Float = 1.5f
+    private const val RESISTANCE_FACTOR: Float = 3f
+
     // These values represent the timeframe for a fling event. A bigger value is assigned
     // to low-res input due to the lower frequency of low-res rotary events.
     internal const val lowResFlingTimeframe: Long = 100L
@@ -116,9 +246,9 @@
  * An implementation of rotary scroll adapter for ScalingLazyColumn
  */
 @OptIn(ExperimentalWearFoundationApi::class)
-internal class ScalingLazyColumnRotaryScrollAdapter(
+internal class ScalingLazyColumnRotaryScrollableAdapter(
     override val scrollableState: ScalingLazyListState
-) : RotaryScrollAdapter {
+) : RotaryScrollableAdapter {
 
     /**
      * Calculates the average item height by averaging the height of visible items.
@@ -189,7 +319,7 @@
  * @return A snap implementation of [RotaryHandler] which is either suitable for low-res or
  * high-res input.
  *
- * @param rotaryScrollAdapter Implementation of [RotaryScrollAdapter], which connects
+ * @param rotaryScrollableAdapter Implementation of [RotaryScrollableAdapter], which connects
  * scrollableState to a rotary input for snapping scroll actions.
  * @param rotaryHaptics Implementation of [RotaryHapticHandler] which handles haptics
  * for rotary usage
@@ -201,7 +331,7 @@
  * @param isLowRes Whether the input is Low-res (a bezel) or high-res(a crown/rsb)
  */
 private fun snapHandler(
-    rotaryScrollAdapter: RotaryScrollAdapter,
+    rotaryScrollableAdapter: RotaryScrollableAdapter,
     rotaryHaptics: RotaryHapticHandler,
     snapOffset: Int,
     maxThresholdDivider: Float,
@@ -213,7 +343,7 @@
             rotaryHaptics = rotaryHaptics,
             snapBehaviourFactory = {
                 RotarySnapHelper(
-                    rotaryScrollAdapter,
+                    rotaryScrollableAdapter,
                     snapOffset,
                 )
             }
@@ -225,24 +355,26 @@
             thresholdBehaviorFactory = {
                 ThresholdBehavior(
                     maxThresholdDivider,
-                    averageItemSize = { rotaryScrollAdapter.averageItemSize() }
+                    averageItemSize = { rotaryScrollableAdapter.averageItemSize() }
                 )
             },
             snapBehaviorFactory = {
                 RotarySnapHelper(
-                    rotaryScrollAdapter,
+                    rotaryScrollableAdapter,
                     snapOffset,
                 )
             },
             scrollBehaviorFactory = {
-                RotaryScrollBehavior(rotaryScrollAdapter.scrollableState)
+                RotaryScrollBehavior(rotaryScrollableAdapter.scrollableState)
             }
         )
     }
 }
 
 /**
- * An abstract class for handling scroll events
+ * An abstract base class for handling scroll events. Has implementations for handling scroll
+ * with/without fling [RotaryScrollHandler] and for handling snap [LowResRotarySnapHandler],
+ * [HighResRotarySnapHandler].
  */
 internal abstract class RotaryHandler {
 
@@ -327,10 +459,10 @@
  * A helper class for snapping with rotary.
  */
 internal class RotarySnapHelper(
-    private val rotaryScrollAdapter: RotaryScrollAdapter,
+    private val rotaryScrollableAdapter: RotaryScrollableAdapter,
     private val snapOffset: Int,
 ) {
-    private var snapTarget: Int = rotaryScrollAdapter.currentItemIndex()
+    private var snapTarget: Int = rotaryScrollableAdapter.currentItemIndex()
     private var sequentialSnap: Boolean = false
 
     private var anim = AnimationState(0f)
@@ -355,10 +487,11 @@
         if (sequentialSnap) {
             snapTarget += moveForElements
         } else {
-            snapTarget = rotaryScrollAdapter.currentItemIndex() + moveForElements
+            snapTarget = rotaryScrollableAdapter.currentItemIndex() + moveForElements
         }
         snapTargetUpdated = true
-        snapTarget = snapTarget.coerceIn(0 until rotaryScrollAdapter.totalItemsCount())
+        snapTarget = snapTarget
+            .coerceIn(0 until rotaryScrollableAdapter.totalItemsCount())
     }
 
     /**
@@ -366,13 +499,13 @@
      */
     suspend fun snapToClosestItem() {
         // Perform the snapping animation
-        rotaryScrollAdapter.scrollableState.scroll(MutatePriority.UserInput) {
+        rotaryScrollableAdapter.scrollableState.scroll(MutatePriority.UserInput) {
             debugLog { "snap to the closest item" }
             var prevPosition = 0f
 
             // Create and execute the snap animation
             AnimationState(0f).animateTo(
-                targetValue = -rotaryScrollAdapter.currentItemOffset(),
+                targetValue = -rotaryScrollableAdapter.currentItemOffset(),
                 animationSpec = tween(durationMillis = 100, easing = FastOutSlowInEasing)
             ) {
                 val animDelta = value - prevPosition
@@ -380,7 +513,7 @@
                 prevPosition = value
             }
             // Update the snap target to ensure consistency
-            snapTarget = rotaryScrollAdapter.currentItemIndex()
+            snapTarget = rotaryScrollableAdapter.currentItemIndex()
         }
     }
 
@@ -393,7 +526,7 @@
      * Returns true if bottom edge was reached
      */
     fun bottomEdgeReached(): Boolean =
-        snapTarget >= rotaryScrollAdapter.totalItemsCount() - 1
+        snapTarget >= rotaryScrollableAdapter.totalItemsCount() - 1
 
     /**
      * Performs snapping to the specified in [updateSnapTarget] element
@@ -401,7 +534,7 @@
     suspend fun snapToTargetItem() {
         if (!sequentialSnap) anim = AnimationState(0f)
 
-        rotaryScrollAdapter.scrollableState.scroll(MutatePriority.UserInput) {
+        rotaryScrollableAdapter.scrollableState.scroll(MutatePriority.UserInput) {
             // If snapTargetUpdated is true -means the target was updated so we
             // need to do snap animation again
             while (snapTargetUpdated) {
@@ -412,12 +545,12 @@
 
                 // First part of animation. Performing it until the target element centered.
                 while (continueFirstScroll) {
-                    latestCenterItem = rotaryScrollAdapter.currentItemIndex()
+                    latestCenterItem = rotaryScrollableAdapter.currentItemIndex()
                     expectedDistance = expectedDistanceTo(snapTarget, snapOffset)
                     debugLog {
                         "expectedDistance = $expectedDistance, " +
                             "scrollableState.centerItemScrollOffset " +
-                            "${rotaryScrollAdapter.currentItemOffset()}"
+                            "${rotaryScrollableAdapter.currentItemOffset()}"
                     }
 
                     continueFirstScroll = false
@@ -441,20 +574,22 @@
                         scrollBy(animDelta)
                         prevPosition = value
 
-                        if (latestCenterItem != rotaryScrollAdapter.currentItemIndex()) {
+                        if (latestCenterItem != rotaryScrollableAdapter.currentItemIndex()) {
                             continueFirstScroll = true
                             cancelAnimation()
                             return@animateTo
                         }
 
-                        debugLog { "centerItemIndex =  ${rotaryScrollAdapter.currentItemIndex()}" }
-                        if (rotaryScrollAdapter.currentItemIndex() == snapTarget) {
+                        debugLog {
+                            "centerItemIndex =  ${rotaryScrollableAdapter.currentItemIndex()}"
+                        }
+                        if (rotaryScrollableAdapter.currentItemIndex() == snapTarget) {
                             debugLog { "Target is near the centre. Cancelling first animation" }
                             debugLog {
                                 "scrollableState.centerItemScrollOffset " +
-                                    "${rotaryScrollAdapter.currentItemOffset()}"
+                                    "${rotaryScrollableAdapter.currentItemOffset()}"
                             }
-                            expectedDistance = -rotaryScrollAdapter.currentItemOffset()
+                            expectedDistance = -rotaryScrollableAdapter.currentItemOffset()
                             continueFirstScroll = false
                             cancelAnimation()
                             return@animateTo
@@ -487,28 +622,28 @@
     }
 
     private fun expectedDistanceTo(index: Int, targetScrollOffset: Int): Float {
-        val averageSize = rotaryScrollAdapter.averageItemSize()
-        val indexesDiff = index - rotaryScrollAdapter.currentItemIndex()
+        val averageSize = rotaryScrollableAdapter.averageItemSize()
+        val indexesDiff = index - rotaryScrollableAdapter.currentItemIndex()
         debugLog { "Average size $averageSize" }
         return (averageSize * indexesDiff) +
-            targetScrollOffset - rotaryScrollAdapter.currentItemOffset()
+            targetScrollOffset - rotaryScrollableAdapter.currentItemOffset()
     }
 }
 
 /**
  * A modifier which handles rotary events.
- * It accepts ScrollHandler as the input - a class that handles the main scroll logic.
+ * It accepts [RotaryHandler] as the input - a class that handles the main scroll logic.
  */
 internal fun Modifier.rotaryHandler(
-    rotaryScrollHandler: RotaryHandler,
+    rotaryHandler: RotaryHandler,
     reverseDirection: Boolean,
     inspectorInfo: InspectorInfo.() -> Unit = debugInspectorInfo {
         name = "rotaryHandler"
-        properties["rotaryScrollHandler"] = rotaryScrollHandler
+        properties["rotaryHandler"] = rotaryHandler
         properties["reverseDirection"] = reverseDirection
     }
 ): Modifier = this then RotaryHandlerElement(
-    rotaryScrollHandler,
+    rotaryHandler,
     reverseDirection,
     inspectorInfo
 )
@@ -949,7 +1084,7 @@
     // Smoothing factor for velocity readings
     private val smoothingConstant: Float = 0.4f,
     private val averageItemSize: () -> Float
-    ) {
+) {
     private val thresholdDividerEasing: Easing = CubicBezierEasing(0.5f, 0.0f, 0.5f, 1.0f)
 
     private val rotaryVelocityTracker = RotaryVelocityTracker()
@@ -1023,18 +1158,18 @@
 }
 
 private data class RotaryHandlerElement(
-    private val rotaryScrollHandler: RotaryHandler,
+    private val rotaryHandler: RotaryHandler,
     private val reverseDirection: Boolean,
     private val inspectorInfo: InspectorInfo.() -> Unit
 ) : ModifierNodeElement<RotaryInputNode>() {
     override fun create(): RotaryInputNode = RotaryInputNode(
-        rotaryScrollHandler,
+        rotaryHandler,
         reverseDirection,
     )
 
     override fun update(node: RotaryInputNode) {
         debugLog { "Update launched!" }
-        node.rotaryScrollHandler = rotaryScrollHandler
+        node.rotaryHandler = rotaryHandler
         node.reverseDirection = reverseDirection
     }
 
@@ -1048,21 +1183,21 @@
 
         other as RotaryHandlerElement
 
-        if (rotaryScrollHandler != other.rotaryScrollHandler) return false
+        if (rotaryHandler != other.rotaryHandler) return false
         if (reverseDirection != other.reverseDirection) return false
 
         return true
     }
 
     override fun hashCode(): Int {
-        var result = rotaryScrollHandler.hashCode()
+        var result = rotaryHandler.hashCode()
         result = 31 * result + reverseDirection.hashCode()
         return result
     }
 }
 
 private class RotaryInputNode(
-    var rotaryScrollHandler: RotaryHandler,
+    var rotaryHandler: RotaryHandler,
     var reverseDirection: Boolean,
 ) : RotaryInputModifierNode, Modifier.Node() {
 
@@ -1077,7 +1212,7 @@
                         "Scroll event received: " +
                             "delta:${it.deltaInPixels}, timestamp:${it.timestamp}"
                     }
-                    rotaryScrollHandler.handleScrollEvent(this, it)
+                    rotaryHandler.handleScrollEvent(this, it)
                 }
         }
     }
diff --git a/work/work-multiprocess/build.gradle b/work/work-multiprocess/build.gradle
index ceb3cb9..2171106 100644
--- a/work/work-multiprocess/build.gradle
+++ b/work/work-multiprocess/build.gradle
@@ -45,7 +45,7 @@
     api(libs.kotlinCoroutinesAndroid)
     api(libs.guavaListenableFuture)
     implementation("androidx.core:core:1.12.0")
-    implementation(project(":concurrent:concurrent-futures-ktx"))
+    implementation("androidx.concurrent:concurrent-futures-ktx:1.2.0-alpha03")
     implementation("androidx.room:room-runtime:2.6.1")
     androidTestImplementation(libs.testExtJunit)
     androidTestImplementation(libs.testCore)
diff --git a/work/work-runtime/api/current.txt b/work/work-runtime/api/current.txt
index bc47ebf..5af96fc 100644
--- a/work/work-runtime/api/current.txt
+++ b/work/work-runtime/api/current.txt
@@ -285,6 +285,7 @@
 
   public static final class OneTimeWorkRequest.Builder extends androidx.work.WorkRequest.Builder<androidx.work.OneTimeWorkRequest.Builder,androidx.work.OneTimeWorkRequest> {
     ctor public OneTimeWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker> workerClass);
+    ctor public OneTimeWorkRequest.Builder(kotlin.reflect.KClass<? extends androidx.work.ListenableWorker> workerClass);
     method public androidx.work.OneTimeWorkRequest.Builder setInputMerger(Class<? extends androidx.work.InputMerger> inputMerger);
   }
 
@@ -342,6 +343,10 @@
     ctor @RequiresApi(26) public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker?> workerClass, java.time.Duration repeatInterval, java.time.Duration flexInterval);
     ctor public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker?> workerClass, long repeatInterval, java.util.concurrent.TimeUnit repeatIntervalTimeUnit);
     ctor public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker?> workerClass, long repeatInterval, java.util.concurrent.TimeUnit repeatIntervalTimeUnit, long flexInterval, java.util.concurrent.TimeUnit flexIntervalTimeUnit);
+    ctor @RequiresApi(26) public PeriodicWorkRequest.Builder(kotlin.reflect.KClass<? extends androidx.work.ListenableWorker> workerClass, java.time.Duration repeatInterval);
+    ctor @RequiresApi(26) public PeriodicWorkRequest.Builder(kotlin.reflect.KClass<? extends androidx.work.ListenableWorker> workerClass, java.time.Duration repeatInterval, java.time.Duration flexInterval);
+    ctor public PeriodicWorkRequest.Builder(kotlin.reflect.KClass<? extends androidx.work.ListenableWorker> workerClass, long repeatInterval, java.util.concurrent.TimeUnit repeatIntervalTimeUnit);
+    ctor public PeriodicWorkRequest.Builder(kotlin.reflect.KClass<? extends androidx.work.ListenableWorker> workerClass, long repeatInterval, java.util.concurrent.TimeUnit repeatIntervalTimeUnit, long flexInterval, java.util.concurrent.TimeUnit flexIntervalTimeUnit);
     method public androidx.work.PeriodicWorkRequest.Builder clearNextScheduleTimeOverride();
     method public androidx.work.PeriodicWorkRequest.Builder setNextScheduleTimeOverride(long nextScheduleTimeOverrideMillis);
   }
diff --git a/work/work-runtime/api/restricted_current.txt b/work/work-runtime/api/restricted_current.txt
index bc47ebf..5af96fc 100644
--- a/work/work-runtime/api/restricted_current.txt
+++ b/work/work-runtime/api/restricted_current.txt
@@ -285,6 +285,7 @@
 
   public static final class OneTimeWorkRequest.Builder extends androidx.work.WorkRequest.Builder<androidx.work.OneTimeWorkRequest.Builder,androidx.work.OneTimeWorkRequest> {
     ctor public OneTimeWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker> workerClass);
+    ctor public OneTimeWorkRequest.Builder(kotlin.reflect.KClass<? extends androidx.work.ListenableWorker> workerClass);
     method public androidx.work.OneTimeWorkRequest.Builder setInputMerger(Class<? extends androidx.work.InputMerger> inputMerger);
   }
 
@@ -342,6 +343,10 @@
     ctor @RequiresApi(26) public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker?> workerClass, java.time.Duration repeatInterval, java.time.Duration flexInterval);
     ctor public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker?> workerClass, long repeatInterval, java.util.concurrent.TimeUnit repeatIntervalTimeUnit);
     ctor public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker?> workerClass, long repeatInterval, java.util.concurrent.TimeUnit repeatIntervalTimeUnit, long flexInterval, java.util.concurrent.TimeUnit flexIntervalTimeUnit);
+    ctor @RequiresApi(26) public PeriodicWorkRequest.Builder(kotlin.reflect.KClass<? extends androidx.work.ListenableWorker> workerClass, java.time.Duration repeatInterval);
+    ctor @RequiresApi(26) public PeriodicWorkRequest.Builder(kotlin.reflect.KClass<? extends androidx.work.ListenableWorker> workerClass, java.time.Duration repeatInterval, java.time.Duration flexInterval);
+    ctor public PeriodicWorkRequest.Builder(kotlin.reflect.KClass<? extends androidx.work.ListenableWorker> workerClass, long repeatInterval, java.util.concurrent.TimeUnit repeatIntervalTimeUnit);
+    ctor public PeriodicWorkRequest.Builder(kotlin.reflect.KClass<? extends androidx.work.ListenableWorker> workerClass, long repeatInterval, java.util.concurrent.TimeUnit repeatIntervalTimeUnit, long flexInterval, java.util.concurrent.TimeUnit flexIntervalTimeUnit);
     method public androidx.work.PeriodicWorkRequest.Builder clearNextScheduleTimeOverride();
     method public androidx.work.PeriodicWorkRequest.Builder setNextScheduleTimeOverride(long nextScheduleTimeOverrideMillis);
   }
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/WorkUpdateTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/WorkUpdateTest.kt
index a453890..158a9b2 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/WorkUpdateTest.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/WorkUpdateTest.kt
@@ -84,13 +84,13 @@
     @MediumTest
     fun constraintsUpdate() = runTest {
         // requiresCharging constraint is faked, so it will never be satisfied
-        val oneTimeWorkRequest = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val oneTimeWorkRequest = OneTimeWorkRequest.Builder(TestWorker::class)
             .setConstraints(Constraints(requiresCharging = true))
             .build()
         workManager.enqueue(oneTimeWorkRequest).result.await()
         val requestId = oneTimeWorkRequest.id
 
-        val updatedRequest = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val updatedRequest = OneTimeWorkRequest.Builder(TestWorker::class)
             .setId(requestId)
             .build()
 
@@ -102,11 +102,11 @@
     @Test
     @MediumTest
     fun updateRunningOneTimeWork() = runTest {
-        val oneTimeWorkRequest = OneTimeWorkRequest.Builder(CompletableWorker::class.java).build()
+        val oneTimeWorkRequest = OneTimeWorkRequest.Builder(CompletableWorker::class).build()
         workManager.enqueue(oneTimeWorkRequest).result.await()
         val worker = workerFactory.await(oneTimeWorkRequest.id) as CompletableWorker
         // requiresCharging constraint is faked, so it will never be satisfied
-        val updatedRequest = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val updatedRequest = OneTimeWorkRequest.Builder(TestWorker::class)
             .setId(oneTimeWorkRequest.id)
             .setConstraints(Constraints(requiresCharging = true))
             .build()
@@ -118,10 +118,10 @@
     @Test
     @MediumTest
     fun failFinished() = runTest {
-        val oneTimeWorkRequest = OneTimeWorkRequest.Builder(TestWorker::class.java).build()
+        val oneTimeWorkRequest = OneTimeWorkRequest.Builder(TestWorker::class).build()
         workManager.enqueue(oneTimeWorkRequest)
         workManager.awaitSuccess(oneTimeWorkRequest.id)
-        val updatedRequest = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val updatedRequest = OneTimeWorkRequest.Builder(TestWorker::class)
             .setId(oneTimeWorkRequest.id)
             .setConstraints(Constraints(requiresCharging = true))
             .build()
@@ -131,10 +131,10 @@
     @Test
     @MediumTest
     fun failWorkDoesntExit() = runTest {
-        val oneTimeWorkRequest = OneTimeWorkRequest.Builder(TestWorker::class.java).build()
+        val oneTimeWorkRequest = OneTimeWorkRequest.Builder(TestWorker::class).build()
         workManager.enqueue(oneTimeWorkRequest)
         workManager.awaitSuccess(oneTimeWorkRequest.id)
-        val updatedRequest = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val updatedRequest = OneTimeWorkRequest.Builder(TestWorker::class)
             .setId(UUID.randomUUID()).build()
         try {
             workManager.updateWork(updatedRequest).await()
@@ -147,13 +147,13 @@
     @Test
     @MediumTest
     fun updateTags() = runTest {
-        val oneTimeWorkRequest = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val oneTimeWorkRequest = OneTimeWorkRequest.Builder(TestWorker::class)
             .setInitialDelay(10, DAYS)
             .addTag("previous")
             .build()
         workManager.enqueue(oneTimeWorkRequest).result.await()
 
-        val updatedWorkRequest = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val updatedWorkRequest = OneTimeWorkRequest.Builder(TestWorker::class)
             .setInitialDelay(10, DAYS)
             .setId(oneTimeWorkRequest.id)
             .addTag("test")
@@ -175,7 +175,7 @@
     @Test
     @MediumTest
     fun updateTagsWhileRunning() = runTest {
-        val request = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val request = OneTimeWorkRequest.Builder(TestWorker::class)
             .setConstraints(Constraints(requiresCharging = true))
             .addTag("original").build()
         workManager.enqueue(request).result.await()
@@ -186,7 +186,7 @@
         }
         // will add startWork task to the serialTaskExecutor queue
         greedyScheduler.onConstraintsStateChanged(request.workSpec, ConstraintsMet)
-        val updatedRequest = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val updatedRequest = OneTimeWorkRequest.Builder(TestWorker::class)
             .setConstraints(Constraints(requiresCharging = true))
             .setId(request.id)
             .addTag("updated")
@@ -204,13 +204,13 @@
     @MediumTest
     fun updateWorkerClass() = runTest {
         // requiresCharging constraint is faked, so it will never be satisfied
-        val oneTimeWorkRequest = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val oneTimeWorkRequest = OneTimeWorkRequest.Builder(TestWorker::class)
             .setConstraints(Constraints(requiresCharging = true))
             .build()
         workManager.enqueue(oneTimeWorkRequest).result.await()
         val requestId = oneTimeWorkRequest.id
 
-        val updatedRequest = OneTimeWorkRequest.Builder(CompletableWorker::class.java)
+        val updatedRequest = OneTimeWorkRequest.Builder(CompletableWorker::class)
             .setId(requestId)
             .build()
 
@@ -225,7 +225,7 @@
     @MediumTest
     fun progressReset() = runTest {
         // requiresCharging constraint is faked, so it will be controlled in the test
-        val request = OneTimeWorkRequest.Builder(ProgressWorker::class.java)
+        val request = OneTimeWorkRequest.Builder(ProgressWorker::class)
             .setConstraints(Constraints(requiresCharging = true))
             .build()
         workManager.enqueue(request).result.await()
@@ -239,7 +239,7 @@
 
         assertThat(info.progress).isEqualTo(TEST_DATA)
 
-        val updatedRequest = OneTimeWorkRequest.Builder(ProgressWorker::class.java)
+        val updatedRequest = OneTimeWorkRequest.Builder(ProgressWorker::class)
             .setId(request.id)
             .addTag("bla")
             .build()
@@ -253,11 +253,11 @@
     @MediumTest
     fun continuationLeafUpdate() = runTest {
         // requiresCharging constraint is faked, so it will never be satisfied
-        val step1 = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val step1 = OneTimeWorkRequest.Builder(TestWorker::class)
             .setConstraints(Constraints(requiresCharging = true)).build()
-        val step2 = OneTimeWorkRequest.Builder(TestWorker::class.java).build()
+        val step2 = OneTimeWorkRequest.Builder(TestWorker::class).build()
         workManager.beginWith(step1).then(step2).enqueue().result.await()
-        val updatedStep2 = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val updatedStep2 = OneTimeWorkRequest.Builder(TestWorker::class)
             .setId(step2.id).addTag("updated").build()
         assertThat(workManager.updateWork(updatedStep2).await()).isEqualTo(APPLIED_IMMEDIATELY)
         val workInfo = workManager.getWorkInfoById(step2.id).await()!!
@@ -269,13 +269,13 @@
     @MediumTest
     fun continuationLeafRoot() = runTest {
         // requiresCharging constraint is faked, so it will never be satisfied
-        val step1 = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val step1 = OneTimeWorkRequest.Builder(TestWorker::class)
             .setConstraints(Constraints(requiresCharging = true)).build()
-        val step2 = OneTimeWorkRequest.Builder(TestWorker::class.java).build()
+        val step2 = OneTimeWorkRequest.Builder(TestWorker::class).build()
         workManager.beginWith(step1).then(step2).enqueue().result.await()
         val workInfo = workManager.getWorkInfoById(step2.id).await()!!
         assertThat(workInfo.state).isEqualTo(State.BLOCKED)
-        val updatedStep1 = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val updatedStep1 = OneTimeWorkRequest.Builder(TestWorker::class)
             .setId(step1.id).build()
         assertThat(workManager.updateWork(updatedStep1).await()).isEqualTo(APPLIED_IMMEDIATELY)
         workManager.awaitSuccess(step2.id)
@@ -285,12 +285,12 @@
     @MediumTest
     fun chainsViaExistingPolicyLeafUpdate() = runTest {
         // requiresCharging constraint is faked, so it will never be satisfied
-        val step1 = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val step1 = OneTimeWorkRequest.Builder(TestWorker::class)
             .setConstraints(Constraints(requiresCharging = true)).build()
-        val step2 = OneTimeWorkRequest.Builder(TestWorker::class.java).build()
+        val step2 = OneTimeWorkRequest.Builder(TestWorker::class).build()
         workManager.enqueueUniqueWork("name", ExistingWorkPolicy.APPEND, step1)
         workManager.enqueueUniqueWork("name", ExistingWorkPolicy.APPEND, step2)
-        val updatedStep2 = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val updatedStep2 = OneTimeWorkRequest.Builder(TestWorker::class)
             .setId(step2.id).addTag("updated").build()
         assertThat(workManager.updateWork(updatedStep2).await()).isEqualTo(APPLIED_IMMEDIATELY)
         val workInfo = workManager.getWorkInfoById(step2.id).await()!!
@@ -302,14 +302,14 @@
     @MediumTest
     fun chainsViaExistingPolicyRootUpdate() = runTest {
         // requiresCharging constraint is faked, so it will never be satisfied
-        val step1 = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val step1 = OneTimeWorkRequest.Builder(TestWorker::class)
             .setConstraints(Constraints(requiresCharging = true)).build()
-        val step2 = OneTimeWorkRequest.Builder(TestWorker::class.java).build()
+        val step2 = OneTimeWorkRequest.Builder(TestWorker::class).build()
         workManager.enqueueUniqueWork("name", ExistingWorkPolicy.APPEND, step1)
         workManager.enqueueUniqueWork("name", ExistingWorkPolicy.APPEND, step2)
         val workInfo = workManager.getWorkInfoById(step2.id).await()!!
         assertThat(workInfo.state).isEqualTo(State.BLOCKED)
-        val updatedStep1 = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val updatedStep1 = OneTimeWorkRequest.Builder(TestWorker::class)
             .setId(step1.id).build()
         assertThat(workManager.updateWork(updatedStep1).await()).isEqualTo(APPLIED_IMMEDIATELY)
         workManager.awaitSuccess(step2.id)
@@ -319,12 +319,11 @@
     @MediumTest
     fun oneTimeWorkToPeriodic() = runTest {
         // requiresCharging constraint is faked, so it will never be satisfied
-        val request = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val request = OneTimeWorkRequest.Builder(TestWorker::class)
             .setConstraints(Constraints(requiresCharging = true)).build()
         workManager.enqueue(request).result.await()
         val updatedRequest =
-            PeriodicWorkRequest.Builder(TestWorker::class.java, 1, DAYS)
-                .build()
+            PeriodicWorkRequest.Builder(TestWorker::class, 1, DAYS).build()
         try {
             workManager.updateWork(updatedRequest).await()
             throw AssertionError()
@@ -337,11 +336,11 @@
     @MediumTest
     fun periodicWorkToOneTime() = runTest {
         // requiresCharging constraint is faked, so it will never be satisfied
-        val request = PeriodicWorkRequest.Builder(TestWorker::class.java, 1, DAYS)
+        val request = PeriodicWorkRequest.Builder(TestWorker::class, 1, DAYS)
             .setConstraints(Constraints(requiresCharging = true))
             .build()
         workManager.enqueue(request).result.await()
-        val updatedRequest = OneTimeWorkRequest.Builder(TestWorker::class.java).build()
+        val updatedRequest = OneTimeWorkRequest.Builder(TestWorker::class).build()
         try {
             workManager.updateWork(updatedRequest).await()
             throw AssertionError()
@@ -353,11 +352,11 @@
     @Test
     @MediumTest
     fun updateRunningPeriodicWorkRequest() = runTest {
-        val request = PeriodicWorkRequest.Builder(CompletableWorker::class.java, 1, DAYS)
+        val request = PeriodicWorkRequest.Builder(CompletableWorker::class, 1, DAYS)
             .addTag("original").build()
         workManager.enqueue(request).result.await()
         val updatedRequest =
-            PeriodicWorkRequest.Builder(CompletableWorker::class.java, 1, DAYS)
+            PeriodicWorkRequest.Builder(CompletableWorker::class, 1, DAYS)
                 .setId(request.id).addTag("updated").build()
         val worker = workerFactory.await(request.id) as CompletableWorker
         assertThat(workManager.updateWork(updatedRequest).await()).isEqualTo(APPLIED_FOR_NEXT_RUN)
@@ -374,14 +373,14 @@
     @MediumTest
     @Test
     fun updatePeriodicWorkAfterFirstPeriod() = runTest {
-        val request = PeriodicWorkRequest.Builder(TestWorker::class.java, 1, DAYS)
+        val request = PeriodicWorkRequest.Builder(TestWorker::class, 1, DAYS)
             .addTag("original").build()
         workManager.enqueue(request).result.await()
         workerFactory.await(request.id)
         workManager.awaitWorkerEnqueued(request.id)
 
         val updatedRequest =
-            PeriodicWorkRequest.Builder(TestWorker::class.java, 1, DAYS)
+            PeriodicWorkRequest.Builder(TestWorker::class, 1, DAYS)
                 // requiresCharging constraint is faked, so it will never be satisfied
                 .setConstraints(Constraints(requiresCharging = true))
                 .setId(request.id).addTag("updated").build()
@@ -398,7 +397,7 @@
     @MediumTest
     @Test
     fun updateRetryingOneTimeWork() = runTest {
-        val request = OneTimeWorkRequest.Builder(RetryWorker::class.java)
+        val request = OneTimeWorkRequest.Builder(RetryWorker::class)
             .setBackoffCriteria(BackoffPolicy.LINEAR, 10, DAYS)
             .build()
         workManager.enqueue(request)
@@ -414,7 +413,7 @@
             request.stringId,
             spec.lastEnqueueTime - delta
         )
-        val updated = OneTimeWorkRequest.Builder(TestWorker::class.java).setId(request.id)
+        val updated = OneTimeWorkRequest.Builder(TestWorker::class).setId(request.id)
             .setBackoffCriteria(BackoffPolicy.LINEAR, 10, DAYS)
             .build()
         workManager.updateWork(updated).await()
@@ -426,7 +425,7 @@
     @MediumTest
     @Test
     fun updateCorrectNextRunTime() = runTest {
-        val request = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val request = OneTimeWorkRequest.Builder(TestWorker::class)
             .setInitialDelay(10, TimeUnit.MINUTES).build()
         val enqueueTime = System.currentTimeMillis()
         workManager.enqueue(request).result.await()
@@ -434,7 +433,7 @@
             request.stringId,
             enqueueTime - TimeUnit.MINUTES.toMillis(5)
         )
-        val updated = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val updated = OneTimeWorkRequest.Builder(TestWorker::class)
             .setInitialDelay(20, TimeUnit.MINUTES)
             .setId(request.id)
             .build()
@@ -451,10 +450,10 @@
     @MediumTest
     @SdkSuppress(minSdkVersion = 23, maxSdkVersion = 25)
     fun testUpdatePeriodicWorker_preservesConstraintTrackingWorker() = runTest {
-        val originRequest = OneTimeWorkRequest.Builder(TestWorker::class.java)
+        val originRequest = OneTimeWorkRequest.Builder(TestWorker::class)
             .setInitialDelay(10, HOURS).build()
         workManager.enqueue(originRequest).result.await()
-        val updateRequest = OneTimeWorkRequest.Builder(RetryWorker::class.java)
+        val updateRequest = OneTimeWorkRequest.Builder(RetryWorker::class)
             .setId(originRequest.id).setInitialDelay(10, HOURS)
             .setConstraints(Constraints(requiresBatteryNotLow = true))
             .build()
@@ -468,12 +467,12 @@
     @Test
     @MediumTest
     fun updateWorkerGeneration() = runTest {
-        val oneTimeWorkRequest = OneTimeWorkRequest.Builder(WorkerWithParam::class.java)
+        val oneTimeWorkRequest = OneTimeWorkRequest.Builder(WorkerWithParam::class)
             .setInitialDelay(10, DAYS)
             .build()
         workManager.enqueue(oneTimeWorkRequest).result.await()
 
-        val updatedWorkRequest = OneTimeWorkRequest.Builder(WorkerWithParam::class.java)
+        val updatedWorkRequest = OneTimeWorkRequest.Builder(WorkerWithParam::class)
             .setId(oneTimeWorkRequest.id)
             .build()
 
@@ -492,13 +491,13 @@
         val nextRunTimeMillis = HOURS.toMillis(10)
 
         val request = PeriodicWorkRequest.Builder(
-            TestWorker::class.java, 1, DAYS
+            TestWorker::class, 1, DAYS
         ).setInitialDelay(2, DAYS).build()
         workManager.enqueue(request).result.await()
 
         workManager.updateWork(
             PeriodicWorkRequest.Builder(
-                TestWorker::class.java, 1, DAYS
+                TestWorker::class, 1, DAYS
             ).setId(request.id)
                 .setNextScheduleTimeOverride(nextRunTimeMillis)
                 .build()
@@ -516,13 +515,13 @@
         val overrideScheduleTimeMillis2 = HOURS.toMillis(12)
 
         val request = PeriodicWorkRequest.Builder(
-            TestWorker::class.java, 1, DAYS
+            TestWorker::class, 1, DAYS
         ).setInitialDelay(2, DAYS).build()
         workManager.enqueue(request).result.await()
 
         workManager.updateWork(
             PeriodicWorkRequest.Builder(
-                TestWorker::class.java, 1, DAYS
+                TestWorker::class, 1, DAYS
             ).setId(request.id)
                 .setNextScheduleTimeOverride(overrideScheduleTimeMillis)
                 .build()
@@ -532,7 +531,7 @@
 
         workManager.updateWork(
             PeriodicWorkRequest.Builder(
-                TestWorker::class.java, 1, DAYS
+                TestWorker::class, 1, DAYS
             ).setId(request.id)
                 .setNextScheduleTimeOverride(overrideScheduleTimeMillis2)
                 .build()
@@ -549,7 +548,7 @@
         val overrideScheduleTimeMillis = HOURS.toMillis(10)
 
         val request = PeriodicWorkRequest.Builder(
-            TestWorker::class.java, 1, DAYS
+            TestWorker::class, 1, DAYS
         ).setBackoffCriteria(BackoffPolicy.LINEAR, HOURS.toMillis(1), HOURS)
             .setInitialDelay(2, DAYS)
             .build()
@@ -558,7 +557,7 @@
 
         workManager.updateWork(
             PeriodicWorkRequest.Builder(
-                TestWorker::class.java, 1, DAYS
+                TestWorker::class, 1, DAYS
             ).setId(request.id)
                 .setNextScheduleTimeOverride(overrideScheduleTimeMillis)
                 .build()
@@ -578,7 +577,7 @@
         val overrideScheduleTimeMillis = HOURS.toMillis(10)
 
         val request = PeriodicWorkRequest.Builder(
-            TestWorker::class.java, 1, DAYS
+            TestWorker::class, 1, DAYS
         ).setInitialDelay(2, DAYS)
             .setNextScheduleTimeOverride(overrideScheduleTimeMillis)
             .build()
@@ -586,7 +585,7 @@
 
         workManager.updateWork(
             PeriodicWorkRequest.Builder(
-                TestWorker::class.java, 1, DAYS
+                TestWorker::class, 1, DAYS
             ).setId(request.id)
                 .clearNextScheduleTimeOverride()
                 .setInitialDelay(2, DAYS)
@@ -610,13 +609,13 @@
         testClock.currentTimeMillis = HOURS.toMillis(5)
 
         val request = PeriodicWorkRequest.Builder(
-            TestWorker::class.java, 1, DAYS
+            TestWorker::class, 1, DAYS
         ).setInitialDelay(2, DAYS).build()
         workManager.enqueue(request).result.await()
 
         workManager.updateWork(
             PeriodicWorkRequest.Builder(
-                TestWorker::class.java, 1, DAYS
+                TestWorker::class, 1, DAYS
             ).setId(request.id)
                 .clearNextScheduleTimeOverride()
                 .build()
diff --git a/work/work-runtime/src/main/java/androidx/work/OneTimeWorkRequest.kt b/work/work-runtime/src/main/java/androidx/work/OneTimeWorkRequest.kt
index 37c4559..0f41311 100644
--- a/work/work-runtime/src/main/java/androidx/work/OneTimeWorkRequest.kt
+++ b/work/work-runtime/src/main/java/androidx/work/OneTimeWorkRequest.kt
@@ -36,6 +36,13 @@
         WorkRequest.Builder<Builder, OneTimeWorkRequest>(workerClass) {
 
         /**
+         * Creates a builder for [OneTimeWorkRequest]s.
+         *
+         * @param workerClass The [ListenableWorker] class to run for this work
+         */
+        constructor(workerClass: KClass<out ListenableWorker>) : this(workerClass.java)
+
+        /**
          * Specifies the [InputMerger] class name for this [OneTimeWorkRequest].
          *
          * Before workers run, they receive input [Data] from their parent workers, as well as
diff --git a/work/work-runtime/src/main/java/androidx/work/PeriodicWorkRequest.kt b/work/work-runtime/src/main/java/androidx/work/PeriodicWorkRequest.kt
index 6fa29f7..200dd41 100644
--- a/work/work-runtime/src/main/java/androidx/work/PeriodicWorkRequest.kt
+++ b/work/work-runtime/src/main/java/androidx/work/PeriodicWorkRequest.kt
@@ -21,6 +21,7 @@
 import androidx.work.impl.utils.toMillisCompat
 import java.time.Duration
 import java.util.concurrent.TimeUnit
+import kotlin.reflect.KClass
 
 /**
  * A [WorkRequest] for repeating work.  This work executes multiple times until it is
@@ -88,6 +89,28 @@
          * may run immediately, at the end of the period, or any time in between so long as the
          * other conditions are satisfied at the time. The run time of the
          * [PeriodicWorkRequest] can be restricted to a flex period within an interval (see
+         * `#Builder(Class, long, TimeUnit, long, TimeUnit)`).
+         *
+         * @param workerClass The [ListenableWorker] class to run for this work
+         * @param repeatInterval The repeat interval in `repeatIntervalTimeUnit` units
+         * @param repeatIntervalTimeUnit The [TimeUnit] for `repeatInterval`
+         */
+        constructor(
+            workerClass: KClass<out ListenableWorker>,
+            repeatInterval: Long,
+            repeatIntervalTimeUnit: TimeUnit
+        ) : super(workerClass.java) {
+            workSpec.setPeriodic(repeatIntervalTimeUnit.toMillis(repeatInterval))
+        }
+
+        /**
+         * Creates a [PeriodicWorkRequest] to run periodically once every interval period. The
+         * [PeriodicWorkRequest] is guaranteed to run exactly one time during this interval
+         * (subject to OS battery optimizations, such as doze mode). The repeat interval must
+         * be greater than or equal to [PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS]. It
+         * may run immediately, at the end of the period, or any time in between so long as the
+         * other conditions are satisfied at the time. The run time of the
+         * [PeriodicWorkRequest] can be restricted to a flex period within an interval (see
          * `#Builder(Class, Duration, Duration)`).
          *
          * @param workerClass The [ListenableWorker] class to run for this work
@@ -102,6 +125,27 @@
         }
 
         /**
+         * Creates a [PeriodicWorkRequest] to run periodically once every interval period. The
+         * [PeriodicWorkRequest] is guaranteed to run exactly one time during this interval
+         * (subject to OS battery optimizations, such as doze mode). The repeat interval must
+         * be greater than or equal to [PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS]. It
+         * may run immediately, at the end of the period, or any time in between so long as the
+         * other conditions are satisfied at the time. The run time of the
+         * [PeriodicWorkRequest] can be restricted to a flex period within an interval (see
+         * `#Builder(Class, Duration, Duration)`).
+         *
+         * @param workerClass The [ListenableWorker] class to run for this work
+         * @param repeatInterval The repeat interval
+         */
+        @RequiresApi(26)
+        constructor(
+            workerClass: KClass<out ListenableWorker>,
+            repeatInterval: Duration
+        ) : super(workerClass.java) {
+            workSpec.setPeriodic(repeatInterval.toMillisCompat())
+        }
+
+        /**
          * Creates a [PeriodicWorkRequest] to run periodically once within the
          * **flex period** of every interval period. See diagram below.  The flex
          * period begins at `repeatInterval - flexInterval` to the end of the interval.
@@ -142,6 +186,40 @@
          * The repeat interval must be greater than or equal to
          * [PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS] and the flex interval must
          * be greater than or equal to [PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS].
+         *  ```
+         * [_____before flex_____|_____flex_____][_____before flex_____|_____flex_____]...
+         * [___cannot run work___|_can run work_][___cannot run work___|_can run work_]...
+         * \____________________________________/\____________________________________/...
+         * interval 1                            interval 2             ...(repeat)
+         * ```
+         *
+         * @param workerClass The [ListenableWorker] class to run for this work
+         * @param repeatInterval The repeat interval in `repeatIntervalTimeUnit` units
+         * @param repeatIntervalTimeUnit The [TimeUnit] for `repeatInterval`
+         * @param flexInterval The duration in `flexIntervalTimeUnit` units for which this
+         * work repeats from the end of the `repeatInterval`
+         * @param flexIntervalTimeUnit The [TimeUnit] for `flexInterval`
+         */
+        constructor(
+            workerClass: KClass<out ListenableWorker>,
+            repeatInterval: Long,
+            repeatIntervalTimeUnit: TimeUnit,
+            flexInterval: Long,
+            flexIntervalTimeUnit: TimeUnit
+        ) : super(workerClass.java) {
+            workSpec.setPeriodic(
+                repeatIntervalTimeUnit.toMillis(repeatInterval),
+                flexIntervalTimeUnit.toMillis(flexInterval)
+            )
+        }
+
+        /**
+         * Creates a [PeriodicWorkRequest] to run periodically once within the
+         * **flex period** of every interval period. See diagram below.  The flex
+         * period begins at `repeatInterval - flexInterval` to the end of the interval.
+         * The repeat interval must be greater than or equal to
+         * [PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS] and the flex interval must
+         * be greater than or equal to [PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS].
          *
          *  ```
          * [_____before flex_____|_____flex_____][_____before flex_____|_____flex_____]...
@@ -165,6 +243,35 @@
         }
 
         /**
+         * Creates a [PeriodicWorkRequest] to run periodically once within the
+         * **flex period** of every interval period. See diagram below.  The flex
+         * period begins at `repeatInterval - flexInterval` to the end of the interval.
+         * The repeat interval must be greater than or equal to
+         * [PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS] and the flex interval must
+         * be greater than or equal to [PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS].
+         *
+         *  ```
+         * [_____before flex_____|_____flex_____][_____before flex_____|_____flex_____]...
+         * [___cannot run work___|_can run work_][___cannot run work___|_can run work_]...
+         * \____________________________________/\____________________________________/...
+         * interval 1                            interval 2             ...(repeat)
+         * ```
+         *
+         * @param workerClass The [ListenableWorker] class to run for this work
+         * @param repeatInterval The repeat interval
+         * @param flexInterval The duration in for which this work repeats from the end of the
+         * `repeatInterval`
+         */
+        @RequiresApi(26)
+        constructor(
+            workerClass: KClass<out ListenableWorker>,
+            repeatInterval: Duration,
+            flexInterval: Duration
+        ) : super(workerClass.java) {
+            workSpec.setPeriodic(repeatInterval.toMillisCompat(), flexInterval.toMillisCompat())
+        }
+
+        /**
          * Overrides the next time this work is scheduled to run.
          *
          * Calling this method sets a specific time at which the work will be scheduled to run next,